tag_id < 1 ? -1 : $this->tag_id; } public function getName(): string { return $this->tag_name; } public function setName(string $name): self { $this->tag_name = $name; return $this; } public function getDescription(): string { return $this->tag_description; } public function hasDescription(): bool { return !empty($this->tag_description); } public function setDescription(string $description): self { $this->tag_description = $description; return $this; } public function getCreatedTime(): int { return $this->tag_created ?? -1; } public function getArchivedTime(): int { return $this->tag_archived ?? -1; } public function isArchived(): bool { return $this->getArchivedTime() >= 0; } public function setArchived(bool $archived): self { if($this->isArchived() !== $archived) $this->tag_archived = $archived ? time() : null; return $this; } public function getChangeCount(): int { if($this->changeCount < 0) $this->changeCount = ChangelogChangeTag::countByTag($this); return $this->changeCount; } public function jsonSerialize(): mixed { return [ 'id' => $this->getId(), 'name' => $this->getName(), 'description' => $this->getDescription(), 'created' => ($time = $this->getCreatedTime()) < 0 ? null : date('c', $time), 'archived' => ($time = $this->getArchivedTime()) < 0 ? null : date('c', $time), ]; } public function compare(ChangelogTag $other): bool { return $other === $this || $other->getId() === $this->getId(); } public function save(): void { $isInsert = $this->getId() < 1; if($isInsert) { $query = 'INSERT INTO `%1$s%2$s` (`tag_name`, `tag_description`, `tag_archived`)' . ' VALUES (:name, :description, FROM_UNIXTIME(:archived))'; } else { $query = 'UPDATE `%1$s%2$s` SET `tag_name` = :name, `tag_description` = :description, `tag_archived` = FROM_UNIXTIME(:archived)' . ' WHERE `tag_id` = :tag'; } $saveTag = DB::prepare(sprintf($query, DB::PREFIX, self::TABLE)) ->bind('name', $this->tag_name) ->bind('description', $this->tag_description) ->bind('archived', $this->tag_archived); if($isInsert) { $this->tag_id = $saveTag->executeGetId(); $this->tag_created = time(); } else { $saveTag->bind('tag', $this->getId()) ->execute(); } } private static function memoizer(): Memoizer { static $memoizer = null; if($memoizer === null) $memoizer = new Memoizer; return $memoizer; } private static function byQueryBase(): string { return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE)); } public static function byId(int $tagId): self { return self::memoizer()->find($tagId, function() use ($tagId) { $tag = DB::prepare(self::byQueryBase() . ' WHERE `tag_id` = :tag') ->bind('tag', $tagId) ->fetchObject(self::class); if(!$tag) throw new ChangelogTagNotFoundException; return $tag; }); } public static function byChange(ChangelogChange $change): array { return DB::prepare( self::byQueryBase() . ' WHERE `tag_id` IN (SELECT `tag_id` FROM `' . DB::PREFIX . ChangelogChangeTag::TABLE . '` WHERE `change_id` = :change)' )->bind('change', $change->getId())->fetchObjects(self::class); } public static function all(): array { return DB::prepare(self::byQueryBase()) ->fetchObjects(self::class); } }