/** * @param string $entityType * @param array $entityData * @return array * @throws \Exception * @throws \Magento\Framework\Exception\LocalizedException */ public function execute($entityType, $entityData) { $data = []; $metadata = $this->metadataPool->getMetadata($entityType); /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */ $attributeTables = []; if ($metadata->getEavEntityType()) { $context = $this->getActionContext($entityType, $entityData); foreach ($this->getAttributes($entityType) as $attribute) { if (!$attribute->isStatic()) { $attributeTables[$attribute->getBackend()->getTable()][] = $attribute->getAttributeId(); } } $selects = []; foreach ($attributeTables as $attributeTable => $attributeCodes) { $select = $metadata->getEntityConnection()->select()->from(['t' => $attributeTable], ['value' => 't.value'])->join(['a' => $this->appResource->getTableName('eav_attribute')], 'a.attribute_id = t.attribute_id', ['attribute_code' => 'a.attribute_code'])->where($metadata->getLinkField() . ' = ?', $entityData[$metadata->getLinkField()])->where('t.attribute_id IN (?)', $attributeCodes)->order('a.attribute_id'); foreach ($context as $field => $value) { //TODO: if (in table exists context field) $select->where($metadata->getEntityConnection()->quoteIdentifier($field) . ' IN (?)', $value)->order('t.' . $field . ' DESC'); } $selects[] = $select; } $unionSelect = new \Magento\Framework\DB\Sql\UnionExpression($selects, \Magento\Framework\DB\Select::SQL_UNION_ALL); $attributeValues = $metadata->getEntityConnection()->fetchAll((string) $unionSelect); foreach ($attributeValues as $attributeValue) { $data[$attributeValue['attribute_code']] = $attributeValue['value']; } } return $data; }
/** * {@inheritdoc} */ public function save(\Magento\Catalog\Api\Data\CategoryInterface $category) { $storeId = (int) $this->storeManager->getStore()->getId(); $existingData = $this->getExtensibleDataObjectConverter()->toNestedArray($category, [], 'Magento\\Catalog\\Api\\Data\\CategoryInterface'); $existingData = array_diff_key($existingData, array_flip(['path', 'level', 'parent_id'])); $existingData['store_id'] = $storeId; if ($category->getId()) { $metadata = $this->metadataPool->getMetadata(CategoryInterface::class); $category = $this->get($category->getId(), $storeId); $existingData[$metadata->getLinkField()] = $category->getData($metadata->getLinkField()); if (isset($existingData['image']) && is_array($existingData['image'])) { $existingData['image_additional_data'] = $existingData['image']; unset($existingData['image']); } } else { $parentId = $category->getParentId() ?: $this->storeManager->getStore()->getRootCategoryId(); $parentCategory = $this->get($parentId, $storeId); $existingData['path'] = $parentCategory->getPath(); $existingData['parent_id'] = $parentId; } $category->addData($existingData); try { $this->validateCategory($category); $this->categoryResource->save($category); } catch (\Exception $e) { throw new CouldNotSaveException(__('Could not save category: %1', $e->getMessage()), $e); } unset($this->instances[$category->getId()]); return $this->get($category->getId(), $storeId); }
/** * Save configurable product relations * * @param \Magento\Catalog\Model\Product $mainProduct the parent id * @param array $productIds the children id array * @return $this */ public function saveProducts($mainProduct, $productIds) { $isProductInstance = false; if ($mainProduct instanceof \Magento\Catalog\Model\Product) { $mainProductId = $mainProduct->getId(); $isProductInstance = true; } $old = []; if (!$mainProduct->getIsDuplicate()) { $old = $mainProduct->getTypeInstance()->getUsedProductIds($mainProduct); } $insert = array_diff($productIds, $old); $delete = array_diff($old, $productIds); if ((!empty($insert) || !empty($delete)) && $isProductInstance) { $mainProduct->setIsRelationsChanged(true); } if (!empty($delete)) { $where = ['parent_id = ?' => $mainProductId, 'product_id IN(?)' => $delete]; $this->getConnection()->delete($this->getMainTable(), $where); } if (!empty($insert)) { $data = []; foreach ($insert as $childId) { $data[] = ['product_id' => (int) $childId, 'parent_id' => (int) $mainProductId]; } $this->getConnection()->insertMultiple($this->getMainTable(), $data); } $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); // configurable product relations should be added to relation table $this->_catalogProductRelation->processRelations($mainProduct->getData($linkField), $productIds); return $this; }
/** * @param string $entityType * @param object $entity * @return object */ public function execute($entityType, $entity) { $entityMetadata = $this->metadataPool->getMetadata($entityType); $linkField = $entityMetadata->getLinkField(); $connection = $entityMetadata->getEntityConnection(); $oldStores = $this->resourcePage->lookupStoreIds((int) $entity->getId()); $newStores = (array) $entity->getStores(); if (empty($newStores)) { $newStores = (array) $entity->getStoreId(); } $table = $this->resourcePage->getTable('cms_page_store'); $delete = array_diff($oldStores, $newStores); if ($delete) { $where = [$linkField . ' = ?' => (int) $entity->getData($linkField), 'store_id IN (?)' => $delete]; $connection->delete($table, $where); } $insert = array_diff($newStores, $oldStores); if ($insert) { $data = []; foreach ($insert as $storeId) { $data[] = [$linkField => (int) $entity->getData($linkField), 'store_id' => (int) $storeId]; } $connection->insertMultiple($table, $data); } return $entity; }
/** * @param string $entityType * @param object $entity * @return object * @throws CouldNotSaveException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function execute($entityType, $entity) { /** * @var $entity \Magento\Catalog\Api\Data\ProductLinkInterface */ $linkedProduct = $this->productRepository->get($entity->getLinkedProductSku()); $product = $this->productRepository->get($entity->getSku()); $links = []; $extensions = $this->dataObjectProcessor->buildOutputDataArray($entity->getExtensionAttributes(), 'Magento\\Catalog\\Api\\Data\\ProductLinkExtensionInterface'); $extensions = is_array($extensions) ? $extensions : []; $data = $entity->__toArray(); foreach ($extensions as $attributeCode => $attribute) { $data[$attributeCode] = $attribute; } unset($data['extension_attributes']); $data['product_id'] = $linkedProduct->getId(); $links[$linkedProduct->getId()] = $data; try { $linkTypesToId = $this->linkTypeProvider->getLinkTypes(); $prodyctHydrator = $this->metadataPool->getHydrator(ProductInterface::class); $productData = $prodyctHydrator->extract($product); $this->linkResource->saveProductLinks($productData[$this->metadataPool->getMetadata(ProductInterface::class)->getLinkField()], $links, $linkTypesToId[$entity->getLinkType()]); } catch (\Exception $exception) { throw new CouldNotSaveException(__('Invalid data provided for linked products')); } return $entity; }
/** * {@inheritdoc} */ public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $installer = $setup; $installer->startSetup(); $metadata = $this->metadataPool->getMetadata(CategoryInterface::class); $this->externalFKSetup->install($installer, $metadata->getEntityTable(), $metadata->getIdentifierField(), ResourceProduct::TABLE_NAME, 'category_id'); $installer->endSetup(); }
/** * @param string $entityType * @param array $entityData * @return array * @throws \Exception */ public function execute($entityType, $entityData) { $linkField = $this->metadataPool->getMetadata($entityType)->getLinkField(); $entityId = $entityData[$linkField]; $entityData['customer_group_ids'] = $this->ruleResource->getCustomerGroupIds($entityId); $entityData['website_ids'] = $this->ruleResource->getWebsiteIds($entityId); return $entityData; }
/** * {@inheritdoc} */ public function execute($entityType, $entity, $identifier) { $metadata = $this->metadataPool->getMetadata($entityType); $entity = $this->readMain->execute($entityType, $entity, $identifier); if (isset($entity[$metadata->getLinkField()])) { $entity = $this->readExtension->execute($entityType, $entity); $entity = $this->readRelation->execute($entityType, $entity); } return $entity; }
/** * @param string $entityType * @param array $data * @return array */ public function execute($entityType, $data) { $metadata = $this->metadataPool->getMetadata($entityType); $linkField = $metadata->getLinkField(); $entityTable = $metadata->getEntityTable(); $connection = $metadata->getEntityConnection(); $connection->insert($entityTable, $this->prepareData($metadata, $data)); $data[$linkField] = $connection->lastInsertId($entityTable); return $data; }
/** * Returns array of fields * * @param string $entityType * @return array * @throws \Exception */ public function getAttributes($entityType) { $metadata = $this->metadataPool->getMetadata($entityType); $searchResult = $this->attributeRepository->getList($metadata->getEavEntityType(), $this->searchCriteriaBuilder->create()); $attributes = []; foreach ($searchResult->getItems() as $attribute) { $attributes[] = $attribute->getAttributeCode(); } return $attributes; }
/** * @param string $entityType * @param string $identifier * @param array $context * @return array * @throws \Exception */ public function execute($entityType, $identifier, $context = []) { $metadata = $this->metadataPool->getMetadata($entityType); $select = $metadata->getEntityConnection()->select()->from(['t' => $metadata->getEntityTable()])->where($metadata->getIdentifierField() . ' = ?', $identifier); foreach ($context as $field => $value) { $select->where($metadata->getEntityConnection()->quoteIdentifier($field) . ' = ?', $value); } $data = $metadata->getEntityConnection()->fetchRow($select); return $data ?: []; }
/** * @param string $entityType * @param object $entity * @return bool|object * @throws \Exception */ public function save($entityType, $entity) { $hydrator = $this->metadataPool->getHydrator($entityType); $metadata = $this->metadataPool->getMetadata($entityType); $entityData = $hydrator->extract($entity); if (!empty($entityData[$metadata->getIdentifierField()]) && $metadata->checkIsEntityExists($entityData[$metadata->getIdentifierField()])) { $operation = $this->orchestratorPool->getWriteOperation($entityType, 'update'); } else { $operation = $this->orchestratorPool->getWriteOperation($entityType, 'create'); } return $operation->execute($entityType, $entity); }
/** * Retrieve cms page collection array * * @param int $storeId * @return array */ public function getCollection($storeId) { $entityMetadata = $this->metadataPool->getMetadata(PageInterface::class); $linkField = $entityMetadata->getLinkField(); $select = $this->getConnection()->select()->from(['main_table' => $this->getMainTable()], [$this->getIdFieldName(), 'url' => 'identifier', 'updated_at' => 'update_time'])->join(['store_table' => $this->getTable('cms_page_store')], "main_table.{$linkField} = store_table.{$linkField}", [])->where('main_table.is_active = 1')->where('main_table.identifier != ?', \Magento\Cms\Model\Page::NOROUTE_PAGE_ID)->where('store_table.store_id IN(?)', [0, $storeId]); $pages = []; $query = $this->getConnection()->query($select); while ($row = $query->fetch()) { $page = $this->_prepareObject($row); $pages[$page->getId()] = $page; } return $pages; }
/** * Check that entity has overridden url attribute for specific store * * @param int $storeId * @param int $entityId * @param string $entityType * @param mixed $attributeName * @throws \InvalidArgumentException * @return bool */ protected function doesEntityHaveOverriddenUrlAttributeForStore($storeId, $entityId, $entityType, $attributeName) { $attribute = $this->eavConfig->getAttribute($entityType, $attributeName); if (!$attribute) { throw new \InvalidArgumentException(sprintf('Cannot retrieve attribute for entity type "%s"', $entityType)); } $linkFieldName = $attribute->getEntity()->getLinkField(); if (!$linkFieldName) { $linkFieldName = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); } $select = $this->connection->select()->from(['e' => $attribute->getEntity()->getEntityTable()], [])->join(['e_attr' => $attribute->getBackendTable()], "e.{$linkFieldName} = e_attr.{$linkFieldName}", 'store_id')->where('e_attr.attribute_id = ?', $attribute->getId())->where('e.entity_id = ?', $entityId); return in_array($storeId, $this->connection->fetchCol($select)); }
/** * Method for product filter * * @param \Magento\Catalog\Model\Product|array|int|null $product * @return $this */ public function addProductToFilter($product) { if (empty($product)) { $this->addFieldToFilter('product_id', ''); } else { $this->join(['cpe' => $this->getTable('catalog_product_entity')], sprintf('cpe.%s = main_table.product_id', $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField())); if (is_array($product)) { $this->addFieldToFilter('cpe.entity_id', ['in' => $product]); } else { $this->addFieldToFilter('cpe.entity_id', $product); } } return $this; }
/** * 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'])->join(['cpe' => $this->getTable('catalog_product_entity')], sprintf('cpe.%s = l.product_id', $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField()))->where('cpe.entity_id = :product_id')->where('link_type_id = :link_type_id'); $select->join(['e' => $this->getTable('catalog_product_entity')], 'e.entity_id = l.linked_product_id AND e.required_options = 0', []); $childrenIds[$typeId] = []; $result = $connection->fetchAll($select, $bind); foreach ($result as $row) { $childrenIds[$typeId][$row['linked_product_id']] = $row['linked_product_id']; } return $childrenIds; }
/** * @param string $entityType * @param int $identifier * @return int * @throws \Exception */ public function delete($entityType, $identifier) { $metadata = $this->metadataPool->getMetadata($entityType); $sequenceInfo = $this->sequenceRegistry->retrieve($entityType); if (!isset($sequenceInfo['sequenceTable'])) { throw new \Exception('TODO: use correct Exception class' . PHP_EOL . ' Sequence table doesnt exists'); } try { return $metadata->getEntityConnection()->delete($this->appResource->getTableName($sequenceInfo['sequenceTable']), ['sequence_value = ?' => $identifier]); } catch (\Exception $e) { $this->logger->critical($e->getMessage(), $e->getTrace()); throw new \Exception('TODO: use correct Exception class' . PHP_EOL . $e->getMessage()); } }
/** * @param string $entityType * @param object $entity * @param array $data * @return object * @throws \Exception */ public function execute($entityType, $entity, $data = []) { $metadata = $this->metadataPool->getMetadata($entityType); if ($metadata->getEavEntityType()) { $hydrator = $this->metadataPool->getHydrator($entityType); $entityData = array_merge($hydrator->extract($entity), $data); $actions = $this->extensionPool->getActions($entityType, 'delete'); foreach ($actions as $action) { $action->execute($entityType, $entityData); } $entity = $hydrator->hydrate($entity, $entityData); } return $entity; }
/** * Check attribute lock state * * @param \Magento\Framework\Model\AbstractModel $object * @param null $attributeSet * @throws \Magento\Framework\Exception\LocalizedException * @return void */ public function validate(\Magento\Framework\Model\AbstractModel $object, $attributeSet = null) { $metadata = $this->metadataPool->getMetadata(ProductInterface::class); $connection = $this->resource->getConnection(); $bind = ['attribute_id' => $object->getAttributeId()]; $select = clone $connection->select(); $select->reset()->from(['main_table' => $this->resource->getTableName('catalog_product_super_attribute')], ['psa_count' => 'COUNT(product_super_attribute_id)'])->join(['entity' => $this->resource->getTableName('catalog_product_entity')], 'main_table.product_id = entity.' . $metadata->getLinkField())->where('main_table.attribute_id = :attribute_id')->group('main_table.attribute_id')->limit(1); if ($attributeSet !== null) { $bind['attribute_set_id'] = $attributeSet; $select->where('entity.attribute_set_id = :attribute_set_id'); } if ($connection->fetchOne($select, $bind)) { throw new \Magento\Framework\Exception\LocalizedException(__('This attribute is used in configurable products.')); } }
/** * {@inheritdoc} * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function save($sku, OptionInterface $option) { $metadata = $this->metadataPool->getMetadata(ProductInterface::class); if ($option->getId()) { /** @var Product $product */ $product = $this->getProduct($sku); $data = $option->getData(); $option->load($option->getId()); $option->setData(array_replace_recursive($option->getData(), $data)); if (!$option->getId() || $option->getProductId() != $product->getData($metadata->getLinkField())) { throw new NoSuchEntityException(__('Option with id "%1" not found', $option->getId())); } } else { /** @var Product $product */ $product = $this->productRepository->get($sku); $this->validateNewOptionData($option); $allowedTypes = [ProductType::TYPE_SIMPLE, ProductType::TYPE_VIRTUAL, ConfigurableType::TYPE_CODE]; if (!in_array($product->getTypeId(), $allowedTypes)) { throw new \InvalidArgumentException('Incompatible product type'); } $option->setProductId($product->getData($metadata->getLinkField())); } try { $option->save(); } catch (\Exception $e) { throw new CouldNotSaveException(__('Something went wrong while saving option.')); } if (!$option->getId()) { throw new CouldNotSaveException(__('Something went wrong while saving option.')); } return $option->getId(); }
/** * Obtain select for categories with attributes. * By default everything from entity table is selected * + name, is_active and is_anchor * Also the correct product_count is selected, depending on is the category anchor or not. * * @param bool $sorted * @param array $optionalAttributes * @return \Magento\Framework\DB\Select */ protected function _createCollectionDataSelect($sorted = true, $optionalAttributes = []) { $meta = $this->metadataPool->getMetadata(CategoryInterface::class); $linkField = $meta->getLinkField(); $select = $this->_getDefaultCollection($sorted ? $this->_orderField : false)->getSelect(); // add attributes to select $attributes = ['name', 'is_active', 'is_anchor']; if ($optionalAttributes) { $attributes = array_unique(array_merge($attributes, $optionalAttributes)); } $resource = $this->_catalogCategory; foreach ($attributes as $attributeCode) { /* @var $attribute \Magento\Eav\Model\Entity\Attribute */ $attribute = $resource->getAttribute($attributeCode); // join non-static attribute table if (!$attribute->getBackend()->isStatic()) { $tableDefault = sprintf('d_%s', $attributeCode); $tableStore = sprintf('s_%s', $attributeCode); $valueExpr = $this->_conn->getCheckSql("{$tableStore}.value_id > 0", "{$tableStore}.value", "{$tableDefault}.value"); $select->joinLeft([$tableDefault => $attribute->getBackend()->getTable()], sprintf('%1$s.' . $linkField . '=e.' . $linkField . ' AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d', $tableDefault, $attribute->getId(), \Magento\Store\Model\Store::DEFAULT_STORE_ID), [$attributeCode => 'value'])->joinLeft([$tableStore => $attribute->getBackend()->getTable()], sprintf('%1$s.' . $linkField . '=e.' . $linkField . ' AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d', $tableStore, $attribute->getId(), $this->getStoreId()), [$attributeCode => $valueExpr]); } } // count children products qty plus self products qty $categoriesTable = $this->_coreResource->getTableName('catalog_category_entity'); $categoriesProductsTable = $this->_coreResource->getTableName('catalog_category_product'); $subConcat = $this->_conn->getConcatSql(['e.path', $this->_conn->quote('/%')]); $subSelect = $this->_conn->select()->from(['see' => $categoriesTable], null)->joinLeft(['scp' => $categoriesProductsTable], 'see.entity_id=scp.category_id', ['COUNT(DISTINCT scp.product_id)'])->where('see.entity_id = e.entity_id')->orWhere('see.path LIKE ?', $subConcat); $select->columns(['product_count' => $subSelect]); $subSelect = $this->_conn->select()->from(['cp' => $categoriesProductsTable], 'COUNT(cp.product_id)')->where('cp.category_id = e.entity_id'); $select->columns(['self_product_count' => $subSelect]); return $select; }
/** * Apply diff. between 0 store and current store to temporary flat table * * @param array $tables * @param array $changedIds * @param int|string $storeId * @param string $valueFieldSuffix * @return void */ protected function _updateTemporaryTableByStoreValues(array $tables, array $changedIds, $storeId, $valueFieldSuffix) { $flatColumns = $this->_productIndexerHelper->getFlatColumns(); $temporaryFlatTableName = $this->_getTemporaryTableName($this->_productIndexerHelper->getFlatTableName($storeId)); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); foreach ($tables as $tableName => $columns) { foreach ($columns as $attribute) { /* @var $attribute \Magento\Eav\Model\Entity\Attribute */ $attributeCode = $attribute->getAttributeCode(); if ($attribute->getBackend()->getType() != 'static') { $joinCondition = sprintf('t.%s = e.%s', $linkField, $linkField) . ' AND t.attribute_id=' . $attribute->getId() . ' AND t.store_id = ' . $storeId . ' AND t.value IS NOT NULL'; /** @var $select \Magento\Framework\DB\Select */ $select = $this->_connection->select()->joinInner(['t' => $tableName], $joinCondition, [$attributeCode => 't.value']); if (!empty($changedIds)) { $select->where($this->_connection->quoteInto('e.entity_id IN (?)', $changedIds)); } $sql = $select->crossUpdateFromSelect(['e' => $temporaryFlatTableName]); $this->_connection->query($sql); } //Update not simple attributes (eg. dropdown) if (isset($flatColumns[$attributeCode . $valueFieldSuffix])) { $select = $this->_connection->select()->joinInner(['t' => $this->_productIndexerHelper->getTable('eav_attribute_option_value')], 't.option_id = e.' . $attributeCode . ' AND t.store_id=' . $storeId, [$attributeCode . $valueFieldSuffix => 't.value']); if (!empty($changedIds)) { $select->where($this->_connection->quoteInto('e.entity_id IN (?)', $changedIds)); } $sql = $select->crossUpdateFromSelect(['e' => $temporaryFlatTableName]); $this->_connection->query($sql); } } } }
/** * Clean unused relation products * * @param int $storeId * @return \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction */ protected function _cleanRelationProducts($storeId) { if (!$this->_productIndexerHelper->isAddChildData()) { return $this; } $metadata = $this->metadataPool->getMetadata(ProductInterface::class); foreach ($this->_getProductTypeInstances() as $typeInstance) { /** @var $typeInstance \Magento\Catalog\Model\Product\Type\AbstractType */ if (!$typeInstance->isComposite(null)) { continue; } $relation = $typeInstance->getRelationInfo(); if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()) { $select = $this->_connection->select()->distinct(true)->from(['t' => $this->_productIndexerHelper->getTable($relation->getTable())], [])->join(['entity_table' => $this->_connection->getTableName('catalog_product_entity')], 'entity_table.' . $metadata->getLinkField() . 't.' . $relation->getParentFieldName(), [$relation->getParentFieldName() => 'entity_table.entity_id']); $joinLeftCond = ["e.entity_id = entity_table.entity_id", "e.child_id = t.{$relation->getChildFieldName()}"]; if ($relation->getWhere() !== null) { $select->where($relation->getWhere()); $joinLeftCond[] = $relation->getWhere(); } $entitySelect = new \Zend_Db_Expr($select->__toString()); /** @var $select \Magento\Framework\DB\Select */ $select = $this->_connection->select()->from(['e' => $this->_productIndexerHelper->getFlatTableName($storeId)], null)->joinLeft(['t' => $this->_productIndexerHelper->getTable($relation->getTable())], implode(' AND ', $joinLeftCond), [])->where('e.is_child = ?', 1)->where('e.entity_id IN(?)', $entitySelect)->where("t.{$relation->getChildFieldName()} IS NULL"); $sql = $select->deleteFromSelect('e'); $this->_connection->query($sql); } } return $this; }
/** * Join linked products and their attributes * * @return $this */ protected function _joinLinks() { $select = $this->getSelect(); $connection = $select->getConnection(); $joinCondition = ['links.linked_product_id = e.entity_id', $connection->quoteInto('links.link_type_id = ?', $this->_linkTypeId)]; $joinType = 'join'; $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); if ($this->getProduct() && $this->getProduct()->getId()) { $linkFieldId = $this->getProduct()->getData($linkField); if ($this->_isStrongMode) { $this->getSelect()->where('links.product_id = ?', (int) $linkFieldId); } else { $joinType = 'joinLeft'; $joinCondition[] = $connection->quoteInto('links.product_id = ?', $linkFieldId); } $this->addFieldToFilter($linkField, ['neq' => $linkFieldId]); } elseif ($this->_isStrongMode) { $this->addFieldToFilter($linkField, ['eq' => -1]); } if ($this->_hasLinkFilter) { $select->{$joinType}(['links' => $this->getTable('catalog_product_link')], implode(' AND ', $joinCondition), ['link_id']); $this->joinAttributes(); } return $this; }
/** * Delete entity * * @param \Magento\Framework\Model\AbstractModel $object * @return $this * @throws \Magento\Framework\Exception\LocalizedException */ public function deleteEntity(\Magento\Framework\Model\AbstractModel $object) { if (!$object->getEntityAttributeId()) { return $this; } $select = $this->getConnection()->select()->from($this->getTable('eav_entity_attribute'))->where('entity_attribute_id = ?', (int) $object->getEntityAttributeId()); $result = $this->getConnection()->fetchRow($select); if ($result) { $attribute = $this->_eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $result['attribute_id']); try { $this->attrLockValidator->validate($attribute, $result['attribute_set_id']); } catch (\Magento\Framework\Exception\LocalizedException $exception) { throw new \Magento\Framework\Exception\LocalizedException(__('Attribute \'%1\' is locked. %2', $attribute->getAttributeCode(), $exception->getMessage())); } $backendTable = $attribute->getBackend()->getTable(); if ($backendTable) { $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $select = $this->getConnection()->select()->from($attribute->getEntity()->getEntityTable(), $linkField)->where('attribute_set_id = ?', $result['attribute_set_id']); $clearCondition = ['attribute_id =?' => $attribute->getId(), $linkField . ' IN (?)' => $select]; $this->getConnection()->delete($backendTable, $clearCondition); } } $condition = ['entity_attribute_id = ?' => $object->getEntityAttributeId()]; $this->getConnection()->delete($this->getTable('eav_entity_attribute'), $condition); return $this; }
/** * {@inheritdoc} */ public function removeChild($sku, $optionId, $childSku) { $product = $this->productRepository->get($sku); if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { throw new InputException(__('Product with specified sku: %1 is not a bundle product', $sku)); } $excludeSelectionIds = []; $usedProductIds = []; $removeSelectionIds = []; foreach ($this->getOptions($product) as $option) { /** @var \Magento\Bundle\Model\Selection $selection */ foreach ($option->getSelections() as $selection) { if (strcasecmp($selection->getSku(), $childSku) == 0 && $selection->getOptionId() == $optionId) { $removeSelectionIds[] = $selection->getSelectionId(); $usedProductIds[] = $selection->getProductId(); continue; } $excludeSelectionIds[] = $selection->getSelectionId(); $usedProductIds[] = $selection->getProductId(); } } if (empty($removeSelectionIds)) { throw new \Magento\Framework\Exception\NoSuchEntityException(__('Requested bundle option product doesn\'t exist')); } $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); /* @var $resource \Magento\Bundle\Model\ResourceModel\Bundle */ $resource = $this->bundleFactory->create(); $resource->dropAllUnneededSelections($product->getData($linkField), $excludeSelectionIds); $resource->removeProductRelations($product->getData($linkField), array_unique($usedProductIds)); return true; }
/** * Retrieve array of related bundle product ids by selection product id(s) * * @param int|array $childId * @return array */ public function getParentIdsByChild($childId) { $connection = $this->getConnection(); $metadata = $this->metadataPool->getMetadata(ProductInterface::class); $select = $connection->select()->distinct(true)->from($this->getMainTable(), '')->join(['e' => $this->metadataPool->getMetadata(ProductInterface::class)->getEntityTable()], 'e.' . $metadata->getLinkField() . ' = ' . $this->getMainTable() . '.parent_product_id', ['e.entity_id as parent_product_id'])->where('e.entity_id IN(?)', $childId); return $connection->fetchCol($select); }
/** * @param string $entityType * @param array $data * @return array * @throws \Exception * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute($entityType, $data) { /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */ $metadata = $this->metadataPool->getMetadata($entityType); if ($metadata->getEavEntityType()) { $context = $this->getActionContext($entityType, $data); $snapshot = $this->readSnapshot->execute($entityType, $data); $processed = []; foreach ($this->getAttributes($entityType) as $attribute) { if ($attribute->isStatic()) { continue; } if (isset($snapshot[$attribute->getAttributeCode()]) && $snapshot[$attribute->getAttributeCode()] !== false && (array_key_exists($attribute->getAttributeCode(), $data) && $attribute->isValueEmpty($data[$attribute->getAttributeCode()]))) { $this->attributePersistor->registerDelete($entityType, $data[$metadata->getLinkField()], $attribute->getAttributeCode()); } if ((!array_key_exists($attribute->getAttributeCode(), $snapshot) || $snapshot[$attribute->getAttributeCode()] === false) && !empty($data[$attribute->getAttributeCode()]) && !$attribute->isValueEmpty($data[$attribute->getAttributeCode()])) { $this->attributePersistor->registerInsert($entityType, $data[$metadata->getLinkField()], $attribute->getAttributeCode(), $data[$attribute->getAttributeCode()]); $processed[$attribute->getAttributeCode()] = $data[$attribute->getAttributeCode()]; } if (array_key_exists($attribute->getAttributeCode(), $snapshot) && $snapshot[$attribute->getAttributeCode()] !== false && !empty($data[$attribute->getAttributeCode()]) && $snapshot[$attribute->getAttributeCode()] != $data[$attribute->getAttributeCode()] && !$attribute->isValueEmpty($data[$attribute->getAttributeCode()])) { $this->attributePersistor->registerUpdate($entityType, $data[$metadata->getLinkField()], $attribute->getAttributeCode(), $data[$attribute->getAttributeCode()]); $processed[$attribute->getAttributeCode()] = $data[$attribute->getAttributeCode()]; } } $this->attributePersistor->flush($entityType, $context); } return $data; }
/** * Get store ids to which specified item is assigned * * @param int $pageId * @return array */ public function lookupStoreIds($pageId) { $connection = $this->getConnection(); $entityMetadata = $this->metadataPool->getMetadata(PageInterface::class); $linkField = $entityMetadata->getLinkField(); $select = $connection->select()->from(['cps' => $this->getTable('cms_page_store')], 'store_id')->join(['cp' => $this->getMainTable()], 'cps.' . $linkField . ' = cp.' . $linkField, [])->where('cp.' . $entityMetadata->getIdentifierField() . ' = :page_id'); return $connection->fetchCol($select, ['page_id' => (int) $pageId]); }
/** * Retrieve links searchable data * * @param int $productId * @param int $storeId * @return array */ public function getSearchableData($productId, $storeId) { $connection = $this->getConnection(); $ifNullDefaultTitle = $connection->getIfNullSql('st.title', 's.title'); $select = $connection->select()->from(['m' => $this->getMainTable()], null)->join(['s' => $this->getTable('downloadable_link_title')], 's.link_id=m.link_id AND s.store_id=0', [])->join(['cpe' => $this->getTable('catalog_product_entity')], sprintf('cpe.entity_id = m.product_id', $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField()), [])->joinLeft(['st' => $this->getTable('downloadable_link_title')], 'st.link_id=m.link_id AND st.store_id=:store_id', ['title' => $ifNullDefaultTitle])->where('cpe.entity_id=:product_id'); $bind = [':store_id' => (int) $storeId, ':product_id' => $productId]; return $connection->fetchCol($select, $bind); }