$slug]); } 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); } }