diff --git a/CHANGELOG.md b/CHANGELOG.md index 0281d56..09ef086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Amélioration : Mise à jour des fichiers .md pour faciliter la collaboration - Amélioration : Le nom de l'auteur et la date d'expiration sont modifiables - Amélioration : Le nom de vote est modifiable + - Amélioration : Affichage du comptage des "Si nécessaire" entre parenthèses - Fix : Purge en 2 étapes → 1. Verrouillage du sondage → 2. 60 jours plus tard suppression du sondage - Fix : Date d'expiration qui devient nulle quand on ajoute une colonne - Fix : clic/focus sur oui/non/si nécessaire → retour à gauche de la barre de scroll sur Chromium diff --git a/admin/purge.php b/admin/purge.php index 5a8e268..fb817f1 100644 --- a/admin/purge.php +++ b/admin/purge.php @@ -21,7 +21,6 @@ use Framadate\Services\InputService; use Framadate\Services\LogService; use Framadate\Services\PurgeService; use Framadate\Services\SecurityService; -use Framadate\Utils; include_once __DIR__ . '/../app/inc/init.php'; include_once __DIR__ . '/../bandeaux.php'; diff --git a/adminstuds.php b/adminstuds.php index 5d7e2d6..d5f9cab 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -16,15 +16,22 @@ * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft) */ -use Framadate\Services\PollService; +use Framadate\Editable; +use Framadate\Message; use Framadate\Services\AdminPollService; use Framadate\Services\InputService; use Framadate\Services\LogService; -use Framadate\Message; -use Framadate\Editable; +use Framadate\Services\MailService; +use Framadate\Services\PollService; +use Framadate\Utils; include_once __DIR__ . '/app/inc/init.php'; +/* Constants */ +/* --------- */ +const UPDATE_POLL = 1; +const DELETED_POLL = 2; + /* Variables */ /* --------- */ @@ -41,6 +48,41 @@ $logService = new LogService(); $pollService = new PollService($connect, $logService); $adminPollService = new AdminPollService($connect, $pollService, $logService); $inputService = new InputService(); +$mailService = new MailService($config['use_smtp']); + +/* Functions */ +/*-----------*/ + +/** + * Send a notification to the poll admin to notify him about an update. + * + * @param stdClass $poll The poll + * @param MailService $mailService The mail service + * @param int $type cf: Constants on the top of this page + */ +function sendUpdateNotification($poll, $mailService, $type) { + if (!isset($_SESSION['mail_sent'])) { + $_SESSION['mail_sent'] = []; + } + + if ($poll->receiveNewVotes) { + + $subject = '[' . NOMAPPLICATION . '] ' . __('Mail', 'Notification of poll') . ' : ' . $poll->title; + + $message = ''; + switch ($type) { + case UPDATE_POLL: + $message = __f('Mail', 'Someone just change your poll available at the following link %s.', Utils::getUrlSondage($poll->admin_id, true)) . "\n\n"; + break; + case DELETED_POLL: + $message = __f('Mail', 'Someone just delete your poll %s.', Utils::htmlEscape($poll->title)) . "\n\n"; + break; + } + + $messageTypeKey = $type . '-' . $poll->id; + $mailService->send($poll->admin_mail, $subject, $message, $messageTypeKey); + } +} /* PAGE */ /* ---- */ @@ -111,7 +153,8 @@ if (isset($_POST['update_poll_info'])) { break; } } elseif ($field == 'expiration_date') { - $expiration_date = filter_input(INPUT_POST, 'expiration_date', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]+[-/][0-9]+[-/][0-9]+#']]); + $expiration_date = filter_input(INPUT_POST, 'expiration_date', FILTER_VALIDATE_REGEXP, + ['options' => ['regexp' => '#^[0-9]{4}-[0-9]{2}-[0-9]{2}$#']]); if ($expiration_date) { $poll->end_date = $expiration_date; $updated = true; @@ -133,6 +176,7 @@ if (isset($_POST['update_poll_info'])) { // Update poll in database if ($updated && $adminPollService->updatePoll($poll)) { $message = new Message('success', __('adminstuds', 'Poll saved')); + sendUpdateNotification($poll, $mailService, UPDATE_POLL); } else { $message = new Message('danger', __('Error', 'Failed to save poll')); $poll = $pollService->findById($poll_id); @@ -297,6 +341,7 @@ if (isset($_POST['delete_poll'])) { if (isset($_POST['confirm_delete_poll'])) { if ($adminPollService->deleteEntirePoll($poll_id)) { $message = new Message('success', __('adminstuds', 'Poll fully deleted')); + sendUpdateNotification($poll, $mailService, DELETED_POLL); } else { $message = new Message('danger', __('Error', 'Failed to delete the poll')); } @@ -322,15 +367,15 @@ if (!empty($_GET['delete_column'])) { $slot->title = $ex[0]; $slot->moment = $ex[1]; - $result = $adminPollService->deleteDateSlot($poll_id, $slot); + $result = $adminPollService->deleteDateSlot($poll, $slot); } else { - $result = $adminPollService->deleteClassicSlot($poll_id, $column); + $result = $adminPollService->deleteClassicSlot($poll, $column); } if ($result) { $message = new Message('success', __('adminstuds', 'Column removed')); } else { - $message = new Message('danger', __('Error', 'Failed to delete the column')); + $message = new Message('danger', __('Error', 'Failed to delete column')); } } @@ -352,10 +397,10 @@ if (isset($_POST['confirm_add_slot'])) { $newmoment = strip_tags($_POST['newmoment']); $ex = explode('/', $newdate); - $result = $adminPollService->addSlot($poll_id, mktime(0, 0, 0, $ex[1], $ex[0], $ex[2]), $newmoment); + $result = $adminPollService->addDateSlot($poll_id, mktime(0, 0, 0, $ex[1], $ex[0], $ex[2]), $newmoment); } else { $newslot = strip_tags($_POST['choice']); - $result = $adminPollService->addSlot($poll_id, $newslot, null); + $result = $adminPollService->addClassicSlot($poll_id, $newslot); } if ($result) { @@ -366,7 +411,7 @@ if (isset($_POST['confirm_add_slot'])) { } // Retrieve data -$slots = $pollService->allSlotsByPollId($poll_id); +$slots = $pollService->allSlotsByPoll($poll); $votes = $pollService->allVotesByPollId($poll_id); $comments = $pollService->allCommentsByPollId($poll_id); @@ -377,7 +422,7 @@ $smarty->assign('admin_poll_id', $admin_poll_id); $smarty->assign('poll', $poll); $smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title); $smarty->assign('expired', strtotime($poll->end_date) < time()); -$smarty->assign('deletion_date', $poll->end_date + PURGE_DELAY * 86400); +$smarty->assign('deletion_date', strtotime($poll->end_date) + PURGE_DELAY * 86400); $smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots); $smarty->assign('votes', $pollService->splitVotes($votes)); $smarty->assign('best_choices', $pollService->computeBestChoices($votes)); diff --git a/app/classes/Framadate/Form.php b/app/classes/Framadate/Form.php index ce802ba..f73cd9e 100644 --- a/app/classes/Framadate/Form.php +++ b/app/classes/Framadate/Form.php @@ -18,8 +18,6 @@ */ namespace Framadate; -use Framadate\Editable; - class Form { diff --git a/app/classes/Framadate/Repositories/SlotRepository.php b/app/classes/Framadate/Repositories/SlotRepository.php index fcd11c2..7d69e00 100644 --- a/app/classes/Framadate/Repositories/SlotRepository.php +++ b/app/classes/Framadate/Repositories/SlotRepository.php @@ -61,7 +61,7 @@ class SlotRepository extends AbstractRepository { } function listByPollId($poll_id) { - $prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? ORDER BY title'); + $prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? ORDER BY id'); $prepared->execute(array($poll_id)); return $prepared->fetchAll(); diff --git a/app/classes/Framadate/Services/AdminPollService.php b/app/classes/Framadate/Services/AdminPollService.php index b4b47d5..fb020bc 100644 --- a/app/classes/Framadate/Services/AdminPollService.php +++ b/app/classes/Framadate/Services/AdminPollService.php @@ -105,17 +105,21 @@ class AdminPollService { /** * Delete a slot from a poll. * - * @param $poll_id int The ID of the poll - * @param $slot object The slot informations (datetime + moment) + * @param object $poll The ID of the poll + * @param object $slot The slot informations (datetime + moment) * @return bool true if action succeeded */ - public function deleteDateSlot($poll_id, $slot) { - $this->logService->log('DELETE_SLOT', 'id:' . $poll_id . ', slot:' . json_encode($slot)); + public function deleteDateSlot($poll, $slot) { + $this->logService->log('DELETE_SLOT', 'id:' . $poll->id . ', slot:' . json_encode($slot)); $datetime = $slot->title; $moment = $slot->moment; - $slots = $this->pollService->allSlotsByPollId($poll_id); + $slots = $this->pollService->allSlotsByPoll($poll); + + if (count($slots) === 1) { + return false; + } $index = 0; $indexToDelete = -1; @@ -139,21 +143,25 @@ class AdminPollService { // Remove votes $this->connect->beginTransaction(); - $this->voteRepository->deleteByIndex($poll_id, $indexToDelete); + $this->voteRepository->deleteByIndex($poll->id, $indexToDelete); if (count($newMoments) > 0) { - $this->slotRepository->update($poll_id, $datetime, implode(',', $newMoments)); + $this->slotRepository->update($poll->id, $datetime, implode(',', $newMoments)); } else { - $this->slotRepository->deleteByDateTime($poll_id, $datetime); + $this->slotRepository->deleteByDateTime($poll->id, $datetime); } $this->connect->commit(); return true; } - public function deleteClassicSlot($poll_id, $slot_title) { - $this->logService->log('DELETE_SLOT', 'id:' . $poll_id . ', slot:' . $slot_title); + public function deleteClassicSlot($poll, $slot_title) { + $this->logService->log('DELETE_SLOT', 'id:' . $poll->id . ', slot:' . $slot_title); - $slots = $this->pollService->allSlotsByPollId($poll_id); + $slots = $this->pollService->allSlotsByPoll($poll); + + if (count($slots) === 1) { + return false; + } $index = 0; $indexToDelete = -1; @@ -168,15 +176,15 @@ class AdminPollService { // Remove votes $this->connect->beginTransaction(); - $this->voteRepository->deleteByIndex($poll_id, $indexToDelete); - $this->slotRepository->deleteByDateTime($poll_id, $slot_title); + $this->voteRepository->deleteByIndex($poll->id, $indexToDelete); + $this->slotRepository->deleteByDateTime($poll->id, $slot_title); $this->connect->commit(); return true; } /** - * Add a new slot to the poll. And insert default values for user's votes. + * Add a new slot to a date poll. And insert default values for user's votes. *