From c6ecd83b9d85c23e6c5453a228d923bd5fc30c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=A4utli?= Date: Sun, 18 Aug 2013 12:41:55 +0200 Subject: [PATCH 1/5] SwiftMailerHandler in Monolog bridge now able to react to kernel.terminate event --- .../Monolog/Handler/SwiftMailerHandler.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php diff --git a/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php b/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php new file mode 100644 index 0000000000..4dfd18d6bd --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Handler; + +use Monolog\Handler\SwiftMailerHandler as BaseSwiftMailerHandler; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; + +/** + * Extended SwiftMailerHandler that flushes mail queue if necessary + * + * @author Philipp Kräutli + */ +class SwiftMailerHandler extends BaseSwiftMailerHandler +{ + protected $transport; + + protected $instantFlush = false; + + /** + * @param \Swift_Transport $transport + */ + public function setTransport(\Swift_Transport $transport) + { + $this->transport = $transport; + } + + /** + * After the kernel has been terminated we will always flush messages + * + * @param PostResponseEvent $event + */ + public function onKernelTerminate(PostResponseEvent $event) + { + $this->instantFlush = true; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + parent::send($content, $records); + + if ($this->instantFlush) { + $this->flushMemorySpool(); + } + } + + /** + * Flushes the mail queue if a memory spool is used + */ + private function flushMemorySpool() + { + $transport = $this->mailer->getTransport(); + if (!$transport instanceof \Swift_Transport_SpoolTransport) { + return; + } + + $spool = $transport->getSpool(); + if (!$spool instanceof \Swift_MemorySpool) { + return; + } + + if (null == $this->transport) { + throw new \Exception('No transport available to flush mail queue'); + } + + $spool->flushQueue($this->transport); + } +} From 191d3203d094d82dd8c12c8667be2c343b4cccdb Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Mon, 19 Aug 2013 12:15:39 +0200 Subject: [PATCH 2/5] [Validation] Fixed IdentityTranslator to pass correct Locale to MessageSelector --- .../Translation/IdentityTranslator.php | 5 ++- .../Tests/IdentityTranslatorTest.php | 37 +++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Translation/IdentityTranslator.php b/src/Symfony/Component/Translation/IdentityTranslator.php index f30556b588..8564aa7b3c 100644 --- a/src/Symfony/Component/Translation/IdentityTranslator.php +++ b/src/Symfony/Component/Translation/IdentityTranslator.php @@ -21,6 +21,7 @@ namespace Symfony\Component\Translation; class IdentityTranslator implements TranslatorInterface { private $selector; + private $locale; /** * Constructor. @@ -41,6 +42,7 @@ class IdentityTranslator implements TranslatorInterface */ public function setLocale($locale) { + $this->locale = $locale; } /** @@ -50,6 +52,7 @@ class IdentityTranslator implements TranslatorInterface */ public function getLocale() { + return $this->locale ?: \Locale::getDefault(); } /** @@ -69,6 +72,6 @@ class IdentityTranslator implements TranslatorInterface */ public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null) { - return strtr($this->selector->choose((string) $id, (int) $number, $locale), $parameters); + return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters); } } diff --git a/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php b/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php index 435f0c2803..ce60995426 100644 --- a/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php +++ b/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php @@ -29,19 +29,43 @@ class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase /** * @dataProvider getTransChoiceTests */ - public function testTransChoice($expected, $id, $number, $parameters) + public function testTransChoiceWithExplicitLocale($expected, $id, $number, $parameters) { + $translator = new IdentityTranslator(new MessageSelector()); + $translator->setLocale('en'); + + $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters)); + } + + /** + * @dataProvider getTransChoiceTests + */ + public function testTransChoiceWithDefaultLocale($expected, $id, $number, $parameters) + { + \Locale::setDefault('en'); + $translator = new IdentityTranslator(new MessageSelector()); $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters)); } - // noop public function testGetSetLocale() { $translator = new IdentityTranslator(new MessageSelector()); $translator->setLocale('en'); - $translator->getLocale(); + + $this->assertEquals('en', $translator->getLocale()); + } + + public function testGetLocaleReturnsDefaultLocaleIfNotSet() + { + $translator = new IdentityTranslator(new MessageSelector()); + + \Locale::setDefault('en'); + $this->assertEquals('en', $translator->getLocale()); + + \Locale::setDefault('pt_BR'); + $this->assertEquals('pt_BR', $translator->getLocale()); } public function getTransTests() @@ -55,7 +79,12 @@ class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase public function getTransChoiceTests() { return array( - array('There is 10 apples', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 10, array('%count%' => 10)), + array('There is no apple', '{0} There is no apple|{1} There is one apple|]1,Inf] There are %count% apples', 0, array('%count%' => 0)), + array('There is one apple', '{0} There is no apple|{1} There is one apple|]1,Inf] There are %count% apples', 1, array('%count%' => 1)), + array('There are 10 apples', '{0} There is no apple|{1} There is one apple|]1,Inf] There are %count% apples', 10, array('%count%' => 10)), + array('There are 0 apples', 'There is 1 apple|There are %count% apples', 0, array('%count%' => 0)), + array('There is 1 apple', 'There is 1 apple|There are %count% apples', 1, array('%count%' => 1)), + array('There are 10 apples', 'There is 1 apple|There are %count% apples', 10, array('%count%' => 10)), ); } } From 85a9c9d11429b2e5f8d9a5afabba9cdc505b62d7 Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Mon, 19 Aug 2013 05:39:23 +0100 Subject: [PATCH 3/5] [HttpFoundation] Fixed removing a nonexisting namespaced attribute. --- .../Session/Attribute/NamespacedAttributeBag.php | 2 +- .../Session/Attribute/NamespacedAttributeBagTest.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php index 25dcd22869..c0dd358e85 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php +++ b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php @@ -86,7 +86,7 @@ class NamespacedAttributeBag extends AttributeBag $retval = null; $attributes = & $this->resolveAttributePath($name); $name = $this->resolveKey($name); - if (array_key_exists($name, $attributes)) { + if (null !== $attributes && array_key_exists($name, $attributes)) { $retval = $attributes[$name]; unset($attributes[$name]); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php index c11d0d6513..0c46a515a0 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php @@ -143,6 +143,16 @@ class NamespacedAttributeBagTest extends \PHPUnit_Framework_TestCase $this->assertNull($this->bag->get('user.login')); } + public function testRemoveExistingNamespacedAttribute() + { + $this->assertSame('cod', $this->bag->remove('category/fishing/first')); + } + + public function testRemoveNonexistingNamespacedAttribute() + { + $this->assertNull($this->bag->remove('foo/bar/baz')); + } + public function testClear() { $this->bag->clear(); From 62238b87bc2a4948d4c6bc5a788066872500dfd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=A4utli?= Date: Mon, 19 Aug 2013 16:09:48 +0200 Subject: [PATCH 4/5] CS fix --- src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php b/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php index 4dfd18d6bd..29134115f3 100644 --- a/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php @@ -60,17 +60,17 @@ class SwiftMailerHandler extends BaseSwiftMailerHandler */ private function flushMemorySpool() { - $transport = $this->mailer->getTransport(); - if (!$transport instanceof \Swift_Transport_SpoolTransport) { + $mailerTransport = $this->mailer->getTransport(); + if (!$mailerTransport instanceof \Swift_Transport_SpoolTransport) { return; } - $spool = $transport->getSpool(); + $spool = $mailerTransport->getSpool(); if (!$spool instanceof \Swift_MemorySpool) { return; } - if (null == $this->transport) { + if (null === $this->transport) { throw new \Exception('No transport available to flush mail queue'); } From 0723c10239025561895a342c6df1a8ed53ae1501 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Tue, 20 Aug 2013 20:22:08 +0200 Subject: [PATCH 5/5] [Process] Use a consistent way to reset data of the process latest run It is actually useful when cloning or running again a process. --- src/Symfony/Component/Process/Process.php | 38 +++++++++++-------- .../Process/Tests/AbstractProcessTest.php | 21 ++++++++++ .../Tests/SigchildDisabledProcessTest.php | 16 ++++++++ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 91634297d8..cd84cd4420 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -165,17 +165,7 @@ class Process public function __clone() { - $this->callback = null; - $this->exitcode = null; - $this->fallbackExitcode = null; - $this->processInformation = null; - $this->stdout = null; - $this->stderr = null; - $this->pipes = null; - $this->process = null; - $this->status = self::STATUS_READY; - $this->fileHandles = null; - $this->readBytes = null; + $this->resetProcessData(); } /** @@ -231,11 +221,8 @@ class Process throw new RuntimeException('Process is already running'); } + $this->resetProcessData(); $this->starttime = microtime(true); - $this->stdout = ''; - $this->stderr = ''; - $this->incrementalOutputOffset = 0; - $this->incrementalErrorOutputOffset = 0; $this->callback = $this->buildCallback($callback); //Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. @@ -1154,4 +1141,25 @@ class Process } } } + + /** + * Resets data related to the latest run of the process. + */ + private function resetProcessData() + { + $this->starttime = null; + $this->callback = null; + $this->exitcode = null; + $this->fallbackExitcode = null; + $this->processInformation = null; + $this->stdout = null; + $this->stderr = null; + $this->pipes = null; + $this->process = null; + $this->status = self::STATUS_READY; + $this->fileHandles = null; + $this->readBytes = null; + $this->incrementalOutputOffset = 0; + $this->incrementalErrorOutputOffset = 0; + } } diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index 1021746e76..e78374ae3d 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -235,6 +235,27 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertTrue(strlen($process->getOutput()) > 0); } + public function testGetExitCodeIsNullOnStart() + { + $process = $this->getProcess('php -r "usleep(200000);"'); + $this->assertNull($process->getExitCode()); + $process->start(); + $this->assertNull($process->getExitCode()); + $process->wait(); + $this->assertEquals(0, $process->getExitCode()); + } + + public function testGetExitCodeIsNullOnWhenStartingAgain() + { + $process = $this->getProcess('php -r "usleep(200000);"'); + $process->run(); + $this->assertEquals(0, $process->getExitCode()); + $process->start(); + $this->assertNull($process->getExitCode()); + $process->wait(); + $this->assertEquals(0, $process->getExitCode()); + } + public function testGetExitCode() { $process = $this->getProcess('php -m'); diff --git a/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php b/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php index 1e4dc1d0a2..0ec96f4765 100644 --- a/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php +++ b/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php @@ -21,6 +21,22 @@ class SigchildDisabledProcessTest extends AbstractProcessTest parent::testGetExitCode(); } + /** + * @expectedException \Symfony\Component\Process\Exception\RuntimeException + */ + public function testGetExitCodeIsNullOnStart() + { + parent::testGetExitCodeIsNullOnStart(); + } + + /** + * @expectedException \Symfony\Component\Process\Exception\RuntimeException + */ + public function testGetExitCodeIsNullOnWhenStartingAgain() + { + parent::testGetExitCodeIsNullOnWhenStartingAgain(); + } + /** * @expectedException \Symfony\Component\Process\Exception\RuntimeException */