diff --git a/src/Posts/Post.php b/src/Posts/Post.php index 5defaad..34d5282 100644 --- a/src/Posts/Post.php +++ b/src/Posts/Post.php @@ -107,6 +107,26 @@ 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 * diff --git a/src/Posts/Taxonomy/Taxonomy.php b/src/Posts/Taxonomy/Taxonomy.php index 548fac6..303dfa6 100644 --- a/src/Posts/Taxonomy/Taxonomy.php +++ b/src/Posts/Taxonomy/Taxonomy.php @@ -7,7 +7,9 @@ use vlw\WP\Database; use vlw\WP\Tables\Taxonomies; + use vlw\WP\Posts\Taxonomy\Term; + require_once "Term.php"; require_once dirname(__DIR__, 2) . "/Tables/Taxonomies.php"; class Taxonomy extends Model { @@ -15,16 +17,24 @@ * Returns a Taxonomy by taxonomy name * * @param string $name - * @return static|null + * @return array */ - public function from(string $taxonomy): ?static { + public static function from(string $taxonomy): array { $query = Database::current() ->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; + return array_map(fn(array $taxonomy): static => new static($taxonomy[Taxonomies::TERM_TAXONOMY_ID->value]), $query->fetch_all(MYSQLI_ASSOC)); + } + + public static function from_term(Term $term): array { + $query = Database::current() + ->from(Database::get_table(Taxonomies::TABLE_NAME)) + ->where([Taxonomies::TERM_ID->value => $term->id]) + ->select(Taxonomies::TERM_TAXONOMY_ID->value); + + return array_map(fn(array $taxonomy): static => new static($taxonomy[Taxonomies::TERM_TAXONOMY_ID->value]), $query->fetch_all(MYSQLI_ASSOC)); } /** @@ -34,15 +44,14 @@ * @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); - } + public static function new(string $taxonomy, Term $term): static { + // Current auto increment value will be the id for this entity + $id = Database::current()->latest(Taxonomies::TABLE_NAME); $values = [ Taxonomies::TERM_TAXONOMY_ID->value => null, - Taxonomies::TERM_ID->value => 0, + Taxonomies::TERM_ID->value => $term->id, + Taxonomies::TAXONOMY->value => $taxonomy, Taxonomies::DESCRIPTION->value => "", Taxonomies::PARENT->value => 0, Taxonomies::COUNT->value => 0 @@ -52,7 +61,8 @@ throw new Exception("Failed to create database entity"); } - return self::from($taxonomy); + // Instance this Taxonomy from the last added taxonomy in the database + return new static($id); } public function __construct(public readonly int $id) { @@ -82,4 +92,9 @@ get => $this->get(Taxonomies::PARENT->value) ? new self($this->get(Taxonomies::PARENT->value)) : null; set (?self $parent) => $this->set(Taxonomies::PARENT->value, $parent->id); } + + public int $count { + get => (int) $this->get(Taxonomies::COUNT->value); + set (int $count) => $this->set(Taxonomies::COUNT->value, $count); + } } diff --git a/src/Posts/Taxonomy/Term.php b/src/Posts/Taxonomy/Term.php index 2ece00d..ad30da6 100644 --- a/src/Posts/Taxonomy/Term.php +++ b/src/Posts/Taxonomy/Term.php @@ -10,9 +10,11 @@ use vlw\WP\Tables\Terms; use vlw\WP\Posts\Taxonomy\Taxonomy; use vlw\WP\Tables\TermRelationships; + use function vlw\WP\Support\slugify; require_once dirname(__DIR__, 1) . "/Post.php"; require_once dirname(__DIR__, 2) . "/Tables/Terms.php"; + require_once dirname(__DIR__, 2) . "/Support/Slugify.php"; require_once dirname(__DIR__, 2) . "/Tables/TermRelationships.php"; class Term extends Model { @@ -55,18 +57,13 @@ * @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; - } + // Current auto increment value will be the id for this entity + $id = Database::current()->latest(Terms::TABLE_NAME); $values = [ Terms::TERM_ID->value => null, Terms::NAME->value => $name, - Terms::SLUG->value => $slug, + Terms::SLUG->value => $slug ? $slug : slugify($name), Terms::TERM_GROUP->value => 0 ]; @@ -74,7 +71,7 @@ throw new Exception("Failed to create database entity"); } - return self::from_name($name); + return new static($id); } public function __construct(public readonly int $id) { @@ -85,59 +82,6 @@ ); } - /** - * 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); @@ -152,4 +96,82 @@ get => $this->get(Terms::TERM_GROUP->value); set (int $term_group) => $this->set(Terms::TERM_GROUP->value, $term_group); } + + /** + * Returns an array of Taxonomies that implement this Term + * + * @return array + */ + public function taxonomies(): array { + return Taxonomy::from_term($this); + } + + /** + * 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 ($this->post_has_term($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"); + } + + // Increase the post count for each Taxonomy implementing this Term + foreach ($this->taxonomies() as $taxonomy) { + $taxonomy->count++; + } + } + + /** + * Remove this Term from a target Post + * + * @param Post $post + * @return void + */ + public function remove_from_post(Post $post): void { + // Bail out if this Term is not set on the target Post + if (!$this->post_has_term($post)) { + return; + } + + $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"); + } + + // Decrease the post count for each Taxonomy implementing this Term + foreach ($this->taxonomies() as $taxonomy) { + $taxonomy->count--; + } + } + + /** + * Returns true if a given Post has this Term + * + * @param Post $post + * @return bool + */ + private function post_has_term(Post $post): bool { + return in_array($this->id, array_column(self::from_post($post), "id")); + } }