findCategoryByAikanenId($aikanenId); if ($existing) { $termId = $existing; wp_update_term($termId, 'product_cat', [ 'name' => $name, 'description' => $description ?? '', ]); return 'updated'; } $result = wp_insert_term($name, 'product_cat', [ 'description' => $description ?? '', ]); if (is_wp_error($result)) { // Term with this name may already exist - try to claim it if unlinked if ($result->get_error_code() === 'term_exists') { $termId = (int) $result->get_error_data(); $linked = get_term_meta($termId, self::META_AIKANEN_ID, true); if (!$linked) { // Unlinked term - claim it update_term_meta($termId, self::META_AIKANEN_ID, $aikanenId); return 'linked'; } } return 'skipped'; } $termId = (int) $result['term_id']; update_term_meta($termId, self::META_AIKANEN_ID, $aikanenId); return 'created'; } // Assign product to categories private function syncCategories(array $service): void { $groups = $service['serviceGroups'] ?? []; $productId = $this->productMapper->findProductByAikanenId((string) ($service['id'] ?? '')); if (!$productId || empty($groups)) { return; } $termIds = []; foreach ($groups as $group) { $groupId = (string) ($group['id'] ?? ''); if ($groupId === '') continue; $termId = $this->categoryMapper->findCategoryByAikanenId($groupId); if ($termId) { $termIds[] = $termId; } } if (!empty($termIds)) { wp_set_object_terms($productId, $termIds, 'product_cat', true); } } // Find category matching service group ID from Aikanen (if exists) public function findCategoryByAikanenId(string $aikanenId): ?int { $terms = get_terms([ 'taxonomy' => 'product_cat', 'hide_empty' => false, 'meta_query' => [ [ 'key' => self::META_AIKANEN_ID, 'value' => $aikanenId, ], ], 'fields' => 'ids', 'number' => 1, ]); if (is_wp_error($terms) || empty($terms)) { return null; } return (int) $terms[0]; } }