ver. 0.292: ShopProduct + ShopPaymentMethod + ShopPromotion + ShopStatuses + ShopTransport frontend migration to Domain

Full migration of front\factory\ — entire directory removed (all 20 classes migrated).
ProductRepository +20 frontend methods, PromotionRepository +5 applyType methods,
TransportRepository +4 cached methods, PaymentMethodRepository +cached frontend methods.
Fix: broken transports_list() in ajax.php replaced with forPaymentMethod().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 21:55:16 +01:00
parent 827b903e1e
commit 89d9e61bec
48 changed files with 1780 additions and 975 deletions

View File

@@ -1848,4 +1848,399 @@ class ProductRepository
], [ 'id' => $row['id'] ] );
}
}
// =========================================================================
// Frontend methods (migrated from front\factory\ShopProduct)
// =========================================================================
/**
* @return string|null
*/
public function getSkuWithFallback(int $productId, bool $withParentFallback = false)
{
if ($productId <= 0) {
return null;
}
$sku = $this->db->get('pp_shop_products', 'sku', ['id' => $productId]);
if (!$sku && $withParentFallback) {
$parentId = $this->db->get('pp_shop_products', 'parent_id', ['id' => $productId]);
if ($parentId) {
return $this->getSkuWithFallback((int)$parentId, true);
}
return null;
}
return $sku ? (string)$sku : null;
}
/**
* @return string|null
*/
public function getEanWithFallback(int $productId, bool $withParentFallback = false)
{
if ($productId <= 0) {
return null;
}
$ean = $this->db->get('pp_shop_products', 'ean', ['id' => $productId]);
if (!$ean && $withParentFallback) {
$parentId = $this->db->get('pp_shop_products', 'parent_id', ['id' => $productId]);
if ($parentId) {
return $this->getEanWithFallback((int)$parentId, true);
}
return null;
}
return $ean ? (string)$ean : null;
}
public function isProductActiveCached(int $productId): int
{
if ($productId <= 0) {
return 0;
}
$cacheHandler = new \Shared\Cache\CacheHandler();
$cacheKey = 'is_product_active:' . $productId;
$cached = $cacheHandler->get($cacheKey);
if ($cached) {
return (int)unserialize($cached) === 1 ? 1 : 0;
}
$status = $this->db->get('pp_shop_products', 'status', ['id' => $productId]);
$cacheHandler->set($cacheKey, $status);
return (int)$status === 1 ? 1 : 0;
}
/**
* @return string|null
*/
public function getMinimalPriceCached(int $productId, $priceBruttoPromo = null)
{
if ($productId <= 0) {
return null;
}
$cacheHandler = new \Shared\Cache\CacheHandler();
$cacheKey = 'get_minimal_price:' . $productId;
$cached = $cacheHandler->get($cacheKey);
if ($cached) {
return unserialize($cached);
}
$price = $this->db->min('pp_shop_product_price_history', 'price', [
'AND' => [
'id_product' => $productId,
'price[!]' => str_replace(',', '.', $priceBruttoPromo),
],
]);
$cacheHandler->set($cacheKey, $price);
return $price;
}
/**
* @return array<int, array<string, mixed>>
*/
public function productCategoriesFront(int $productId): array
{
if ($productId <= 0) {
return [];
}
$parentId = $this->db->get('pp_shop_products', 'parent_id', ['id' => $productId]);
$targetId = $parentId ? (int)$parentId : $productId;
$stmt = $this->db->query(
'SELECT category_id FROM pp_shop_products_categories WHERE product_id = :pid',
[':pid' => $targetId]
);
return $stmt ? $stmt->fetchAll(\PDO::FETCH_ASSOC) : [];
}
/**
* @return string|null
*/
public function getProductNameCached(int $productId, string $langId)
{
if ($productId <= 0) {
return null;
}
$cacheHandler = new \Shared\Cache\CacheHandler();
$cacheKey = 'product_name' . $langId . '_' . $productId;
$cached = $cacheHandler->get($cacheKey);
if ($cached) {
return unserialize($cached);
}
$name = $this->db->get('pp_shop_products_langs', 'name', [
'AND' => ['product_id' => $productId, 'lang_id' => $langId],
]);
$cacheHandler->set($cacheKey, $name);
return $name;
}
/**
* @return string|null
*/
public function getFirstImageCached(int $productId)
{
if ($productId <= 0) {
return null;
}
$cacheHandler = new \Shared\Cache\CacheHandler();
$cacheKey = 'product_image:' . $productId;
$cached = $cacheHandler->get($cacheKey);
if ($cached) {
return unserialize($cached);
}
$stmt = $this->db->query(
'SELECT src FROM pp_shop_products_images WHERE product_id = :pid ORDER BY o ASC LIMIT 1',
[':pid' => $productId]
);
$rows = $stmt ? $stmt->fetchAll(\PDO::FETCH_ASSOC) : [];
$image = isset($rows[0]['src']) ? $rows[0]['src'] : null;
$cacheHandler->set($cacheKey, $image);
return $image;
}
public function getWeightCached(int $productId)
{
if ($productId <= 0) {
return null;
}
$cacheHandler = new \Shared\Cache\CacheHandler();
$cacheKey = 'product_wp:' . $productId;
$cached = $cacheHandler->get($cacheKey);
if ($cached) {
return unserialize($cached);
}
$wp = $this->db->get('pp_shop_products', 'wp', ['id' => $productId]);
$cacheHandler->set($cacheKey, $wp);
return $wp;
}
/**
* @return array<int, int>
*/
public function promotedProductIdsCached(int $limit = 6): array
{
$cacheHandler = new \Shared\Cache\CacheHandler();
$cacheKey = 'promoted_products-' . $limit;
$cached = $cacheHandler->get($cacheKey);
if ($cached) {
return unserialize($cached);
}
$stmt = $this->db->query(
'SELECT id FROM pp_shop_products WHERE status = 1 AND promoted = 1 ORDER BY RAND() LIMIT ' . (int)$limit
);
$rows = $stmt ? $stmt->fetchAll() : [];
$products = [];
if (is_array($rows)) {
foreach ($rows as $row) {
$products[] = (int)$row['id'];
}
}
$cacheHandler->set($cacheKey, $products);
return $products;
}
/**
* @return array<int, int>
*/
public function topProductIds(int $limit = 6): array
{
$date30 = date('Y-m-d', strtotime('-30 days'));
$stmt = $this->db->query(
"SELECT COUNT(0) AS sell_count, psop.parent_product_id
FROM pp_shop_order_products AS psop
INNER JOIN pp_shop_orders AS pso ON pso.id = psop.order_id
WHERE pso.date_order >= :d
GROUP BY parent_product_id
ORDER BY sell_count DESC",
[':d' => $date30]
);
$rows = $stmt ? $stmt->fetchAll(\PDO::FETCH_ASSOC) : [];
$ids = [];
foreach ($rows as $row) {
if ($this->isProductActiveCached((int)$row['parent_product_id'])) {
$ids[] = (int)$row['parent_product_id'];
}
}
return $ids;
}
/**
* @return array<int, int>
*/
public function newProductIds(int $limit = 10): array
{
$stmt = $this->db->query(
'SELECT id FROM pp_shop_products WHERE status = 1 ORDER BY date_add DESC LIMIT ' . (int)$limit
);
$rows = $stmt ? $stmt->fetchAll(\PDO::FETCH_ASSOC) : [];
return array_column($rows, 'id');
}
/**
* @return array|null
*/
public function productDetailsFrontCached(int $productId, string $langId)
{
if ($productId <= 0) {
return null;
}
$cacheHandler = new \Shared\Cache\CacheHandler();
$cacheKey = 'product_details_front:' . $productId . ':' . $langId;
$cached = $cacheHandler->get($cacheKey);
if ($cached) {
return unserialize($cached);
}
$product = $this->db->get('pp_shop_products', '*', ['id' => $productId]);
if (!is_array($product)) {
return null;
}
// language
$langRows = $this->db->select('pp_shop_products_langs', '*', [
'AND' => ['product_id' => $productId, 'lang_id' => $langId],
]);
if (is_array($langRows)) {
foreach ($langRows as $row) {
if ($row['copy_from']) {
$copyRows = $this->db->select('pp_shop_products_langs', '*', [
'AND' => ['product_id' => $productId, 'lang_id' => $row['copy_from']],
]);
if (is_array($copyRows)) {
foreach ($copyRows as $row2) {
$product['language'] = $row2;
}
}
} else {
$product['language'] = $row;
}
}
}
// attributes
$attrStmt = $this->db->query(
'SELECT DISTINCT(attribute_id) FROM pp_shop_products_attributes AS pspa '
. 'INNER JOIN pp_shop_attributes AS psa ON psa.id = pspa.attribute_id '
. 'WHERE product_id = ' . $productId . ' ORDER BY o ASC'
);
$attrRows = $attrStmt ? $attrStmt->fetchAll() : [];
if (is_array($attrRows)) {
foreach ($attrRows as $row) {
$row['type'] = $this->db->get('pp_shop_attributes', 'type', ['id' => $row['attribute_id']]);
$row['language'] = $this->db->get('pp_shop_attributes_langs', ['name'], [
'AND' => ['attribute_id' => $row['attribute_id'], 'lang_id' => $langId],
]);
$valStmt = $this->db->query(
'SELECT value_id, is_default FROM pp_shop_products_attributes AS pspa '
. 'INNER JOIN pp_shop_attributes_values AS psav ON psav.id = pspa.value_id '
. 'WHERE product_id = :pid AND pspa.attribute_id = :aid',
[':pid' => $productId, ':aid' => $row['attribute_id']]
);
$valRows = $valStmt ? $valStmt->fetchAll(\PDO::FETCH_ASSOC) : [];
if (is_array($valRows)) {
foreach ($valRows as $row2) {
$row2['language'] = $this->db->get('pp_shop_attributes_values_langs', ['name', 'value'], [
'AND' => ['value_id' => $row2['value_id'], 'lang_id' => $langId],
]);
$row['values'][] = $row2;
}
}
$product['attributes'][] = $row;
}
}
$product['images'] = $this->db->select('pp_shop_products_images', '*', [
'product_id' => $productId,
'ORDER' => ['o' => 'ASC', 'id' => 'ASC'],
]);
$product['files'] = $this->db->select('pp_shop_products_files', '*', ['product_id' => $productId]);
$product['categories'] = $this->db->select('pp_shop_products_categories', 'category_id', ['product_id' => $productId]);
$product['products_related'] = $this->db->select('pp_shop_products_related', 'product_related_id', ['product_id' => $productId]);
$setId = $this->db->select('pp_shop_product_sets_products', 'set_id', ['product_id' => $productId]);
$productsSets = $this->db->select('pp_shop_product_sets_products', 'product_id', ['set_id' => (int)$setId]);
$product['products_sets'] = is_array($productsSets) ? array_unique($productsSets) : [];
$attributes = $this->db->select('pp_shop_products_attributes', ['attribute_id', 'value_id'], ['product_id' => $productId]);
$attributesTmp = [];
if (is_array($attributes)) {
foreach ($attributes as $attr) {
$attributesTmp[$attr['attribute_id']][] = $attr['value_id'];
}
}
if (!empty($attributesTmp)) {
$product['permutations'] = \Shared\Helpers\Helpers::array_cartesian_product($attributesTmp);
}
$cacheHandler->set($cacheKey, $product);
return $product;
}
/**
* @return string|null
*/
public function getWarehouseMessageZero(int $productId, string $langId)
{
if ($productId <= 0) {
return null;
}
return $this->db->get('pp_shop_products_langs', 'warehouse_message_zero', [
'AND' => ['product_id' => $productId, 'lang_id' => $langId],
]);
}
/**
* @return string|null
*/
public function getWarehouseMessageNonzero(int $productId, string $langId)
{
if ($productId <= 0) {
return null;
}
return $this->db->get('pp_shop_products_langs', 'warehouse_message_nonzero', [
'AND' => ['product_id' => $productId, 'lang_id' => $langId],
]);
}
}