First implementation

This commit is contained in:
Romain Neutron
2012-10-23 14:55:41 +02:00
parent 4661a02e1f
commit b5980ab866
18 changed files with 326 additions and 30 deletions

View File

@@ -20,6 +20,7 @@ use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider; use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider;
use Alchemy\Phrasea\Core\Provider\FtpServiceProvider; use Alchemy\Phrasea\Core\Provider\FtpServiceProvider;
use Alchemy\Phrasea\Core\Provider\GeonamesServiceProvider; use Alchemy\Phrasea\Core\Provider\GeonamesServiceProvider;
use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider;
use Alchemy\Phrasea\Core\Provider\ORMServiceProvider; use Alchemy\Phrasea\Core\Provider\ORMServiceProvider;
use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider; use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider;
use Alchemy\Phrasea\Core\Provider\TaskManagerServiceProvider; use Alchemy\Phrasea\Core\Provider\TaskManagerServiceProvider;
@@ -38,6 +39,7 @@ use Silex\Application as SilexApplication;
use Silex\Provider\MonologServiceProvider; use Silex\Provider\MonologServiceProvider;
use Silex\Provider\SessionServiceProvider; use Silex\Provider\SessionServiceProvider;
use Silex\Provider\TwigServiceProvider; use Silex\Provider\TwigServiceProvider;
use Silex\Provider\SwiftmailerServiceProvider;
use Silex\Provider\UrlGeneratorServiceProvider; use Silex\Provider\UrlGeneratorServiceProvider;
use Silex\Provider\ValidatorServiceProvider; use Silex\Provider\ValidatorServiceProvider;
use Unoconv\UnoconvServiceProvider; use Unoconv\UnoconvServiceProvider;
@@ -126,6 +128,7 @@ class Application extends SilexApplication
$this->register(new MediaVorusServiceProvider()); $this->register(new MediaVorusServiceProvider());
$this->register(new MonologServiceProvider()); $this->register(new MonologServiceProvider());
$this->register(new MP4BoxServiceProvider()); $this->register(new MP4BoxServiceProvider());
$this->register(new NotificationDelivererServiceProvider());
$this->register(new ORMServiceProvider()); $this->register(new ORMServiceProvider());
$this->register(new PhraseanetServiceProvider()); $this->register(new PhraseanetServiceProvider());
$this->register(new PHPExiftoolServiceProvider()); $this->register(new PHPExiftoolServiceProvider());
@@ -139,10 +142,41 @@ class Application extends SilexApplication
$this->register(new UnicodeServiceProvider()); $this->register(new UnicodeServiceProvider());
$this->register(new ValidatorServiceProvider()); $this->register(new ValidatorServiceProvider());
$this->register(new XPDFServiceProvider()); $this->register(new XPDFServiceProvider());
$this->register(new SwiftmailerServiceProvider());
$this['swiftmailer.transport'] = $this->share(function ($app) {
$transport = new \Swift_Transport_MailTransport(
new \Swift_Transport_SimpleMailInvoker(),
$app['swiftmailer.transport.eventdispatcher']
);
// $transport = new \Swift_Transport_EsmtpTransport(
// $app['swiftmailer.transport.buffer'],
// array($app['swiftmailer.transport.authhandler']),
// $app['swiftmailer.transport.eventdispatcher']
// );
//
// $options = $app['swiftmailer.options'] = array_replace(array(
// 'host' => 'localhost',
// 'port' => 25,
// 'username' => '',
// 'password' => '',
// 'encryption' => null,
// 'auth_mode' => null,
// ), $app['swiftmailer.options']);
//
// $transport->setHost($options['host']);
// $transport->setPort($options['port']);
// $transport->setEncryption($options['encryption']);
// $transport->setUsername($options['username']);
// $transport->setPassword($options['password']);
// $transport->setAuthMode($options['auth_mode']);
return $transport;
});
// $this->register(new \Silex\Provider\HttpCacheServiceProvider()); // $this->register(new \Silex\Provider\HttpCacheServiceProvider());
// $this->register(new \Silex\Provider\SecurityServiceProvider()); // $this->register(new \Silex\Provider\SecurityServiceProvider());
// $this->register(new \Silex\Provider\SwiftmailerServiceProvider());
$this['imagine.factory'] = $this->share(function(Application $app) { $this['imagine.factory'] = $this->share(function(Application $app) {
if ($app['phraseanet.registry']->get('GV_imagine_driver') != '') { if ($app['phraseanet.registry']->get('GV_imagine_driver') != '') {

View File

@@ -198,7 +198,7 @@ class Install extends Command
do { do {
$email = $dialog->ask($output, 'Please provide a valid e-mail address : '); $email = $dialog->ask($output, 'Please provide a valid e-mail address : ');
} while (!\mail::validateEmail($email)); } while (!\Swift_Validate::email($email));
do { do {
$password = $dialog->ask($output, 'Please provide a password (6 character min) : '); $password = $dialog->ask($output, 'Please provide a password (6 character min) : ');
@@ -206,7 +206,7 @@ class Install extends Command
$output->writeln("\n\t<info>Email / Password successfully set</info>\n"); $output->writeln("\n\t<info>Email / Password successfully set</info>\n");
} elseif ($input->getOption('email') && $input->getOption('password')) { } elseif ($input->getOption('email') && $input->getOption('password')) {
if (!\mail::validateEmail($input->getOption('email'))) { if (!\Swift_Validate::email($input->getOption('email'))) {
throw new \RuntimeException('Invalid email addess'); throw new \RuntimeException('Invalid email addess');
} }
$email = $input->getOption('email'); $email = $input->getOption('email');

View File

@@ -11,6 +11,8 @@
namespace Alchemy\Phrasea\Controller\Admin; namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Notification\Receiver;
use Alchemy\Phrasea\Notification\Mail\MailTest;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface; use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@@ -181,8 +183,15 @@ class Dashboard implements ControllerProviderInterface
$app->abort(400, 'Bad request missing email parameter'); $app->abort(400, 'Bad request missing email parameter');
}; };
if (\mail::mail_test($app, $mail)) { try {
$receiver = new Receiver(null, $mail);
$mail = MailTest::create($app, $receiver);
$app['notification.deliverer']->deliver($mail);
$app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']);
return $app->redirect('/admin/dashboard/?email=sent'); return $app->redirect('/admin/dashboard/?email=sent');
} catch (\Exception $e) {
exit($e->getMessage());
} }
return $app->redirect('/admin/dashboard/?email=error'); return $app->redirect('/admin/dashboard/?email=error');

View File

@@ -538,7 +538,7 @@ class Users implements ControllerProviderInterface
if ($row) { if ($row) {
if (\PHPMailer::ValidateAddress($row['usr_mail'])) { if (\Swift_Validate::email($row['usr_mail'])) {
foreach ($bases as $bas => $isok) { foreach ($bases as $bas => $isok) {
if ($isok) { if ($isok) {
$accept .= '<li>' . \phrasea::bas_names($bas, $app) . "</li>\n"; $accept .= '<li>' . \phrasea::bas_names($bas, $app) . "</li>\n";

View File

@@ -507,7 +507,7 @@ class Push implements ControllerProviderInterface
if (!$request->request->get('email')) if (!$request->request->get('email'))
throw new ControllerException(_('Email is required')); throw new ControllerException(_('Email is required'));
if (!\mail::validateEmail($request->request->get('email'))) if (!\Swift_Validate::email($request->request->get('email')))
throw new ControllerException(_('Email is invalid')); throw new ControllerException(_('Email is invalid'));
} catch (ControllerException $e) { } catch (ControllerException $e) {
$result['message'] = $e->getMessage(); $result['message'] = $e->getMessage();

View File

@@ -285,7 +285,7 @@ class Account implements ControllerProviderInterface
} catch (\Exception $e) { } catch (\Exception $e) {
return $app->redirect('/account/reset-email/?notice=bad-password'); return $app->redirect('/account/reset-email/?notice=bad-password');
} }
if (!\PHPMailer::ValidateAddress($email)) { if (!\Swift_Validate::email($email)) {
return $app->redirect('/account/reset-email/?notice=mail-invalid'); return $app->redirect('/account/reset-email/?notice=mail-invalid');
} }

View File

@@ -275,7 +275,7 @@ class Login implements ControllerProviderInterface
\random::removeToken($app, $code); \random::removeToken($app, $code);
if (\PHPMailer::ValidateAddress($user->get_email())) { if (\Swift_Validate::email($user->get_email())) {
if (count($user->ACL()->get_granted_base()) > 0) { if (count($user->ACL()->get_granted_base()) > 0) {
\mail::mail_confirm_registered($app, $user->get_email()); \mail::mail_confirm_registered($app, $user->get_email());
} }
@@ -313,7 +313,7 @@ class Login implements ControllerProviderInterface
public function renewPassword(Application $app, Request $request) public function renewPassword(Application $app, Request $request)
{ {
if (null !== $mail = $request->request->get('mail')) { if (null !== $mail = $request->request->get('mail')) {
if (!\PHPMailer::ValidateAddress($mail)) { if (!\Swift_Validate::email($mail)) {
return $app->redirect($app['url_generator']->generate('login_forgot_password', array('error' => 'invalidmail'))); return $app->redirect($app['url_generator']->generate('login_forgot_password', array('error' => 'invalidmail')));
} }
@@ -573,7 +573,7 @@ class Login implements ControllerProviderInterface
$needed['form_password'] = 'pass-invalid'; $needed['form_password'] = 'pass-invalid';
} }
if (false === \PHPMailer::ValidateAddress($email = $request->request->get('form_email'))) { if (false === \Swift_Validate::email($email = $request->request->get('form_email'))) {
$needed['form_email'] = 'mail-invalid'; $needed['form_email'] = 'mail-invalid';
} }

View File

@@ -0,0 +1,21 @@
<?php
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Notification\Deliverer;
use Silex\Application;
use Silex\ServiceProviderInterface;
class NotificationDelivererServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['notification.deliverer'] = $app->share(function($app) {
return new Deliverer($app['mailer'], $app['phraseanet.registry']);
});
}
public function boot(Application $app)
{
}
}

View File

@@ -515,7 +515,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper
$parm = $request->get_parms_from_serialized_datas($infos, 'user_infos'); $parm = $request->get_parms_from_serialized_datas($infos, 'user_infos');
if ($parm['email'] && !\mail::validateEmail($parm['email'])) { if ($parm['email'] && !\Swift_Validate::email($parm['email'])) {
throw new \Exception_InvalidArgument(_('Email addess is not valid')); throw new \Exception_InvalidArgument(_('Email addess is not valid'));
} }

View File

@@ -146,7 +146,7 @@ class Manage extends Helper
{ {
$email = $this->request->get('value'); $email = $this->request->get('value');
if (!\mail::validateEmail($email)) { if ( ! \Swift_Validate::email($email)) {
throw new \Exception_InvalidArgument(_('Invalid mail address')); throw new \Exception_InvalidArgument(_('Invalid mail address'));
} }

View File

@@ -0,0 +1,47 @@
<?php
namespace Alchemy\Phrasea\Notification;
use Alchemy\Phrasea\Notification\Mail\MailInterface;
class Deliverer
{
/**
* @var \Swift_Mailer
*/
private $mailer;
/**
*
* @var \registry
*/
private $registry;
public function __construct(\Swift_Mailer $mailer, \registry $registry)
{
$this->mailer = $mailer;
$this->registry = $registry;
}
public function deliver(MailInterface $mail)
{
if (!$mail->receiver()) {
throw new \LogicException('You should provide a receiver for a mail notification');
}
$prefix = $this->registry->get('GV_mail_prefix') ? ($this->registry->get('GV_mail_prefix') . ' ') : null;
$message = \Swift_Message::newInstance($prefix . $mail->subject(), $mail->renderHTML(), 'text/html', 'utf-8');
$message->addPart($mail->message(), 'text/plain', 'utf-8');
$message->setFrom($this->registry->get('GV_defaulmailsenderaddr', 'no-reply@phraseanet.com'), $this->registry->get('GV_homeTitle', 'Phraseanet'));
$message->setTo($mail->receiver()->email(), $mail->receiver()->name());
if ($mail->emitter()) {
$message->setReplyTo($mail->emitter()->email(), $mail->emitter()->name());
}
$this->mailer->send($message);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Alchemy\Phrasea\Notification;
class Emitter
{
private $name;
private $email;
public function __construct($name, $email)
{
$this->name = $name;
$this->email = $email;
}
public function name()
{
return $this->name;
}
public function email()
{
return $this->email;
}
public static function fromUser(\User_Adapter $user)
{
return new static($user->get_display_name(), $user->get_email());
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Alchemy\Phrasea\Notification\Mail;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Notification\Emitter;
use Alchemy\Phrasea\Notification\Receiver;
abstract class AbstractMail implements MailInterface
{
private $twig;
protected $registry;
private $emitter;
private $receiver;
private $message;
public function __construct(\Twig_Environment $twig, \registry $registry, Receiver $receiver, Emitter $emitter = null, $message = null)
{
$this->twig = $twig;
$this->registry = $registry;
$this->emitter = $emitter;
$this->receiver = $receiver;
$this->message = $message;
}
public function renderHTML()
{
return $this->twig->render('email-template.html.twig', array(
'phraseanetURL' => $this->phraseanetURL(),
'logoUrl' => $this->logoUrl(),
'logoText' => $this->logoText(),
'subject' => $this->subject(),
'senderName' => $this->emitter() ? $this->emitter()->getName() : null,
'senderMail' => $this->emitter() ? $this->emitter()->getEmail() : null,
'messageText' => $this->message(),
'buttonUrl' => $this->buttonURL(),
'buttonText' => $this->buttonText(),
));
}
public function phraseanetURL()
{
return $this->registry->get('GV_ServerName');
}
public function logoUrl()
{
return;
}
public function logoText()
{
return $this->registry->get('GV_homeTitle');
}
public function emitter()
{
return $this->emitter;
}
public function receiver()
{
return $this->receiver;
}
abstract public function subject();
abstract public function message();
abstract public function buttonText();
abstract public function buttonURL();
public static function create(Application $app, Receiver $receiver, Emitter $emitter = null, $message = null)
{
return new static($app['twig'], $app['phraseanet.registry'], $receiver, $emitter, $message);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Alchemy\Phrasea\Notification\Mail;
use Alchemy\Phrasea\Notification\Emitter;
use Alchemy\Phrasea\Notification\Receiver;
interface MailInterface
{
/**
* @return Emitter
*/
public function emitter();
/**
* @return Receiver
*/
public function receiver();
public function subject();
public function message();
public function renderHTML();
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Alchemy\Phrasea\Notification\Mail;
class MailTest extends AbstractMail
{
public function subject()
{
return _('mail:: test d\'envoi d\'email');
}
public function message()
{
return sprintf(
_('Ce mail est un test d\'envoi de mail depuis %s'), $this->registry->get('GV_ServerName')
);
}
public function buttonText()
{
return _('Return to Phraseanet');
}
public function buttonURL()
{
return $this->registry->get('GV_ServerName');
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Alchemy\Phrasea\Notification;
class Receiver
{
private $name;
private $email;
public function __construct($name, $email)
{
$this->name = $name;
$this->email = $email;
}
public function name()
{
return $this->name;
}
public function email()
{
return $this->email;
}
public static function fromUser(\User_Adapter $user)
{
return new static($user->get_display_name(), $user->get_email());
}
}

View File

@@ -188,14 +188,9 @@ class mail
return self::send_mail($app, $subject, $body, $to); return self::send_mail($app, $subject, $body, $to);
} }
public static function validateEmail($email)
{
return PHPMailer::ValidateAddress($email);
}
public static function send_mail(Application $app, $subject, $body, $to, $from = false, $files = array(), $reading_confirm_to = false) public static function send_mail(Application $app, $subject, $body, $to, $from = false, $files = array(), $reading_confirm_to = false)
{ {
if ( ! isset($to['email']) || ! PHPMailer::ValidateAddress($to['email'])) { if ( ! isset($to['email']) || !\Swift_Validate::email($to['email'])) {
return false; return false;
} }

View File

@@ -22,7 +22,7 @@
{% endif %} {% endif %}
</td> </td>
<td width="400" height="40" valign="center" align="center" style="font-family:Tahoma,sans-serif; font-size:14px; font-weight:bold; color:#FFF;"> <td width="400" height="40" valign="center" align="center" style="font-family:Tahoma,sans-serif; font-size:14px; font-weight:bold; color:#FFF;">
{{ title }} {{ subject }}
</td> </td>
<td width="160" height="40" valign="center" align="left" style="font-size:0px;"></td> <td width="160" height="40" valign="center" align="left" style="font-size:0px;"></td>
</tr> </tr>
@@ -41,11 +41,11 @@
<tr> <tr>
<td width="620" height="115" valign="center" align="left" style="font-family:sans-serif,'Lucida Console'; font-size:14px; color:#494949;"> <td width="620" height="115" valign="center" align="left" style="font-family:sans-serif,'Lucida Console'; font-size:14px; color:#494949;">
{% if senderName is defined and senderMail is defined %} {% if senderName is defined and senderMail is defined %}
{{ senderName }} - <a href="mailto:{{ authorMail }}" target="_blank" style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; cursor:pointer;"> {{ senderName }} - <a href="mailto:{{ senderMail }}" target="_blank" style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; cursor:pointer;">
<span style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; cursor:pointer;">{{ senderMail }}</span></a><br/> <span style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; cursor:pointer;">{{ senderMail }}</span></a><br/>
{% endif %} {% endif %}
<br/> <br/>
{{ messageText }} {{ messageText | nl2br }}
<br/> <br/>
</td> </td>
</tr> </tr>
@@ -92,8 +92,8 @@
<td width="710" height="50" valign="center" align="left" style="font-family:Tahoma,sans-serif; font-size:11px; font-style:italic; color:#FFF;"> <td width="710" height="50" valign="center" align="left" style="font-family:Tahoma,sans-serif; font-size:11px; font-style:italic; color:#FFF;">
Si cet email contient des liens non cliquables, copiez/collez ces liens dans votre navigateur.<br/> Si cet email contient des liens non cliquables, copiez/collez ces liens dans votre navigateur.<br/>
Message automatique de Phraseanet - Pour gérer l'envoi d'email automatique, connectez-vous à Message automatique de Phraseanet - Pour gérer l'envoi d'email automatique, connectez-vous à
<a href="{{ phraseanetUrl }}" target="_blank" style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; font-weight:bold; cursor:pointer;"> <a href="{{ phraseanetURL }}" target="_blank" style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; font-weight:bold; cursor:pointer;">
<span style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; font-weight:bold; cursor:pointer;">{{ phraseanetUrl }}</span> <span style="color:#FFA500; color:#FFA500 !important; text-decoration:underline; font-weight:bold; cursor:pointer;">{{ phraseanetURL }}</span>
</a> </a>
</td> </td>
</tr> </tr>