Couple of fixes following DBAL migration

* Make sure we save timestamp as a string (🙈) inside slot table
* Make sure to set poll format properly at creation
* More Repository methods use DBAL specifics
* Clear legacy check all tables call

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2018-04-23 10:27:15 +02:00
parent b008bfea9b
commit 87a61ebea3
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
7 changed files with 110 additions and 73 deletions

View File

@ -39,9 +39,8 @@ class PollRepository extends AbstractRepository {
*/
public function findById($poll_id)
{
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('poll') . ' WHERE id = ?');
$prepared = $this->connect->executeQuery('SELECT * FROM ' . Utils::table('poll') . ' WHERE id = ?', [$poll_id]);
$prepared->execute([$poll_id]);
$poll = $prepared->fetch();
$prepared->closeCursor();
@ -54,9 +53,8 @@ class PollRepository extends AbstractRepository {
* @return mixed
*/
public function findByAdminId($admin_poll_id) {
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('poll') . ' WHERE admin_id = ?');
$prepared = $this->connect->executeQuery('SELECT * FROM ' . Utils::table('poll') . ' WHERE admin_id = ?', [$admin_poll_id]);
$prepared->execute([$admin_poll_id]);
$poll = $prepared->fetch();
$prepared->closeCursor();
@ -124,14 +122,12 @@ class PollRepository extends AbstractRepository {
/**
* Find old polls. Limit: 20.
*
* @param int $limit
* @throws \Doctrine\DBAL\DBALException
* @return array Array of old polls
*/
public function findOldPolls($limit = 20)
public function findOldPolls()
{
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('poll') . ' WHERE DATE_ADD(end_date, INTERVAL ? DAY) < NOW() AND end_date != 0 LIMIT ?');
$prepared->execute([PURGE_DELAY, $limit]);
$prepared = $this->connect->executeQuery('SELECT * FROM ' . Utils::table('poll') . ' WHERE DATE_ADD(end_date, INTERVAL ? DAY) < NOW() AND end_date != 0 LIMIT 20', [PURGE_DELAY]);
return $prepared->fetchAll();
}

View File

@ -18,6 +18,7 @@
*/
namespace Framadate\Repositories;
use Framadate\Choice;
use Framadate\Utils;
class SlotRepository extends AbstractRepository {
@ -29,6 +30,7 @@ class SlotRepository extends AbstractRepository {
*/
public function insertSlots($poll_id, $choices) {
foreach ($choices as $choice) {
/** @var Choice $choice */
// We prepared the slots (joined by comas)
$joinedSlots = null;
$first = true;
@ -42,7 +44,11 @@ class SlotRepository extends AbstractRepository {
}
// We execute the insertion
$this->connect->insert(Utils::table('slot'), ['poll_id' => $poll_id, 'title' => $choice->getName(), 'moments' => $joinedSlots]);
$this->connect->insert(Utils::table('slot'), [
'poll_id' => $poll_id,
'title' => $choice->getName(),
'moments' => $joinedSlots
]);
}
}

View File

@ -2,6 +2,7 @@
namespace Framadate\Services;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Framadate\Exception\MomentAlreadyExistsException;
use Framadate\Repositories\RepositoryFactory;
@ -196,36 +197,46 @@ class AdminPollService {
* @param $datetime int The datetime
* @param $new_moment string The moment's name
* @throws MomentAlreadyExistsException When the moment to add already exists in database
* @throws \Doctrine\DBAL\ConnectionException
*/
public function addDateSlot($poll_id, $datetime, $new_moment) {
$this->logService->log('ADD_COLUMN', 'id:' . $poll_id . ', datetime:' . $datetime . ', moment:' . $new_moment);
$slots = $this->slotRepository->listByPollId($poll_id);
$result = $this->findInsertPosition($slots, $datetime);
// Begin transaction
$this->connect->beginTransaction();
if ($result->slot !== null) {
$slot = $result->slot;
$moments = explode(',', $slot->moments);
// Check if moment already exists (maybe not necessary)
if (in_array($new_moment, $moments, true)) {
throw new MomentAlreadyExistsException();
}
// Update found slot
$moments[] = $new_moment;
$this->slotRepository->update($poll_id, $datetime, implode(',', $moments));
} else {
$this->slotRepository->insert($poll_id, $datetime, $new_moment);
try {
$slots = $this->slotRepository->listByPollId($poll_id);
$result = $this->findInsertPosition($slots, $datetime);
} catch (DBALException $e) {
$this->logService->log('ERROR', "Database error, couldn't find slot insert position" . $e->getMessage());
return;
}
$this->voteRepository->insertDefault($poll_id, $result->insert);
try {
// Begin transaction
$this->connect->beginTransaction();
// Commit transaction
$this->connect->commit();
if ($result->slot !== null) {
$slot = $result->slot;
$moments = explode(',', $slot->moments);
// Check if moment already exists (maybe not necessary)
if (in_array($new_moment, $moments, true)) {
throw new MomentAlreadyExistsException();
}
// Update found slot
$moments[] = $new_moment;
$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();
} catch (DBALException $e) {
$this->connect->rollBack();
}
}
/**
@ -237,6 +248,8 @@ class AdminPollService {
* @param $poll_id int The ID of the poll
* @param $title int The title
* @throws MomentAlreadyExistsException When the moment to add already exists in database
* @throws \Doctrine\DBAL\ConnectionException
* @throws \Doctrine\DBAL\DBALException
*/
public function addClassicSlot($poll_id, $title) {
$this->logService->log('ADD_COLUMN', 'id:' . $poll_id . ', title:' . $title);

View File

@ -19,6 +19,7 @@
namespace Framadate\Services;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\DBALException;
use Framadate\Exception\AlreadyExistsException;
use Framadate\Exception\ConcurrentEditionException;
@ -49,20 +50,31 @@ class PollService {
* Find a poll from its ID.
*
* @param $poll_id int The ID of the poll
* @throws \Doctrine\DBAL\DBALException
* @return \stdClass|null The found poll, or null
*/
function findById($poll_id) {
if (preg_match(POLL_REGEX, $poll_id)) {
return $this->pollRepository->findById($poll_id);
try {
if (preg_match(POLL_REGEX, $poll_id)) {
return $this->pollRepository->findById($poll_id);
}
} catch (DBALException $e) {
$this->logService->log('ERROR', 'Database error : ' . $e->getMessage());
}
return null;
}
/**
* @param $admin_poll_id
* @return mixed|null
*/
public function findByAdminId($admin_poll_id) {
if (preg_match(ADMIN_POLL_REGEX, $admin_poll_id)) {
return $this->pollRepository->findByAdminId($admin_poll_id);
try {
if (preg_match(ADMIN_POLL_REGEX, $admin_poll_id)) {
return $this->pollRepository->findByAdminId($admin_poll_id);
}
} catch (DBALException $e) {
$this->logService->log('ERROR', 'Database error : ' . $e->getMessage());
}
return null;
@ -149,27 +161,36 @@ class PollService {
function createPoll(Form $form) {
// Generate poll IDs, loop while poll ID already exists
if (empty($form->id)) { // User want us to generate an id for him
do {
$poll_id = $this->random(16);
} while ($this->pollRepository->existsById($poll_id));
$admin_poll_id = $poll_id . $this->random(8);
} else { // User have choosen the poll id
$poll_id = $form->id;
do {
$admin_poll_id = $this->random(24);
} while ($this->pollRepository->existsByAdminId($admin_poll_id));
try {
if (empty($form->id)) { // User want us to generate an id for him
do {
$poll_id = $this->random(16);
} while ($this->pollRepository->existsById($poll_id));
$admin_poll_id = $poll_id . $this->random(8);
} else { // User have choosen the poll id
$poll_id = $form->id;
do {
$admin_poll_id = $this->random(24);
} while ($this->pollRepository->existsByAdminId($admin_poll_id));
}
// Insert poll + slots
$this->pollRepository->beginTransaction();
$this->pollRepository->insertPoll($poll_id, $admin_poll_id, $form);
$this->slotRepository->insertSlots($poll_id, $form->getChoices());
$this->pollRepository->commit();
$this->logService->log(
'CREATE_POLL',
'id:' . $poll_id . ', title: ' . $form->title . ', format:' . $form->format . ', admin:' . $form->admin_name . ', mail:' . $form->admin_mail
);
return [$poll_id, $admin_poll_id];
} catch (DBALException $e) {
$this->pollRepository->rollback();
$this->logService->log('ERROR', "Poll couldn't be saved : " . $e->getMessage());
return null;
}
// Insert poll + slots
$this->pollRepository->beginTransaction();
$this->pollRepository->insertPoll($poll_id, $admin_poll_id, $form);
$this->slotRepository->insertSlots($poll_id, $form->getChoices());
$this->pollRepository->commit();
$this->logService->log('CREATE_POLL', 'id:' . $poll_id . ', title: ' . $form->title . ', format:' . $form->format . ', admin:' . $form->admin_name . ', mail:' . $form->admin_mail);
return [$poll_id, $admin_poll_id];
}
public function findAllByAdminMail($mail) {

View File

@ -43,15 +43,6 @@ function bandeau_titre($titre)
<hr class="trait" role="presentation" />
</header>
<main role="main">';
global $connect;
$tables = $connect->allTables();
$diff = array_diff([Utils::table('comment'), Utils::table('poll'), Utils::table('slot'), Utils::table('vote')], $tables);
if (0 !== count($diff)) {
echo '<div class="alert alert-danger">' . __('Error', 'Framadate is not properly installed, please check the "INSTALL" to setup the database before continuing.') . '</div>';
bandeau_pied();
die();
}
}
function liste_lang()

View File

@ -51,8 +51,12 @@ if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (
$min_expiry_time = $pollService->minExpiryDate();
$max_expiry_time = $pollService->maxExpiryDate();
// The poll format is AUTRE (other)
if ($_SESSION['form']->format !== 'A') {
// The poll format is other (A) if we are in this file
if (!isset($_SESSION['form'])) {
$_SESSION['form']->format = 'A';
}
// If we come from another format, we need to clear choices
if (isset($_SESSION['form']->format) && $_SESSION['form']->format !== 'A') {
$_SESSION['form']->format = 'A';
$_SESSION['form']->clearChoices();
}
@ -111,7 +115,7 @@ if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (
// creation message
$sessionService->set("Framadate", "messagePollCreated", TRUE);
// Redirect to poll administration
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
exit;

View File

@ -44,8 +44,12 @@ if (is_readable('bandeaux_local.php')) {
$min_expiry_time = $pollService->minExpiryDate();
$max_expiry_time = $pollService->maxExpiryDate();
// The poll format is DATE
if (isset($_SESSION['form']->format) && ($_SESSION['form']->format !== 'D')) {
// The poll format is DATE if we are in this file
if (!isset($_SESSION['form'])) {
$_SESSION['form']->format = 'D';
}
// If we come from another format, we need to clear choices
if (isset($_SESSION['form']->format) && $_SESSION['form']->format !== 'D') {
$_SESSION['form']->format = 'D';
$_SESSION['form']->clearChoices();
}
@ -73,6 +77,7 @@ switch ($step) {
// Prefill form->choices
foreach ($_SESSION['form']->getChoices() as $c) {
/** @var Choice $c */
$count = 3 - count($c->getSlots());
for ($i = 0; $i < $count; $i++) {
$c->addSlot('');
@ -136,7 +141,7 @@ switch ($step) {
if (!empty($day)) {
// Add choice to Form data
$date = DateTime::createFromFormat(__('Date', 'datetime_parseformat'), $_POST['days'][$i])->setTime(0, 0, 0);
$time = $date->getTimestamp();
$time = (string) $date->getTimestamp();
$choice = new Choice($time);
$_SESSION['form']->addChoice($choice);
@ -155,6 +160,7 @@ switch ($step) {
$summary = '<ul>';
$choices = $_SESSION['form']->getChoices();
foreach ($choices as $choice) {
/** @var Choice $choice */
$summary .= '<li>' . strftime($date_format['txt_full'], $choice->getName());
$first = true;
foreach ($choice->getSlots() as $slots) {
@ -235,7 +241,7 @@ switch ($step) {
// creation message
$sessionService->set("Framadate", "messagePollCreated", TRUE);
// Redirect to poll administration
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
exit;