Untitled

mail@pastecode.io avatarunknown
php
2 months ago
10 kB
2
Indexable
Never
<?php
class ModSNPopularProductsHelper
{
    public const IMAGE_EXTENSION = '_promo.png';
    public const IMAGE_DIR = '/images/stories/sn/';
    public const OVERLAY_DIR = '/images/stories/sn/_overlays/';
    public const GTM_POSITION = 'most-popular-products';

    /**
     * @param Registry $params
     * @return array
     */
    public static function getProductIds(Registry &$params): array
    {
        $productsId = [];
        if (!empty($params->get('use_recomendation')) && $params->get('use_recomendation') === '1' && Factory::getUser()->guest === 0) {
            $productsId = RecommendationHelper::getByUser();
        } elseif (!empty($params->get('use_recomendation')) && $params->get('use_recomendation') === '1' && Factory::getUser()->guest === 1) {
            $productsId = RecommendationHelper::getByNewUser($params->get('new_user_period', 168));
        } else {
            foreach ($params as $key => $value) {
                if (strpos($key, 'product') !== false && strpos($key, 'gtm') === false) {
                    $productsId[$key] = $value;
                }
            }
        }
        return array_filter($productsId);
    }

    /**
     * @param Registry $params
     * @param array $productIds
     * @return array
     * @throws Exception
     */
    public static function fetchProducts(Registry $params, array $productIds): array
    {
        $items = [];
        $mainParams = ComponentHelper::getParams('com_snv2');

        $db = Factory::getDbo();
        $query = $db->getQuery(true);
        $query
            ->select(
                [
                    $db->qn('p.id'),
                    $db->qn('p.alias'),
                    $db->qn('p.price'),
                    $db->qn('p.price_crossed'),
                    $db->qn('p.published'),
                    $db->qn('p.instock'),
                    $db->qn('p.short_usp'),
                    $db->qn('p.usp'),
                    $db->qn('p.name'),
                    $db->qn('p.show_price'),
                    $db->qn('p.overlay')
                ]
            )
            ->from($db->qn('#__sn_products', 'p'))
            ->where($db->qn('p.published') . ' = 1')
            ->where($db->qn('p.instock') . ' = 1');
        if (!empty($params->get('use_recomendation')) && $params->get('use_recomendation') === '1') {
            $query->where($db->qn('p.vista_only') . ' = 0')->where($db->qn('p.lp_published') . ' = 0');
        }
        $query->where('p.id IN (' . implode(',', $productIds) . ')');

        $db->setQuery($query);
        try {
            $products = $db->loadAssocList();
            $prodArr = [];
            foreach ($products as $key => $product) {
                $prodArr[$product['id']] = $product;
            }
            $finalProdArr = [];
            foreach ($productIds as $key => $product) {
                if (!empty($prodArr[$product])) {
                    $finalProdArr[$product] = $prodArr[$product];
                    // add gtm tags
                    $finalProdArr[$product]['gtm_ac'] = $params->get($key . '_gtm_ac');
                    $finalProdArr[$product]['gtm_campaign'] = $params->get($key . '_gtm_campaign');
                    $finalProdArr[$product]['gtm_creative'] = $params->get($key . '_gtm_creative');
                    $finalProdArr[$product]['gtm_position'] = self::GTM_POSITION;
                }
            }
            $finalProdArr = array_filter($finalProdArr);
            foreach ($finalProdArr as $key => $product) {
                if ((int) $product['published']) {
                    $finalProdArr[$key]['showPrice'] = ($product['instock'] || (!$product['instock'] && $mainParams->get('show_sold_out_price', '0', 'STRING') === '1'));
                    $finalProdArr[$key]['link'] = Route::_('index.php?option=com_snv2&view=product&id=' . $product['id']);
                    $finalProdArr[$key]['cartlink'] = rtrim(Uri::root(), '/') . '/index.php?option=com_snv2&task=basket.addToCart&pId=' . $product['id'];
                    $finalProdArr[$key]['price_crossed'] = (is_null($product['price_crossed']) || $product['price_crossed'] === "0.00") ? null : $product['price_crossed'];
                    $finalProdArr[$key]['price'] = SNPrice::_($product['price']);
                    $finalProdArr[$key]['price_crossed'] = SNPrice::_($product['price_crossed']);
                    $finalProdArr[$key]['overlay'] = (is_null($product['overlay']) || $product['overlay'] === "-1") ? null : rtrim(Uri::root(), '/') . self::OVERLAY_DIR . $product['overlay'];
                }
            }
            foreach ($productIds as $key => $product) {
                if (!empty($finalProdArr[$product])) {
                    $productNumber = (int) str_replace('product', '', $key);
                    $finalProdArr[$product] = (object) $finalProdArr[$product];
                    $finalProdArr[$product] = self::addGtmToSingleProduct($finalProdArr[$product], $productNumber, $params);
                    if ($productNumber <= 8) {
                        $items['new'][] = $finalProdArr[$product];
                    } elseif ($params->get('use_recomendation') !== '1') {
                        $items['returning'][] = $finalProdArr[$product];
                    }
                }
            }
        } catch (\RuntimeException $e) {
            Factory::getApplication()->enqueueMessage('Unable to fetch products from the most popular products module', 'error');
        }
        return $items;
    }

    /**
     * @param array $productIds
     * @return array
     */
    public static function fetchImages(array $productIds): array
    {
        $db = Factory::getDbo();
        $query = $db->getQuery(true);
        $query
            ->select(
                [
                    $db->qn('i.product_id'),
                    $db->qn('i.name'),
                    $db->qn('i.alias'),
                    $db->qn('i.ordering'),
                    $db->qn('i.background'),
                    $db->qn('i.published')
                ]
            )
            ->from($db->qn('#__sn_products_pictures', 'i'))
            ->where($db->qn('i.published') . ' = 1')
            ->where('i.product_id IN (' . implode(',', $productIds) . ')');
        $query->order($db->qn('i.ordering') . ' ASC');
        $db->setQuery($query);
        try {
            $images = $db->loadAssocList();
        } catch (\RuntimeException $e) {
            $images = [];
        }
        $results = [];
        foreach ($images as $k => $img) {
            $results[$img['product_id']][] = $img['alias'];
        }
        return $results;
    }

    /**
     * @param array $products
     * @param array $images
     * @return array
     */
    public static function sanitizeProducts(array $products, array $images): array
    {
        foreach ($products as $product) {
            foreach ($product as $pr) {
                if (!isset($images[$pr->id])) {
                    continue;
                }
                $pr->images = [];
                foreach ($images[$pr->id] as $img) {
                    $pr->images[] = self::generateImgPath($pr->alias, $img);
                }
                $pr->path = JPATH_ROOT . self::IMAGE_DIR . $pr->alias . '/' . $images[$pr->id][0] . '.png';
            }
        }
        return $products;
    }

    /**
     * @param stdClass $product
     * @param int $productNumber
     * @param Registry $params
     * @return stdClass
     */
    public static function addGtmToSingleProduct(stdClass $product, int $productNumber, Registry $params): stdClass
    {
        if ($params->get('use_recomendation') === '1') {
            $product->gtm_ac = !empty($product->gtm_ac) ? $product->gtm_ac : $params->get('gtm_ac');
            $product->gtm_campaign = !empty($product->gtm_campaign) ? $product->gtm_campaign : $params->get('gtm_campaign');
            $product->gtm_creative = !empty($product->gtm_creative) ? $product->gtm_creative : $params->get('gtm_creative');
            $product->gtm_position = self::GTM_POSITION;
            return $product;
        }
        $product->gtm_ac = !empty($product->gtm_ac) ? $product->gtm_ac : $params->get('product' . $productNumber . '_gtm_ac');
        $product->gtm_campaign = !empty($product->gtm_campaign) ? $product->gtm_campaign : $params->get('product' . $productNumber . '_gtm_campaign');
        $product->gtm_creative = !empty($product->gtm_creative) ? $product->gtm_creative : $params->get('product' . $productNumber . '_gtm_creative');
        $product->gtm_position = self::GTM_POSITION;
        return $product;
    }

    /**
     * @param string $productAlias
     * @param string $imageName
     * @return string
     */
    public static function generateImgPath(string $productAlias, string $imageName): string
    {
        return rtrim(Uri::root(), '/') . self::IMAGE_DIR . $productAlias . '/' . $imageName . self::IMAGE_EXTENSION;
    }

    /**
     * @param Registry $params
     * @return array
     * @throws Exception
     */
    public static function getProducts(Registry &$params): array
    {
        $productIds = self::getProductIds($params);
        $products = self::fetchProducts($params, $productIds);
        if (!empty($products['new']) && count($products['new']) > 8) {
            $products['new'] = array_slice($products['new'], 0, 8);
        }
        $images = self::fetchImages($productIds);

        return self::sanitizeProducts($products, $images);
    }

    /**
     * Get View/Buy buttons
     * @return array button states
     */
    public static function getButtons($params)
    {
        if ($params->get('show_view_button') == null) {
            $viewButton = 1;
        } else {
            $viewButton = $params->get('show_view_button');
        }
        $buyButton = $params->get('show_buy_button') ? 1 : 0;
        return ['viewButton' => $viewButton, 'buyButton' => $buyButton];
    }
}