. * * @copyright (c) Visman * @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; } }