![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-catalog/Model/ResourceModel/Product/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Catalog\Model\ResourceModel\Product; use Magento\Framework\DB\Adapter\AdapterInterface; /** * Catalog product link resource model * * @author Magento Core Team <[email protected]> */ class Link extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { /** * Product Link Attributes Table * * @var string */ protected $_attributesTable; /** * Catalog product relation * * @var Relation */ protected $_catalogProductRelation; /** * Link constructor. * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param Relation $catalogProductRelation * @param string|null $connectionName * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, Relation $catalogProductRelation, $connectionName = null ) { parent::__construct($context, $connectionName); } /** * Define main table name and attributes table * * @return void */ protected function _construct() { $this->_init('catalog_product_link', 'link_id'); $this->_attributesTable = $this->getTable('catalog_product_link_attribute'); } /** * Delete product link by link_id * * @param int $linkId * @return int * @throws \Magento\Framework\Exception\LocalizedException */ public function deleteProductLink($linkId) { return $this->getConnection()->delete($this->getMainTable(), ['link_id = ?' => $linkId]); } /** * Retrieve product link_id by link product id and type id * * @param int $parentId * @param int $linkedProductId * @param int $typeId * @return string * @throws \Magento\Framework\Exception\LocalizedException */ public function getProductLinkId($parentId, $linkedProductId, $typeId) { $connection = $this->getConnection(); $bind = [ ':product_id' => (int)$parentId, ':link_type_id' => (int)$typeId, ':linked_product_id' => (int)$linkedProductId ]; $select = $connection->select()->from( $this->getMainTable(), ['link_id'] )->where( 'product_id = :product_id' )->where( 'link_type_id = :link_type_id' )->where( 'linked_product_id = :linked_product_id' ); return $connection->fetchOne($select, $bind); } /** * Check if product has links. * * @param int $parentId ID of product * @return bool */ public function hasProductLinks($parentId) { $connection = $this->getConnection(); $select = $connection->select()->from( $this->getMainTable(), ['count' => new \Zend_Db_Expr('COUNT(*)')] )->where( 'product_id = :product_id' ) ; return $connection->fetchOne( $select, [ 'product_id' => $parentId ] ) > 0; } /** * Save Product Links process * * @param int $parentId * @param array $data * @param int $typeId * @return $this * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function saveProductLinks($parentId, $data, $typeId) { if (!is_array($data)) { $data = []; } $connection = $this->getConnection(); $bind = [':product_id' => (int)$parentId, ':link_type_id' => (int)$typeId]; $select = $connection->select()->from( $this->getMainTable(), ['linked_product_id', 'link_id'] )->where( 'product_id = :product_id' )->where( 'link_type_id = :link_type_id' ); $links = $connection->fetchPairs($select, $bind); list($insertData, $updateData, $deleteConditions) = $this->prepareProductLinksData( $parentId, $data, $typeId, $links ); if ($insertData) { $insertColumns = [ 'product_link_attribute_id', 'link_id', 'value', ]; foreach ($insertData as $table => $values) { $connection->insertArray($table, $insertColumns, $values, AdapterInterface::INSERT_IGNORE); } } if ($updateData) { // for mass update product links with constraint by unique key use insert on duplicate statement foreach ($updateData as $table => $values) { $connection->insertOnDuplicate($table, $values, ['value']); } } if ($deleteConditions) { foreach ($deleteConditions as $table => $deleteCondition) { $connection->delete( $table, [ 'link_id = ?' => $deleteCondition['link_id'], 'product_link_attribute_id = ?' => $deleteCondition['product_link_attribute_id'] ] ); } } return $this; } /** * Prepare link attribute value by attribute type * * @param string $type * @param mixed $value * @return mixed */ protected function _prepareAttributeValue($type, $value) { if ($type == 'int') { $value = (int)$value; } elseif ($type == 'decimal') { $value = (double)sprintf('%F', $value); } return $value; } /** * Retrieve product link attributes by link type * * @param int $typeId * @return array */ public function getAttributesByType($typeId) { $connection = $this->getConnection(); $select = $connection->select()->from( $this->_attributesTable, ['id' => 'product_link_attribute_id', 'code' => 'product_link_attribute_code', 'type' => 'data_type'] )->where( 'link_type_id = ?', $typeId ); return $connection->fetchAll($select); } /** * Returns table for link attribute by attribute type * * @param string $type * @return string */ public function getAttributeTypeTable($type) { return $this->getTable('catalog_product_link_attribute_' . $type); } /** * Retrieve Required children ids * Return grouped array, ex array( * group => array(ids) * ) * * @param int $parentId * @param int $typeId * @return array */ public function getChildrenIds($parentId, $typeId) { $connection = $this->getConnection(); $childrenIds = []; $bind = [':product_id' => (int)$parentId, ':link_type_id' => (int)$typeId]; $select = $connection->select()->from( ['l' => $this->getMainTable()], ['linked_product_id'] )->where( 'product_id = :product_id' )->where( 'link_type_id = :link_type_id' ); $childrenIds[$typeId] = []; $result = $connection->fetchAll($select, $bind); foreach ($result as $row) { $childrenIds[$typeId][$row['linked_product_id']] = $row['linked_product_id']; } return $childrenIds; } /** * Retrieve parent ids array by required child * * @param int|array $childId * @param int $typeId * @return string[] */ public function getParentIdsByChild($childId, $typeId) { $parentIds = []; $connection = $this->getConnection(); $select = $connection->select()->from( $this->getMainTable(), ['product_id', 'linked_product_id'] )->where( 'linked_product_id IN(?)', $childId )->where( 'link_type_id = ?', $typeId ); $result = $connection->fetchAll($select); foreach ($result as $row) { $parentIds[] = $row['product_id']; } return $parentIds; } /** * Prepare data for insert, update or delete product link attributes * * @param int $parentId * @param array $data * @param int $typeId * @param array $links * @return array */ private function prepareProductLinksData($parentId, $data, $typeId, $links) { $connection = $this->getConnection(); $attributes = $this->getAttributesByType($typeId); $insertData = []; $updateData = []; $deleteConditions = []; foreach ($data as $linkedProductId => $linkInfo) { $linkId = null; if (isset($links[$linkedProductId])) { $linkId = $links[$linkedProductId]; } else { $bind = [ 'product_id' => $parentId, 'linked_product_id' => $linkedProductId, 'link_type_id' => $typeId, ]; $connection->insert($this->getMainTable(), $bind); $linkId = $connection->lastInsertId($this->getMainTable()); } foreach ($attributes as $attributeInfo) { $attributeTable = $this->getAttributeTypeTable($attributeInfo['type']); if (!$attributeTable) { continue; } if (isset($linkInfo[$attributeInfo['code']])) { $value = $this->_prepareAttributeValue( $attributeInfo['type'], $linkInfo[$attributeInfo['code']] ); if (isset($links[$linkedProductId])) { $updateData[$attributeTable][] = [ 'product_link_attribute_id' => $attributeInfo['id'], 'link_id' => $linkId, 'value' => $value, ]; } else { $insertData[$attributeTable][] = [ 'product_link_attribute_id' => $attributeInfo['id'], 'link_id' => $linkId, 'value' => $value, ]; } } else { $deleteConditions[$attributeTable]['link_id'][] = $linkId; $deleteConditions[$attributeTable]['product_link_attribute_id'][] = $attributeInfo['id']; } } } return [$insertData, $updateData, $deleteConditions]; } }