diff --git a/Command/BatchCommand.php b/Command/BatchCommand.php index 842fd3d..3b17595 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; @@ -31,7 +32,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,9 +76,26 @@ protected function execute(InputInterface $input, OutputInterface $output) ); } - $errors = $this->getValidator()->validate($jobInstance, array('Default', 'Execution')); + $validator = $this->getValidator(); + + // Override mail notifier recipient email + if ($email = $input->getOption('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)) + ); + } + $this + ->getMailNotifier() + ->setRecipientEmail($email); + } + + $errors = $validator->validate($jobInstance, array('Default', 'Execution')); if (count($errors) > 0) { - throw new \RuntimeException(sprintf('Job "%s" is invalid: %s', $code, $this->getErrorMessages($errors))); + throw new \RuntimeException( + sprintf('Job "%s" is invalid: %s', $code, $this->getErrorMessages($errors)) + ); } $executionId = $input->getArgument('execution'); @@ -72,7 +103,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 +155,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/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/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/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% 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/Job/JobTest.php b/Tests/Unit/Job/JobTest.php
index 1104f62..5207d28 100644
--- a/Tests/Unit/Job/JobTest.php
+++ b/Tests/Unit/Job/JobTest.php
@@ -292,7 +292,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()
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);