forkbb/app/Models/Poll/Save.php

152 lines
4.2 KiB
PHP

<?php
/**
* This file is part of the ForkBB <https://github.com/forkbb>.
*
* @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
* @license The MIT License (MIT)
*/
declare(strict_types=1);
namespace ForkBB\Models\Poll;
use ForkBB\Models\Action;
use ForkBB\Models\Poll\Poll;
use ForkBB\Models\Topic\Topic;
use RuntimeException;
class Save extends Action
{
/**
* Обновляет опрос в БД
*/
public function update(Poll $poll): Poll
{
$poll->itWasModified = false;
if (true !== $this->manager->revision($poll, true)) {
throw new RuntimeException('The poll model has errors');
}
$old = $this->manager->Load->load($poll->tid);
if (! $old instanceof Poll) {
throw new RuntimeException('No such poll found');
}
$vars = [
':tid' => $poll->tid,
];
$queryIn = 'INSERT INTO ::poll (tid, question_id, field_id, qna_text)
VALUES (?i:tid, ?i:qid, ?i:fid, ?s:qna)';
$queryU1 = 'UPDATE ::poll
SET qna_text=?s:qna
WHERE tid=?i:tid AND question_id=?i:qid AND field_id=?i:fid';
$queryD1 = 'DELETE FROM ::poll
WHERE tid=?i:tid AND question_id IN (?ai:qids)';
$queryD2 = 'DELETE FROM ::poll
WHERE tid=?i:tid AND question_id=?i:qid AND field_id IN (?ai:fid)';
$modified = false;
$oldQuestion = $old->question;
$oldType = $old->type;
foreach ($poll->question as $qid => $qna) {
$vars[':qid'] = $qid;
$vars[':fid'] = 0;
$vars[':qna'] = $poll->type[$qid] . '|' . $qna;
if (! isset($oldQuestion[$qid])) {
$modified = true;
$this->c->DB->exec($queryIn, $vars);
} elseif (
$qna !== $oldQuestion[$qid]
|| $poll->type[$qid] !== $oldType[$qid]
) {
$modified = true;
$this->c->DB->exec($queryU1, $vars);
}
$oldAnswer = $old->answer[$qid] ?? [];
foreach ($poll->answer[$qid] as $fid => $qna) {
$vars[':fid'] = $fid;
$vars[':qna'] = $qna;
if (! isset($oldAnswer[$fid])) {
$modified = true;
$this->c->DB->exec($queryIn, $vars);
} elseif ($qna !== $oldAnswer[$fid]) {
$modified = true;
$this->c->DB->exec($queryU1, $vars);
}
unset($oldAnswer[$fid]);
}
if (! empty($oldAnswer)) {
$modified = true;
$vars[':fid'] = \array_keys($oldAnswer);
$this->c->DB->exec($queryD2, $vars);
}
unset($oldQuestion[$qid]);
}
if (! empty($oldQuestion)) {
$modified = true;
$vars[':qid'] = \array_keys($oldQuestion);
$this->c->DB->exec($queryD1, $vars);
}
$poll->itWasModified = $modified;
$poll->resModified();
return $poll;
}
/**
* Добавляет новый опрос в БД
*/
public function insert(Poll $poll): int
{
if (true !== $this->manager->revision($poll, true)) {
throw new RuntimeException('The poll model has errors');
}
if (null !== $this->manager->Load->load($poll->tid)) {
throw new RuntimeException('Such the poll already exists');
}
$vars = [
':tid' => $poll->tid,
];
$query = 'INSERT INTO ::poll (tid, question_id, field_id, qna_text)
VALUES (?i:tid, ?i:qid, ?i:fid, ?s:qna)';
foreach ($poll->question as $qid => $qna) {
$vars[':qid'] = $qid;
$vars[':fid'] = 0;
$vars[':qna'] = $poll->type[$qid] . '|' . $qna;
$this->c->DB->exec($query, $vars);
foreach ($poll->answer[$qid] as $fid => $qna) {
$vars[':fid'] = $fid;
$vars[':qna'] = $qna;
$this->c->DB->exec($query, $vars);
}
}
$poll->resModified();
return $poll->tid;
}
}