From 288ddd2efc765d91389951fe0286caaa0d29f1a0 Mon Sep 17 00:00:00 2001 From: Olivier PEREZ <olivier@olivierperez.fr> Date: Tue, 23 Dec 2014 00:30:05 +0100 Subject: [PATCH] admin: Add availability to add a slot to a poll --- app/classes/Framadate/FramaDB.php | 19 ++- .../Framadate/Services/AdminPollService.php | 112 +++++++++++++++--- app/classes/Framadate/Utils.php | 2 +- 3 files changed, 117 insertions(+), 16 deletions(-) diff --git a/app/classes/Framadate/FramaDB.php b/app/classes/Framadate/FramaDB.php index 2e03d577..aab3fc1a 100644 --- a/app/classes/Framadate/FramaDB.php +++ b/app/classes/Framadate/FramaDB.php @@ -48,6 +48,18 @@ class FramaDB { $this->pdo->commit(); } + function rollback() { + $this->pdo->rollback(); + } + + function errorCode() { + return $this->pdo->errorCode(); + } + + function errorInfo() { + return $this->pdo->errorInfo(); + } + function query($sql) { return $this->pdo->query($sql); } @@ -63,7 +75,7 @@ class FramaDB { } function updatePoll($poll) { - $prepared = $this->prepare('UPDATE sondage SET title=?, admin_mail=?, comment=?, active=?, editable=? WHERE sondage.poll_id = ?'); + $prepared = $this->prepare('UPDATE sondage SET title=?, admin_mail=?, comment=?, active=?, editable=? WHERE poll_id = ?'); return $prepared->execute([$poll->title, $poll->admin_mail, $poll->comment, $poll->active, $poll->editable, $poll->poll_id]); } @@ -86,6 +98,11 @@ class FramaDB { return $prepared->fetchAll(); } + function insertDefaultVote($poll_id, $insert_position) { + $prepared = $this->prepare('UPDATE user_studs SET reponses = CONCAT(SUBSTRING(reponses, 1, ?), "0", SUBSTRING(reponses, ?)) WHERE id_sondage = ?'); + return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]); + } + function insertVote($poll_id, $name, $choices) { $prepared = $this->prepare('INSERT INTO user_studs (id_sondage,nom,reponses) VALUES (?,?,?)'); $prepared->execute([$poll_id, $name, $choices]); diff --git a/app/classes/Framadate/Services/AdminPollService.php b/app/classes/Framadate/Services/AdminPollService.php index b6bca393..ce4deb6d 100644 --- a/app/classes/Framadate/Services/AdminPollService.php +++ b/app/classes/Framadate/Services/AdminPollService.php @@ -1,8 +1,11 @@ <?php namespace Framadate\Services; +use Framadate\Utils; + /** * Class AdminPollService + * * @package Framadate\Services */ class AdminPollService { @@ -106,30 +109,111 @@ class AdminPollService { $this->connect->commit(); } - public function addSlot($poll_id, $newdate, $newmoment) { - $ex = explode('/', $newdate); - $datetime = mktime(0,0,0, $ex[1], $ex[0], $ex[2]); + /** + * Add a new slot to the poll. And insert default values for user's votes. + * <ul> + * <li>Create a new slot if no one exists for the given date</li> + * <li>Create a new moment if a slot already exists for the given date</li> + * </ul> + * + * @param $poll_id int The ID of the poll + * @param $new_date string The date (format: d/m/Y) + * @param $new_moment string The moment's name + * @return bool true if added + */ + public function addSlot($poll_id, $new_date, $new_moment) { + $ex = explode('/', $new_date); + $datetime = mktime(0, 0, 0, $ex[1], $ex[0], $ex[2]); - $slot = $this->connect->findSlotByPollIdAndDatetime($poll_id, $datetime); + $slots = $this->connect->allSlotsByPollId($poll_id); + $result = $this->findInsertPosition($slots, $datetime, $new_moment); - if ($slot != null) { - // Update found slot - $moments = explode('@', $slot->sujet)[1]; - foreach ($moments as $moment) { - if ($moment == $newmoment) { - return false; - } + // Begin transaction + $this->connect->beginTransaction(); + + if ($result == null) { + // The moment already exists + return false; + } elseif ($result->slot != null) { + $slot = $result->slot; + + $joined_moments = explode('@', $slot->sujet)[1]; + $moments = explode(',', $joined_moments); + + // Check if moment already exists (maybe not necessary) + if (in_array($new_moment, $moments)) { + return false; } - // TODO Implements + + // Update found slot + $moments[] = $new_moment; + sort($moments); + $this->connect->updateSlot($poll_id, $datetime, $datetime . '@' . implode(',', $moments)); } else { - // TODO Found index of insertion, in order to update user votes - $this->connect->insertSlot($poll_id, $datetime . '@' . $newmoment); + $this->connect->insertSlot($poll_id, $datetime . '@' . $new_moment); } + $this->connect->insertDefaultVote($poll_id, $result->insert); + + // Commit transaction + $this->connect->commit(); + return true; } + /** + * This method find where to insert a datatime+moment into a list of slots.<br/> + * Return the {insert:X}, where X is the index of the moment into the whole poll (ex: X=0 => Insert to the first column). + * Return {slot:Y}, where Y is not null if there is a slot existing for the given datetime. + * + * @param $slots array All the slots of the poll + * @param $datetime int The datetime of the new slot + * @param $moment string The moment's name + * @return null|\stdClass An object like this one: {insert:X, slot:Y} where Y can be null. + */ + private function findInsertPosition($slots, $datetime, $moment) { + $result = new \stdClass(); + $result->slot = null; + $result->insert = -1; + + $i = 0; + + foreach ($slots as $slot) { + $ex = explode('@', $slot->sujet); + $rowDatetime = $ex[0]; + $moments = explode(',', $ex[1]); + + if ($datetime == $rowDatetime) { + $result->slot = $slot; + + foreach ($moments as $rowMoment) { + $strcmp = strcmp($moment, $rowMoment); + if ($strcmp < 0) { + // Here we have to insert at First place or middle of the slot + break(2); + } elseif ($strcmp == 0) { + // Here we dont have to insert at all + return null; + } + $i++; + } + + // Here we have to insert at the end of a slot + $result->insert = $i; + break; + } elseif ($datetime < $rowDatetime) { + // Here we have to insert a new slot + break; + } else { + $i += count($moments); + } + } + $result->insert = $i; + + return $result; + } + } \ No newline at end of file diff --git a/app/classes/Framadate/Utils.php b/app/classes/Framadate/Utils.php index cb8a0783..0226eb7c 100644 --- a/app/classes/Framadate/Utils.php +++ b/app/classes/Framadate/Utils.php @@ -214,7 +214,7 @@ class Utils /** * This method pretty prints an object to the page framed by pre tags. - * @param Object $object The object to print. + * @param mixed $object The object to print. */ public static function debug($object) { -- GitLab