Last active
January 31, 2024 09:17
-
-
Save sandipklevu/ab2909c35c37018cf0f0b710b1b342bb to your computer and use it in GitHub Desktop.
\Klevu\Search\Model\Product\Product
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Klevu\Search\Model\Product; | |
use Klevu\Search\Api\Service\Catalog\Product\GetReviewCountInterface; | |
use Klevu\Logger\Constants as LoggerConstants; | |
use Klevu\Search\Api\Service\Catalog\Product\Review\ConvertRatingToStarsInterface; | |
use Klevu\Search\Api\Service\Catalog\Product\Review\GetAverageRatingInterface; | |
use Klevu\Search\Helper\Compat as CompatHelper; | |
use Klevu\Search\Helper\Config as ConfigHelper; | |
use Klevu\Search\Helper\Data as DataHelper; | |
use Klevu\Search\Helper\Image as ImageHelper; | |
use Klevu\Search\Helper\Price as PriceHelper; | |
use Klevu\Search\Model\Context; | |
use Magento\Catalog\Api\Data\ProductInterface as MagentoProductInterface; | |
use Magento\Catalog\Model\Product as MagentoProduct; | |
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as ProductCollectionFactory; | |
use Magento\Catalog\Pricing\Price\TierPrice; | |
use Magento\Customer\Model\Group as CustomerGroup; | |
use Magento\Framework\DataObject; | |
use Magento\Framework\Exception\LocalizedException; | |
use Magento\Framework\Exception\NoSuchEntityException; | |
use Magento\Framework\App\ObjectManager; | |
use Magento\Framework\UrlInterface; | |
use Magento\Store\Api\Data\StoreInterface; | |
use Magento\Store\Model\StoreManagerInterface; | |
use Magento\Framework\App\ResourceConnection; | |
class Product extends DataObject implements ProductInterface | |
{ | |
/** | |
* @var StoreManagerInterface | |
*/ | |
protected $_storeModelStoreManagerInterface; | |
/** | |
* @var DataHelper | |
*/ | |
protected $_searchHelperData; | |
/** | |
* @var ImageHelper | |
*/ | |
protected $_imageHelper; | |
/** | |
* @var PriceHelper | |
*/ | |
protected $_priceHelper; | |
/** | |
* @var ConfigHelper | |
*/ | |
protected $_configHelper; | |
/** | |
* @var CompatHelper | |
*/ | |
protected $_searchHelperCompat; | |
/** | |
* @var CustomerGroup | |
*/ | |
protected $_customerModelGroup; | |
/** | |
* @var GetReviewCountInterface | |
*/ | |
private $getRatingsCount; | |
/** | |
* @var GetAverageRatingInterface | |
*/ | |
private $getAverageRating; | |
/** | |
* @var ConvertRatingToStarsInterface | |
*/ | |
private $convertRatingToStars; | |
/** | |
* @var ProductCollectionFactory | |
*/ | |
private $productCollectionFactory; | |
private $resourceConnection; | |
/** | |
* @param Context $context | |
* @param array $data | |
* @param ResourceConnection $resourceConnection | |
* @param GetReviewCountInterface|null $getRatingsCount | |
* @param GetAverageRatingInterface|null $getAverageRating | |
* @param ConvertRatingToStarsInterface|null $convertRatingToStars | |
* @param ProductCollectionFactory|null $productCollectionFactory | |
*/ | |
public function __construct( | |
Context $context, | |
array $data = [], | |
ResourceConnection $resourceConnection = null, | |
GetReviewCountInterface $getRatingsCount = null, | |
GetAverageRatingInterface $getAverageRating = null, | |
ConvertRatingToStarsInterface $convertRatingToStars = null, | |
ProductCollectionFactory $productCollectionFactory = null | |
) { | |
$this->_storeModelStoreManagerInterface = $context->getStoreManagerInterface(); | |
$this->_searchHelperData = $context->getHelperManager()->getDataHelper(); | |
$this->_imageHelper = $context->getHelperManager()->getImageHelper(); | |
$this->_priceHelper = $context->getHelperManager()->getPriceHelper(); | |
$this->_configHelper = $context->getHelperManager()->getConfigHelper(); | |
$this->_searchHelperCompat = $context->getHelperManager()->getCompatHelper(); | |
$this->_customerModelGroup = $context->getKlevuCustomerGroup(); | |
$objectManager = ObjectManager::getInstance(); | |
$this->getRatingsCount = $getRatingsCount | |
?: $objectManager->get(GetReviewCountInterface::class); | |
$this->getAverageRating = $getAverageRating | |
?: $objectManager->get(GetAverageRatingInterface::class); | |
$this->convertRatingToStars = $convertRatingToStars | |
?: $objectManager->get(ConvertRatingToStarsInterface::class); | |
$this->productCollectionFactory = $productCollectionFactory | |
?: $objectManager->get(ProductCollectionFactory::class); | |
$this->resourceConnection = $resourceConnection | |
?: $objectManager->get( | |
\Magento\Framework\App\ResourceConnection::class | |
); | |
parent::__construct($data); | |
} | |
/** | |
* @param MagentoProductInterface|null $parent | |
* @param MagentoProductInterface $item | |
* | |
* @return array | |
*/ | |
public function getListCategory($parent, $item) | |
{ | |
if ($parent) { | |
$product['listCategory'] = $this->getCategoryNames($parent->getCategoryIds()); | |
} elseif ($item->getCategoryIds()) { | |
$product['listCategory'] = $this->getCategoryNames($item->getCategoryIds()); | |
} else { | |
$product['listCategory'] = ["KLEVU_PRODUCT"]; | |
} | |
return $product['listCategory']; | |
} | |
/** | |
* @param MagentoProductInterface|null $parent | |
* @param MagentoProductInterface $item | |
* | |
* @return string | |
*/ | |
public function getAllCategoryId($parent, $item) | |
{ | |
if ($parent) { | |
//category ids parent | |
$product['categoryIds'] = $this->getAllCategoryIdProcessed($parent); | |
} elseif ($item->getCategoryIds()) { | |
$product['categoryIds'] = $this->getAllCategoryIdProcessed($item); | |
} else { | |
$product['categoryIds'] = ""; | |
} | |
return $product['categoryIds']; | |
} | |
/** | |
* @param MagentoProductInterface $item | |
* | |
* @return string | |
*/ | |
private function getAllCategoryIdProcessed($item) | |
{ | |
$itemCategories = $item->getCategoryIds(); | |
$category_paths_ids = $this->getCategoryPathIds(); | |
if ($category_paths_ids) { | |
$itemCategories = array_intersect($itemCategories, array_keys($category_paths_ids)); | |
} | |
$category_anchors = $this->getCategoryAnchors(); | |
$return = []; | |
$storeId = null; | |
try { | |
$store = $this->_storeModelStoreManagerInterface->getStore(); | |
$storeId = $store->getId(); | |
} catch (NoSuchEntityException $exception) { | |
$this->_searchHelperData->log(LoggerConstants::ZEND_LOG_ERR, $exception->getMessage()); | |
} | |
$isCatAnchorSingle = $this->_configHelper->getTreatCategoryAnchorAsSingle($storeId); | |
if ($isCatAnchorSingle && is_array($itemCategories)) { | |
foreach ($itemCategories as $id) { | |
if (!isset($category_paths_ids[$id]) || !count($category_paths_ids[$id])) { | |
continue; | |
} | |
foreach ($category_paths_ids[$id] as $catIsAnchor) { | |
if (!isset($category_anchors[$catIsAnchor], $category_paths_ids[$catIsAnchor])) { | |
continue; | |
} | |
$return[] = end($category_paths_ids[$catIsAnchor]); | |
} | |
} | |
$return = array_merge($return, $itemCategories); | |
$itemCategories = array_unique($return); | |
} | |
return implode(";", | |
(is_array($itemCategories) | |
? $itemCategories | |
: [])); | |
} | |
/** | |
* @param MagentoProductInterface|null $parent | |
* @param MagentoProductInterface $item | |
* | |
* @return string|null | |
*/ | |
public function getAllCategoryPaths($parent, $item) | |
{ | |
if ($parent) { | |
$product['categoryPaths'] = $this->getCategoryNamesAndPath($parent->getCategoryIds()); | |
} elseif ($item->getCategoryIds()) { | |
$product['categoryPaths'] = $this->getCategoryNamesAndPath($item->getCategoryIds()); | |
} else { | |
$product['categoryPaths'] = ""; | |
} | |
return isset($product['categoryPaths']) | |
? (string)$product['categoryPaths'] | |
: null; | |
} | |
/** | |
* Given a list of category IDs, return the name of the category | |
* in that list that has the longest path. | |
* | |
* @param array $categories | |
* | |
* @return string | |
*/ | |
public function getLongestPathCategoryName(array $categories) | |
{ | |
$storeId = null; | |
try { | |
$store = $this->_storeModelStoreManagerInterface->getStore(); | |
$storeId = $store->getId(); | |
} catch (NoSuchEntityException $e) { | |
$this->_searchHelperData->log(LoggerConstants::ZEND_LOG_ERR, $e->getMessage()); | |
} | |
$category_paths = $this->getCategoryPaths(); | |
$category_anchors = $this->getCategoryAnchors(); | |
$category_paths_ids = $this->getCategoryPathIds(); | |
$isCatAnchorSingle = $this->_configHelper->getTreatCategoryAnchorAsSingle($storeId); | |
$name = []; | |
foreach ($categories as $id) { | |
if (!isset($category_paths[$id])) { | |
continue; | |
} | |
$name[] = end($category_paths[$id]) . ";"; | |
//added to support category anchors | |
if (!$isCatAnchorSingle || empty($category_paths_ids) || !count($category_paths[$id])) { | |
continue; | |
} | |
foreach ($category_paths_ids[$id] as $catIsAnchor) { | |
if (!isset($category_anchors[$catIsAnchor], $category_paths[$catIsAnchor])) { | |
continue; | |
} | |
$name[] = end($category_paths[$catIsAnchor]) . ";"; | |
} | |
} | |
$name = array_unique($name); | |
$name = implode("", $name); | |
return substr($name, 0, strrpos($name, ";") + 1 - 1); | |
} | |
/** | |
* Return a list of the names of all the categories in the | |
* paths of the given categories (including the given categories) | |
* up to, but not including the store root. | |
* | |
* @param array $categories | |
* | |
* @return array | |
*/ | |
public function getCategoryNames(array $categories) | |
{ | |
$storeId = null; | |
try { | |
$store = $this->_storeModelStoreManagerInterface->getStore(); | |
$storeId = $store->getId(); | |
} catch (NoSuchEntityException $e) { | |
$this->_searchHelperData->log(LoggerConstants::ZEND_LOG_ERR, $e->getMessage()); | |
} | |
$category_paths = $this->getCategoryPaths(); | |
$category_paths_ids = $this->getCategoryPathIds(); | |
$category_anchors = $this->getCategoryAnchors(); | |
$isCatAnchorSingle = $this->_configHelper->getTreatCategoryAnchorAsSingle($storeId); | |
$catPaths = []; | |
foreach ($categories as $category) { | |
if (!isset($category_paths[$category])) { | |
continue; | |
} | |
if (count($category_paths[$category]) > 0) { | |
$catPaths[$category][] = implode(";", $category_paths[$category]); | |
//added to support category anchors | |
if (!$isCatAnchorSingle) { | |
continue; | |
} | |
foreach ($category_paths_ids[$category] as $catIsAnchor) { | |
if (!isset($category_anchors[$catIsAnchor], $category_paths[$catIsAnchor])) { | |
continue; | |
} | |
if (count($category_paths[$catIsAnchor]) > 0) { | |
$catPaths[$catIsAnchor][] = implode(";", $category_paths[$catIsAnchor]); | |
} else { | |
$catPaths[$catIsAnchor] = $category_paths[$catIsAnchor]; | |
} | |
} | |
} else { | |
$catPaths[$category] = $category_paths[$category]; | |
} | |
} | |
$result = array_merge(["KLEVU_PRODUCT"], ...$catPaths); | |
return array_values( | |
array_unique($result) | |
); | |
} | |
/** | |
* Return a list of the names of all the categories in the | |
* paths of the given categories (including the given categories) | |
* up to, but not including the store root. | |
* | |
* @param array $categories | |
* | |
* @return string | |
*/ | |
public function getCategoryNamesAndPath(array $categories) | |
{ | |
$storeId = null; | |
try { | |
$store = $this->_storeModelStoreManagerInterface->getStore(); | |
$storeId = $store->getId(); | |
} catch (NoSuchEntityException $e) { | |
$this->_searchHelperData->log(LoggerConstants::ZEND_LOG_ERR, $e->getMessage()); | |
} | |
$categoryPaths = $this->getCategoryPathsAndIds(); | |
$categoryIds = $this->getCategoryPathIds(); | |
$categoryAnchors = $this->getCategoryAnchors(); | |
$isCatAnchorSingle = $this->_configHelper->getTreatCategoryAnchorAsSingle($storeId); | |
$catPath = []; | |
foreach ($categories as $category) { | |
if (!isset($categoryPaths[$category])) { | |
continue; | |
} | |
if (count($categoryPaths[$category]) > 0) { | |
$catName = implode(";", $categoryPaths[$category]); | |
$catId = implode("/", $categoryIds[$category]); | |
$catPath[$category][] = $catName . '::' . $catId; | |
// check if need to treat anchors as standalone | |
if (!$isCatAnchorSingle) { | |
continue; | |
} | |
foreach ($categoryIds[$category] as $isCatAnchor) { | |
if (!isset($categoryAnchors[$isCatAnchor], $categoryPaths[$isCatAnchor])) { | |
continue; | |
} | |
if (count($categoryPaths[$isCatAnchor]) > 0) { | |
$catName = implode(";", $categoryPaths[$isCatAnchor]); | |
$catId = implode("/", $categoryIds[$isCatAnchor]); | |
$catPath[$isCatAnchor][] = $catName . '::' . $catId; | |
} else { | |
$catName = $categoryPaths[$isCatAnchor]; | |
$catId = $categoryIds[$isCatAnchor]; | |
$catPath[$isCatAnchor] = (!is_array($catName) && !is_array($catId)) | |
? | |
$catName . '::' . $catId | |
: | |
[]; | |
} | |
} | |
} else { | |
$catName = $categoryPaths[$category]; | |
$catId = $categoryIds[$category]; | |
if (!is_array($catName) && !is_array($catId)) { | |
$catPath[$category] = $catName . '::' . $catId; | |
} else { | |
$catPath[$category] = []; | |
} | |
} | |
} | |
$result = (count($catPath)) | |
? array_merge(...$catPath) | |
: []; | |
return implode(";;", array_unique($result)); | |
} | |
/** | |
* Return an array of category paths for all the categories in the | |
* current store, not including the store root. | |
* | |
* @return array A list of category paths where each key is a category | |
* ID and each value is an array of category names for | |
* each category in the path, the last element being the | |
* name of the category referenced by the ID. | |
*/ | |
public function getCategoryPaths() | |
{ | |
$categoryPaths = $this->getData('category_paths'); | |
try { | |
$store = $this->_storeModelStoreManagerInterface->getStore(); | |
$storeId = $store->getId(); | |
$rootId = $store->getRootCategoryId(); | |
} catch (NoSuchEntityException $e) { | |
$this->_searchHelperData->log(LoggerConstants::ZEND_LOG_ERR, $e->getMessage()); | |
return $categoryPaths; | |
} | |
if (($categoryPaths) && ((int)$storeId === (int)$this->getData('catFieldStoreID'))) { | |
return $categoryPaths; | |
} | |
$this->setData('catFieldStoreID', $storeId); | |
$categoryPaths = []; | |
$categoryIds = []; | |
$categoryPathsAndIds = []; | |
try { | |
$collection = $this->productCollectionFactory->create(); | |
$collection->setStoreId($storeId); | |
$collection->addAttributeToSelect('is_exclude_cat'); | |
$collection->addAttributeToSelect('is_anchor'); | |
$collection->addAttributeToSelect('is_active'); | |
$collection->addFieldToFilter('level', ['gt' => 1]); | |
$collection->addFieldToFilter('path', ['like' => "1/$rootId/%"]); | |
$collection->addNameToResult(); | |
$this->_searchHelperData->log( | |
LoggerConstants::ZEND_LOG_INFO, | |
'CategoryCollection:' | |
); | |
$this->_searchHelperData->log( | |
LoggerConstants::ZEND_LOG_INFO, | |
$collection->getSelect()->__toString() | |
); | |
} catch (LocalizedException $e) { | |
$this->_searchHelperData->log(LoggerConstants::ZEND_LOG_ERR, $e->getMessage()); | |
return $categoryPaths; | |
} | |
$categoryAnchors = []; | |
$connection = $this->resourceConnection->getConnection(); | |
$tableNameCategoryEntity = $this->resourceConnection->getTableName('catalog_category_entity'); | |
$tableNameCategoryEntityInt = $this->resourceConnection->getTableName('catalog_category_entity_int'); | |
//change row_id to entity_id if it is open source edition | |
$select = $connection->select() | |
->from(['ce' => $tableNameCategoryEntity], ['row_id' => 'ce.row_id']) | |
->joinLeft( | |
['cpei' => $tableNameCategoryEntityInt], | |
'ce.row_id = cpei.row_id', | |
['store_id', 'attribute_id', 'store_value' => 'value'] | |
) | |
//Change 180 attribute_id value as per your system, you can write subquery to pull dynamic | |
->where('cpei.attribute_id = ?', 180) | |
->where('cpei.value = ?', 1) | |
->where('cpei.store_id = ?', 0); | |
$listOfCategoriesIsExcludeOnGlobal = $connection->fetchAll($select); | |
//$listOfCategoriesIsExcludeOnGlobal will have similar below array, | |
/*( | |
[row_id] => 30 | |
[store_id] => 0 | |
[attribute_id] => 180 | |
[store_value] => 1 | |
)*/ | |
$this->_searchHelperData->log( | |
LoggerConstants::ZEND_LOG_INFO, | |
print_r($listOfCategoriesIsExcludeOnGlobal, true) | |
); | |
$isExcludeCategoryIds = []; | |
foreach ($listOfCategoriesIsExcludeOnGlobal as $isExcludeCategory) { | |
$isExcludeCategoryIds['row_id'] = $isExcludeCategory['row_id']; | |
} | |
foreach ($collection as $category) { | |
//This will prevent if value is 1 then it won't included in `listCategory`. | |
if (in_array($category->getId(), $isExcludeCategoryIds)) { | |
continue; | |
} | |
if ($category->getIsExcludeCat() || !(int)$category->getIsActive()) { | |
continue; | |
} | |
if ($category->getIsAnchor()) { | |
$categoryAnchors[$category->getId()] = $category->getId(); | |
} | |
$categoryPaths[$category->getId()] = []; | |
$categoryPathsAndIds[$category->getId()] = []; | |
$categoryIds[$category->getId()] = []; | |
$pathIds = $category->getPathIds(); | |
foreach ($pathIds as $id) { | |
$item = $collection->getItemById($id); | |
if (!$item) { | |
continue; | |
} | |
$categoryIds[$category->getId()][] = $item->getId(); | |
$categoryPathsAndIds[$category->getId()][] = $item->getName(); | |
$categoryPaths[$category->getId()][] = $item->getName(); | |
} | |
} | |
$this->setData('category_anchors', $categoryAnchors); | |
$this->setData('category_paths_and_ids', $categoryPathsAndIds); | |
$this->setData('category_path_ids', $categoryIds); | |
$this->setData('category_paths', $categoryPaths); | |
$this->_searchHelperData->log( | |
LoggerConstants::ZEND_LOG_INFO, | |
print_r($categoryPaths, true) | |
); | |
return $categoryPaths; | |
} | |
/** | |
* Ref: KS-7557 Added to triage temporal coupling with getCategoryPaths() | |
* setting additional data | |
* | |
* @return array | |
*/ | |
public function getCategoryAnchors() | |
{ | |
if (!$this->hasData('category_anchors')) { | |
$this->getCategoryPaths(); | |
} | |
return $this->getData('category_anchors'); | |
} | |
/** | |
* Ref: KS-7557 Added to triage temporal coupling with getCategoryPaths() | |
* setting additional data | |
* | |
* @return array | |
*/ | |
public function getCategoryPathsAndIds() | |
{ | |
if (!$this->hasData('category_paths_and_ids')) { | |
$this->getCategoryPaths(); | |
} | |
return $this->getData('category_paths_and_ids'); | |
} | |
/** | |
* Ref: KS-7557 Added to triage temporal coupling with getCategoryPaths() | |
* setting additional data | |
* | |
* @return array | |
*/ | |
public function getCategoryPathIds() | |
{ | |
if (!$this->hasData('category_path_ids')) { | |
$this->getCategoryPaths(); | |
} | |
return $this->getData('category_path_ids'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment