mirror of
https://codeberg.org/vlw/wp.git
synced 2026-02-26 03:51:58 +01:00
177 lines
4.8 KiB
PHP
177 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace vlw\WP\Posts\Taxonomy;
|
|
|
|
use Exception;
|
|
use vlw\Scaffold\Database\Model;
|
|
|
|
use vlw\WP\Database;
|
|
use vlw\WP\Posts\Post;
|
|
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 {
|
|
/**
|
|
* Returns a Term by a name
|
|
*
|
|
* @param string $name
|
|
* @return static|null
|
|
*/
|
|
public static function from_name(string $name): ?static {
|
|
$query = Database::current()
|
|
->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 {
|
|
// 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 ? $slug : slugify($name),
|
|
Terms::TERM_GROUP->value => 0
|
|
];
|
|
|
|
if (!parent::create(Database::get_table(Terms::TABLE_NAME), $values)) {
|
|
throw new Exception("Failed to create database entity");
|
|
}
|
|
|
|
return new static($id);
|
|
}
|
|
|
|
public function __construct(public readonly int $id) {
|
|
parent::__construct(
|
|
Database::get_table(Terms::TABLE_NAME),
|
|
Terms::values(),
|
|
[Terms::TERM_ID->value => $id]
|
|
);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* 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"));
|
|
}
|
|
}
|