from(Database::get_table(Posts::TABLE_NAME)) ->where([Posts::POST_NAME->value => $slugify ? slugify($name) : $name]) ->limit(1) ->select(Posts::ID->value); return $query->num_rows === 1 ? new static($query->fetch_assoc()[Posts::ID->value]) : null; } /** * Create a new post * * @param string $title Post title * @param string $type Post type * @return static */ public static function new(string $title): static { // Return existing post if exists if (self::from_name($title)) { return self::from_name($title); } $values = [ Posts::ID->value => null, Posts::POST_AUTHOR->value => 0, Posts::POST_DATE->value => date(static::DATETIME_FORMAT), Posts::POST_DATE_GMT->value => date(static::DATETIME_FORMAT), Posts::POST_CONTENT->value => "", Posts::POST_TITLE->value => $title, Posts::POST_EXCERPT->value => "", Posts::POST_STATUS->value => "private", Posts::COMMENT_STATUS->value => "closed", Posts::PING_STATUS->value => "closed", Posts::POST_PASSWORD->value => "", Posts::POST_NAME->value => slugify($title), Posts::TO_PING->value => "", Posts::PINGED->value => "", Posts::POST_MODIFIED->value => date(static::DATETIME_FORMAT), Posts::POST_MODIFIED_GMT->value => date(static::DATETIME_FORMAT), Posts::POST_CONTENT_FILTERED->value => "", Posts::POST_PARENT->value => 0, Posts::GUID->value => "", Posts::MENU_ORDER->value => 0, Posts::POST_TYPE->value => "post", Posts::POST_MIME_TYPE->value => "", Posts::COMMENT_COUNT->value => 0 ]; if (!parent::create(Database::get_table(Posts::TABLE_NAME), $values)) { throw new Exception("Failed to create database entity"); } return self::from_name($title); } public function __construct(public readonly int $id) { parent::__construct( Database::get_table(Posts::TABLE_NAME), Posts::values(), [Posts::ID->value => (int) $id] ); } /** * Get post meta fields for this Post. An array of all post meta is returned if no $key is provided * * @param string|null $key Return the value of this post meta key. Null for all post meta fields * @return string|array|null Returns a string or null if a single key is selected. Array if all post meta fields are returned */ public function meta(?string $key = null): string|array|null { return $key ? PostMeta::get_post_meta($this, $key) : PostMeta::get_all_post_meta($this); } /** * Returns an array of all Terms assigned to this Post * * @return array */ public function terms(): array { return Term::from_post($this); } /** * Add a Term to this Post * * @param Term $term * @return void */ public function add_term(Term $term): void { $term->add_to_post($this); } /** * Remove a Term from this Post * * @param Term $term * @return void */ public function remove_term(Term $term): void { $term->remove_from_post($this); } /** * Get, set, or unset featured media for this Post * * @param Attachment|false|null $attachment Pass Attachment to set featured media, false to unset, and null (or nothing) to get featured media * @return Attachment|null Returns an Attachment if featured media is set. Null if no featured media is set */ public function featured_media(Attachment|false|null $featured_media = null): ?Attachment { // Remove featured media from this Post if ($featured_media === false) { Attachment::remove_post_featured_media($this); return null; } // Set Attachment as the featured media for this Post if ($featured_media instanceof Attachment) { $featured_media->set_post_featured($this); return $featured_media; } return Attachment::from_post_featured($this); } public int $post_author { get => $this->get(Posts::POST_AUTHOR->value); set (int $post_author) => $this->set(Posts::POST_AUTHOR->value, $post_author); } public DateTimeImmutable $post_date { get => new DateTimeImmutable($this->get(Posts::POST_DATE->value)); set (DateTimeImmutable $post_date) => $this->set(Posts::POST_DATE->value, $post_date->format(static::DATETIME_FORMAT)); } public DateTimeImmutable $post_date_gmt { get => new DateTimeImmutable($this->get(Posts::POST_DATE_GMT->value)); set (DateTimeImmutable $post_date_gmt) => $this->set(Posts::POST_DATE_GMT->value, $post_date_gmt->format(static::DATETIME_FORMAT)); } public string $post_content { get => $this->get(Posts::POST_CONTENT->value); set (string $post_content) => $this->set(Posts::POST_CONTENT->value, $post_content); } public string $post_title { get => $this->get(Posts::POST_TITLE->value); set (string $post_title) => $this->set(Posts::POST_TITLE->value, $post_title); } public string $post_excerpt { get => $this->get(Posts::POST_EXCERPT->value); set (string $post_excerpt) => $this->set(Posts::POST_EXCERPT->value, $post_excerpt); } public string $post_status { get => $this->get(Posts::POST_STATUS->value); set (string $post_status) => $this->set(Posts::POST_STATUS->value, $post_status); } public string $comment_status { get => $this->get(Posts::COMMENT_STATUS->value); set (string $comment_status) => $this->set(Posts::COMMENT_STATUS->value, $comment_status); } public string $ping_status { get => $this->get(Posts::PING_STATUS->value); set (string $ping_status) => $this->set(Posts::PING_STATUS->value, $ping_status); } public string $post_password { get => $this->get(Posts::POST_PASSWORD->value); set (string $post_password) => $this->set(Posts::POST_PASSWORD->value, $post_password); } public string $post_name { get => $this->get(Posts::POST_NAME->value); set (string $post_name) => $this->set(Posts::POST_NAME->value, $post_name); } public string $to_ping { get => $this->get(Posts::TO_PING->value); set (string $to_ping) => $this->set(Posts::TO_PING->value, $to_ping); } public string $pinged { get => $this->get(Posts::PINGED->value); set (string $pinged) => $this->set(Posts::PINGED->value, $pinged); } public DateTimeImmutable $post_modified { get => new DateTimeImmutable($this->get(Posts::POST_MODIFIED->value)); set (DateTimeImmutable $post_modified) => $this->set(Posts::POST_MODIFIED->value, $post_modified->format(static::DATETIME_FORMAT)); } public DateTimeImmutable $post_modified_gmt { get => new DateTimeImmutable($this->get(Posts::POST_MODIFIED_GMT->value)); set (DateTimeImmutable $post_modified_gmt) => $this->set(Posts::POST_MODIFIED_GMT->value, $post_modified_gmt->format(static::DATETIME_FORMAT)); } public Post|false|null $post_parent { get => $this->get(Posts::POST_PARENT->value) !== 0 ? new self($this->get(Posts::POST_PARENT->value)) : null; set (Post|false|null $post_parent) => $this->set(Posts::POST_PARENT->value, $post_parent ? $post_parent->id : 0); } public string $guid { get => $this->get(Posts::GUID->value); set (string $guid) => $this->set(Posts::GUID->value, $guid); } public int $menu_order { get => $this->get(Posts::MENU_ORDER->value); set (int $menu_order) => $this->set(Posts::MENU_ORDER->value, $menu_order); } public string $post_type { get => $this->get(Posts::POST_TYPE->value); set (string $post_type) => $this->set(Posts::POST_TYPE->value, $post_type); } public string $post_mime_type { get => $this->get(Posts::POST_MIME_TYPE->value); set (string $post_mime_type) => $this->set(Posts::POST_MIME_TYPE->value, $post_mime_type); } public int $comment_count { get => $this->get(Posts::COMMENT_COUNT->value); set (int $comment_count) => $this->set(Posts::COMMENT_COUNT->value, $comment_count); } }