Merge branch 'use-php-intl' into 'develop'
[Big] Move displaying dates from libc to PHP-intl / ICU See merge request framasoft/framadate/framadate!396
This commit is contained in:
commit
cd55e9a40a
@ -16,11 +16,14 @@
|
|||||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
use Framadate\Editable;
|
use Framadate\Editable;
|
||||||
use Framadate\Exception\AlreadyExistsException;
|
use Framadate\Exception\AlreadyExistsException;
|
||||||
use Framadate\Exception\ConcurrentEditionException;
|
use Framadate\Exception\ConcurrentEditionException;
|
||||||
use Framadate\Exception\ConcurrentVoteException;
|
use Framadate\Exception\ConcurrentVoteException;
|
||||||
use Framadate\Exception\MomentAlreadyExistsException;
|
use Framadate\Exception\MomentAlreadyExistsException;
|
||||||
|
use Framadate\Exception\SlotAlreadyExistsException;
|
||||||
use Framadate\Message;
|
use Framadate\Message;
|
||||||
use Framadate\Security\PasswordHasher;
|
use Framadate\Security\PasswordHasher;
|
||||||
use Framadate\Services\AdminPollService;
|
use Framadate\Services\AdminPollService;
|
||||||
@ -465,7 +468,7 @@ if (isset($_POST['confirm_add_column'])) {
|
|||||||
exit_displaying_add_column(new Message('danger', __('Error', "Can't create an empty column.")));
|
exit_displaying_add_column(new Message('danger', __('Error', "Can't create an empty column.")));
|
||||||
}
|
}
|
||||||
if ($poll->format === 'D') {
|
if ($poll->format === 'D') {
|
||||||
$date = DateTime::createFromFormat(__('Date', 'Y-m-d'), $_POST['newdate'])->setTime(0, 0, 0);
|
$date = $inputService->filterDate($_POST['newdate']);
|
||||||
$time = $date->getTimestamp();
|
$time = $date->getTimestamp();
|
||||||
$newmoment = strip_tags($_POST['newmoment']);
|
$newmoment = strip_tags($_POST['newmoment']);
|
||||||
$adminPollService->addDateSlot($poll_id, $time, $newmoment);
|
$adminPollService->addDateSlot($poll_id, $time, $newmoment);
|
||||||
@ -475,8 +478,12 @@ if (isset($_POST['confirm_add_column'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$message = new Message('success', __('adminstuds', 'Choice added'));
|
$message = new Message('success', __('adminstuds', 'Choice added'));
|
||||||
|
} catch (SlotAlreadyExistsException $e) {
|
||||||
|
exit_displaying_add_column(new Message('danger', __f('Error', 'The column %s already exists', $e->getSlot())));
|
||||||
} catch (MomentAlreadyExistsException $e) {
|
} catch (MomentAlreadyExistsException $e) {
|
||||||
exit_displaying_add_column(new Message('danger', __('Error', 'The column already exists')));
|
exit_displaying_add_column(new Message('danger', __f('Error', 'The column %s already exists with %s', $e->getSlot(), $e->getMoment())));
|
||||||
|
} catch (DBALException $e) {
|
||||||
|
exit_displaying_add_column(new Message('danger', __('Error', 'Error while adding a column')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,14 +491,16 @@ if (isset($_POST['confirm_add_column'])) {
|
|||||||
$slots = $pollService->allSlotsByPoll($poll);
|
$slots = $pollService->allSlotsByPoll($poll);
|
||||||
$votes = $pollService->allVotesByPollId($poll_id);
|
$votes = $pollService->allVotesByPollId($poll_id);
|
||||||
$comments = $pollService->allCommentsByPollId($poll_id);
|
$comments = $pollService->allCommentsByPollId($poll_id);
|
||||||
|
$deletion_date = clone $poll->end_date;
|
||||||
|
$deletion_date->add(new DateInterval('P' . PURGE_DELAY . 'D'));
|
||||||
|
|
||||||
// Assign data to template
|
// Assign data to template
|
||||||
$smarty->assign('poll_id', $poll_id);
|
$smarty->assign('poll_id', $poll_id);
|
||||||
$smarty->assign('admin_poll_id', $admin_poll_id);
|
$smarty->assign('admin_poll_id', $admin_poll_id);
|
||||||
$smarty->assign('poll', $poll);
|
$smarty->assign('poll', $poll);
|
||||||
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title);
|
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title);
|
||||||
$smarty->assign('expired', strtotime($poll->end_date) < time());
|
$smarty->assign('expired', $poll->end_date < new DateTime());
|
||||||
$smarty->assign('deletion_date', strtotime($poll->end_date) + PURGE_DELAY * 86400);
|
$smarty->assign('deletion_date', $deletion_date);
|
||||||
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
||||||
$smarty->assign('slots_hash', $pollService->hashSlots($slots));
|
$smarty->assign('slots_hash', $pollService->hashSlots($slots));
|
||||||
$smarty->assign('votes', $pollService->splitVotes($votes));
|
$smarty->assign('votes', $pollService->splitVotes($votes));
|
||||||
|
@ -26,11 +26,11 @@ class Choice
|
|||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All availables slots for this Choice.
|
* All available slots for this Choice.
|
||||||
*/
|
*/
|
||||||
private $slots;
|
private $slots;
|
||||||
|
|
||||||
public function __construct($name='')
|
public function __construct($name = '')
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->slots = [];
|
$this->slots = [];
|
||||||
@ -51,7 +51,7 @@ class Choice
|
|||||||
return $this->slots;
|
return $this->slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function compare(Choice $a, Choice $b)
|
public static function compare(Choice $a, Choice $b)
|
||||||
{
|
{
|
||||||
return strcmp($a->name, $b->name);
|
return strcmp($a->name, $b->name);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Framadate\Exception;
|
namespace Framadate\Exception;
|
||||||
|
|
||||||
class MomentAlreadyExistsException extends \Exception {
|
class MomentAlreadyExistsException extends SlotAlreadyExistsException {
|
||||||
function __construct() {
|
public $moment;
|
||||||
|
|
||||||
|
public function __construct($slot, $moment, $message = '')
|
||||||
|
{
|
||||||
|
parent::__construct($slot, $message);
|
||||||
|
$this->moment = $moment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getMoment()
|
||||||
|
{
|
||||||
|
return $this->moment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
namespace Framadate\Exception;
|
||||||
|
|
||||||
|
class SlotAlreadyExistsException extends \Exception {
|
||||||
|
public $slot;
|
||||||
|
|
||||||
|
public function __construct($slot, $message = '')
|
||||||
|
{
|
||||||
|
parent::__construct($message);
|
||||||
|
$this->slot = $slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getSlot()
|
||||||
|
{
|
||||||
|
return $this->slot;
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
namespace Framadate;
|
namespace Framadate;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
|
||||||
class Form
|
class Form
|
||||||
{
|
{
|
||||||
public $title;
|
public $title;
|
||||||
@ -26,7 +28,17 @@ class Form
|
|||||||
public $admin_name;
|
public $admin_name;
|
||||||
public $admin_mail;
|
public $admin_mail;
|
||||||
public $format;
|
public $format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DateTime
|
||||||
|
*/
|
||||||
public $end_date;
|
public $end_date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DateTime
|
||||||
|
*/
|
||||||
|
public $creation_date;
|
||||||
|
|
||||||
public $choix_sondage;
|
public $choix_sondage;
|
||||||
public $ValueMax;
|
public $ValueMax;
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
namespace Framadate\Repositories;
|
namespace Framadate\Repositories;
|
||||||
|
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\ConnectionException;
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Doctrine\DBAL\Driver\Statement;
|
||||||
|
use Doctrine\DBAL\Query\QueryBuilder;
|
||||||
|
use PDOStatement;
|
||||||
|
|
||||||
abstract class AbstractRepository {
|
abstract class AbstractRepository {
|
||||||
/**
|
/**
|
||||||
@ -24,7 +29,7 @@ abstract class AbstractRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \Doctrine\DBAL\ConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function commit()
|
public function commit()
|
||||||
{
|
{
|
||||||
@ -32,17 +37,25 @@ abstract class AbstractRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \Doctrine\DBAL\ConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function rollback()
|
public function rollback()
|
||||||
{
|
{
|
||||||
$this->connect->rollback();
|
$this->connect->rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return QueryBuilder
|
||||||
|
*/
|
||||||
|
public function createQueryBuilder()
|
||||||
|
{
|
||||||
|
return $this->connect->createQueryBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sql
|
* @param string $sql
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
*@throws DBALException
|
||||||
* @return bool|\Doctrine\DBAL\Driver\Statement|\PDOStatement
|
* @return bool|Statement|PDOStatement
|
||||||
*/
|
*/
|
||||||
public function prepare($sql)
|
public function prepare($sql)
|
||||||
{
|
{
|
||||||
@ -51,8 +64,8 @@ abstract class AbstractRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sql
|
* @param string $sql
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
*@throws DBALException
|
||||||
* @return bool|\Doctrine\DBAL\Driver\Statement|\PDOStatement
|
* @return bool|Statement|PDOStatement
|
||||||
*/
|
*/
|
||||||
public function query($sql)
|
public function query($sql)
|
||||||
{
|
{
|
||||||
|
@ -1,19 +1,30 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Framadate\Repositories;
|
namespace Framadate\Repositories;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Doctrine\DBAL\Exception\InvalidArgumentException;
|
||||||
|
use Doctrine\DBAL\Types\Type;
|
||||||
use Framadate\Utils;
|
use Framadate\Utils;
|
||||||
|
|
||||||
class CommentRepository extends AbstractRepository {
|
class CommentRepository extends AbstractRepository {
|
||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function findAllByPollId($poll_id) {
|
public function findAllByPollId($poll_id) {
|
||||||
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('comment') . ' WHERE poll_id = ? ORDER BY id');
|
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('comment') . ' WHERE poll_id = ? ORDER BY id');
|
||||||
$prepared->execute([$poll_id]);
|
$prepared->execute([$poll_id]);
|
||||||
|
|
||||||
return $prepared->fetchAll();
|
$comments = $prepared->fetchAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack to make date a proper DateTime
|
||||||
|
*/
|
||||||
|
return array_map(function($comment) {
|
||||||
|
$comment->date = Type::getType(Type::DATETIME)->convertToPhpValue($comment->date, $this->connect->getDatabasePlatform());
|
||||||
|
return $comment;
|
||||||
|
}, $comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,7 +35,7 @@ class CommentRepository extends AbstractRepository {
|
|||||||
* @param $comment
|
* @param $comment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function insert($poll_id, $name, $comment)
|
public function insert($poll_id, $name, $comment)
|
||||||
{
|
{
|
||||||
return $this->connect->insert(Utils::table('comment'), ['poll_id' => $poll_id, 'name' => $name, 'comment' => $comment]) > 0;
|
return $this->connect->insert(Utils::table('comment'), ['poll_id' => $poll_id, 'name' => $name, 'comment' => $comment]) > 0;
|
||||||
}
|
}
|
||||||
@ -32,10 +43,10 @@ class CommentRepository extends AbstractRepository {
|
|||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @param $comment_id
|
* @param $comment_id
|
||||||
* @throws \Doctrine\DBAL\Exception\InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function deleteById($poll_id, $comment_id)
|
public function deleteById($poll_id, $comment_id)
|
||||||
{
|
{
|
||||||
return $this->connect->delete(Utils::table('comment'), ['poll_id' => $poll_id, 'id' => $comment_id]) > 0;
|
return $this->connect->delete(Utils::table('comment'), ['poll_id' => $poll_id, 'id' => $comment_id]) > 0;
|
||||||
}
|
}
|
||||||
@ -44,10 +55,10 @@ class CommentRepository extends AbstractRepository {
|
|||||||
* Delete all comments of a given poll.
|
* Delete all comments of a given poll.
|
||||||
*
|
*
|
||||||
* @param $poll_id int The ID of the given poll.
|
* @param $poll_id int The ID of the given poll.
|
||||||
* @throws \Doctrine\DBAL\Exception\InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
* @return bool true if action succeeded.
|
* @return bool true if action succeeded.
|
||||||
*/
|
*/
|
||||||
function deleteByPollId($poll_id)
|
public function deleteByPollId($poll_id)
|
||||||
{
|
{
|
||||||
return $this->connect->delete(Utils::table('comment'), ['poll_id' => $poll_id]) > 0;
|
return $this->connect->delete(Utils::table('comment'), ['poll_id' => $poll_id]) > 0;
|
||||||
}
|
}
|
||||||
@ -56,7 +67,7 @@ class CommentRepository extends AbstractRepository {
|
|||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @param $name
|
* @param $name
|
||||||
* @param $comment
|
* @param $comment
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function exists($poll_id, $name, $comment)
|
public function exists($poll_id, $name, $comment)
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Framadate\Repositories;
|
namespace Framadate\Repositories;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Doctrine\DBAL\Exception\InvalidArgumentException;
|
||||||
|
use Doctrine\DBAL\Types\Type;
|
||||||
|
use Exception;
|
||||||
|
use Framadate\Form;
|
||||||
use Framadate\Utils;
|
use Framadate\Utils;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
|
||||||
@ -8,9 +13,10 @@ class PollRepository extends AbstractRepository {
|
|||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @param $admin_poll_id
|
* @param $admin_poll_id
|
||||||
* @param $form
|
* @param Form $form
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function insertPoll($poll_id, $admin_poll_id, $form)
|
public function insertPoll($poll_id, $admin_poll_id, Form $form)
|
||||||
{
|
{
|
||||||
$this->connect->insert(Utils::table('poll'), [
|
$this->connect->insert(Utils::table('poll'), [
|
||||||
'id' => $poll_id,
|
'id' => $poll_id,
|
||||||
@ -19,7 +25,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
'description' => $form->description,
|
'description' => $form->description,
|
||||||
'admin_name' => $form->admin_name,
|
'admin_name' => $form->admin_name,
|
||||||
'admin_mail' => $form->admin_mail,
|
'admin_mail' => $form->admin_mail,
|
||||||
'end_date' => (new \DateTime)->setTimestamp($form->end_date)->format('Y-m-d H:i:s'),
|
'end_date' => $form->end_date->format('Y-m-d H:i:s'),
|
||||||
'format' => $form->format,
|
'format' => $form->format,
|
||||||
'editable' => ($form->editable>=0 && $form->editable<=2) ? $form->editable : 0,
|
'editable' => ($form->editable>=0 && $form->editable<=2) ? $form->editable : 0,
|
||||||
'receiveNewVotes' => $form->receiveNewVotes ? 1 : 0,
|
'receiveNewVotes' => $form->receiveNewVotes ? 1 : 0,
|
||||||
@ -34,7 +40,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function findById($poll_id)
|
public function findById($poll_id)
|
||||||
@ -44,12 +50,18 @@ class PollRepository extends AbstractRepository {
|
|||||||
$poll = $prepared->fetch();
|
$poll = $prepared->fetch();
|
||||||
$prepared->closeCursor();
|
$prepared->closeCursor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack to make date a proper DateTime
|
||||||
|
*/
|
||||||
|
$poll->creation_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->creation_date, $this->connect->getDatabasePlatform());
|
||||||
|
$poll->end_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->end_date, $this->connect->getDatabasePlatform());
|
||||||
|
|
||||||
return $poll;
|
return $poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $admin_poll_id
|
* @param $admin_poll_id
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function findByAdminId($admin_poll_id) {
|
public function findByAdminId($admin_poll_id) {
|
||||||
@ -58,12 +70,15 @@ class PollRepository extends AbstractRepository {
|
|||||||
$poll = $prepared->fetch();
|
$poll = $prepared->fetch();
|
||||||
$prepared->closeCursor();
|
$prepared->closeCursor();
|
||||||
|
|
||||||
|
$poll->creation_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->creation_date, $this->connect->getDatabasePlatform());
|
||||||
|
$poll->end_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->end_date, $this->connect->getDatabasePlatform());
|
||||||
|
|
||||||
return $poll;
|
return $poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function existsById($poll_id) {
|
public function existsById($poll_id) {
|
||||||
@ -76,7 +91,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $admin_poll_id
|
* @param $admin_poll_id
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function existsByAdminId($admin_poll_id) {
|
public function existsByAdminId($admin_poll_id) {
|
||||||
@ -98,7 +113,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
'admin_name' => $poll->admin_name,
|
'admin_name' => $poll->admin_name,
|
||||||
'admin_mail' => $poll->admin_mail,
|
'admin_mail' => $poll->admin_mail,
|
||||||
'description' => $poll->description,
|
'description' => $poll->description,
|
||||||
'end_date' => $poll->end_date, # TODO : Harmonize dates between here and insert
|
'end_date' => $poll->end_date->format('Y-m-d H:i:s'), # TODO : Harmonize dates between here and insert
|
||||||
'active' => $poll->active,
|
'active' => $poll->active,
|
||||||
'editable' => $poll->editable >= 0 && $poll->editable <= 2 ? $poll->editable : 0,
|
'editable' => $poll->editable >= 0 && $poll->editable <= 2 ? $poll->editable : 0,
|
||||||
'hidden' => $poll->hidden ? 1 : 0,
|
'hidden' => $poll->hidden ? 1 : 0,
|
||||||
@ -111,7 +126,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @throws \Doctrine\DBAL\Exception\InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function deleteById($poll_id)
|
public function deleteById($poll_id)
|
||||||
@ -122,7 +137,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
/**
|
/**
|
||||||
* Find old polls. Limit: 20.
|
* Find old polls. Limit: 20.
|
||||||
*
|
*
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return array Array of old polls
|
* @return array Array of old polls
|
||||||
*/
|
*/
|
||||||
public function findOldPolls()
|
public function findOldPolls()
|
||||||
@ -138,7 +153,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>..., 'mail'=>...]
|
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>..., 'mail'=>...]
|
||||||
* @param int $start The number of first entry to select
|
* @param int $start The number of first entry to select
|
||||||
* @param int $limit The number of entries to find
|
* @param int $limit The number of entries to find
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return array The found polls
|
* @return array The found polls
|
||||||
*/
|
*/
|
||||||
public function findAll($search, $start, $limit) {
|
public function findAll($search, $start, $limit) {
|
||||||
@ -194,7 +209,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
* Find all polls that are created with the given admin mail.
|
* Find all polls that are created with the given admin mail.
|
||||||
*
|
*
|
||||||
* @param string $mail Email address of the poll admin
|
* @param string $mail Email address of the poll admin
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return array The list of matching polls
|
* @return array The list of matching polls
|
||||||
*/
|
*/
|
||||||
public function findAllByAdminMail($mail) {
|
public function findAllByAdminMail($mail) {
|
||||||
@ -208,7 +223,7 @@ class PollRepository extends AbstractRepository {
|
|||||||
* Get the total number of polls in database.
|
* Get the total number of polls in database.
|
||||||
*
|
*
|
||||||
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>...]
|
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>...]
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return int The number of polls
|
* @return int The number of polls
|
||||||
*/
|
*/
|
||||||
public function count($search = null) {
|
public function count($search = null) {
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Framadate\Repositories;
|
namespace Framadate\Repositories;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Doctrine\DBAL\Driver\Statement;
|
||||||
|
use Doctrine\DBAL\Query\QueryBuilder;
|
||||||
use Framadate\Utils;
|
use Framadate\Utils;
|
||||||
|
|
||||||
class VoteRepository extends AbstractRepository {
|
class VoteRepository extends AbstractRepository {
|
||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function allUserVotesByPollId($poll_id)
|
public function allUserVotesByPollId($poll_id)
|
||||||
@ -18,17 +21,24 @@ class VoteRepository extends AbstractRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* Insert default values for slots
|
||||||
* @param $insert_position
|
*
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @param string $poll_id
|
||||||
* @return bool
|
* @param integer $insert_position
|
||||||
|
* @return Statement|int
|
||||||
*/
|
*/
|
||||||
public function insertDefault($poll_id, $insert_position)
|
public function insertDefault($poll_id, $insert_position)
|
||||||
{
|
{
|
||||||
# TODO : Handle this on PHP's side
|
$qb = $this->createQueryBuilder();
|
||||||
$prepared = $this->prepare('UPDATE ' . Utils::table('vote') . ' SET choices = CONCAT(SUBSTRING(choices, 1, ?), " ", SUBSTRING(choices, ?)) WHERE poll_id = ?'); //#51 : default value for unselected vote
|
$sql = $this->connect->getDatabasePlatform()->getName() === 'sqlite' ?
|
||||||
|
$this->generateSQLForInsertDefaultSQLite($qb, $insert_position) :
|
||||||
return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]);
|
$this->generateSQLForInsertDefault($qb, $insert_position)
|
||||||
|
;
|
||||||
|
$query = $qb->update(Utils::table('vote'))
|
||||||
|
->set('choices', $sql)
|
||||||
|
->where($qb->expr()->eq('poll_id', $qb->createNamedParameter($poll_id)))
|
||||||
|
;
|
||||||
|
return $query->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
function insert($poll_id, $name, $choices, $token, $mail) {
|
function insert($poll_id, $name, $choices, $token, $mail) {
|
||||||
@ -48,7 +58,7 @@ class VoteRepository extends AbstractRepository {
|
|||||||
/**
|
/**
|
||||||
* @param $poll_id
|
* @param $poll_id
|
||||||
* @param $vote_id
|
* @param $vote_id
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function deleteById($poll_id, $vote_id)
|
public function deleteById($poll_id, $vote_id)
|
||||||
@ -66,7 +76,7 @@ class VoteRepository extends AbstractRepository {
|
|||||||
* Delete all votes of a given poll.
|
* Delete all votes of a given poll.
|
||||||
*
|
*
|
||||||
* @param $poll_id int The ID of the given poll.
|
* @param $poll_id int The ID of the given poll.
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return bool|null true if action succeeded.
|
* @return bool|null true if action succeeded.
|
||||||
*/
|
*/
|
||||||
public function deleteByPollId($poll_id)
|
public function deleteByPollId($poll_id)
|
||||||
@ -79,14 +89,20 @@ class VoteRepository extends AbstractRepository {
|
|||||||
*
|
*
|
||||||
* @param $poll_id int The ID of the poll
|
* @param $poll_id int The ID of the poll
|
||||||
* @param $index int The index of the vote into the poll
|
* @param $index int The index of the vote into the poll
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
|
||||||
* @return bool|null true if action succeeded.
|
* @return bool|null true if action succeeded.
|
||||||
*/
|
*/
|
||||||
public function deleteByIndex($poll_id, $index)
|
public function deleteByIndex($poll_id, $index)
|
||||||
{
|
{
|
||||||
$prepared = $this->prepare('UPDATE ' . Utils::table('vote') . ' SET choices = CONCAT(SUBSTR(choices, 1, ?), SUBSTR(choices, ?)) WHERE poll_id = ?');
|
$qb = $this->createQueryBuilder();
|
||||||
|
$sql = $this->connect->getDatabasePlatform()->getName() === 'sqlite' ?
|
||||||
return $prepared->execute([$index, $index + 2, $poll_id]);
|
$this->generateSQLForInsertDefaultSQLite($qb, $index, true) :
|
||||||
|
$this->generateSQLForInsertDefault($qb, $index, true)
|
||||||
|
;
|
||||||
|
$query = $qb->update(Utils::table('vote'))
|
||||||
|
->set('choices', $sql)
|
||||||
|
->where($qb->expr()->eq('poll_id', $qb->createNamedParameter($poll_id)))
|
||||||
|
;
|
||||||
|
return $query->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,7 +129,7 @@ class VoteRepository extends AbstractRepository {
|
|||||||
*
|
*
|
||||||
* @param int $poll_id ID of the poll
|
* @param int $poll_id ID of the poll
|
||||||
* @param string $name Name of the vote
|
* @param string $name Name of the vote
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return bool true if vote already exists
|
* @return bool true if vote already exists
|
||||||
*/
|
*/
|
||||||
public function existsByPollIdAndName($poll_id, $name) {
|
public function existsByPollIdAndName($poll_id, $name) {
|
||||||
@ -128,7 +144,7 @@ class VoteRepository extends AbstractRepository {
|
|||||||
* @param int $poll_id ID of the poll
|
* @param int $poll_id ID of the poll
|
||||||
* @param string $name Name of the vote
|
* @param string $name Name of the vote
|
||||||
* @param int $vote_id ID of the current vote
|
* @param int $vote_id ID of the current vote
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws DBALException
|
||||||
* @return bool true if vote already exists
|
* @return bool true if vote already exists
|
||||||
*/
|
*/
|
||||||
public function existsByPollIdAndNameAndVoteId($poll_id, $name, $vote_id) {
|
public function existsByPollIdAndNameAndVoteId($poll_id, $name, $vote_id) {
|
||||||
@ -136,5 +152,37 @@ class VoteRepository extends AbstractRepository {
|
|||||||
$prepared->execute([$poll_id, $name, $vote_id]);
|
$prepared->execute([$poll_id, $name, $vote_id]);
|
||||||
return $prepared->rowCount() > 0;
|
return $prepared->rowCount() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param QueryBuilder $qb
|
||||||
|
* @param $insert_position
|
||||||
|
* @param bool $delete
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function generateSQLForInsertDefaultSQLite($qb, $insert_position, $delete = false)
|
||||||
|
{
|
||||||
|
$position = $insert_position + ($delete ? 2 : 1);
|
||||||
|
return 'SUBSTR(choices, 1, '
|
||||||
|
. $qb->createNamedParameter($insert_position)
|
||||||
|
. ') || " " || SUBSTR(choices, '
|
||||||
|
. $qb->createNamedParameter($position)
|
||||||
|
. ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param QueryBuilder $qb
|
||||||
|
* @param int $insert_position
|
||||||
|
* @param bool $delete
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function generateSQLForInsertDefault($qb, $insert_position, $delete = false)
|
||||||
|
{
|
||||||
|
$position = $insert_position + ($delete ? 2 : 1);
|
||||||
|
return 'CONCAT(SUBSTR(choices, 1, '
|
||||||
|
. $qb->createNamedParameter($insert_position)
|
||||||
|
. '), " ", SUBSTR(choices, '
|
||||||
|
. $qb->createNamedParameter($position)
|
||||||
|
. '))';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Framadate\Security;
|
namespace Framadate\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
namespace Framadate\Services;
|
namespace Framadate\Services;
|
||||||
|
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\ConnectionException;
|
||||||
use Doctrine\DBAL\DBALException;
|
use Doctrine\DBAL\DBALException;
|
||||||
use Framadate\Exception\MomentAlreadyExistsException;
|
use Framadate\Exception\MomentAlreadyExistsException;
|
||||||
|
use Framadate\Form;
|
||||||
use Framadate\Repositories\RepositoryFactory;
|
use Framadate\Repositories\RepositoryFactory;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AdminPollService
|
* Class AdminPollService
|
||||||
@ -31,15 +34,15 @@ class AdminPollService {
|
|||||||
$this->commentRepository = RepositoryFactory::commentRepository();
|
$this->commentRepository = RepositoryFactory::commentRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePoll($poll) {
|
/**
|
||||||
global $config;
|
* @param Form $poll
|
||||||
|
* @return bool
|
||||||
$end_date = strtotime($poll->end_date);
|
*/
|
||||||
|
public function updatePoll($poll) {
|
||||||
if ($end_date < strtotime($poll->creation_date)) {
|
if ($poll->end_date < $poll->creation_date) {
|
||||||
$poll->end_date = $poll->creation_date;
|
$poll->end_date = $poll->creation_date;
|
||||||
} elseif ($end_date > $this->pollService->maxExpiryDate()) {
|
} elseif ($poll->end_date > $this->pollService->maxExpiryDate()) {
|
||||||
$poll->end_date = utf8_encode(strftime('%Y-%m-%d', $this->pollService->maxExpiryDate()));
|
$poll->end_date = $this->pollService->maxExpiryDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->pollRepository->update($poll);
|
return $this->pollRepository->update($poll);
|
||||||
@ -216,7 +219,7 @@ class AdminPollService {
|
|||||||
* @param $datetime int The datetime
|
* @param $datetime int The datetime
|
||||||
* @param $new_moment string The moment's name
|
* @param $new_moment string The moment's name
|
||||||
* @throws MomentAlreadyExistsException When the moment to add already exists in database
|
* @throws MomentAlreadyExistsException When the moment to add already exists in database
|
||||||
* @throws \Doctrine\DBAL\ConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function addDateSlot($poll_id, $datetime, $new_moment) {
|
public function addDateSlot($poll_id, $datetime, $new_moment) {
|
||||||
$this->logService->logEntries(
|
$this->logService->logEntries(
|
||||||
@ -242,7 +245,7 @@ class AdminPollService {
|
|||||||
|
|
||||||
// Check if moment already exists (maybe not necessary)
|
// Check if moment already exists (maybe not necessary)
|
||||||
if (in_array($new_moment, $moments, true)) {
|
if (in_array($new_moment, $moments, true)) {
|
||||||
throw new MomentAlreadyExistsException();
|
throw new MomentAlreadyExistsException($slot, $new_moment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update found slot
|
// Update found slot
|
||||||
@ -257,6 +260,7 @@ class AdminPollService {
|
|||||||
// Commit transaction
|
// Commit transaction
|
||||||
$this->connect->commit();
|
$this->connect->commit();
|
||||||
} catch (DBALException $e) {
|
} catch (DBALException $e) {
|
||||||
|
$this->logService->log('ERROR', "Database error, couldn't insert date slot" . $e->getMessage());
|
||||||
$this->connect->rollBack();
|
$this->connect->rollBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +274,7 @@ class AdminPollService {
|
|||||||
* @param $poll_id int The ID of the poll
|
* @param $poll_id int The ID of the poll
|
||||||
* @param $title int The title
|
* @param $title int The title
|
||||||
* @throws MomentAlreadyExistsException When the moment to add already exists in database
|
* @throws MomentAlreadyExistsException When the moment to add already exists in database
|
||||||
* @throws \Doctrine\DBAL\ConnectionException
|
* @throws ConnectionException
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function addClassicSlot($poll_id, $title) {
|
public function addClassicSlot($poll_id, $title) {
|
||||||
@ -309,10 +313,10 @@ class AdminPollService {
|
|||||||
*
|
*
|
||||||
* @param $slots array All the slots of the poll
|
* @param $slots array All the slots of the poll
|
||||||
* @param $datetime int The datetime of the new slot
|
* @param $datetime int The datetime of the new slot
|
||||||
* @return \stdClass An object like this one: {insert:X, slot:Y} where Y can be null.
|
* @return stdClass An object like this one: {insert:X, slot:Y} where Y can be null.
|
||||||
*/
|
*/
|
||||||
private function findInsertPosition($slots, $datetime) {
|
private function findInsertPosition($slots, $datetime) {
|
||||||
$result = new \stdClass();
|
$result = new stdClass();
|
||||||
$result->slot = null;
|
$result->slot = null;
|
||||||
$result->insert = 0;
|
$result->insert = 0;
|
||||||
|
|
||||||
@ -329,7 +333,9 @@ class AdminPollService {
|
|||||||
$result->insert += count($moments);
|
$result->insert += count($moments);
|
||||||
$result->slot = $slot;
|
$result->slot = $slot;
|
||||||
break;
|
break;
|
||||||
} elseif ($datetime < $rowDatetime) {
|
}
|
||||||
|
|
||||||
|
if ($datetime < $rowDatetime) {
|
||||||
// We have to insert before this slot
|
// We have to insert before this slot
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ namespace Framadate\Services;
|
|||||||
use DateTime;
|
use DateTime;
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
use Egulias\EmailValidator\Validation\RFCValidation;
|
use Egulias\EmailValidator\Validation\RFCValidation;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class helps to clean all inputs from the users or external services.
|
* This class helps to clean all inputs from the users or external services.
|
||||||
@ -124,9 +125,16 @@ class InputService {
|
|||||||
return $this->returnIfNotBlank($comment);
|
return $this->returnIfNotBlank($comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $date
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
public function filterDate($date) {
|
public function filterDate($date) {
|
||||||
$dDate = DateTime::createFromFormat(__('Date', 'Y-m-d'), $date)->setTime(0, 0, 0);
|
$dDate = parse_translation_date($date);
|
||||||
return $dDate->format('Y-m-d H:i:s');
|
if ($dDate) {
|
||||||
|
return $dDate;
|
||||||
|
}
|
||||||
|
throw new InvalidArgumentException('Invalid date');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Framadate\Services;
|
namespace Framadate\Services;
|
||||||
|
|
||||||
use \stdClass;
|
use \stdClass;
|
||||||
|
@ -17,32 +17,43 @@
|
|||||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||||
*/
|
*/
|
||||||
namespace Framadate\Services;
|
namespace Framadate\Services;
|
||||||
|
|
||||||
|
use DateInterval;
|
||||||
|
use DateTime;
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
use Doctrine\DBAL\ConnectionException;
|
use Doctrine\DBAL\ConnectionException;
|
||||||
use Doctrine\DBAL\DBALException;
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Exception;
|
||||||
use Framadate\Exception\AlreadyExistsException;
|
use Framadate\Exception\AlreadyExistsException;
|
||||||
use Framadate\Exception\ConcurrentEditionException;
|
use Framadate\Exception\ConcurrentEditionException;
|
||||||
use Framadate\Exception\ConcurrentVoteException;
|
use Framadate\Exception\ConcurrentVoteException;
|
||||||
use Framadate\Form;
|
use Framadate\Form;
|
||||||
use Framadate\Repositories\RepositoryFactory;
|
use Framadate\Repositories\RepositoryFactory;
|
||||||
use Framadate\Security\Token;
|
use Framadate\Security\Token;
|
||||||
use Framadate\Services\LogService;
|
use RuntimeException;
|
||||||
use Framadate\Services\NotificationService;
|
use stdClass;
|
||||||
use Framadate\Services\PurgeService;
|
|
||||||
use Framadate\Services\SessionService;
|
|
||||||
use Framadate\Utils;
|
|
||||||
|
|
||||||
class PollService {
|
class PollService {
|
||||||
private $connect;
|
|
||||||
private $logService;
|
private $logService;
|
||||||
|
|
||||||
private $pollRepository;
|
private $pollRepository;
|
||||||
private $slotRepository;
|
private $slotRepository;
|
||||||
private $voteRepository;
|
private $voteRepository;
|
||||||
private $commentRepository;
|
private $commentRepository;
|
||||||
|
/**
|
||||||
|
* @var NotificationService
|
||||||
|
*/
|
||||||
|
private $notificationService;
|
||||||
|
/**
|
||||||
|
* @var SessionService
|
||||||
|
*/
|
||||||
|
private $sessionService;
|
||||||
|
/**
|
||||||
|
* @var PurgeService
|
||||||
|
*/
|
||||||
|
private $purgeService;
|
||||||
|
|
||||||
function __construct(Connection $connect, LogService $logService, NotificationService $notificationService) {
|
public function __construct(Connection $connect, LogService $logService, NotificationService $notificationService) {
|
||||||
$this->connect = $connect;
|
|
||||||
$this->logService = $logService;
|
$this->logService = $logService;
|
||||||
$this->notificationService = $notificationService;
|
$this->notificationService = $notificationService;
|
||||||
$this->sessionService = new SessionService();
|
$this->sessionService = new SessionService();
|
||||||
@ -57,7 +68,7 @@ class PollService {
|
|||||||
* Find a poll from its ID.
|
* Find a poll from its ID.
|
||||||
*
|
*
|
||||||
* @param $poll_id int The ID of the poll
|
* @param $poll_id int The ID of the poll
|
||||||
* @return \stdClass|null The found poll, or null
|
* @return stdClass|null The found poll, or null
|
||||||
*/
|
*/
|
||||||
function findById($poll_id) {
|
function findById($poll_id) {
|
||||||
try {
|
try {
|
||||||
@ -142,7 +153,7 @@ class PollService {
|
|||||||
* @throws AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
* @throws ConcurrentEditionException
|
* @throws ConcurrentEditionException
|
||||||
* @throws ConcurrentVoteException
|
* @throws ConcurrentVoteException
|
||||||
* @return \stdClass
|
* @return stdClass
|
||||||
*/
|
*/
|
||||||
function addVote($poll_id, $name, $choices, $slots_hash, $mail) {
|
function addVote($poll_id, $name, $choices, $slots_hash, $mail) {
|
||||||
$this->checkVoteConstraints($choices, $poll_id, $slots_hash, $name);
|
$this->checkVoteConstraints($choices, $poll_id, $slots_hash, $name);
|
||||||
@ -218,9 +229,10 @@ class PollService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Form $form
|
* @param Form $form
|
||||||
|
* @throws ConnectionException
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function createPoll(Form $form) {
|
public function createPoll(Form $form) {
|
||||||
// Generate poll IDs, loop while poll ID already exists
|
// Generate poll IDs, loop while poll ID already exists
|
||||||
|
|
||||||
$this->pollRepository->beginTransaction();
|
$this->pollRepository->beginTransaction();
|
||||||
@ -230,7 +242,7 @@ class PollService {
|
|||||||
$poll_id = $this->random(16);
|
$poll_id = $this->random(16);
|
||||||
} while ($this->pollRepository->existsById($poll_id));
|
} while ($this->pollRepository->existsById($poll_id));
|
||||||
$admin_poll_id = $poll_id . $this->random(8);
|
$admin_poll_id = $poll_id . $this->random(8);
|
||||||
} else { // User have choosen the poll id
|
} else { // User have chosen the poll id
|
||||||
$poll_id = $form->id;
|
$poll_id = $form->id;
|
||||||
do {
|
do {
|
||||||
$admin_poll_id = $this->random(24);
|
$admin_poll_id = $this->random(24);
|
||||||
@ -261,7 +273,7 @@ class PollService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $votes
|
* @param array $votes
|
||||||
* @param \stdClass $poll
|
* @param stdClass $poll
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function computeBestChoices($votes, $poll) {
|
public function computeBestChoices($votes, $poll) {
|
||||||
@ -293,8 +305,8 @@ class PollService {
|
|||||||
function splitSlots($slots) {
|
function splitSlots($slots) {
|
||||||
$splitted = [];
|
$splitted = [];
|
||||||
foreach ($slots as $slot) {
|
foreach ($slots as $slot) {
|
||||||
$obj = new \stdClass();
|
$obj = new stdClass();
|
||||||
$obj->day = $slot->title;
|
$obj->day = (new DateTime())->setTimestamp((int) $slot->title);
|
||||||
$obj->moments = explode(',', $slot->moments);
|
$obj->moments = explode(',', $slot->moments);
|
||||||
|
|
||||||
$splitted[] = $obj;
|
$splitted[] = $obj;
|
||||||
@ -316,7 +328,7 @@ class PollService {
|
|||||||
function splitVotes($votes) {
|
function splitVotes($votes) {
|
||||||
$splitted = [];
|
$splitted = [];
|
||||||
foreach ($votes as $vote) {
|
foreach ($votes as $vote) {
|
||||||
$obj = new \stdClass();
|
$obj = new stdClass();
|
||||||
$obj->id = $vote->id;
|
$obj->id = $vote->id;
|
||||||
$obj->name = $vote->name;
|
$obj->name = $vote->name;
|
||||||
$obj->uniqId = $vote->uniqId;
|
$obj->uniqId = $vote->uniqId;
|
||||||
@ -330,18 +342,25 @@ class PollService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int The max timestamp allowed for expiry date
|
* @throws Exception
|
||||||
|
* @return DateTime The max timestamp allowed for expiry date
|
||||||
*/
|
*/
|
||||||
public function maxExpiryDate() {
|
public function maxExpiryDate() {
|
||||||
|
try {
|
||||||
global $config;
|
global $config;
|
||||||
return time() + (86400 * $config['default_poll_duration']);
|
$default_poll_duration = isset($config['default_poll_duration']) ? $config['default_poll_duration'] : 60;
|
||||||
|
return (new DateTime())->add(new DateInterval('P' . $default_poll_duration . 'D'));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new RuntimeException('Configuration Exception');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int The min timestamp allowed for expiry date
|
* @throws Exception
|
||||||
|
* @return DateTime The min timestamp allowed for expiry date
|
||||||
*/
|
*/
|
||||||
public function minExpiryDate() {
|
public function minExpiryDate() {
|
||||||
return time() + 86400;
|
return (new DateTime())->add(new DateInterval('P1D'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -355,7 +374,7 @@ class PollService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \stdClass $poll
|
* @param stdClass $poll
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function computeEmptyBestChoices($poll)
|
private function computeEmptyBestChoices($poll)
|
||||||
@ -440,7 +459,7 @@ class PollService {
|
|||||||
* This method checks if the votes doesn't conflicts the maximum votes constraint
|
* This method checks if the votes doesn't conflicts the maximum votes constraint
|
||||||
*
|
*
|
||||||
* @param $user_choice
|
* @param $user_choice
|
||||||
* @param \stdClass $poll
|
* @param stdClass $poll
|
||||||
* @param string $poll_id
|
* @param string $poll_id
|
||||||
* @throws ConcurrentVoteException
|
* @throws ConcurrentVoteException
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Framadate\Services;
|
namespace Framadate\Services;
|
||||||
|
|
||||||
class SessionService {
|
class SessionService {
|
||||||
|
@ -17,9 +17,16 @@
|
|||||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const DATE_FORMAT_FULL = 'EEEE d MMMM y';
|
||||||
|
const DATE_FORMAT_SHORT = 'EEEE d MMMM y';
|
||||||
|
const DATE_FORMAT_DAY = 'E d';
|
||||||
|
const DATE_FORMAT_DATE = 'dd-MM-y';
|
||||||
|
const DATE_FORMAT_MONTH_YEAR = 'MMMM y';
|
||||||
|
const DATE_FORMAT_DATETIME_SHORT = 'EEEE d';
|
||||||
|
|
||||||
// Change session language when requested
|
// Change session language when requested
|
||||||
if (isset($_REQUEST['lang'])
|
if (isset($_REQUEST['lang'])
|
||||||
&& in_array($_REQUEST['lang'], array_keys($ALLOWED_LANGUAGES), true)) {
|
&& array_key_exists($_REQUEST['lang'], $ALLOWED_LANGUAGES)) {
|
||||||
$_SESSION['lang'] = $_REQUEST['lang'];
|
$_SESSION['lang'] = $_REQUEST['lang'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +39,79 @@ if (isset($_SESSION['lang'])) {
|
|||||||
// Use the best available locale.
|
// Use the best available locale.
|
||||||
$locale = locale_lookup(array_keys($ALLOWED_LANGUAGES), $wanted_locale, false, DEFAULT_LANGUAGE);
|
$locale = locale_lookup(array_keys($ALLOWED_LANGUAGES), $wanted_locale, false, DEFAULT_LANGUAGE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a DateTime according to the IntlDateFormatter
|
||||||
|
*
|
||||||
|
* @param DateTime $date
|
||||||
|
* @param string $pattern
|
||||||
|
* @param $forceLocale
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function date_format_intl(DateTime $date, $pattern = DATE_FORMAT_FULL, $forceLocale = null) {
|
||||||
|
global $locale;
|
||||||
|
$local_locale = $forceLocale || $locale;
|
||||||
|
|
||||||
|
$dateFormatter = IntlDateFormatter::create(
|
||||||
|
$local_locale,
|
||||||
|
IntlDateFormatter::FULL,
|
||||||
|
IntlDateFormatter::FULL,
|
||||||
|
date_default_timezone_get(),
|
||||||
|
IntlDateFormatter::GREGORIAN,
|
||||||
|
$pattern
|
||||||
|
);
|
||||||
|
return $dateFormatter->format($date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a DateTime according to a translated format
|
||||||
|
*
|
||||||
|
* @param DateTime $date
|
||||||
|
* @param string $pattern
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function date_format_translation(DateTime $date, $pattern = 'Y-m-d') {
|
||||||
|
return $date->format(__('Date', $pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string into a DateTime according to the IntlDateFormatter
|
||||||
|
*
|
||||||
|
* @param $dateString
|
||||||
|
* @param string $pattern
|
||||||
|
* @param string|null $forceLocale
|
||||||
|
* @return DateTime|null
|
||||||
|
*/
|
||||||
|
function parse_intl_date($dateString, $pattern = DATE_FORMAT_DATE, $forceLocale = null) {
|
||||||
|
global $locale;
|
||||||
|
$local_locale = $forceLocale || $locale;
|
||||||
|
|
||||||
|
$dateFormatter = IntlDateFormatter::create(
|
||||||
|
$local_locale,
|
||||||
|
IntlDateFormatter::FULL,
|
||||||
|
IntlDateFormatter::FULL,
|
||||||
|
date_default_timezone_get(),
|
||||||
|
IntlDateFormatter::GREGORIAN,
|
||||||
|
$pattern
|
||||||
|
);
|
||||||
|
$timestamp = $dateFormatter->parse($dateString);
|
||||||
|
try {
|
||||||
|
return (new DateTime())->setTimestamp($timestamp);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string into a DateTime according to a translated format
|
||||||
|
*
|
||||||
|
* @param string $dateString
|
||||||
|
* @param string $pattern
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
function parse_translation_date($dateString, $pattern = 'Y-m-d') {
|
||||||
|
return DateTime::createFromFormat(__('Date', $pattern), $dateString);
|
||||||
|
}
|
||||||
|
|
||||||
/* i18n helper functions */
|
/* i18n helper functions */
|
||||||
use Symfony\Component\Translation\Loader\PoFileLoader;
|
use Symfony\Component\Translation\Loader\PoFileLoader;
|
||||||
use Symfony\Component\Translation\Translator;
|
use Symfony\Component\Translation\Translator;
|
||||||
@ -68,16 +148,3 @@ function __f($section, $key, $args) {
|
|||||||
$args = array_slice(func_get_args(), 2);
|
$args = array_slice(func_get_args(), 2);
|
||||||
return vsprintf($msg, $args);
|
return vsprintf($msg, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Date Format */
|
|
||||||
$date_format['txt_full'] = __('Date', '%A, %B %e, %Y'); //summary in create_date_poll.php and removal date in choix_(date|autre).php
|
|
||||||
$date_format['txt_short'] = __('Date', '%A %e %B %Y'); // radio title
|
|
||||||
$date_format['txt_day'] = __('Date', '%a %e');
|
|
||||||
$date_format['txt_date'] = __('Date', '%Y-%m-%d');
|
|
||||||
$date_format['txt_month_year'] = __('Date', '%B %Y');
|
|
||||||
$date_format['txt_datetime_short'] = __('Date', '%m/%d/%Y %H:%M');
|
|
||||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { //%e can't be used on Windows platform, use %#d instead
|
|
||||||
foreach ($date_format as $k => $v) {
|
|
||||||
$date_format[$k] = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $v); //replace %e by %#d for windows
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -66,7 +66,7 @@ if (is_file(CONF_FILENAME)) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (DB_DRIVER === 'pdo_sqlite') {
|
if (DB_DRIVER === 'pdo_sqlite') {
|
||||||
$connectionParams['path'] = 'test_database.sqlite';
|
$connectionParams['path'] = ROOT_DIR . '/test_database.sqlite';
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -37,7 +37,6 @@ $smarty->assign('use_nav_js', strstr($serverName, 'framadate.org'));
|
|||||||
$smarty->assign('provide_fork_awesome', !isset($config['provide_fork_awesome']) || $config['provide_fork_awesome']);
|
$smarty->assign('provide_fork_awesome', !isset($config['provide_fork_awesome']) || $config['provide_fork_awesome']);
|
||||||
$smarty->assign('locale', $locale);
|
$smarty->assign('locale', $locale);
|
||||||
$smarty->assign('langs', $ALLOWED_LANGUAGES);
|
$smarty->assign('langs', $ALLOWED_LANGUAGES);
|
||||||
$smarty->assign('date_format', $date_format);
|
|
||||||
if (isset($config['tracking_code'])) {
|
if (isset($config['tracking_code'])) {
|
||||||
$smarty->assign('tracking_code', $config['tracking_code']);
|
$smarty->assign('tracking_code', $config['tracking_code']);
|
||||||
}
|
}
|
||||||
@ -46,7 +45,8 @@ if (defined('FAVICON')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dev Mode
|
// Dev Mode
|
||||||
if (isset($_SERVER['FRAMADATE_DEVMODE']) && $_SERVER['FRAMADATE_DEVMODE'] || php_sapi_name() === 'cli-server') {
|
if (php_sapi_name() === 'cli-server') {
|
||||||
|
$smarty->caching = 0;
|
||||||
$smarty->force_compile = true;
|
$smarty->force_compile = true;
|
||||||
$smarty->compile_check = true;
|
$smarty->compile_check = true;
|
||||||
} else {
|
} else {
|
||||||
@ -125,3 +125,38 @@ function smarty_modifier_locale_2_lang($locale) {
|
|||||||
function path_for_datepicker_locale($lang) {
|
function path_for_datepicker_locale($lang) {
|
||||||
return __DIR__ . '/../../js/locales/bootstrap-datepicker.' . $lang . '.js';
|
return __DIR__ . '/../../js/locales/bootstrap-datepicker.' . $lang . '.js';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $date
|
||||||
|
* @param string $pattern
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_modifier_date_format_intl(DateTime $date, $pattern) {
|
||||||
|
return date_format_intl($date, $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DateTime $date
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function smarty_modifier_date_to_timestamp(DateTime $date) {
|
||||||
|
return $date->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param integer $timestamp
|
||||||
|
* @throws Exception
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
function smarty_modifier_timestamp_to_date($timestamp) {
|
||||||
|
return (new DateTime())->setTimestamp((int) $timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DateTime $date
|
||||||
|
* @param string $pattern
|
||||||
|
* @return bool|DateTime
|
||||||
|
*/
|
||||||
|
function smarty_modifier_date_format_translation(DateTime $date, $pattern = 'Y-m-d') {
|
||||||
|
return date_format_translation($date, $pattern);
|
||||||
|
}
|
||||||
|
@ -56,10 +56,10 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.6.0",
|
"php": ">=5.6.0",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
"ext-intl": "*",
|
||||||
"smarty/smarty": "^3.1",
|
"smarty/smarty": "^3.1",
|
||||||
"phpmailer/phpmailer": "~6.0",
|
"phpmailer/phpmailer": "~6.0",
|
||||||
"ircmaxell/password-compat": "dev-master",
|
"ircmaxell/password-compat": "dev-master",
|
||||||
"roave/security-advisories": "dev-master",
|
|
||||||
"erusev/parsedown": "^1.7",
|
"erusev/parsedown": "^1.7",
|
||||||
"egulias/email-validator": "~2.1",
|
"egulias/email-validator": "~2.1",
|
||||||
"doctrine/dbal": "^2.5",
|
"doctrine/dbal": "^2.5",
|
||||||
@ -70,7 +70,8 @@
|
|||||||
|
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^5.7",
|
"phpunit/phpunit": "^5.7",
|
||||||
"friendsofphp/php-cs-fixer": "~2.0"
|
"friendsofphp/php-cs-fixer": "~2.0",
|
||||||
|
"roave/security-advisories": "dev-master"
|
||||||
},
|
},
|
||||||
|
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -41,7 +41,7 @@ $sessionService = new SessionService();
|
|||||||
if (is_file('bandeaux_local.php')) {
|
if (is_file('bandeaux_local.php')) {
|
||||||
include_once('bandeaux_local.php');
|
include_once('bandeaux_local.php');
|
||||||
} else {
|
} else {
|
||||||
include_once('bandeaux.php');
|
include_once 'bandeaux.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
$max_expiry_time = $pollService->maxExpiryDate();
|
$max_expiry_time = $pollService->maxExpiryDate();
|
||||||
@ -142,7 +142,7 @@ switch ($step) {
|
|||||||
}
|
}
|
||||||
$summary .= '</ol>';
|
$summary .= '</ol>';
|
||||||
|
|
||||||
$end_date_str = utf8_encode(strftime($date_format['txt_date'], $max_expiry_time)); //textual date
|
$end_date_str = date_format_intl($max_expiry_time); //textual date
|
||||||
|
|
||||||
$_SESSION['form'] = serialize($form);
|
$_SESSION['form'] = serialize($form);
|
||||||
|
|
||||||
|
@ -166,7 +166,8 @@ switch ($step) {
|
|||||||
$choices = $form->getChoices();
|
$choices = $form->getChoices();
|
||||||
foreach ($choices as $choice) {
|
foreach ($choices as $choice) {
|
||||||
/** @var Choice $choice */
|
/** @var Choice $choice */
|
||||||
$summary .= '<li>' . strftime($date_format['txt_full'], $choice->getName());
|
$date = (new DateTime())->setTimestamp((int) $choice->getName());
|
||||||
|
$summary .= '<li>' . $end_date_str = date_format_intl($date); //textual date
|
||||||
$first = true;
|
$first = true;
|
||||||
foreach ($choice->getSlots() as $slots) {
|
foreach ($choice->getSlots() as $slots) {
|
||||||
$summary .= $first ? ': ' : ', ';
|
$summary .= $first ? ': ' : ', ';
|
||||||
@ -177,7 +178,7 @@ switch ($step) {
|
|||||||
}
|
}
|
||||||
$summary .= '</ul>';
|
$summary .= '</ul>';
|
||||||
|
|
||||||
$end_date_str = utf8_encode(strftime($date_format['txt_date'], $max_expiry_time)); // textual date
|
$end_date_str = date_format_intl($max_expiry_time); //textual date
|
||||||
|
|
||||||
$_SESSION['form'] = serialize($form);
|
$_SESSION['form'] = serialize($form);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ if ($poll->format === 'D') {
|
|||||||
$titles_line = ',';
|
$titles_line = ',';
|
||||||
$moments_line = ',';
|
$moments_line = ',';
|
||||||
foreach ($slots as $slot) {
|
foreach ($slots as $slot) {
|
||||||
$title = Utils::csvEscape(strftime($date_format['txt_date'], $slot->title));
|
$title = Utils::csvEscape($dateFormatter->format($slot->title));
|
||||||
$moments = explode(',', $slot->moments);
|
$moments = explode(',', $slot->moments);
|
||||||
|
|
||||||
$titles_line .= str_repeat($title . ',', count($moments));
|
$titles_line .= str_repeat($title . ',', count($moments));
|
||||||
|
@ -218,7 +218,7 @@ function checkCommentSending() {
|
|||||||
button.data("textSend", button.text());
|
button.data("textSend", button.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!form.get(0).checkValidity()) {
|
if (form.get(0) && !form.get(0).checkValidity()) {
|
||||||
button.prop("disabled", true);
|
button.prop("disabled", true);
|
||||||
button.text(button.data("textWait"));
|
button.text(button.data("textWait"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -232,12 +232,15 @@ if ($resultPubliclyVisible || $accessGranted) {
|
|||||||
$comments = $pollService->allCommentsByPollId($poll_id);
|
$comments = $pollService->allCommentsByPollId($poll_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$deletion_date = clone $poll->end_date;
|
||||||
|
$deletion_date->add(new DateInterval('P' . PURGE_DELAY . 'D'));
|
||||||
|
|
||||||
// Assign data to template
|
// Assign data to template
|
||||||
$smarty->assign('poll_id', $poll_id);
|
$smarty->assign('poll_id', $poll_id);
|
||||||
$smarty->assign('poll', $poll);
|
$smarty->assign('poll', $poll);
|
||||||
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title);
|
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title);
|
||||||
$smarty->assign('expired', strtotime($poll->end_date) < time());
|
$smarty->assign('expired', $poll->end_date < new DateTime());
|
||||||
$smarty->assign('deletion_date', strtotime($poll->end_date) + PURGE_DELAY * 86400);
|
$smarty->assign('deletion_date', $deletion_date);
|
||||||
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
||||||
$smarty->assign('slots_hash', $pollService->hashSlots($slots));
|
$smarty->assign('slots_hash', $pollService->hashSlots($slots));
|
||||||
$smarty->assign('votes', $pollService->splitVotes($votes));
|
$smarty->assign('votes', $pollService->splitVotes($votes));
|
||||||
|
@ -93,10 +93,10 @@
|
|||||||
<td>{$poll->admin_name|html}</td>
|
<td>{$poll->admin_name|html}</td>
|
||||||
<td>{$poll->admin_mail|html}</td>
|
<td>{$poll->admin_mail|html}</td>
|
||||||
|
|
||||||
{if strtotime($poll->end_date) > time()}
|
{if $poll->end_date > date_create()}
|
||||||
<td>{date('d/m/y', strtotime($poll->end_date))}</td>
|
<td>{$poll->end_date|date_format_intl:'d/m/Y'}</td>
|
||||||
{else}
|
{else}
|
||||||
<td><span class="text-danger">{strtotime($poll->end_date)|date_format:'d/m/Y'}</span></td>
|
<td><span class="text-danger">{$poll->end_date|date_format_intl:'d/m/Y'}</span></td>
|
||||||
{/if}
|
{/if}
|
||||||
<td>{$poll->votes|html}</td>
|
<td>{$poll->votes|html}</td>
|
||||||
<td>{$poll->id|html}</td>
|
<td>{$poll->id|html}</td>
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
<div id="days_container">
|
<div id="days_container">
|
||||||
{foreach $choices as $i=>$choice}
|
{foreach $choices as $i=>$choice}
|
||||||
{if $choice->getName()}
|
{if $choice->getName()}
|
||||||
{$day_value = $choice->getName()|date_format:$date_format['txt_date']}
|
{$day_value = $choice->getName()|timestamp_to_date|date_format_translation}
|
||||||
{else}
|
{else}
|
||||||
{$day_value = ''}
|
{$day_value = ''}
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{foreach $polls as $poll}
|
{foreach $polls as $poll}
|
||||||
<li>
|
<li>
|
||||||
<a href="{poll_url id=$poll->admin_id admin=true}">{$poll->title|html}</a>
|
<a href="{poll_url id=$poll->admin_id admin=true}">{$poll->title|html}</a>
|
||||||
({__('Generic', 'Creation date:')} {$poll->creation_date|date_format:$date_format['txt_full']})
|
({__('Generic', 'Creation date:')} {$poll->creation_date|date_format_intl:DATE_FORMAT_FULL})
|
||||||
</li>
|
</li>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
{if $admin && !$expired}
|
{if $admin && !$expired}
|
||||||
<button type="submit" name="delete_comment" value="{$comment->id|html}" class="btn btn-link" title="{__('Comments', 'Remove comment')}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span></button>
|
<button type="submit" name="delete_comment" value="{$comment->id|html}" class="btn btn-link" title="{__('Comments', 'Remove comment')}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span></button>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="comment_date">{$comment->date|date_format:$date_format['txt_datetime_short']}</span>
|
{* <span>{$comment->date}</span>*}
|
||||||
|
{* <span>{$comment->date|date_format_intl}</span>*}
|
||||||
|
<span class="comment_date">{$comment->date|date_format_intl:DATE_FORMAT_SHORT}</span>
|
||||||
<b>{$comment->name|html}</b>
|
<b>{$comment->name|html}</b>
|
||||||
<span>{$comment->comment|escape|nl2br}</span>
|
<span>{$comment->comment|escape|nl2br}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -116,15 +116,37 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="expiration-form" class="form-group col-md-4">
|
<div id="expiration-form" class="form-group col-md-4">
|
||||||
<label class="control-label">{__('Generic', 'Expiry date')}</label>
|
<label class="control-label">{__('Generic', 'Expiry date')}</label>
|
||||||
<p>{$poll->end_date|date_format:$date_format['txt_date']|html} <button class="btn btn-link btn-sm btn-edit" title="{__('PollInfo', 'Edit the expiry date')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span></button></p>
|
<p>{$poll->end_date|date_format_intl:DATE_FORMAT_FULL|html}
|
||||||
|
<button class="btn btn-link btn-sm btn-edit" title="{__('PollInfo', 'Edit the expiry date')}">
|
||||||
|
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="hidden js-expiration">
|
<div class="hidden js-expiration">
|
||||||
<label class="sr-only" for="newexpirationdate">{__('Generic', 'Expiry date')}</label>
|
<label class="sr-only" for="newexpirationdate">{__('Generic', 'Expiry date')}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" id="newexpirationdate" name="expiration_date" size="40" value="{$poll->end_date|date_format:$date_format['txt_date']|html}" />
|
<input type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="newexpirationdate"
|
||||||
|
name="expiration_date"
|
||||||
|
size="40"
|
||||||
|
value="{$poll->end_date|date_format_translation|html}"
|
||||||
|
/>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="submit" class="btn btn-success" name="update_poll_info" value="expiration_date" title="{__('PollInfo', 'Save the new expiration date')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Save')}</span></button>
|
<button type="submit"
|
||||||
<button class="btn btn-link btn-cancel" title="{__('PollInfo', 'Cancel the expiration date edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{__('Generic', 'Cancel')}</span></button>
|
class="btn btn-success"
|
||||||
|
name="update_poll_info"
|
||||||
|
value="expiration_date"
|
||||||
|
title="{__('PollInfo', 'Save the new expiration date')}"
|
||||||
|
>
|
||||||
|
<span class="glyphicon glyphicon-ok"></span>
|
||||||
|
<span class="sr-only">{__('Generic', 'Save')}</span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-link btn-cancel"
|
||||||
|
title="{__('PollInfo', 'Cancel the expiration date edit')}">
|
||||||
|
<span class="glyphicon glyphicon-remove"></span>
|
||||||
|
<span class="sr-only">{__('Generic', 'Cancel')}</span>
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,16 +26,16 @@
|
|||||||
{foreach $slots as $slot}
|
{foreach $slots as $slot}
|
||||||
{foreach $slot->moments as $id=>$moment}
|
{foreach $slot->moments as $id=>$moment}
|
||||||
<td headers="M{$slot@key} D{$headersDCount} H{$headersDCount}">
|
<td headers="M{$slot@key} D{$headersDCount} H{$headersDCount}">
|
||||||
<a href="{poll_url id=$admin_poll_id admin=true action='delete_column' action_value=$slot->day|cat:'@'|cat:$moment}"
|
<a href="{poll_url id=$admin_poll_id admin=true action='delete_column' action_value=($slot->day|date_to_timestamp)|cat:'@'|cat:$moment}"
|
||||||
data-remove-confirmation="{__('adminstuds', 'Confirm removal of the column.')}"
|
data-remove-confirmation="{__('adminstuds', 'Confirm removal of the column.')}"
|
||||||
class="btn btn-link btn-sm remove-column"
|
class="btn btn-link btn-sm remove-column"
|
||||||
title="{__('adminstuds', 'Remove column')} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
title="{__('adminstuds', 'Remove column')} {$slot->day|date_format_intl:DATE_FORMAT_SHORT|html} - {$moment|html}">
|
||||||
<i class="glyphicon glyphicon-remove text-danger"></i><span class="sr-only">{__('Generic', 'Remove')}</span>
|
<i class="glyphicon glyphicon-remove text-danger"></i><span class="sr-only">{__('Generic', 'Remove')}</span>
|
||||||
</a>
|
</a>
|
||||||
{if $poll->collect_users_mail != constant("Framadate\CollectMail::NO_COLLECT")}
|
{if $poll->collect_users_mail != constant("Framadate\CollectMail::NO_COLLECT")}
|
||||||
<a href="{poll_url id=$admin_poll_id admin=true action='collect_mail' action_value=($headersDCount)}"
|
<a href="{poll_url id=$admin_poll_id admin=true action='collect_mail' action_value=($headersDCount)}"
|
||||||
class="btn btn-link btn-sm collect-mail"
|
class="btn btn-link btn-sm collect-mail"
|
||||||
title="{__('adminstuds', 'Collect the emails of the polled users for the choice')} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
title="{__('adminstuds', 'Collect the emails of the polled users for the choice')} {$slot->day|date_format_intl:DATE_FORMAT_SHORT|html} - {$moment|html}">
|
||||||
<i class="glyphicon glyphicon-envelope"></i><span class="sr-only">{__('Generic', 'Collect emails')}</span>
|
<i class="glyphicon glyphicon-envelope"></i><span class="sr-only">{__('Generic', 'Collect emails')}</span>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
@ -56,7 +56,7 @@
|
|||||||
{$count_same = 0}
|
{$count_same = 0}
|
||||||
{$previous = 0}
|
{$previous = 0}
|
||||||
{foreach $slots as $id=>$slot}
|
{foreach $slots as $id=>$slot}
|
||||||
{$display = $slot->day|date_format:$date_format.txt_month_year|html}
|
{$display = $slot->day|date_format_intl:DATE_FORMAT_MONTH_YEAR|html}
|
||||||
{if $previous !== 0 && $previous != $display}
|
{if $previous !== 0 && $previous != $display}
|
||||||
<th colspan="{$count_same}" class="bg-primary month" id="M{$id}">{$previous}</th>
|
<th colspan="{$count_same}" class="bg-primary month" id="M{$id}">{$previous}</th>
|
||||||
{$count_same = 0}
|
{$count_same = 0}
|
||||||
@ -79,7 +79,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th role="presentation"></th>
|
<th role="presentation"></th>
|
||||||
{foreach $slots as $id=>$slot}
|
{foreach $slots as $id=>$slot}
|
||||||
<th colspan="{$slot->moments|count}" class="bg-primary day" id="D{$id}">{$slot->day|date_format:$date_format.txt_day|html}</th>
|
<th colspan="{$slot->moments|count}" class="bg-primary day" id="D{$id}">{$slot->day|date_format_intl:DATE_FORMAT_DAY|html}</th>
|
||||||
{for $foo=0 to ($slot->moments|count)-1}
|
{for $foo=0 to ($slot->moments|count)-1}
|
||||||
{append var='headersD' value=$id}
|
{append var='headersD' value=$id}
|
||||||
{/for}
|
{/for}
|
||||||
@ -95,7 +95,7 @@
|
|||||||
<th colspan="1" class="bg-info" id="H{$headersDCount}">{$moment|html}</th>
|
<th colspan="1" class="bg-info" id="H{$headersDCount}">{$moment|html}</th>
|
||||||
{append var='headersH' value=$headersDCount}
|
{append var='headersH' value=$headersDCount}
|
||||||
{$headersDCount = $headersDCount+1}
|
{$headersDCount = $headersDCount+1}
|
||||||
{$slots_raw[] = $slot->day|date_format:$date_format.txt_full|cat:' - '|cat:$moment}
|
{$slots_raw[] = $slot->day|date_format_intl:DATE_FORMAT_FULL|cat:' - '|cat:$moment}
|
||||||
{/foreach}
|
{/foreach}
|
||||||
{/foreach}
|
{/foreach}
|
||||||
<th></th>
|
<th></th>
|
||||||
@ -258,12 +258,12 @@
|
|||||||
|
|
||||||
<td class="bg-info" headers="M{$headersM[$i]} D{$headersD[$i]} H{$headersH[$i]}">
|
<td class="bg-info" headers="M{$headersM[$i]} D{$headersD[$i]} H{$headersH[$i]}">
|
||||||
<ul class="list-unstyled choice">
|
<ul class="list-unstyled choice">
|
||||||
{if $poll->valuemax eq NULL || $best_choices['y'][$i] lt $poll->valuemax}
|
{if $poll->ValueMax eq NULL || $best_choices['y'][$i] lt $poll->ValueMax}
|
||||||
<li class="yes">
|
<li class="yes">
|
||||||
<input type="radio" id="y-choice-{$i}" name="choices[{$i}]" value="2"
|
<input type="radio" id="y-choice-{$i}" name="choices[{$i}]" value="2"
|
||||||
{(!isset($selectedNewVotes[$i]) || ("2" !== $selectedNewVotes[$i])) ? "" : " checked"}
|
{(!isset($selectedNewVotes[$i]) || ("2" !== $selectedNewVotes[$i])) ? "" : " checked"}
|
||||||
/>
|
/>
|
||||||
<label class="btn btn-default btn-xs" for="y-choice-{$i}" title="{__('Poll results', 'Vote "yes" for')|html} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
<label class="btn btn-default btn-xs" for="y-choice-{$i}" title="{__('Poll results', 'Vote "yes" for')|html} {$slot->day|date_format_intl:DATE_FORMAT_SHORT|html} - {$moment|html}">
|
||||||
<i class="glyphicon glyphicon-ok"></i><span class="sr-only">{__('Generic', 'Yes')}</span>
|
<i class="glyphicon glyphicon-ok"></i><span class="sr-only">{__('Generic', 'Yes')}</span>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
@ -271,7 +271,7 @@
|
|||||||
<input type="radio" id="i-choice-{$i}" name="choices[{$i}]" value="1"
|
<input type="radio" id="i-choice-{$i}" name="choices[{$i}]" value="1"
|
||||||
{(!isset($selectedNewVotes[$i]) || ("1" !== $selectedNewVotes[$i])) ? "" : " checked"}
|
{(!isset($selectedNewVotes[$i]) || ("1" !== $selectedNewVotes[$i])) ? "" : " checked"}
|
||||||
/>
|
/>
|
||||||
<label class="btn btn-default btn-xs" for="i-choice-{$i}" title="{__('Poll results', 'Votes under reserve for')|html} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
<label class="btn btn-default btn-xs" for="i-choice-{$i}" title="{__('Poll results', 'Votes under reserve for')|html} {$slot->day|date_format_intl:DATE_FORMAT_SHORT|html} - {$moment|html}">
|
||||||
(<i class="glyphicon glyphicon-ok"></i>)<span class="sr-only">{__('Generic', 'Under reserve')}</span>
|
(<i class="glyphicon glyphicon-ok"></i>)<span class="sr-only">{__('Generic', 'Under reserve')}</span>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
@ -281,7 +281,7 @@
|
|||||||
<input type="radio" id="n-choice-{$i}" name="choices[{$i}]" value="0"
|
<input type="radio" id="n-choice-{$i}" name="choices[{$i}]" value="0"
|
||||||
{(!isset($selectedNewVotes[$i]) || ("0" !== $selectedNewVotes[$i])) ? "" : " checked"}
|
{(!isset($selectedNewVotes[$i]) || ("0" !== $selectedNewVotes[$i])) ? "" : " checked"}
|
||||||
/>
|
/>
|
||||||
<label class="btn btn-default btn-xs {(!isset($selectedNewVotes[$i]) || ("0" !== $selectedNewVotes[$i])) ? "startunchecked" : ""}" for="n-choice-{$i}" title="{__('Poll results', 'Vote "no" for')|html} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
<label class="btn btn-default btn-xs {(!isset($selectedNewVotes[$i]) || ("0" !== $selectedNewVotes[$i])) ? "startunchecked" : ""}" for="n-choice-{$i}" title="{__('Poll results', 'Vote "no" for')|html} {$slot->day|date_format_intl:DATE_FORMAT_SHORT|html} - {$moment|html}">
|
||||||
<i class="glyphicon glyphicon-ban-circle"></i><span class="sr-only">{__('Generic', 'No')}</span>
|
<i class="glyphicon glyphicon-ban-circle"></i><span class="sr-only">{__('Generic', 'No')}</span>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
@ -364,7 +364,7 @@
|
|||||||
var cols = [
|
var cols = [
|
||||||
{foreach $slots as $slot}
|
{foreach $slots as $slot}
|
||||||
{foreach $slot->moments as $moment}
|
{foreach $slot->moments as $moment}
|
||||||
$('<div/>').html('{$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}').text(),
|
$('<div/>').html('{$slot->day|date_format_intl:DATE_FORMAT_SHORT|html} - {$moment|html}').text(),
|
||||||
{/foreach}
|
{/foreach}
|
||||||
{/foreach}
|
{/foreach}
|
||||||
];
|
];
|
||||||
@ -424,7 +424,7 @@
|
|||||||
{foreach $slots as $slot}
|
{foreach $slots as $slot}
|
||||||
{foreach $slot->moments as $moment}
|
{foreach $slot->moments as $moment}
|
||||||
{if $best_choices['y'][$i] == $max}
|
{if $best_choices['y'][$i] == $max}
|
||||||
<li><strong>{$slot->day|date_format:$date_format.txt_full|html} - {$moment|html}</strong></li>
|
<li><strong>{$slot->day|date_format_intl:DATE_FORMAT_SHORT|html} - {$moment|html}</strong></li>
|
||||||
{/if}
|
{/if}
|
||||||
{$i = $i+1}
|
{$i = $i+1}
|
||||||
{/foreach}
|
{/foreach}
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
{if $expired}
|
{if $expired}
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
<p>{__('studs', 'The poll has expired, it will soon be deleted.')}</p>
|
<p>{__('studs', 'The poll has expired, it will soon be deleted.')}</p>
|
||||||
<p>{__('studs', 'Deletion date:')} {$deletion_date|date_format:$date_format['txt_short']|html}</p>
|
<p>{__('studs', 'Deletion date:')} {$deletion_date|date_format_intl:DATE_FORMAT_SHORT|html}</p>
|
||||||
</div>
|
</div>
|
||||||
{else}
|
{else}
|
||||||
{if $admin}
|
{if $admin}
|
||||||
|
Loading…
Reference in New Issue
Block a user