setTable('messages') ->setFactory($factory); } protected Factory\Model $factory; public function getFactory(): Factory\Model { return $this->factory; } public function setFactory(Factory\Model $factory): Message { $this->factory = $factory; return $this; } public function install(): void { $query = " CREATE TABLE {$this->getTable()} ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `uid` VARCHAR(255) NOT NULL, `mailbox_id` INT UNSIGNED NOT NULL, `position` INT UNSIGNED NOT NULL, `subject` VARCHAR(255) NOT NULL, `from` VARCHAR(255) NOT NULL, `date_time` DATETIME NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY `fk_mailboxes_{$this->getTable()}` (`mailbox_id`) REFERENCES `mailboxes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE )"; $this->getConnection()->query($query); } protected function fieldsForUpdate(): array { return $this->fieldsForInsert(); } protected function fieldsForInsert(): array { return [ 'uid', 'mailbox_id', 'position', 'subject', 'from', 'date_time' ]; } protected function fieldsForCreate(): array { return $this->fieldsForUpdate(); } protected function valuesForUpdate(Model $model): array { return array_merge($this->valuesForInsert($model), [ $model->getId() ]); } protected function valuesForInsert(Model $model): array { return [ $model->getUID(), $model->getMailbox()->getId(), $model->getPosition(), $model->getSubject(), $model->getFrom(), $model->getDateTime()->format('Y-m-d H:i:s') ]; } protected function defaultFind(Model $model): Model { return $this->fetchByUID($model->getUID()); } protected function valuesForCreate(array $data): array { return [ $data['mailbox_id'], $data['position'], $data['uid'], $data['subject'], $data['from'], $data['date_time'] ]; } protected function defaultSearch(array $data): Model { return $this->fetchByUID($data['uid']); } /** * @param array $row * @return \ProVM\Emails\Model\Message */ public function load(array $row): \ProVM\Emails\Model\Message { return (new \ProVM\Emails\Model\Message()) ->setId($row['id']) ->setUID($row['uid']) ->setMailbox($this->getFactory()->find(\ProVM\Emails\Model\Mailbox::class)->fetchById($row['mailbox_id'])) ->setPosition($row['position']) ->setSubject($row['subject']) ->setFrom($row['from']) ->setDateTime(new DateTimeImmutable($row['date_time'])) ->setFactory($this->getFactory()); } public function save(Model &$model): void { parent::save($model); $valid_states = [ 'has_attachments', 'valid_attachments', 'downloaded_attachments', 'scheduled_downloads' ]; $stateRepository = $this->getFactory()->find(\ProVM\Emails\Model\State\Message::class); foreach ($valid_states as $state_name) { try { $model->getState($state_name); } catch (\Exception $e) { $this->getLogger()->warning($e); $data = [ 'message_id' => $model->getId(), 'name' => $state_name ]; $state = $stateRepository->create($data); $model->addState($state); } } foreach ($model->getStates() as $state) { //$state->setMessage($model); $stateRepository->save($state); } } public function fetchByUID(string $uid): \ProVM\Emails\Model\Message { $query = "SELECT * FROM `{$this->getTable()}` WHERE `uid` = ?"; return $this->fetchOne($query, [$uid]); } public function fetchByMailbox(int $mailbox_id): array { $query = "SELECT * FROM `{$this->getTable()}` WHERE `mailbox_id` = ?"; return $this->fetchMany($query, [$mailbox_id]); } public function fetchByMailboxAndPosition(int $mailbox_id, int $start, int $amount): array { $query = "SELECT * FROM `{$this->getTable()}` WHERE `mailbox_id` = ? AND `position` BETWEEN ? AND ? LIMIT {$amount}"; return $this->fetchMany($query, [$mailbox_id, $start, $start + $amount]); } public function fetchValidByMailbox(int $mailbox_id): array { $query = "SELECT a.* FROM `{$this->getTable()}` a JOIN `messages_states` b ON b.`message_id` = a.`id` WHERE a.`mailbox_id` = ? AND b.`name` = 'valid_attachments' AND b.`value` = 1"; return $this->fetchMany($query, [$mailbox_id]); } public function fetchByMailboxSubjectFromAndDate(int $mailbox_id, string $subject, string $from, DateTimeInterface $dateTime): \ProVM\Emails\Model\Message { $query = "SELECT * FROM `{$this->getTable()}` WHERE `mailbox_id` = ? `subject` = ? AND `from` = ? AND `date_time` = ?"; return $this->fetchOne($query, [$mailbox_id, $subject, $from, $dateTime->format('Y-m-d H:i:s')]); } public function fetchAllBySubjectAndDate(string $subject, DateTimeInterface $dateTime): array { $query = "SELECT * FROM `{$this->getTable()}` WHERE `subject` = ? AND `date_time` BETWEEN ? AND ?"; return $this->fetchMany($query, [$subject, $dateTime->format('Y-m-d 00:00:00'), $dateTime->format('Y-m-d 23:59:59')]); } }