279 lines
8.7 KiB
PHP
279 lines
8.7 KiB
PHP
<?php
|
|
namespace Framadate\Services;
|
|
|
|
use Framadate\FramaDB;
|
|
use Framadate\Repositories\RepositoryFactory;
|
|
|
|
/**
|
|
* Class AdminPollService
|
|
*
|
|
* @package Framadate\Services
|
|
*/
|
|
class AdminPollService {
|
|
|
|
private $connect;
|
|
private $pollService;
|
|
private $logService;
|
|
|
|
private $pollRepository;
|
|
private $slotRepository;
|
|
private $voteRepository;
|
|
private $commentRepository;
|
|
|
|
function __construct(FramaDB $connect, PollService $pollService, LogService $logService) {
|
|
$this->connect = $connect;
|
|
$this->pollService = $pollService;
|
|
$this->logService = $logService;
|
|
$this->pollRepository = RepositoryFactory::pollRepository();
|
|
$this->slotRepository = RepositoryFactory::slotRepository();
|
|
$this->voteRepository = RepositoryFactory::voteRepository();
|
|
$this->commentRepository = RepositoryFactory::commentRepository();
|
|
}
|
|
|
|
function updatePoll($poll) {
|
|
global $config;
|
|
if ($poll->end_date > $poll->creation_date && $poll->end_date <= strtotime($poll->creation_date) + (86400 * $config['default_poll_duration'])) {
|
|
return $this->pollRepository->update($poll);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a comment from a poll.
|
|
*
|
|
* @param $poll_id int The ID of the poll
|
|
* @param $comment_id int The ID of the comment
|
|
* @return mixed true is action succeeded
|
|
*/
|
|
function deleteComment($poll_id, $comment_id) {
|
|
return $this->commentRepository->deleteById($poll_id, $comment_id);
|
|
}
|
|
|
|
/**
|
|
* Remove all comments of a poll.
|
|
*
|
|
* @param $poll_id int The ID a the poll
|
|
* @return bool|null true is action succeeded
|
|
*/
|
|
function cleanComments($poll_id) {
|
|
$this->logService->log("CLEAN_COMMENTS", "id:$poll_id");
|
|
return $this->commentRepository->deleteByPollId($poll_id);
|
|
}
|
|
|
|
/**
|
|
* Delete a vote from a poll.
|
|
*
|
|
* @param $poll_id int The ID of the poll
|
|
* @param $vote_id int The ID of the vote
|
|
* @return mixed true is action succeeded
|
|
*/
|
|
function deleteVote($poll_id, $vote_id) {
|
|
return $this->voteRepository->deleteById($poll_id, $vote_id);
|
|
}
|
|
|
|
/**
|
|
* Remove all votes of a poll.
|
|
*
|
|
* @param $poll_id int The ID of the poll
|
|
* @return bool|null true is action succeeded
|
|
*/
|
|
function cleanVotes($poll_id) {
|
|
$this->logService->log('CLEAN_VOTES', 'id:' . $poll_id);
|
|
return $this->voteRepository->deleteByPollId($poll_id);
|
|
}
|
|
|
|
/**
|
|
* Delete the entire given poll.
|
|
*
|
|
* @param $poll_id int The ID of the poll
|
|
* @return bool true is action succeeded
|
|
*/
|
|
function deleteEntirePoll($poll_id) {
|
|
$poll = $this->pollRepository->findById($poll_id);
|
|
$this->logService->log('DELETE_POLL', "id:$poll->id, format:$poll->format, admin:$poll->admin_name, mail:$poll->admin_mail");
|
|
|
|
// Delete the entire poll
|
|
$this->voteRepository->deleteByPollId($poll_id);
|
|
$this->commentRepository->deleteByPollId($poll_id);
|
|
$this->slotRepository->deleteByPollId($poll_id);
|
|
$this->pollRepository->deleteById($poll_id);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Delete a slot from a poll.
|
|
*
|
|
* @param $poll_id int The ID of the poll
|
|
* @param $slot object 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));
|
|
|
|
$datetime = $slot->title;
|
|
$moment = $slot->moment;
|
|
|
|
$slots = $this->pollService->allSlotsByPollId($poll_id);
|
|
|
|
$index = 0;
|
|
$indexToDelete = -1;
|
|
$newMoments = [];
|
|
|
|
// Search the index of the slot to delete
|
|
foreach ($slots as $aSlot) {
|
|
$moments = explode(',', $aSlot->moments);
|
|
|
|
foreach ($moments as $rowMoment) {
|
|
if ($datetime == $aSlot->title) {
|
|
if ($moment == $rowMoment) {
|
|
$indexToDelete = $index;
|
|
} else {
|
|
$newMoments[] = $rowMoment;
|
|
}
|
|
}
|
|
$index++;
|
|
}
|
|
}
|
|
|
|
// Remove votes
|
|
$this->connect->beginTransaction();
|
|
$this->voteRepository->deleteByIndex($poll_id, $indexToDelete);
|
|
if (count($newMoments) > 0) {
|
|
$this->slotRepository->update($poll_id, $datetime, implode(',', $newMoments));
|
|
} else {
|
|
$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);
|
|
|
|
$slots = $this->pollService->allSlotsByPollId($poll_id);
|
|
|
|
$index = 0;
|
|
$indexToDelete = -1;
|
|
|
|
// Search the index of the slot to delete
|
|
foreach ($slots as $aSlot) {
|
|
if ($slot_title == $aSlot->title) {
|
|
$indexToDelete = $index;
|
|
}
|
|
$index++;
|
|
}
|
|
|
|
// Remove votes
|
|
$this->connect->beginTransaction();
|
|
$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.
|
|
* <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 $datetime int The datetime
|
|
* @param $new_moment string The moment's name
|
|
* @return bool true if added
|
|
*/
|
|
public function addSlot($poll_id, $datetime, $new_moment) {
|
|
$slots = $this->slotRepository->listByPollId($poll_id);
|
|
$result = $this->findInsertPosition($slots, $datetime, $new_moment);
|
|
|
|
// Begin transaction
|
|
$this->connect->beginTransaction();
|
|
|
|
if ($result == null) {
|
|
// The moment already exists
|
|
return false;
|
|
} elseif ($result->slot != null) {
|
|
$slot = $result->slot;
|
|
$moments = explode(',', $slot->moments);
|
|
|
|
// Check if moment already exists (maybe not necessary)
|
|
if (in_array($new_moment, $moments)) {
|
|
return false;
|
|
}
|
|
|
|
// Update found slot
|
|
$moments[] = $new_moment;
|
|
sort($moments);
|
|
$this->slotRepository->update($poll_id, $datetime, implode(',', $moments));
|
|
|
|
} else {
|
|
$this->slotRepository->insert($poll_id, $datetime, $new_moment);
|
|
}
|
|
|
|
$this->voteRepository->insertDefault($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) {
|
|
$rowDatetime = $slot->title;
|
|
$moments = explode(',', $slot->moments);
|
|
|
|
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;
|
|
}
|
|
|
|
}
|
|
|