From b47c153aaea1d862ce6bdfdfdbf8e78ac5fc11e5 Mon Sep 17 00:00:00 2001
From: Olivier PEREZ <olivier@olivierperez.fr>
Date: Fri, 3 Apr 2015 00:11:36 +0200
Subject: [PATCH] More Splitting between Services and Repositories

---
 admin/polls.php                               |   2 +-
 adminstuds.php                                |   2 -
 app/classes/Framadate/FramaDB.php             | 196 +-----------------
 .../Repositories/AbstractRepository.php       |  12 ++
 .../Repositories/CommentRepository.php        |   6 +-
 .../Framadate/Repositories/PollRepository.php |  63 ++++++
 .../Repositories/RepositoryFactory.php        |  12 ++
 .../Framadate/Repositories/SlotRepository.php |  65 ++++++
 .../Framadate/Repositories/VoteRepository.php |  86 ++++++++
 .../Framadate/Services/AdminPollService.php   |  31 +--
 .../Framadate/Services/InputService.php       |   4 +
 .../Framadate/Services/MailService.php        |   2 +-
 .../Framadate/Services/PollService.php        |  13 +-
 .../Framadate/Services/PurgeService.php       |  27 ++-
 .../Framadate/Services/SuperAdminService.php  |  12 +-
 15 files changed, 297 insertions(+), 236 deletions(-)
 create mode 100644 app/classes/Framadate/Repositories/VoteRepository.php

diff --git a/admin/polls.php b/admin/polls.php
index 37593479..198b7cf6 100644
--- a/admin/polls.php
+++ b/admin/polls.php
@@ -52,7 +52,7 @@ $poll_to_delete = null;
 $logService = new LogService();
 $pollService = new PollService($connect, $logService);
 $adminPollService = new AdminPollService($connect, $pollService, $logService);
-$superAdminService = new SuperAdminService($connect);
+$superAdminService = new SuperAdminService();
 $securityService = new SecurityService();
 
 /* GET */
diff --git a/adminstuds.php b/adminstuds.php
index 38c92bf8..cefbac1c 100644
--- a/adminstuds.php
+++ b/adminstuds.php
@@ -21,7 +21,6 @@ use Framadate\Services\AdminPollService;
 use Framadate\Services\InputService;
 use Framadate\Services\LogService;
 use Framadate\Message;
-use Framadate\Utils;
 
 include_once __DIR__ . '/app/inc/init.php';
 
@@ -105,7 +104,6 @@ if (isset($_POST['update_poll_info'])) {
         }
     } 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 = strtotime($expiration_date);
         if ($expiration_date) {
             $poll->end_date = $expiration_date;
             $updated = true;
diff --git a/app/classes/Framadate/FramaDB.php b/app/classes/Framadate/FramaDB.php
index b8c6c79b..7c5101b2 100644
--- a/app/classes/Framadate/FramaDB.php
+++ b/app/classes/Framadate/FramaDB.php
@@ -79,199 +79,7 @@ class FramaDB {
         return $this->pdo->query($sql);
     }
 
-    function allUserVotesByPollId($poll_id) {
-        $prepared = $this->prepare('SELECT * FROM `' . Utils::table('vote') . '` WHERE poll_id = ? ORDER BY id');
-        $prepared->execute(array($poll_id));
-
-        return $prepared->fetchAll();
-    }
-
-    function insertDefaultVote($poll_id, $insert_position) {
-        $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTRING(choices, 1, ?), "0", SUBSTRING(choices, ?)) WHERE poll_id = ?');
-
-        return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]);
-    }
-
-    function insertVote($poll_id, $name, $choices) {
-        $prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices) VALUES (?,?,?)');
-        $prepared->execute([$poll_id, $name, $choices]);
-
-        $newVote = new \stdClass();
-        $newVote->poll_id = $poll_id;
-        $newVote->id = $this->pdo->lastInsertId();
-        $newVote->name = $name;
-        $newVote->choices = $choices;
-
-        return $newVote;
-    }
-
-    function deleteVote($poll_id, $vote_id) {
-        $prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND id = ?');
-
-        return $prepared->execute([$poll_id, $vote_id]);
-    }
-
-    /**
-     * Delete all votes of a given poll.
-     *
-     * @param $poll_id int The ID of the given poll.
-     * @return bool|null true if action succeeded.
-     */
-    function deleteVotesByPollId($poll_id) {
-        $prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
-
-        return $prepared->execute([$poll_id]);
-    }
-
-    /**
-     * Delete all votes made on given moment index.
-     *
-     * @param $poll_id int The ID of the poll
-     * @param $index int The index of the vote into the poll
-     * @return bool|null true if action succeeded.
-     */
-    function deleteVotesByIndex($poll_id, $index) {
-        $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTR(choices, 1, ?), SUBSTR(choices, ?)) WHERE poll_id = ?');
-
-        return $prepared->execute([$index, $index + 2, $poll_id]);
-    }
-
-    /**
-     * Find the slot into poll for a given datetime.
-     *
-     * @param $poll_id int The ID of the poll
-     * @param $datetime int The datetime of the slot
-     * @return mixed Object The slot found, or null
-     */
-    function findSlotByPollIdAndDatetime($poll_id, $datetime) {
-        $prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND SUBSTRING_INDEX(title, \'@\', 1) = ?');
-
-        $prepared->execute([$poll_id, $datetime]);
-        $slot = $prepared->fetch();
-        $prepared->closeCursor();
-
-        return $slot;
-    }
-
-    /**
-     * Insert a new slot into a given poll.
-     *
-     * @param $poll_id int The ID of the poll
-     * @param $title mixed The title of the slot
-     * @param $moments mixed|null The moments joined with ","
-     * @return bool true if action succeeded
-     */
-    function insertSlot($poll_id, $title, $moments) {
-        $prepared = $this->prepare('INSERT INTO `' . Utils::table('slot') . '` (poll_id, title, moments) VALUES (?,?,?)');
-
-        return $prepared->execute([$poll_id, $title, $moments]);
-    }
-
-    /**
-     * Update a slot into a poll.
-     *
-     * @param $poll_id int The ID of the poll
-     * @param $datetime int The datetime of the slot to update
-     * @param $newMoments mixed The new moments
-     * @return bool|null true if action succeeded.
-     */
-    function updateSlot($poll_id, $datetime, $newMoments) {
-        $prepared = $this->prepare('UPDATE `' . Utils::table('slot') . '` SET moments = ? WHERE poll_id = ? AND title = ?');
-
-        return $prepared->execute([$newMoments, $poll_id, $datetime]);
-    }
-
-    /**
-     * Delete a entire slot from a poll.
-     *
-     * @param $poll_id int The ID of the poll
-     * @param $datetime mixed The datetime of the slot
-     */
-    function deleteSlot($poll_id, $datetime) {
-        $prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND title = ?');
-        $prepared->execute([$poll_id, $datetime]);
-    }
-
-    function deleteSlotsByPollId($poll_id) {
-        $prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ?');
-
-        return $prepared->execute([$poll_id]);
-    }
-
-    function updateVote($poll_id, $vote_id, $name, $choices) {
-        $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = ?, name = ? WHERE poll_id = ? AND id = ?');
-
-        return $prepared->execute([$choices, $name, $poll_id, $vote_id]);
-    }
-
-    function deletePollById($poll_id) {
-        $prepared = $this->prepare('DELETE FROM `' . Utils::table('poll') . '` WHERE id = ?');
-
-        return $prepared->execute([$poll_id]);
-    }
-
-    /**
-     * Find old polls. Limit: 20.
-     *
-     * @return array Array of old polls
-     */
-    public function findOldPolls() {
-        $prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE DATE_ADD(`end_date`, INTERVAL ' . PURGE_DELAY . ' DAY) < NOW() AND `end_date` != 0 LIMIT 20');
-        $prepared->execute([]);
-
-        return $prepared->fetchAll();
-    }
-
-    /**
-     * Search polls in databse.
-     *
-     * @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>...]
-     * @return array The found polls
-     */
-    public function findAllPolls($search) {
-        // Polls
-        $prepared = $this->prepare('
-SELECT p.*,
-       (SELECT count(1) FROM `' . Utils::table('vote') . '` v WHERE p.id=v.poll_id) votes
-  FROM `' . Utils::table('poll') . '` p
- WHERE (:id = "" OR p.id LIKE :id)
-   AND (:title = "" OR p.title LIKE :title)
-   AND (:name = "" OR p.admin_name LIKE :name)
- ORDER BY p.title ASC
- ');
-
-        $poll = $search['poll'] . '%';
-        $title = '%' . $search['title'] . '%';
-        $name = '%' . $search['name'] . '%';
-        $prepared->bindParam(':id', $poll, PDO::PARAM_STR);
-        $prepared->bindParam(':title', $title, PDO::PARAM_STR);
-        $prepared->bindParam(':name', $name, PDO::PARAM_STR);
-        $prepared->execute();
-
-        return $prepared->fetchAll();
-    }
-
-    /**
-     * Get the total number of polls in databse.
-     *
-     * @return int The number of polls
-     */
-    public function countPolls() {
-        // Total count
-        $stmt = $this->query('SELECT count(1) nb FROM `' . Utils::table('poll') . '`');
-        $count = $stmt->fetch();
-        $stmt->closeCursor();
-
-        return $count->nb;
-    }
-
-    public function countVotesByPollId($poll_id) {
-        $prepared = $this->prepare('SELECT count(1) nb FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
-
-        $prepared->execute([$poll_id]);
-        $result = $prepared->fetch();
-        $prepared->closeCursor();
-
-        return $result->nb;
+    public function lastInsertId() {
+        return $this->pdo->lastInsertId();
     }
 }
diff --git a/app/classes/Framadate/Repositories/AbstractRepository.php b/app/classes/Framadate/Repositories/AbstractRepository.php
index 35c03445..736436fa 100644
--- a/app/classes/Framadate/Repositories/AbstractRepository.php
+++ b/app/classes/Framadate/Repositories/AbstractRepository.php
@@ -26,8 +26,20 @@ abstract class AbstractRepository {
         $this->connect->commit();
     }
 
+    function rollback() {
+        $this->connect->rollback();
+    }
+
     public function prepare($sql) {
         return $this->connect->prepare($sql);
     }
 
+    function query($sql) {
+        return $this->connect->query($sql);
+    }
+
+    function lastInsertId() {
+        return $this->connect->lastInsertId();
+    }
+
 }
diff --git a/app/classes/Framadate/Repositories/CommentRepository.php b/app/classes/Framadate/Repositories/CommentRepository.php
index 4511390b..4fb5fd91 100644
--- a/app/classes/Framadate/Repositories/CommentRepository.php
+++ b/app/classes/Framadate/Repositories/CommentRepository.php
@@ -10,7 +10,7 @@ class CommentRepository extends AbstractRepository {
         parent::__construct($connect);
     }
 
-    function allCommentsByPollId($poll_id) {
+    function findAllByPollId($poll_id) {
         $prepared = $this->prepare('SELECT * FROM `' . Utils::table('comment') . '` WHERE poll_id = ? ORDER BY id');
         $prepared->execute(array($poll_id));
 
@@ -31,7 +31,7 @@ class CommentRepository extends AbstractRepository {
         return $prepared->execute([$poll_id, $name, $comment]);
     }
 
-    function delete($poll_id, $comment_id) {
+    function deleteById($poll_id, $comment_id) {
         $prepared = $this->prepare('DELETE FROM `' . Utils::table('comment') . '` WHERE poll_id = ? AND id = ?');
 
         return $prepared->execute([$poll_id, $comment_id]);
@@ -50,7 +50,7 @@ class CommentRepository extends AbstractRepository {
     }
 
     public function exists($poll_id, $name, $comment) {
-        $prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('comment') . '` WHERE poll_id = ? QND name = ? AND comment = ?');
+        $prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('comment') . '` WHERE poll_id = ? AND name = ? AND comment = ?');
         $prepared->execute(array($poll_id, $name, $comment));
 
         return $prepared->rowCount() > 0;
diff --git a/app/classes/Framadate/Repositories/PollRepository.php b/app/classes/Framadate/Repositories/PollRepository.php
index 041b3e7d..76013e9e 100644
--- a/app/classes/Framadate/Repositories/PollRepository.php
+++ b/app/classes/Framadate/Repositories/PollRepository.php
@@ -1,7 +1,9 @@
 <?php
 namespace Framadate\Repositories;
 
+use Framadate\FramaDB;
 use Framadate\Utils;
+use PDO;
 
 class PollRepository extends AbstractRepository {
 
@@ -41,4 +43,65 @@ class PollRepository extends AbstractRepository {
         return $prepared->execute([$poll->title, $poll->admin_name, $poll->admin_mail, $poll->description, $poll->end_date, $poll->active, $poll->editable, $poll->id]);
     }
 
+    function deleteById($poll_id) {
+        $prepared = $this->prepare('DELETE FROM `' . Utils::table('poll') . '` WHERE id = ?');
+
+        return $prepared->execute([$poll_id]);
+    }
+
+    /**
+     * Find old polls. Limit: 20.
+     *
+     * @return array Array of old polls
+     */
+    public function findOldPolls() {
+        $prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE DATE_ADD(`end_date`, INTERVAL ' . PURGE_DELAY . ' DAY) < NOW() AND `end_date` != 0 LIMIT 20');
+        $prepared->execute([]);
+
+        return $prepared->fetchAll();
+    }
+
+    /**
+     * Search polls in databse.
+     *
+     * @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>...]
+     * @return array The found polls
+     */
+    public function findAll($search) {
+        // Polls
+        $prepared = $this->prepare('
+SELECT p.*,
+       (SELECT count(1) FROM `' . Utils::table('vote') . '` v WHERE p.id=v.poll_id) votes
+  FROM `' . Utils::table('poll') . '` p
+ WHERE (:id = "" OR p.id LIKE :id)
+   AND (:title = "" OR p.title LIKE :title)
+   AND (:name = "" OR p.admin_name LIKE :name)
+ ORDER BY p.title ASC
+ ');
+
+        $poll = $search['poll'] . '%';
+        $title = '%' . $search['title'] . '%';
+        $name = '%' . $search['name'] . '%';
+        $prepared->bindParam(':id', $poll, PDO::PARAM_STR);
+        $prepared->bindParam(':title', $title, PDO::PARAM_STR);
+        $prepared->bindParam(':name', $name, PDO::PARAM_STR);
+        $prepared->execute();
+
+        return $prepared->fetchAll();
+    }
+
+    /**
+     * Get the total number of polls in databse.
+     *
+     * @return int The number of polls
+     */
+    public function count() {
+        // Total count
+        $stmt = $this->query('SELECT count(1) nb FROM `' . Utils::table('poll') . '`');
+        $count = $stmt->fetch();
+        $stmt->closeCursor();
+
+        return $count->nb;
+    }
+
 }
diff --git a/app/classes/Framadate/Repositories/RepositoryFactory.php b/app/classes/Framadate/Repositories/RepositoryFactory.php
index 6e2437d2..f7a6fbff 100644
--- a/app/classes/Framadate/Repositories/RepositoryFactory.php
+++ b/app/classes/Framadate/Repositories/RepositoryFactory.php
@@ -26,6 +26,7 @@ class RepositoryFactory {
 
     private static $pollRepository;
     private static $slotRepository;
+    private static $voteRepository;
     private static $commentRepository;
 
     /**
@@ -57,6 +58,17 @@ class RepositoryFactory {
         return self::$slotRepository;
     }
 
+    /**
+     * @return VoteRepository The singleton of VoteRepository
+     */
+    static function voteRepository() {
+        if (self::$voteRepository == null) {
+            self::$voteRepository = new VoteRepository(self::$connect);
+        }
+
+        return self::$voteRepository;
+    }
+
     /**
      * @return CommentRepository The singleton of CommentRepository
      */
diff --git a/app/classes/Framadate/Repositories/SlotRepository.php b/app/classes/Framadate/Repositories/SlotRepository.php
index b816a6ef..fcd11c26 100644
--- a/app/classes/Framadate/Repositories/SlotRepository.php
+++ b/app/classes/Framadate/Repositories/SlotRepository.php
@@ -18,6 +18,9 @@
  */
 namespace Framadate\Repositories;
 
+use Framadate\FramaDB;
+use Framadate\Utils;
+
 class SlotRepository extends AbstractRepository {
 
     function __construct(FramaDB $connect) {
@@ -64,4 +67,66 @@ class SlotRepository extends AbstractRepository {
         return $prepared->fetchAll();
     }
 
+    /**
+     * Find the slot into poll for a given datetime.
+     *
+     * @param $poll_id int The ID of the poll
+     * @param $datetime int The datetime of the slot
+     * @return mixed Object The slot found, or null
+     */
+    function findByPollIdAndDatetime($poll_id, $datetime) {
+        $prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND SUBSTRING_INDEX(title, \'@\', 1) = ?');
+
+        $prepared->execute([$poll_id, $datetime]);
+        $slot = $prepared->fetch();
+        $prepared->closeCursor();
+
+        return $slot;
+    }
+
+    /**
+     * Insert a new slot into a given poll.
+     *
+     * @param $poll_id int The ID of the poll
+     * @param $title mixed The title of the slot
+     * @param $moments mixed|null The moments joined with ","
+     * @return bool true if action succeeded
+     */
+    function insert($poll_id, $title, $moments) {
+        $prepared = $this->prepare('INSERT INTO `' . Utils::table('slot') . '` (poll_id, title, moments) VALUES (?,?,?)');
+
+        return $prepared->execute([$poll_id, $title, $moments]);
+    }
+
+    /**
+     * Update a slot into a poll.
+     *
+     * @param $poll_id int The ID of the poll
+     * @param $datetime int The datetime of the slot to update
+     * @param $newMoments mixed The new moments
+     * @return bool|null true if action succeeded.
+     */
+    function update($poll_id, $datetime, $newMoments) {
+        $prepared = $this->prepare('UPDATE `' . Utils::table('slot') . '` SET moments = ? WHERE poll_id = ? AND title = ?');
+
+        return $prepared->execute([$newMoments, $poll_id, $datetime]);
+    }
+
+    /**
+     * Delete a entire slot from a poll.
+     *
+     * @param $poll_id int The ID of the poll
+     * @param $datetime mixed The datetime of the slot
+     */
+    function deleteByDateTime($poll_id, $datetime) {
+        $prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND title = ?');
+        $prepared->execute([$poll_id, $datetime]);
+    }
+
+    function deleteByPollId($poll_id) {
+        $prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ?');
+
+        return $prepared->execute([$poll_id]);
+    }
+
 }
diff --git a/app/classes/Framadate/Repositories/VoteRepository.php b/app/classes/Framadate/Repositories/VoteRepository.php
new file mode 100644
index 00000000..467dd0a7
--- /dev/null
+++ b/app/classes/Framadate/Repositories/VoteRepository.php
@@ -0,0 +1,86 @@
+<?php
+namespace Framadate\Repositories;
+
+use Framadate\FramaDB;
+use Framadate\Utils;
+
+class VoteRepository extends AbstractRepository {
+
+    function __construct(FramaDB $connect) {
+        parent::__construct($connect);
+    }
+
+    function allUserVotesByPollId($poll_id) {
+        $prepared = $this->prepare('SELECT * FROM `' . Utils::table('vote') . '` WHERE poll_id = ? ORDER BY id');
+        $prepared->execute(array($poll_id));
+
+        return $prepared->fetchAll();
+    }
+
+    function insertDefault($poll_id, $insert_position) {
+        $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTRING(choices, 1, ?), "0", SUBSTRING(choices, ?)) WHERE poll_id = ?');
+
+        return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]);
+    }
+
+    function insert($poll_id, $name, $choices) {
+        $prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices) VALUES (?,?,?)');
+        $prepared->execute([$poll_id, $name, $choices]);
+
+        $newVote = new \stdClass();
+        $newVote->poll_id = $poll_id;
+        $newVote->id = $this->lastInsertId();
+        $newVote->name = $name;
+        $newVote->choices = $choices;
+
+        return $newVote;
+    }
+
+    function deleteById($poll_id, $vote_id) {
+        $prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND id = ?');
+
+        return $prepared->execute([$poll_id, $vote_id]);
+    }
+
+    /**
+     * Delete all votes of a given poll.
+     *
+     * @param $poll_id int The ID of the given poll.
+     * @return bool|null true if action succeeded.
+     */
+    function deleteByPollId($poll_id) {
+        $prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
+
+        return $prepared->execute([$poll_id]);
+    }
+
+    /**
+     * Delete all votes made on given moment index.
+     *
+     * @param $poll_id int The ID of the poll
+     * @param $index int The index of the vote into the poll
+     * @return bool|null true if action succeeded.
+     */
+    function deleteByIndex($poll_id, $index) {
+        $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTR(choices, 1, ?), SUBSTR(choices, ?)) WHERE poll_id = ?');
+
+        return $prepared->execute([$index, $index + 2, $poll_id]);
+    }
+
+    function update($poll_id, $vote_id, $name, $choices) {
+        $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = ?, name = ? WHERE poll_id = ? AND id = ?');
+
+        return $prepared->execute([$choices, $name, $poll_id, $vote_id]);
+    }
+
+    public function countByPollId($poll_id) {
+        $prepared = $this->prepare('SELECT count(1) nb FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
+
+        $prepared->execute([$poll_id]);
+        $result = $prepared->fetch();
+        $prepared->closeCursor();
+
+        return $result->nb;
+    }
+
+}
diff --git a/app/classes/Framadate/Services/AdminPollService.php b/app/classes/Framadate/Services/AdminPollService.php
index 4e4f9d6d..b4b47d56 100644
--- a/app/classes/Framadate/Services/AdminPollService.php
+++ b/app/classes/Framadate/Services/AdminPollService.php
@@ -14,8 +14,10 @@ class AdminPollService {
     private $connect;
     private $pollService;
     private $logService;
+
     private $pollRepository;
     private $slotRepository;
+    private $voteRepository;
     private $commentRepository;
 
     function __construct(FramaDB $connect, PollService $pollService, LogService $logService) {
@@ -24,6 +26,7 @@ class AdminPollService {
         $this->logService = $logService;
         $this->pollRepository = RepositoryFactory::pollRepository();
         $this->slotRepository = RepositoryFactory::slotRepository();
+        $this->voteRepository = RepositoryFactory::voteRepository();
         $this->commentRepository = RepositoryFactory::commentRepository();
     }
 
@@ -44,7 +47,7 @@ class AdminPollService {
      * @return mixed true is action succeeded
      */
     function deleteComment($poll_id, $comment_id) {
-        return $this->commentRepository->delete($poll_id, $comment_id);
+        return $this->commentRepository->deleteById($poll_id, $comment_id);
     }
 
     /**
@@ -66,7 +69,7 @@ class AdminPollService {
      * @return mixed true is action succeeded
      */
     function deleteVote($poll_id, $vote_id) {
-        return $this->connect->deleteVote($poll_id, $vote_id);
+        return $this->voteRepository->deleteById($poll_id, $vote_id);
     }
 
     /**
@@ -77,7 +80,7 @@ class AdminPollService {
      */
     function cleanVotes($poll_id) {
         $this->logService->log('CLEAN_VOTES', 'id:' . $poll_id);
-        return $this->connect->deleteVotesByPollId($poll_id);
+        return $this->voteRepository->deleteByPollId($poll_id);
     }
 
     /**
@@ -91,10 +94,10 @@ class AdminPollService {
         $this->logService->log('DELETE_POLL', "id:$poll->id, format:$poll->format, admin:$poll->admin_name, mail:$poll->admin_mail");
 
         // Delete the entire poll
-        $this->connect->deleteVotesByPollId($poll_id);
+        $this->voteRepository->deleteByPollId($poll_id);
         $this->commentRepository->deleteByPollId($poll_id);
-        $this->connect->deleteSlotsByPollId($poll_id);
-        $this->connect->deletePollById($poll_id);
+        $this->slotRepository->deleteByPollId($poll_id);
+        $this->pollRepository->deleteById($poll_id);
 
         return true;
     }
@@ -136,11 +139,11 @@ class AdminPollService {
 
         // Remove votes
         $this->connect->beginTransaction();
-        $this->connect->deleteVotesByIndex($poll_id, $indexToDelete);
+        $this->voteRepository->deleteByIndex($poll_id, $indexToDelete);
         if (count($newMoments) > 0) {
-            $this->connect->updateSlot($poll_id, $datetime, implode(',', $newMoments));
+            $this->slotRepository->update($poll_id, $datetime, implode(',', $newMoments));
         } else {
-            $this->connect->deleteSlot($poll_id, $datetime);
+            $this->slotRepository->deleteByDateTime($poll_id, $datetime);
         }
         $this->connect->commit();
 
@@ -165,8 +168,8 @@ class AdminPollService {
 
         // Remove votes
         $this->connect->beginTransaction();
-        $this->connect->deleteVotesByIndex($poll_id, $indexToDelete);
-        $this->connect->deleteSlot($poll_id, $slot_title);
+        $this->voteRepository->deleteByIndex($poll_id, $indexToDelete);
+        $this->slotRepository->deleteByDateTime($poll_id, $slot_title);
         $this->connect->commit();
 
         return true;
@@ -206,13 +209,13 @@ class AdminPollService {
             // Update found slot
             $moments[] = $new_moment;
             sort($moments);
-            $this->connect->updateSlot($poll_id, $datetime, implode(',', $moments));
+            $this->slotRepository->update($poll_id, $datetime, implode(',', $moments));
 
         } else {
-            $this->connect->insertSlot($poll_id, $datetime, $new_moment);
+            $this->slotRepository->insert($poll_id, $datetime, $new_moment);
         }
 
-        $this->connect->insertDefaultVote($poll_id, $result->insert);
+        $this->voteRepository->insertDefault($poll_id, $result->insert);
 
         // Commit transaction
         $this->connect->commit();
diff --git a/app/classes/Framadate/Services/InputService.php b/app/classes/Framadate/Services/InputService.php
index aafed00d..cf3b55ee 100644
--- a/app/classes/Framadate/Services/InputService.php
+++ b/app/classes/Framadate/Services/InputService.php
@@ -28,6 +28,10 @@ class InputService {
     /**
      * This method filter an array calling "filter_var" on each items.
      * Only items validated are added at their own indexes, the others are not returned.
+     * @param array $arr The array to filter
+     * @param int $type The type of filter to apply
+     * @param array|null $options The associative array of options
+     * @return array The filtered array
      */
     function filterArray(array $arr, $type, $options = null) {
         $newArr = [];
diff --git a/app/classes/Framadate/Services/MailService.php b/app/classes/Framadate/Services/MailService.php
index c8ce77dd..3095869b 100644
--- a/app/classes/Framadate/Services/MailService.php
+++ b/app/classes/Framadate/Services/MailService.php
@@ -39,7 +39,7 @@ class MailService {
             $headers .= "Auto-Submitted:auto-generated\n";
             $headers .= 'Return-Path: <>';
 
-            $body = html_entity_decode($body, ENT_QUOTES, 'UTF-8') . _("\n--\n\n« La route est longue, mais la voie est libre… »\nFramasoft ne vit que par vos dons (déductibles des impôts).\nMerci d'avance pour votre soutien http://soutenir.framasoft.org.");
+            $body = html_entity_decode($body, ENT_QUOTES, 'UTF-8') . __('Mail', "\n--\n\n« La route est longue, mais la voie est libre… »\nFramasoft ne vit que par vos dons (déductibles des impôts).\nMerci d'avance pour votre soutien http://soutenir.framasoft.org.");
 
             mail($to, $subject, $body, $headers, $param);
         }
diff --git a/app/classes/Framadate/Services/PollService.php b/app/classes/Framadate/Services/PollService.php
index 4cc7fa14..832dfe5d 100644
--- a/app/classes/Framadate/Services/PollService.php
+++ b/app/classes/Framadate/Services/PollService.php
@@ -26,8 +26,10 @@ class PollService {
 
     private $connect;
     private $logService;
+
     private $pollRepository;
     private $slotRepository;
+    private $voteRepository;
     private $commentRepository;
 
     function __construct(FramaDB $connect, LogService $logService) {
@@ -35,6 +37,7 @@ class PollService {
         $this->logService = $logService;
         $this->pollRepository = RepositoryFactory::pollRepository();
         $this->slotRepository = RepositoryFactory::slotRepository();
+        $this->voteRepository = RepositoryFactory::voteRepository();
         $this->commentRepository = RepositoryFactory::commentRepository();
     }
 
@@ -53,11 +56,11 @@ class PollService {
     }
 
     function allCommentsByPollId($poll_id) {
-        return $this->commentRepository->allCommentsByPollId($poll_id);
+        return $this->commentRepository->findAllByPollId($poll_id);
     }
 
     function allVotesByPollId($poll_id) {
-        return $this->connect->allUserVotesByPollId($poll_id);
+        return $this->voteRepository->allUserVotesByPollId($poll_id);
     }
 
     function allSlotsByPollId($poll_id) {
@@ -67,13 +70,13 @@ class PollService {
     public function updateVote($poll_id, $vote_id, $name, $choices) {
         $choices = implode($choices);
 
-        return $this->connect->updateVote($poll_id, $vote_id, $name, $choices);
+        return $this->voteRepository->update($poll_id, $vote_id, $name, $choices);
     }
 
     function addVote($poll_id, $name, $choices) {
         $choices = implode($choices);
 
-        return $this->connect->insertVote($poll_id, $name, $choices);
+        return $this->voteRepository->insert($poll_id, $name, $choices);
     }
 
     function addComment($poll_id, $name, $comment) {
@@ -85,7 +88,7 @@ class PollService {
     }
 
     public function countVotesByPollId($poll_id) {
-        return $this->connect->countVotesByPollId($poll_id);
+        return $this->voteRepository->countByPollId($poll_id);
     }
 
     /**
diff --git a/app/classes/Framadate/Services/PurgeService.php b/app/classes/Framadate/Services/PurgeService.php
index fc05365b..c9011736 100644
--- a/app/classes/Framadate/Services/PurgeService.php
+++ b/app/classes/Framadate/Services/PurgeService.php
@@ -1,6 +1,7 @@
 <?php
 namespace Framadate\Services;
 use Framadate\FramaDB;
+use Framadate\Repositories\RepositoryFactory;
 
 /**
  * This service helps to purge data.
@@ -9,12 +10,18 @@ use Framadate\FramaDB;
  */
 class PurgeService {
 
-    private $connect;
     private $logService;
+    private $pollRepository;
+    private $slotRepository;
+    private $voteRepository;
+    private $commentRepository;
 
     function __construct(FramaDB $connect, LogService $logService) {
-        $this->connect = $connect;
         $this->logService = $logService;
+        $this->pollRepository = RepositoryFactory::pollRepository();
+        $this->slotRepository = RepositoryFactory::slotRepository();
+        $this->voteRepository = RepositoryFactory::voteRepository();
+        $this->commentRepository = RepositoryFactory::commentRepository();
     }
 
     /**
@@ -23,7 +30,7 @@ class PurgeService {
      * @return bool true is action succeeded
      */
     function purgeOldPolls() {
-        $oldPolls = $this->connect->findOldPolls();
+        $oldPolls = $this->pollRepository->findOldPolls();
         $count = count($oldPolls);
 
         if ($count > 0) {
@@ -50,16 +57,16 @@ class PurgeService {
     function purgePollById($poll_id) {
         $done = true;
 
-        $this->connect->beginTransaction();
-        $done &= $this->connect->deleteCommentsByPollId($poll_id);
-        $done &= $this->connect->deleteVotesByPollId($poll_id);
-        $done &= $this->connect->deleteSlotsByPollId($poll_id);
-        $done &= $this->connect->deletePollById($poll_id);
+        $this->pollRepository->beginTransaction();
+        $done &= $this->commentRepository->deleteByPollId($poll_id);
+        $done &= $this->voteRepository->deleteByPollId($poll_id);
+        $done &= $this->slotRepository->deleteByPollId($poll_id);
+        $done &= $this->pollRepository->deleteById($poll_id);
 
         if ($done) {
-            $this->connect->commit();
+            $this->pollRepository->commit();
         } else {
-            $this->connect->rollback();
+            $this->pollRepository->rollback();
         }
 
         return $done;
diff --git a/app/classes/Framadate/Services/SuperAdminService.php b/app/classes/Framadate/Services/SuperAdminService.php
index 066af955..a4b78500 100644
--- a/app/classes/Framadate/Services/SuperAdminService.php
+++ b/app/classes/Framadate/Services/SuperAdminService.php
@@ -1,7 +1,7 @@
 <?php
 namespace Framadate\Services;
 
-use Framadate\FramaDB;
+use Framadate\Repositories\RepositoryFactory;
 
 /**
  * The class provides action for application administrators.
@@ -10,10 +10,10 @@ use Framadate\FramaDB;
  */
 class SuperAdminService {
 
-    private $connect;
+    private $pollRepository;
 
-    function __construct(FramaDB $connect) {
-        $this->connect = $connect;
+    function __construct() {
+        $this->pollRepository = RepositoryFactory::pollRepository();
     }
 
     /**
@@ -26,8 +26,8 @@ class SuperAdminService {
      */
     public function findAllPolls($search, $page, $limit) {
         $start = $page * $limit;
-        $polls = $this->connect->findAllPolls($search);
-        $total = $this->connect->countPolls();
+        $polls = $this->pollRepository->findAll($search);
+        $total = $this->pollRepository->count();
 
 
         return ['polls' => array_slice($polls, $start, $limit), 'count' => count($polls), 'total' => $total];
-- 
GitLab