|
|
@ -227,30 +227,66 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
return $sorted_siblings; |
|
|
|
return $sorted_siblings; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function get_category_products(){ |
|
|
|
protected function get_category_products() { |
|
|
|
// Получаем все товары с похожими атрибутами |
|
|
|
// Получаем категории текущего товара |
|
|
|
|
|
|
|
$current_product_categories = get_the_terms($this->id, 'product_cat'); |
|
|
|
|
|
|
|
if (!$current_product_categories || is_wp_error($current_product_categories)) { |
|
|
|
|
|
|
|
return []; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$current_category_ids = array_map(function($cat) { |
|
|
|
|
|
|
|
return $cat->term_id; |
|
|
|
|
|
|
|
}, $current_product_categories); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Получаем текущий товар |
|
|
|
|
|
|
|
$current_product = Timber::get_post($this->id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Получаем ВСЕ товары |
|
|
|
$args = array( |
|
|
|
$args = array( |
|
|
|
'posts_per_page' => -1, |
|
|
|
'posts_per_page' => -1, |
|
|
|
'post_type' => 'product', |
|
|
|
'post_type' => 'product', |
|
|
|
'order' => 'ASC', |
|
|
|
'order' => 'ASC', |
|
|
|
'orderby' => 'name', |
|
|
|
'orderby' => 'name', |
|
|
|
'post_status' => 'publish' |
|
|
|
'post_status' => 'publish', |
|
|
|
|
|
|
|
'tax_query' => [ |
|
|
|
|
|
|
|
[ |
|
|
|
|
|
|
|
'taxonomy' => 'product_visibility', |
|
|
|
|
|
|
|
'field' => 'slug', |
|
|
|
|
|
|
|
'terms' => 'exclude-from-catalog', |
|
|
|
|
|
|
|
'operator' => 'NOT IN' |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
'fields' => 'ids' // Получаем только ID товаров для оптимизации |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
error_log("get_category_products: Запрос товаров"); |
|
|
|
$all_products = Timber::get_posts($args); |
|
|
|
$posts = Timber::get_posts($args); |
|
|
|
$matching_products = []; |
|
|
|
error_log("get_category_products: Получено товаров: " . (is_array($posts) ? count($posts) : 'не массив')); |
|
|
|
|
|
|
|
|
|
|
|
foreach ($all_products as $product) { |
|
|
|
|
|
|
|
// Получаем категории товара |
|
|
|
|
|
|
|
$product_categories = get_the_terms($product->ID, 'product_cat'); |
|
|
|
|
|
|
|
if (!$product_categories || is_wp_error($product_categories)) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$product_category_ids = array_map(function($cat) { |
|
|
|
|
|
|
|
return $cat->term_id; |
|
|
|
|
|
|
|
}, $product_categories); |
|
|
|
|
|
|
|
|
|
|
|
// Преобразуем в массив, если это PostCollection или PostQuery |
|
|
|
// Проверяем полное совпадение категорий |
|
|
|
if ($posts instanceof \Timber\PostCollection || $posts instanceof \Timber\PostQuery) { |
|
|
|
if (empty(array_diff($current_category_ids, $product_category_ids)) && |
|
|
|
$result = $posts->get_posts(); |
|
|
|
empty(array_diff($product_category_ids, $current_category_ids))) { |
|
|
|
error_log("get_category_products: Преобразовано в массив: " . count($result)); |
|
|
|
$matching_products[] = $product; |
|
|
|
return $result; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Добавляем текущий товар в начало массива |
|
|
|
|
|
|
|
if ($current_product) { |
|
|
|
|
|
|
|
array_unshift($matching_products, $current_product); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$result = is_array($posts) ? $posts : []; |
|
|
|
error_log("get_category_products: Полное совпадение категорий. Найдено товаров: " . count($matching_products)); |
|
|
|
error_log("get_category_products: Возвращаем: " . count($result)); |
|
|
|
return $matching_products; |
|
|
|
return $result; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function getProductConstructor() { |
|
|
|
public function getProductConstructor() { |
|
|
@ -271,8 +307,6 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Получаем упорядоченные таксономии |
|
|
|
// Получаем упорядоченные таксономии |
|
|
|
$ordered_taxonomies = $this->getOrderedTaxonomies(); |
|
|
|
$ordered_taxonomies = $this->getOrderedTaxonomies(); |
|
|
|
|
|
|
|
|
|
|
@ -288,9 +322,13 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ОБХОДИМ МАССИВ ТОВАРОВ ТОЛЬКО ОДИН РАЗ |
|
|
|
// Создаем массив для отслеживания уже добавленных товаров по таксономиям |
|
|
|
|
|
|
|
$added_products = []; |
|
|
|
|
|
|
|
foreach (array_keys($constructor) as $taxonomy) { |
|
|
|
|
|
|
|
$added_products[$taxonomy] = []; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
foreach ($all_products as $product) { |
|
|
|
foreach ($all_products as $product) { |
|
|
|
// Получаем все атрибуты сравниваемого товара за один раз |
|
|
|
|
|
|
|
$compare_attributes = []; |
|
|
|
$compare_attributes = []; |
|
|
|
$compare_weight = $product->getNumericWeight(); |
|
|
|
$compare_weight = $product->getNumericWeight(); |
|
|
|
|
|
|
|
|
|
|
@ -303,31 +341,25 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Проверяем, подходит ли товар для каждой таксономии |
|
|
|
// Проверяем для каждой таксономии, куда можно добавить этот товар |
|
|
|
foreach ($this->sibling_categories as $taxonomy) { |
|
|
|
foreach ($this->sibling_categories as $taxonomy) { |
|
|
|
// Пропускаем, если у текущего товара нет значения для этой категории |
|
|
|
if (!isset($current_product_attributes[$taxonomy]) || |
|
|
|
if (!isset($current_product_attributes[$taxonomy])) { |
|
|
|
!isset($constructor[$taxonomy]) || |
|
|
|
|
|
|
|
in_array($product->id, $added_products[$taxonomy])) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Проверяем, совпадают ли все остальные атрибуты и вес |
|
|
|
|
|
|
|
$attributes_match = true; |
|
|
|
$attributes_match = true; |
|
|
|
|
|
|
|
|
|
|
|
// Проверяем все атрибуты кроме текущей таксономии |
|
|
|
|
|
|
|
foreach ($this->sibling_categories as $compare_taxonomy) { |
|
|
|
foreach ($this->sibling_categories as $compare_taxonomy) { |
|
|
|
if ($compare_taxonomy === $taxonomy) { |
|
|
|
if ($compare_taxonomy === $taxonomy) continue; |
|
|
|
continue; // Пропускаем проверяемую категорию |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Если у текущего товара есть значение для этой категории |
|
|
|
|
|
|
|
if (isset($current_product_attributes[$compare_taxonomy])) { |
|
|
|
if (isset($current_product_attributes[$compare_taxonomy])) { |
|
|
|
// Проверяем, есть ли у сравниваемого товара значение для этой категории |
|
|
|
|
|
|
|
if (!isset($compare_attributes[$compare_taxonomy])) { |
|
|
|
if (!isset($compare_attributes[$compare_taxonomy])) { |
|
|
|
$attributes_match = false; |
|
|
|
$attributes_match = false; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Проверяем, совпадают ли значения |
|
|
|
|
|
|
|
$current_values = $current_product_attributes[$compare_taxonomy]; |
|
|
|
$current_values = $current_product_attributes[$compare_taxonomy]; |
|
|
|
$compare_values = $compare_attributes[$compare_taxonomy]; |
|
|
|
$compare_values = $compare_attributes[$compare_taxonomy]; |
|
|
|
|
|
|
|
|
|
|
@ -336,10 +368,7 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
$attributes_match = false; |
|
|
|
$attributes_match = false; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Если у текущего товара НЕТ значения для этой категории, |
|
|
|
|
|
|
|
// то у сравниваемого товара тоже не должно быть значения |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
if (isset($compare_attributes[$compare_taxonomy])) { |
|
|
|
if (isset($compare_attributes[$compare_taxonomy])) { |
|
|
|
$attributes_match = false; |
|
|
|
$attributes_match = false; |
|
|
|
break; |
|
|
|
break; |
|
|
@ -347,17 +376,16 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Проверяем вес (числовое сравнение) |
|
|
|
|
|
|
|
if (abs($current_weight - $compare_weight) > 0.01) { |
|
|
|
if (abs($current_weight - $compare_weight) > 0.01) { |
|
|
|
$attributes_match = false; |
|
|
|
$attributes_match = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Если все атрибуты и вес совпадают, добавляем товар в группу |
|
|
|
|
|
|
|
if ($attributes_match) { |
|
|
|
if ($attributes_match) { |
|
|
|
$product_terms = get_the_terms($product->id, $taxonomy); |
|
|
|
$product_terms = get_the_terms($product->id, $taxonomy); |
|
|
|
if ($product_terms && !is_wp_error($product_terms)) { |
|
|
|
if ($product_terms && !is_wp_error($product_terms)) { |
|
|
|
foreach ($product_terms as $term) { |
|
|
|
foreach ($product_terms as $term) { |
|
|
|
$option_key = $term->term_id; |
|
|
|
$option_key = $term->term_id; |
|
|
|
|
|
|
|
|
|
|
|
if (!isset($constructor[$taxonomy]['options'][$option_key])) { |
|
|
|
if (!isset($constructor[$taxonomy]['options'][$option_key])) { |
|
|
|
$constructor[$taxonomy]['options'][$option_key] = [ |
|
|
|
$constructor[$taxonomy]['options'][$option_key] = [ |
|
|
|
'term_id' => $term->term_id, |
|
|
|
'term_id' => $term->term_id, |
|
|
@ -367,7 +395,12 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
'products' => [] |
|
|
|
'products' => [] |
|
|
|
]; |
|
|
|
]; |
|
|
|
} |
|
|
|
} |
|
|
|
$constructor[$taxonomy]['options'][$option_key]['products'][] = $product; |
|
|
|
|
|
|
|
|
|
|
|
// Добавляем товар только если его еще нет в этой опции |
|
|
|
|
|
|
|
if (!in_array($product->id, $added_products[$taxonomy])) { |
|
|
|
|
|
|
|
$constructor[$taxonomy]['options'][$option_key]['products'][] = $product; |
|
|
|
|
|
|
|
$added_products[$taxonomy][] = $product->id; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -385,7 +418,6 @@ class CosmopetProduct extends TimberProduct { |
|
|
|
} |
|
|
|
} |
|
|
|
$constructor[$taxonomy]['options'] = $ordered_options; |
|
|
|
$constructor[$taxonomy]['options'] = $ordered_options; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Сортируем итоговый конструктор по порядку таксономий |
|
|
|
// Сортируем итоговый конструктор по порядку таксономий |
|
|
|