export mail : make it event oriented to facilitate worker treatement

This commit is contained in:
aynsix
2019-09-20 16:15:49 +04:00
parent c712cb7cc3
commit 65d7affcb5
5 changed files with 137 additions and 34 deletions

View File

@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Application\Helper\FilesystemAware;
use Alchemy\Phrasea\Application\Helper\NotifierAware; use Alchemy\Phrasea\Application\Helper\NotifierAware;
use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Core\Event\ExportFailureEvent; use Alchemy\Phrasea\Core\Event\ExportFailureEvent;
use Alchemy\Phrasea\Core\Event\ExportMailEvent;
use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator; use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
@@ -193,42 +194,26 @@ class ExportController extends Controller
$token = $this->getTokenManipulator()->createEmailExportToken(serialize($list)); $token = $this->getTokenManipulator()->createEmailExportToken(serialize($list));
if (count($destMails) > 0) { if (count($destMails) > 0) {
//zip documents $emitterId = $this->getAuthenticatedUser()->getId();
\set_export::build_zip(
$this->app,
$token,
$list,
$this->app['tmp.download.path'].'/'. $token->getValue() . '.zip'
);
$remaingEmails = $destMails; $tokenValue = $token->getValue();
$url = $this->app->url('prepare_download', ['token' => $token->getValue(), 'anonymous' => false, 'type' => \Session_Logger::EVENT_EXPORTMAIL]); $url = $this->app->url('prepare_download', ['token' => $token->getValue(), 'anonymous' => false, 'type' => \Session_Logger::EVENT_EXPORTMAIL]);
$user = $this->getAuthenticatedUser(); $params = [
$emitter = new Emitter($user->getDisplayName(), $user->getEmail()); 'url' => $url,
'textmail' => $request->request->get('textmail'),
'reading_confirm' => !!$request->request->get('reading_confirm', false),
'ssttid' => $ssttid = $request->request->get('ssttid', ''),
'lst' => $lst = $request->request->get('lst', ''),
];
foreach ($destMails as $key => $mail) { $this->dispatch(PhraseaEvents::EXPORT_MAIL_CREATE, new ExportMailEvent(
try { $emitterId,
$receiver = new Receiver(null, trim($mail)); $tokenValue,
} catch (InvalidArgumentException $e) { $destMails,
continue; $params
} ));
$mail = MailRecordsExport::create($this->app, $receiver, $emitter, $request->request->get('textmail'));
$mail->setButtonUrl($url);
$mail->setExpiration($token->getExpiration());
$this->deliver($mail, !!$request->request->get('reading_confirm', false));
unset($remaingEmails[$key]);
}
//some mails failed
if (count($remaingEmails) > 0) {
foreach ($remaingEmails as $mail) {
$this->dispatch(PhraseaEvents::EXPORT_MAIL_FAILURE, new ExportFailureEvent($this->getAuthenticatedUser(), $ssttid, $lst, \eventsmanager_notify_downloadmailfail::MAIL_FAIL, $mail));
}
}
} }
return $this->app->json([ return $this->app->json([

View File

@@ -0,0 +1,53 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2019 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Event;
use Symfony\Component\EventDispatcher\Event as SfEvent;
class ExportMailEvent extends SfEvent
{
private $emitterUserId;
private $tokenValue;
/** @var array */
private $destinationMails;
/** @var array */
private $params;
public function __construct($emitterUserId, $tokenValue, array $destMails, array $params)
{
$this->emitterUserId = $emitterUserId;
$this->tokenValue = $tokenValue;
$this->destinationMails = $destMails;
$this->params = $params;
}
public function getTokenValue()
{
return $this->tokenValue;
}
public function getDestinationMails()
{
return $this->destinationMails;
}
public function getEmitterUserId()
{
return $this->emitterUserId;
}
public function getParams()
{
return $this->params;
}
}

View File

@@ -12,7 +12,15 @@
namespace Alchemy\Phrasea\Core\Event\Subscriber; namespace Alchemy\Phrasea\Core\Event\Subscriber;
use Alchemy\Phrasea\Core\Event\ExportFailureEvent; use Alchemy\Phrasea\Core\Event\ExportFailureEvent;
use Alchemy\Phrasea\Core\Event\ExportMailEvent;
use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Model\Entities\Token;
use Alchemy\Phrasea\Model\Repositories\TokenRepository;
use Alchemy\Phrasea\Model\Repositories\UserRepository;
use Alchemy\Phrasea\Notification\Emitter;
use Alchemy\Phrasea\Notification\Mail\MailRecordsExport;
use Alchemy\Phrasea\Notification\Receiver;
class ExportSubscriber extends AbstractNotificationSubscriber class ExportSubscriber extends AbstractNotificationSubscriber
{ {
@@ -39,10 +47,65 @@ class ExportSubscriber extends AbstractNotificationSubscriber
$this->app['event-manager']->notify($params['usr_id'], 'eventsmanager_notify_downloadmailfail', $datas, $mailed); $this->app['event-manager']->notify($params['usr_id'], 'eventsmanager_notify_downloadmailfail', $datas, $mailed);
} }
public function onCreateExportMail(ExportMailEvent $event)
{
$destMails = $event->getDestinationMails();
$params = $event->getParams();
/** @var UserRepository $userRepository */
$userRepository = $this->app['repo.users'];
$user = $userRepository->find($event->getEmitterUserId());
/** @var TokenRepository $tokenRepository */
$tokenRepository = $this->app['repo.tokens'];
/** @var Token $token */
$token = $tokenRepository->findValidToken($event->getTokenValue());
$list = unserialize($token->getData());
//zip documents
\set_export::build_zip(
$this->app,
$token,
$list,
$this->app['tmp.download.path'].'/'. $token->getValue() . '.zip'
);
$remaingEmails = $destMails;
$emitter = new Emitter($user->getDisplayName(), $user->getEmail());
foreach ($destMails as $key => $mail) {
try {
$receiver = new Receiver(null, trim($mail));
} catch (InvalidArgumentException $e) {
continue;
}
$mail = MailRecordsExport::create($this->app, $receiver, $emitter, $params['textmail']);
$mail->setButtonUrl($params['url']);
$mail->setExpiration($token->getExpiration());
$this->deliver($mail, $params['reading_confirm']);
unset($remaingEmails[$key]);
}
//some mails failed
if (count($remaingEmails) > 0) {
foreach ($remaingEmails as $mail) {
$this->app['dispatcher']->dispatch(PhraseaEvents::EXPORT_MAIL_FAILURE, new ExportFailureEvent($user, $params['ssttid'], $params['lst'], \eventsmanager_notify_downloadmailfail::MAIL_FAIL, $mail));
}
}
}
public static function getSubscribedEvents() public static function getSubscribedEvents()
{ {
return [ return [
PhraseaEvents::EXPORT_MAIL_FAILURE => 'onMailExportFailure' PhraseaEvents::EXPORT_MAIL_FAILURE => 'onMailExportFailure',
PhraseaEvents::EXPORT_MAIL_CREATE => 'onCreateExportMail',
]; ];
} }
} }

View File

@@ -48,7 +48,8 @@ final class PhraseaEvents
const BRIDGE_UPLOAD_FAILURE = 'bridge.upload-failure'; const BRIDGE_UPLOAD_FAILURE = 'bridge.upload-failure';
const EXPORT_MAIL_FAILURE = 'export.mail-failure'; const EXPORT_MAIL_FAILURE = 'export.mail-failure';
const EXPORT_CREATE = 'export.create'; const EXPORT_CREATE = 'export.create';
const EXPORT_MAIL_CREATE = 'export.mail-create';
const RECORD_EDIT = 'record.edit'; const RECORD_EDIT = 'record.edit';
const RECORD_UPLOAD = 'record.upload'; const RECORD_UPLOAD = 'record.upload';

View File

@@ -165,7 +165,8 @@ class ExportTest extends \PhraseanetAuthenticatedWebTestCase
*/ */
public function testExportMail() public function testExportMail()
{ {
$this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailRecordsExport'); // deliver method removed in the listener
// $this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailRecordsExport');
$this->getClient()->request('POST', '/prod/export/mail/', [ $this->getClient()->request('POST', '/prod/export/mail/', [
'lst' => $this->getRecord1()->getId(), 'lst' => $this->getRecord1()->getId(),