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 @@