diff --git a/.env.example.ini b/.env.example.ini deleted file mode 100644 index 77e81ba..0000000 --- a/.env.example.ini +++ /dev/null @@ -1,4 +0,0 @@ -[mariadb] -host = "" -user = "" -pass = "" diff --git a/.gitignore b/.gitignore index 76bfadb..22d0d82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -.env.ini - vendor diff --git a/src/Posts/Post.php b/src/Posts/Post.php index e431677..5b7ff07 100644 --- a/src/Posts/Post.php +++ b/src/Posts/Post.php @@ -9,8 +9,11 @@ use vlw\WP\Database; use vlw\WP\Tables\Posts; use vlw\WP\Posts\PostMeta; + use vlw\WP\Posts\Taxonomy\Term; + use vlw\WP\Posts\Type\Attachment; use function vlw\WP\Support\slugify; + require_once "Taxonomy/Term.php"; require_once dirname(__DIR__, 1) . "/Tables/Posts.php"; require_once dirname(__DIR__, 1) . "/Support/Slugify.php"; @@ -21,10 +24,10 @@ * @param string $name * @return static|null */ - public static function from_name(string $name): ?static { + public static function from_name(string $name, bool $slugify = true): ?static { $query = Database::current() - ->from(Database::get_table(Posts::NAME)) - ->where([Posts::POST_NAME->value => slugify($name)]) + ->from(Database::get_table(Posts::TABLE_NAME)) + ->where([Posts::POST_NAME->value => $slugify ? slugify($name) : $name]) ->limit(1) ->select(Posts::ID->value); @@ -70,7 +73,7 @@ Posts::COMMENT_COUNT->value => 0 ]; - if (!parent::create(Database::get_table(Posts::NAME), $values)) { + if (!parent::create(Database::get_table(Posts::TABLE_NAME), $values)) { throw new Exception("Failed to create database entity"); } @@ -79,7 +82,7 @@ public function __construct(public readonly int $id) { parent::__construct( - Database::get_table(Posts::NAME), + Database::get_table(Posts::TABLE_NAME), Posts::values(), [Posts::ID->value => (int) $id] ); @@ -95,6 +98,15 @@ 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); + } + public int $post_author { get => $this->get(Posts::POST_AUTHOR->value); set (int $post_author) => $this->set(Posts::POST_AUTHOR->value, $post_author); diff --git a/src/Posts/PostMeta.php b/src/Posts/PostMeta.php index 7c14594..750f08d 100644 --- a/src/Posts/PostMeta.php +++ b/src/Posts/PostMeta.php @@ -22,7 +22,7 @@ */ public static function get_post_meta(Post $post, string $key): static|false { $query = Database::current() - ->from(Database::get_table(PostMetaTable::NAME)) + ->from(Database::get_table(PostMetaTable::TABLE_NAME)) ->where([ PostMetaTable::POST_ID->value => $post->id, PostMetaTable::META_KEY->value => $key @@ -41,7 +41,7 @@ */ public static function get_all_post_meta(Post $post): array { $query = Database::current() - ->from(Database::get_table(PostMetaTable::NAME)) + ->from(Database::get_table(PostMetaTable::TABLE_NAME)) ->where([PostMetaTable::POST_ID->value => $post->id]) ->select(PostMetaTable::META_ID->value); @@ -71,7 +71,7 @@ PostMetaTable::META_VALUE->value => $meta_value ]; - if (!parent::create(Database::get_table(PostMetaTable::NAME), $values)) { + if (!parent::create(Database::get_table(PostMetaTable::TABLE_NAME), $values)) { throw new Exception("Failed to create database entity"); } @@ -80,12 +80,23 @@ public function __construct(public readonly int $id) { parent::__construct( - Database::get_table(PostMetaTable::NAME), + Database::get_table(PostMetaTable::TABLE_NAME), PostMetaTable::values(), [PostMetaTable::META_ID->value => (int) $id] ); } + /** + * Delete this post meta field from the database + * + * @return void + */ + public function delete(): void { + $this->db + ->from(PostMetaTable::TABLE_NAME) + ->delete([PostMetaTable::META_ID->value => $this->id]); + } + public Post $post { get => new Post($this->get(PostMetaTable::POST_ID->value)); set (Post $post) => $this->set(PostMetaTable::POST_ID->value, $post->id); diff --git a/src/Posts/Taxonomy/Taxonomy.php b/src/Posts/Taxonomy/Taxonomy.php new file mode 100644 index 0000000..548fac6 --- /dev/null +++ b/src/Posts/Taxonomy/Taxonomy.php @@ -0,0 +1,85 @@ +from(Database::get_table(Taxonomies::TABLE_NAME)) + ->where([Taxonomies::TAXONOMY->value => $taxonomy]) + ->limit(1) + ->select(Taxonomies::TERM_TAXONOMY_ID->value); + + return $query->num_rows === 1 ? new static($query->fetch_assoc()[Taxonomies::TERM_ID->value]) : null; + } + + /** + * Create a new post meta field for a given post + * + * @param string $title Post title + * @param string $type Post type + * @return static + */ + public static function new(string $taxonomy): static { + // Return existing instance of Taxonomy if it exists + if (self::from($taxonomy)) { + return self::from($taxonomy); + } + + $values = [ + Taxonomies::TERM_TAXONOMY_ID->value => null, + Taxonomies::TERM_ID->value => 0, + Taxonomies::DESCRIPTION->value => "", + Taxonomies::PARENT->value => 0, + Taxonomies::COUNT->value => 0 + ]; + + if (!parent::create(Database::get_table(Taxonomies::TABLE_NAME), $values)) { + throw new Exception("Failed to create database entity"); + } + + return self::from($taxonomy); + } + + public function __construct(public readonly int $id) { + parent::__construct( + Database::get_table(Taxonomies::TABLE_NAME), + Taxonomies::values(), + [Taxonomies::TERM_TAXONOMY_ID->value => (int) $id] + ); + } + + public Term $term { + get => new Term($this->get(Taxonomies::TERM_ID->value)); + set (Term $term) => $this->set(Taxonomies::TERM_ID->value, $term->id); + } + + public string $taxonomy { + get => $this->get(Taxonomies::TAXONOMY->value); + set (string $taxonomy) => $this->set(Taxonomies::TAXONOMY->value, $taxonomy); + } + + public string $description { + get => $this->get(Taxonomies::DESCRIPTION->value); + set (string $description) => $this->set(Taxonomies::DESCRIPTION->value, $description); + } + + public ?self $parent { + get => $this->get(Taxonomies::PARENT->value) ? new self($this->get(Taxonomies::PARENT->value)) : null; + set (?self $parent) => $this->set(Taxonomies::PARENT->value, $parent->id); + } + } diff --git a/src/Posts/Taxonomy/Term.php b/src/Posts/Taxonomy/Term.php new file mode 100644 index 0000000..2ece00d --- /dev/null +++ b/src/Posts/Taxonomy/Term.php @@ -0,0 +1,155 @@ +from(Database::get_table(Terms::TABLE_NAME)) + ->where([Terms::NAME->value => $name]) + ->limit(1) + ->select(Terms::TERM_ID->value); + + return $query->num_rows === 1 ? new static($query->fetch_assoc()[Terms::TERM_ID->value]) : null; + } + + /** + * Returns an array of all Terms associated with a Post + * + * @param Post $post + * @return array + */ + public static function from_post(Post $post): array { + $query = Database::current() + ->from(Database::get_table(TermRelationships::TABLE_NAME)) + ->where([TermRelationships::OBJECT_ID->value => $post->id]) + ->select(TermRelationships::TERM_TAXONOMY_ID->value); + + return array_map(fn(array $post_meta): static => new static($post_meta[TermRelationships::TERM_TAXONOMY_ID->value]), $query->fetch_all(MYSQLI_ASSOC)); + } + + /** + * Create a new post meta field for a given post + * + * @param string $title Post title + * @param string $type Post type + * @return static + */ + public static function new(string $name, ?string $slug = null): static { + // Update and return meta key for existing id + if (self::from_name($name)) { + $model = self::from_name($name); + $model->slug = $slug; + + return $model; + } + + $values = [ + Terms::TERM_ID->value => null, + Terms::NAME->value => $name, + Terms::SLUG->value => $slug, + Terms::TERM_GROUP->value => 0 + ]; + + if (!parent::create(Database::get_table(Terms::TABLE_NAME), $values)) { + throw new Exception("Failed to create database entity"); + } + + return self::from_name($name); + } + + public function __construct(public readonly int $id) { + parent::__construct( + Database::get_table(Terms::TABLE_NAME), + Terms::values(), + [Terms::TERM_ID->value => $id] + ); + } + + /** + * Returns the corresponding Taxonomy for this Term + * + * @return Taxonomy + */ + public function taxonomy(): Taxonomy { + return new Taxonomy($this->id); + } + + /** + * Add this Term to a target Post + * + * @param Post $post + * @return void + */ + public function add_to_post(Post $post): void { + // Bail out if this term has already been added to the target Post + if (self::from_post($post)) { + return; + } + + $query = Database::current() + ->from(Database::get_table(TermRelationships::TABLE_NAME)) + ->insert([ + TermRelationships::OBJECT_ID->value => $post->id, + TermRelationships::TERM_TAXONOMY_ID->value => $this->id, + TermRelationships::TERM_ORDER->value => 0 + ]); + + if ($query === false) { + throw new Exception("Failed to create database entity"); + } + } + + /** + * Remove this Term from a target Post + * + * @param Post $post + * @return void + */ + public function remove_from_post(Post $post): void { + $query = Database::current() + ->from(Database::get_table(TermRelationships::TABLE_NAME)) + ->delete([ + TermRelationships::OBJECT_ID->value => $post->id, + TermRelationships::TERM_TAXONOMY_ID->value => $this->id + ]); + + if ($query === false) { + throw new Exception("Failed to create database entity"); + } + } + + public string $name { + get => $this->get(Terms::NAME->value); + set (string $name) => $this->set(Terms::NAME->value, $name); + } + + public string $slug { + get => $this->get(Terms::SLUG->value); + set (string $slug) => $this->set(Terms::SLUG->value, $slug); + } + + public int $term_group { + get => $this->get(Terms::TERM_GROUP->value); + set (int $term_group) => $this->set(Terms::TERM_GROUP->value, $term_group); + } + } diff --git a/src/Shortcode/Shortcode.php b/src/Shortcode/Shortcode.php index 257e38e..e3228a6 100644 --- a/src/Shortcode/Shortcode.php +++ b/src/Shortcode/Shortcode.php @@ -17,7 +17,7 @@ * @param string $name * @return array */ - public static function get_shortcodes(string &$source, string $name): array { + public static function get_shortcodes(string $source, string $name): array { $matches = []; preg_match_all("/\[{$name} /", $source, $matches, PREG_OFFSET_CAPTURE); diff --git a/src/Tables/PostMeta.php b/src/Tables/PostMeta.php index 58830da..d4d2613 100644 --- a/src/Tables/PostMeta.php +++ b/src/Tables/PostMeta.php @@ -7,7 +7,7 @@ enum PostMeta: string { use xEnum; - public const NAME = "postmeta"; + public const TABLE_NAME = "postmeta"; case META_ID = "meta_id"; case POST_ID = "post_id"; diff --git a/src/Tables/Posts.php b/src/Tables/Posts.php index d57884f..b9e8e50 100644 --- a/src/Tables/Posts.php +++ b/src/Tables/Posts.php @@ -7,7 +7,7 @@ enum Posts: string { use xEnum; - public const NAME = "posts"; + public const TABLE_NAME = "posts"; case ID = 'ID'; case POST_AUTHOR = 'post_author'; diff --git a/src/Tables/Taxonomies.php b/src/Tables/Taxonomies.php new file mode 100644 index 0000000..7632672 --- /dev/null +++ b/src/Tables/Taxonomies.php @@ -0,0 +1,18 @@ +