From efd3ae150191151585b7f99780f8cc959e0caa0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Tue, 15 Oct 2013 11:51:35 +0200 Subject: [PATCH 1/5] Provided a configuration to enable/disable batch mail notification --- DependencyInjection/Configuration.php | 1 + DependencyInjection/OroBatchExtension.php | 5 +++++ Resources/config/services.yml | 3 --- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index cdac8c2..5acb06b 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -22,6 +22,7 @@ public function getConfigTreeBuilder() $root ->children() + ->booleanNode('enable_mail_notification')->defaultFalse()->end() ->scalarNode('sender_email')->defaultValue('mailer@bap.com')->end() ->end() ->end(); diff --git a/DependencyInjection/OroBatchExtension.php b/DependencyInjection/OroBatchExtension.php index 93b74a6..d63dada 100644 --- a/DependencyInjection/OroBatchExtension.php +++ b/DependencyInjection/OroBatchExtension.php @@ -25,5 +25,10 @@ public function load(array $configs, ContainerBuilder $container) $loader->load('services.yml'); $container->setParameter('oro_batch.mail_notifier.sender_email', $config['sender_email']); + if ($config['enable_mail_notification']) { + $container + ->getDefinition('oro_batch.mail_notifier') + ->addTag('oro_batch.notifier'); + } } } diff --git a/Resources/config/services.yml b/Resources/config/services.yml index e334951..99de3fb 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -51,9 +51,6 @@ services: - @twig - @mailer - %oro_batch.mail_notifier.sender_email% - # There is no need to send email on each job - # tags: - # - { name: oro_batch.notifier } oro_batch.step_factory: class: %oro_batch.step_factory.class% From b99cf7d98623c892afc5afc039fc53033dfce4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Tue, 15 Oct 2013 12:22:38 +0200 Subject: [PATCH 2/5] Override batch notification recipient email --- Command/BatchCommand.php | 32 ++++++++++- Notification/MailNotifier.php | 35 +++++++++--- Resources/views/Mails/notification.html.twig | 2 - Resources/views/Mails/notification.txt.twig | 4 +- Tests/Unit/Notification/MailNotifierTest.php | 58 +++++++++++++++++++- 5 files changed, 116 insertions(+), 15 deletions(-) diff --git a/Command/BatchCommand.php b/Command/BatchCommand.php index 842fd3d..0218aef 100644 --- a/Command/BatchCommand.php +++ b/Command/BatchCommand.php @@ -31,7 +31,20 @@ protected function configure() ->setDescription('Launch a registered job instance') ->addArgument('code', InputArgument::REQUIRED, 'Job instance code') ->addArgument('execution', InputArgument::OPTIONAL, 'Job execution id') - ->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Override job configuration (formatted as json. ie: php app/console oro:batch:job -c \'[{"reader":{"filePath":"/tmp/foo.csv"}}]\' acme_product_import)'); + ->addOption( + 'config', + 'c', + InputOption::VALUE_REQUIRED, + 'Override job configuration (formatted as json. ie: ' . + 'php app/console oro:batch:job -c \'[{"reader":{"filePath":"/tmp/foo.csv"}}]\' ' . + 'acme_product_import)' + ) + ->addOption( + 'email', + null, + InputOption::VALUE_REQUIRED, + 'The email to notify at the end of the job execution' + ); } /** @@ -62,6 +75,13 @@ protected function execute(InputInterface $input, OutputInterface $output) ); } + // Override mail notifier recipient email + if ($email = $input->getOption('email')) { + $this + ->getMailNotifier() + ->setRecipientEmail($email); + } + $errors = $this->getValidator()->validate($jobInstance, array('Default', 'Execution')); if (count($errors) > 0) { throw new \RuntimeException(sprintf('Job "%s" is invalid: %s', $code, $this->getErrorMessages($errors))); @@ -72,7 +92,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $jobExecution = $this->getEntityManager()->getRepository('OroBatchBundle:JobExecution')->find($executionId); if (!$jobExecution) { throw new \InvalidArgumentException(sprintf('Could not find job execution "%s".', $id)); - } + } if (!$jobExecution->getStatus()->isStarting()) { throw new \RuntimeException( sprintf('Job execution "%s" has invalid status: %s', $executionId, $jobExecution->getStatus()) @@ -124,6 +144,14 @@ protected function getValidator() return $this->getContainer()->get('validator'); } + /** + * @return Validator + */ + protected function getMailNotifier() + { + return $this->getContainer()->get('oro_batch.mail_notifier'); + } + /** * @return \Oro\Bundle\BatchBundle\Connector\ConnectorRegistry */ diff --git a/Notification/MailNotifier.php b/Notification/MailNotifier.php index 289a81d..4fabd07 100644 --- a/Notification/MailNotifier.php +++ b/Notification/MailNotifier.php @@ -37,6 +37,11 @@ class MailNotifier implements Notifier */ protected $senderEmail; + /** + * @var string $recipientEmail + */ + protected $recipientEmail; + /** * @param BatchLogHandler $logger * @param SecurityContextInterface $securityContext @@ -58,18 +63,30 @@ public function __construct( $this->senderEmail = $senderEmail; } + /** + * Set the recipient email + * + * @param string $recipientEmail + * + * @return MailNotifier + */ + public function setRecipientEmail($recipientEmail) + { + $this->recipientEmail = $recipientEmail; + + return $this; + } + /** * {@inheritdoc} */ public function notify(JobExecution $jobExecution) { - $user = $this->getUser(); - if (!$user) { + if (null === $email = $this->getEmail()) { return; } $parameters = array( - 'user' => $user, 'jobExecution' => $jobExecution, 'log' => $this->logger->getFilename(), ); @@ -80,7 +97,7 @@ public function notify(JobExecution $jobExecution) $message = $this->mailer->createMessage(); $message->setSubject('Job has been executed'); $message->setFrom($this->senderEmail); - $message->setTo($user->getEmail()); + $message->setTo($email); $message->setBody($txtBody, 'text/plain'); $message->addPart($htmlBody, 'text/html'); @@ -90,10 +107,14 @@ public function notify(JobExecution $jobExecution) /** * Get the current authenticated user * - * @return null|UserInterface + * @return null|string */ - private function getUser() + private function getEmail() { + if ($this->recipientEmail) { + return $this->recipientEmail; + } + if (null === $token = $this->securityContext->getToken()) { return; } @@ -102,6 +123,6 @@ private function getUser() return; } - return $user; + return $user->getEmail(); } } diff --git a/Resources/views/Mails/notification.html.twig b/Resources/views/Mails/notification.html.twig index 2621632..4735588 100644 --- a/Resources/views/Mails/notification.html.twig +++ b/Resources/views/Mails/notification.html.twig @@ -1,5 +1,3 @@ -

{{ user.firstName }} {{ user.lastName }},

-

Akeneo successfully completed your batch {{ jobExecution.jobInstance.type }}.

diff --git a/Resources/views/Mails/notification.txt.twig b/Resources/views/Mails/notification.txt.twig index 19aaac6..9a31e9a 100644 --- a/Resources/views/Mails/notification.txt.twig +++ b/Resources/views/Mails/notification.txt.twig @@ -1,5 +1,3 @@ -{{ user.firstName }} {{ user.lastName }}, - Akeneo successfully completed your batch {{ jobExecution.jobInstance.type }}. Started on {{ jobExecution.startTime|date("Y-m-d") }} at {{ jobExecution.startTime|date("H:i:s") }}. @@ -12,5 +10,5 @@ Results: - {{ stepExecution.writeCount }} item(s) written {% endfor %} --- +-- Oro Platform diff --git a/Tests/Unit/Notification/MailNotifierTest.php b/Tests/Unit/Notification/MailNotifierTest.php index c7b427b..6258322 100644 --- a/Tests/Unit/Notification/MailNotifierTest.php +++ b/Tests/Unit/Notification/MailNotifierTest.php @@ -51,7 +51,6 @@ public function testNotifyWithLoggedInUserEmail() $jobExecution = $this->getDisabledConstructorMock('Oro\Bundle\BatchBundle\Entity\JobExecution'); $parameters = array( - 'user' => $user, 'jobExecution' => $jobExecution, 'log' => '/tmp/foo.log', ); @@ -102,6 +101,63 @@ public function testNotifyWithLoggedInUserEmail() $this->notifier->notify($jobExecution); } + public function testNotifyIfRecipientEmailIsSet() + { + $this->handler + ->expects($this->once()) + ->method('getFilename') + ->will($this->returnValue('/tmp/foo.log')); + + $jobExecution = $this->getDisabledConstructorMock('Oro\Bundle\BatchBundle\Entity\JobExecution'); + $parameters = array( + 'jobExecution' => $jobExecution, + 'log' => '/tmp/foo.log', + ); + $this->twig + ->expects($this->exactly(2)) + ->method('render') + ->will( + $this->returnValueMap( + array( + array('OroBatchBundle:Mails:notification.txt.twig', $parameters, 'notification'), + array('OroBatchBundle:Mails:notification.html.twig', $parameters, '

notification

'), + ) + ) + ); + + $message = $this->getDisabledConstructorMock('\Swift_Message'); + $this->mailer + ->expects($this->once()) + ->method('createMessage') + ->will($this->returnValue($message)); + + $message->expects($this->once()) + ->method('setSubject') + ->with('Job has been executed'); + + $message->expects($this->once()) + ->method('setFrom') + ->with('no-reply@example.com'); + + $message->expects($this->once()) + ->method('setTo') + ->with('patricia.jekyll@example.com'); + $message->expects($this->once()) + ->method('setBody') + ->with('notification', 'text/plain'); + $message->expects($this->once()) + ->method('addPart') + ->with('

notification

', 'text/html'); + + $this->mailer + ->expects($this->once()) + ->method('send') + ->with($message); + + $this->notifier->setRecipientEmail('patricia.jekyll@example.com'); + $this->notifier->notify($jobExecution); + } + public function testDoNotNotifyIfNoUserLoggedIn() { $token = $this->getTokenMock(null); From 6912e8e5b8324aec0611539d041f785f18b8d39f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Tue, 15 Oct 2013 16:35:35 +0200 Subject: [PATCH 3/5] Validate the email option of the batch command --- Command/BatchCommand.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Command/BatchCommand.php b/Command/BatchCommand.php index 0218aef..5d1fd12 100644 --- a/Command/BatchCommand.php +++ b/Command/BatchCommand.php @@ -9,6 +9,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\Validator; +use Symfony\Component\Validator\Constraints as Assert; use Monolog\Handler\StreamHandler; use Doctrine\ORM\EntityManager; use Oro\Bundle\BatchBundle\Entity\JobExecution; @@ -75,16 +76,24 @@ protected function execute(InputInterface $input, OutputInterface $output) ); } + $validator = $this->getValidator(); + // Override mail notifier recipient email if ($email = $input->getOption('email')) { + if ($errors = $validator->validateValue($email, new Assert\Email())) { + throw new \RuntimeException( + sprintf('Email "%s" is invalid: %s', $email, $this->getErrorMessages($errors)) + ); + } $this ->getMailNotifier() ->setRecipientEmail($email); } - $errors = $this->getValidator()->validate($jobInstance, array('Default', 'Execution')); - if (count($errors) > 0) { - throw new \RuntimeException(sprintf('Job "%s" is invalid: %s', $code, $this->getErrorMessages($errors))); + if ($errors = $validator->validate($jobInstance, array('Default', 'Execution'))) { + throw new \RuntimeException( + sprintf('Job "%s" is invalid: %s', $code, $this->getErrorMessages($errors)) + ); } $executionId = $input->getArgument('execution'); From e9a70675a640b3723f60ce0a560c73845e3529cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Wed, 16 Oct 2013 09:36:39 +0200 Subject: [PATCH 4/5] Fixed batch command validations --- Command/BatchCommand.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Command/BatchCommand.php b/Command/BatchCommand.php index 5d1fd12..3b17595 100644 --- a/Command/BatchCommand.php +++ b/Command/BatchCommand.php @@ -80,7 +80,8 @@ protected function execute(InputInterface $input, OutputInterface $output) // Override mail notifier recipient email if ($email = $input->getOption('email')) { - if ($errors = $validator->validateValue($email, new Assert\Email())) { + $errors = $validator->validateValue($email, new Assert\Email()); + if (count($errors) > 0) { throw new \RuntimeException( sprintf('Email "%s" is invalid: %s', $email, $this->getErrorMessages($errors)) ); @@ -90,7 +91,8 @@ protected function execute(InputInterface $input, OutputInterface $output) ->setRecipientEmail($email); } - if ($errors = $validator->validate($jobInstance, array('Default', 'Execution'))) { + $errors = $validator->validate($jobInstance, array('Default', 'Execution')); + if (count($errors) > 0) { throw new \RuntimeException( sprintf('Job "%s" is invalid: %s', $code, $this->getErrorMessages($errors)) ); From cdee99f05e7e79980995cf97de1f51ad143ffc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Fri, 18 Oct 2013 15:51:40 +0200 Subject: [PATCH 5/5] Fixed Job tests --- Tests/Unit/Job/JobTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Unit/Job/JobTest.php b/Tests/Unit/Job/JobTest.php index 5401352..5478cb4 100644 --- a/Tests/Unit/Job/JobTest.php +++ b/Tests/Unit/Job/JobTest.php @@ -295,7 +295,7 @@ public function testAddStep() $this->job->addStep('name1', $mockStep1); $this->job->addStep('name2', $mockStep2); - $this->assertEquals(array('name1' => $mockStep1, 'name2' => $mockStep2), $this->job->getSteps()); + $this->assertEquals(array($mockStep1, $mockStep2), $this->job->getSteps()); } public function testSetSteps()