diff --git a/lib/Alchemy/Phrasea/Application/Overview.php b/lib/Alchemy/Phrasea/Application/Overview.php index 7fa225ac68..ea2d561569 100644 --- a/lib/Alchemy/Phrasea/Application/Overview.php +++ b/lib/Alchemy/Phrasea/Application/Overview.php @@ -57,7 +57,7 @@ return call_user_func( } - $response = \set_export::stream_file($pathOut, $file->get_file(), $file->get_mime(), 'attachment'); + $response = \set_export::stream_file($pathOut, $file->get_file(), $file->get_mime(), 'inline'); $response->setPrivate(); /* @var $response \Symfony\Component\HttpFoundation\Response */ diff --git a/lib/Alchemy/Phrasea/Controller/Setup/Installer.php b/lib/Alchemy/Phrasea/Controller/Setup/Installer.php index d8eea5740a..a2b5fcec64 100644 --- a/lib/Alchemy/Phrasea/Controller/Setup/Installer.php +++ b/lib/Alchemy/Phrasea/Controller/Setup/Installer.php @@ -180,8 +180,6 @@ class Installer implements ControllerProviderInterface \setup::rollback($conn, $connbas); try { - $setupRegistry = new \Setup_Registry(); - $setupRegistry->set('GV_ServerName', $servername, \registry::TYPE_STRING); $appbox = \appbox::create($app['Core'], $setupRegistry, $conn, $appbox_name, true); diff --git a/lib/Doctrine/Repositories/ValidationParticipantRepository.php b/lib/Doctrine/Repositories/ValidationParticipantRepository.php index 53a222762a..1f210d5b23 100644 --- a/lib/Doctrine/Repositories/ValidationParticipantRepository.php +++ b/lib/Doctrine/Repositories/ValidationParticipantRepository.php @@ -12,6 +12,7 @@ namespace Repositories; use Doctrine\ORM\EntityRepository; +use Doctrine\DBAL\Types\Type; /** * @@ -21,5 +22,26 @@ use Doctrine\ORM\EntityRepository; class ValidationParticipantRepository extends EntityRepository { + /** + * Retrieve all not reminded participants where the validation has not expired + * + * @param $expireDate The expiration Date + * @return array + */ + public function findNotConfirmedAndNotRemindedParticipantsByExpireDate(\DateTime $expireDate) + { + $dql = ' + SELECT p, s + FROM Entities\ValidationParticipant p + JOIN p.session s + JOIN s.basket b + WHERE p.is_confirmed = 0 + AND p.reminded IS NULL + AND s.expires < :date'; + + return $this->_em->createQuery($dql) + ->setParameter('date', $expireDate, Type::DATETIME) + ->getResult(); + } } diff --git a/lib/classes/Session/Handler.class.php b/lib/classes/Session/Handler.class.php index 2b5d7680fb..6eebf2480d 100644 --- a/lib/classes/Session/Handler.class.php +++ b/lib/classes/Session/Handler.class.php @@ -367,16 +367,13 @@ class Session_Handler throw new Exception_ServiceUnavailable(); } - $registry = $this->appbox->get_registry(); - $conn = $this->appbox->get_connection(); $browser = Browser::getInstance(); - $sbases = array(); - $this->send_reminders(); $auth->prelog(); + if ($this->is_authenticated() && $this->get_usr_id() == $auth->get_user()->get_id()) { return $this; } @@ -533,38 +530,39 @@ class Session_Handler return $this; } - $Core = bootstrap::getCore(); + $core = bootstrap::getCore(); - $registry = $Core->getRegistry(); - $date_two_day = new DateTime('+' . (int) $registry->get('GV_validation_reminder') . ' days'); + $registry = $core->getRegistry(); - $events_mngr = eventsmanager_broker::getInstance($this->appbox, $Core); + $date = new DateTime('+' . (int) $registry->get('GV_validation_reminder') . ' days'); - $sql = 'SELECT v.id as validate_id, v.usr_id, v.ssel_id - , s.usr_id as owner, t.value - FROM (validate v, ssel s) - INNER JOIN tokens t - ON (t.datas = s.ssel_id - AND v.usr_id=t.usr_id AND t.type="validate") - WHERE expires_on < :expires_on - AND ISNULL(last_reminder) AND confirmed="0" AND s.ssel_id = v.ssel_id '; + $eventsMngr = eventsmanager_broker::getInstance($this->appbox, $core); - $stmt = $this->appbox->get_connection()->prepare($sql); - $stmt->execute(array(':expires_on' => phraseadate::format_mysql($date_two_day))); - $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $em = $core->getEntityManager(); + /* @var $em \Doctrine\ORM\EntityManager */ + $participantRepo = $em->getRepository('\Entities\ValidationParticipant'); + /* @var $participantRepo \Repositories\ValidationParticipantRepository */ + $participants = $participantRepo->findNotConfirmedAndNotRemindedParticipantsByExpireDate($date); - foreach ($rs as $row) { - $params = array( - 'to' => $row['usr_id'], - 'ssel_id' => $row['ssel_id'], - 'from' => $row['owner'], - 'validate_id' => $row['validate_id'], - 'url' => $registry->get('GV_ServerName') - . 'lightbox/validate/' . $row['ssel_id'] . '/?LOG=' . $row['value'] - ); + foreach ($participants as $participant) { + /* @var $participant \Entities\ValidationParticipant */ + $validationSession = $participant->getSession(); + $participantId = $participant->getUsrId(); + $basketId = $validationSession->getBasket()->getId(); - $events_mngr->trigger('__VALIDATION_REMINDER__', $params); + try { + $token = \random::getValidationToken($participantId, $basketId); + } catch (\Exception_NotFound $e) { + continue; + } + + $eventsMngr->trigger('__VALIDATION_REMINDER__', array( + 'to' => $participantId, + 'ssel_id' => $basketId, + 'from' => $validationSession->getInitiatorId(), + 'validate_id' => $validationSession->getId(), + 'url' => $registry->get('GV_ServerName') . 'lightbox/validate/' . $basketId . '/?LOG=' . $token + )); } return $this; diff --git a/lib/classes/eventsmanager/notify/validationreminder.class.php b/lib/classes/eventsmanager/notify/validationreminder.class.php index 58732e80fc..0bb44ab774 100644 --- a/lib/classes/eventsmanager/notify/validationreminder.class.php +++ b/lib/classes/eventsmanager/notify/validationreminder.class.php @@ -110,13 +110,19 @@ class eventsmanager_notify_validationreminder extends eventsmanager_notifyAbstra $mailed = true; } - try { - $sql = 'UPDATE validate SET last_reminder=NOW() WHERE id = :validate_id'; - $stmt = $this->appbox->get_connection()->prepare($sql); - $stmt->execute(array(':validate_id' => $params['validate_id'])); - $stmt->closeCursor(); - } catch (Exception $e) { + $core = \bootstrap::getCore(); + $em = $core->getEntityManager(); + + $validationParticipant = $em->getRepository('\Entities\ValidationParticipant')->find($params['to']); + /* @var $validationParticipant \Entities\ValidationParticipant */ + + if (null !== $validationParticipant) { + $validationParticipant->setReminded(new \DateTime('now')); + + $em->persist($validationParticipant); + + $em->flush(); } return $this->broker->notify($params['to'], __CLASS__, $datas, $mailed); diff --git a/lib/classes/random.class.php b/lib/classes/random.class.php index 6dcd58a5c6..d117c0e411 100644 --- a/lib/classes/random.class.php +++ b/lib/classes/random.class.php @@ -221,4 +221,38 @@ class random return $row; } + + /** + * Get the validation token for one user and one validation basket + * + * @param integer $userId + * @param integer $basketId + * @return string The desired token + * @throws \Exception_NotFound + */ + public static function getValidationToken($userId, $basketId) + { + $conn = \connection::getPDOConnection(); + $sql = ' + SELECT value FROM tokens + WHERE type = :type + AND usr_id = :usr_id + AND datas = :basket_id + AND (expire_on > NOW() OR expire_on IS NULL)'; + + $stmt = $conn->prepare($sql); + $stmt->execute(array( + ':type' => self::TYPE_VALIDATE, + ':usr_id' => (int) $userId, + ':basket_id' => (int) $basketId, + )); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $stmt->closeCursor(); + + if ( ! $row) { + throw new \Exception_NotFound('Token not found'); + } + + return $row['value']; + } } diff --git a/lib/classes/set/export.class.php b/lib/classes/set/export.class.php index da3aab94b5..52d02b0487 100644 --- a/lib/classes/set/export.class.php +++ b/lib/classes/set/export.class.php @@ -770,13 +770,13 @@ class set_export extends set_abstract * @return \Symfony\Component\HttpFoundation\Response */ public static function stream_file( - $file, $exportname, $mime, $disposition = 'attachment') + $file, $exportname, $mime, $disposition = 'inline') { $registry = registry::get_instance(); $response = new Symfony\Component\HttpFoundation\Response(); - $disposition = $disposition != 'attachment' ? ResponseHeaderBag::DISPOSITION_INLINE : ResponseHeaderBag::DISPOSITION_ATTACHMENT; + $disposition = $disposition === 'attachment' ? ResponseHeaderBag::DISPOSITION_ATTACHMENT : ResponseHeaderBag::DISPOSITION_INLINE; $headerDisposition = $response->headers->makeDisposition($disposition, $exportname); if (is_file($file)) { diff --git a/templates/web/prod/actions/Tools/index.html.twig b/templates/web/prod/actions/Tools/index.html.twig index eb880e9b7d..3079f3aab8 100644 --- a/templates/web/prod/actions/Tools/index.html.twig +++ b/templates/web/prod/actions/Tools/index.html.twig @@ -124,6 +124,7 @@ {% for subdef in previewHtml5 %} {% endfor %} + {% trans 'No preview available' %} @@ -374,7 +375,7 @@