This commit is contained in:
Sven Steinert
2026-05-13 12:19:42 +02:00
parent f4511b9213
commit 3ff9146a63
13 changed files with 499 additions and 76 deletions

View File

@@ -16,4 +16,117 @@ final class ProductRepository
return is_wp_error($term) ? 0 : (int) ($term['term_id'] ?? $term);
}
public function allWithStats(): array
{
$terms = get_terms([
'taxonomy' => 'kb_product',
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
]);
if (is_wp_error($terms)) {
return [];
}
$items = [];
foreach ($terms as $term) {
$pageIds = $this->pageIdsForProduct((int) $term->term_id);
$versions = [];
foreach ($pageIds as $pageId) {
$pageVersions = wp_get_object_terms($pageId, 'kb_version');
if (is_wp_error($pageVersions)) {
continue;
}
foreach ($pageVersions as $version) {
$versions[$version->slug] = $version;
}
}
uasort($versions, static fn ($a, $b): int => strnatcasecmp($b->name, $a->name));
$items[] = [
'term' => $term,
'page_count' => count($pageIds),
'versions' => array_values($versions),
];
}
return $items;
}
public function update(int $termId, string $name, string $slug): \WP_Term|\WP_Error
{
$name = trim($name);
$slug = sanitize_title($slug ?: $name);
if ('' === $name || '' === $slug) {
return new \WP_Error('kb_product_invalid', __('Product name and slug are required.', 'kb-markdown-importer'));
}
$updated = wp_update_term($termId, 'kb_product', [
'name' => $name,
'slug' => $slug,
]);
if (is_wp_error($updated)) {
return $updated;
}
foreach ($this->pageIdsForProduct($termId) as $pageId) {
update_post_meta($pageId, '_kb_product_slug', $slug);
}
$term = get_term((int) $updated['term_id'], 'kb_product');
return $term instanceof \WP_Term ? $term : new \WP_Error('kb_product_missing', __('Product could not be loaded after update.', 'kb-markdown-importer'));
}
public function trashProductPages(int $termId): int
{
$count = 0;
foreach ($this->pageIdsForProduct($termId, ['publish', 'draft', 'private', 'pending', 'future']) as $pageId) {
if (wp_trash_post($pageId)) {
++$count;
}
}
return $count;
}
public function deleteProduct(int $termId, bool $trashPages): true|\WP_Error
{
if ($trashPages) {
$this->trashProductPages($termId);
}
$deleted = wp_delete_term($termId, 'kb_product');
if (is_wp_error($deleted)) {
return $deleted;
}
return true;
}
private function pageIdsForProduct(int $termId, array $postStatus = ['publish']): array
{
$query = new \WP_Query([
'post_type' => 'kb_doc_page',
'post_status' => $postStatus,
'posts_per_page' => -1,
'fields' => 'ids',
'tax_query' => [
['taxonomy' => 'kb_product', 'field' => 'term_id', 'terms' => $termId],
],
]);
return array_map('intval', $query->posts);
}
}