fix: proper creation and assignment of post taxonomies and terms

This commit is contained in:
Victor Westerlund 2026-02-16 11:17:55 +01:00
parent b14c14d9b3
commit 617662b8d8
Signed by: vlw
GPG key ID: D0AD730E1057DFC6
3 changed files with 130 additions and 73 deletions

View file

@ -107,6 +107,26 @@
return Term::from_post($this); 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 * Get, set, or unset featured media for this Post
* *

View file

@ -7,7 +7,9 @@
use vlw\WP\Database; use vlw\WP\Database;
use vlw\WP\Tables\Taxonomies; use vlw\WP\Tables\Taxonomies;
use vlw\WP\Posts\Taxonomy\Term;
require_once "Term.php";
require_once dirname(__DIR__, 2) . "/Tables/Taxonomies.php"; require_once dirname(__DIR__, 2) . "/Tables/Taxonomies.php";
class Taxonomy extends Model { class Taxonomy extends Model {
@ -15,16 +17,24 @@
* Returns a Taxonomy by taxonomy name * Returns a Taxonomy by taxonomy name
* *
* @param string $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() $query = Database::current()
->from(Database::get_table(Taxonomies::TABLE_NAME)) ->from(Database::get_table(Taxonomies::TABLE_NAME))
->where([Taxonomies::TAXONOMY->value => $taxonomy]) ->where([Taxonomies::TAXONOMY->value => $taxonomy])
->limit(1)
->select(Taxonomies::TERM_TAXONOMY_ID->value); ->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 * @param string $type Post type
* @return static * @return static
*/ */
public static function new(string $taxonomy): static { public static function new(string $taxonomy, Term $term): static {
// Return existing instance of Taxonomy if it exists // Current auto increment value will be the id for this entity
if (self::from($taxonomy)) { $id = Database::current()->latest(Taxonomies::TABLE_NAME);
return self::from($taxonomy);
}
$values = [ $values = [
Taxonomies::TERM_TAXONOMY_ID->value => null, 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::DESCRIPTION->value => "",
Taxonomies::PARENT->value => 0, Taxonomies::PARENT->value => 0,
Taxonomies::COUNT->value => 0 Taxonomies::COUNT->value => 0
@ -52,7 +61,8 @@
throw new Exception("Failed to create database entity"); 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) { 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; get => $this->get(Taxonomies::PARENT->value) ? new self($this->get(Taxonomies::PARENT->value)) : null;
set (?self $parent) => $this->set(Taxonomies::PARENT->value, $parent->id); 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);
}
} }

View file

@ -10,9 +10,11 @@
use vlw\WP\Tables\Terms; use vlw\WP\Tables\Terms;
use vlw\WP\Posts\Taxonomy\Taxonomy; use vlw\WP\Posts\Taxonomy\Taxonomy;
use vlw\WP\Tables\TermRelationships; use vlw\WP\Tables\TermRelationships;
use function vlw\WP\Support\slugify;
require_once dirname(__DIR__, 1) . "/Post.php"; require_once dirname(__DIR__, 1) . "/Post.php";
require_once dirname(__DIR__, 2) . "/Tables/Terms.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"; require_once dirname(__DIR__, 2) . "/Tables/TermRelationships.php";
class Term extends Model { class Term extends Model {
@ -55,18 +57,13 @@
* @return static * @return static
*/ */
public static function new(string $name, ?string $slug = null): static { public static function new(string $name, ?string $slug = null): static {
// Update and return meta key for existing id // Current auto increment value will be the id for this entity
if (self::from_name($name)) { $id = Database::current()->latest(Terms::TABLE_NAME);
$model = self::from_name($name);
$model->slug = $slug;
return $model;
}
$values = [ $values = [
Terms::TERM_ID->value => null, Terms::TERM_ID->value => null,
Terms::NAME->value => $name, Terms::NAME->value => $name,
Terms::SLUG->value => $slug, Terms::SLUG->value => $slug ? $slug : slugify($name),
Terms::TERM_GROUP->value => 0 Terms::TERM_GROUP->value => 0
]; ];
@ -74,7 +71,7 @@
throw new Exception("Failed to create database entity"); throw new Exception("Failed to create database entity");
} }
return self::from_name($name); return new static($id);
} }
public function __construct(public readonly int $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 { public string $name {
get => $this->get(Terms::NAME->value); get => $this->get(Terms::NAME->value);
set (string $name) => $this->set(Terms::NAME->value, $name); set (string $name) => $this->set(Terms::NAME->value, $name);
@ -152,4 +96,82 @@
get => $this->get(Terms::TERM_GROUP->value); get => $this->get(Terms::TERM_GROUP->value);
set (int $term_group) => $this->set(Terms::TERM_GROUP->value, $term_group); 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"));
}
} }