Skip to content

Commit

Permalink
Merge pull request #19 from romainruaud/fix_store-view-constraint
Browse files Browse the repository at this point in the history
Remove table unique key, and check it by the code.
  • Loading branch information
romainruaud authored Jun 21, 2019
2 parents d31a0db + 82e2f26 commit 4043393
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 11 deletions.
79 changes: 73 additions & 6 deletions Model/ResourceModel/ProductLabel.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
use Magento\Framework\DB\Select;
use Magento\Framework\EntityManager\EntityManager;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use Magento\Framework\Model\ResourceModel\Db\Context;
use Magento\Framework\Model\AbstractModel;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
use Smile\ProductLabel\Api\Data\ProductLabelInterface;

/**
Expand All @@ -40,24 +43,32 @@ class ProductLabel extends AbstractDb
*/
protected $metadataPool;

/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;

/**
* Resource initialization
*
* @param Context $context Context
* @param EntityManager $entityManager Entity Manager
* @param MetadataPool $metadataPool Metadata Pool
* @param null $connectionName Connection Name
* @param Context $context Context
* @param EntityManager $entityManager Entity Manager
* @param MetadataPool $metadataPool Metadata Pool
* @param StoreManagerInterface $storeManager Store Manager
* @param null $connectionName Connection Name
*/
public function __construct(
Context $context,
EntityManager $entityManager,
MetadataPool $metadataPool,
StoreManagerInterface $storeManager,
$connectionName = null
) {
parent::__construct($context, $connectionName);

$this->entityManager = $entityManager;
$this->metadataPool = $metadataPool;
$this->storeManager = $storeManager;
}

/**
Expand Down Expand Up @@ -100,7 +111,6 @@ public function delete(AbstractModel $object)

/**
* Persist relation between a given product label and his stores.
*
* @SuppressWarnings(PHPMD.ElseExpression)
*
* @param \Magento\Framework\Model\AbstractModel $object The rule
Expand All @@ -117,13 +127,15 @@ public function saveStoreRelation(\Magento\Framework\Model\AbstractModel $object
$newStores = $object->getStores();
}

$this->checkUnicity($object, $newStores);

$table = $this->getTable(ProductLabelInterface::STORE_TABLE_NAME);

$delete = array_diff($oldStores, $newStores);
if ($delete) {
$where = [
$this->getIdFieldName() . ' = ?' => (int) $object->getData($this->getIdFieldName()),
'store_id IN (?)' => $delete,
'store_id IN (?)' => $delete,
];
$this->getConnection()->delete($table, $where);
}
Expand Down Expand Up @@ -179,4 +191,59 @@ protected function _construct()
ProductLabelInterface::PRODUCTLABEL_ID
);
}

/**
* Check unicity between a product label and stores.
* Unique constraint is : product_label_id / attribute_id / option_id / store_id
* A product label can also not be created for store 0 (all store views) if other exists for specific stores.
*
* @param \Magento\Framework\Model\AbstractModel $object The product label
* @param array $stores The stores to be associated with
*
* @return bool
*
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
private function checkUnicity(\Magento\Framework\Model\AbstractModel $object, array $stores)
{
$isDefaultStore = $this->storeManager->isSingleStoreMode()
|| array_search(Store::DEFAULT_STORE_ID, $stores) !== false;

if (!$isDefaultStore) {
$stores[] = Store::DEFAULT_STORE_ID;
}

$select = $this->getConnection()->select()
->from(['pl' => $this->getMainTable()])
->join(
['pls' => $this->getTable(ProductLabelInterface::STORE_TABLE_NAME)],
'pl.' . $this->getIdFieldName() . ' = pls.' . $this->getIdFieldName(),
[ProductLabelInterface::STORE_ID]
)
->where('pl.' . ProductLabelInterface::ATTRIBUTE_ID . ' = ? ', $object->getData(ProductLabelInterface::ATTRIBUTE_ID))
->where('pl.' . ProductLabelInterface::OPTION_ID . ' = ? ', $object->getData(ProductLabelInterface::OPTION_ID));

if (!$isDefaultStore) {
$select->where('pls.store_id IN (?)', $stores);
}

if ($object->getId()) {
$select->where('pl.' . $this->getIdFieldName() . ' <> ?', $object->getId());
}

if ($row = $this->getConnection()->fetchRow($select)) {
$error = new \Magento\Framework\Phrase(
'Label for attribute %1, option %2, and store %3 already exist.',
[
$object->getData(ProductLabelInterface::ATTRIBUTE_ID),
$object->getData(ProductLabelInterface::OPTION_ID),
$row[ProductLabelInterface::STORE_ID],
]
);

throw new AlreadyExistsException($error);
}

return true;
}
}
1 change: 0 additions & 1 deletion Ui/Component/ProductLabel/Form/Modifier/Stores.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,4 @@ public function modifyMeta(array $meta)
{
return $meta;
}

}
4 changes: 0 additions & 4 deletions etc/db_schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="product_label_id"/>
</constraint>
<constraint xsi:type="unique" referenceId="SMILE_PRODUCTLABEL_ATTRIBUTEID_OPTIONID">
<column name="attribute_id"/>
<column name="option_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="SMILE_PRODUCTLABEL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="smile_productlabel"
column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/>
<constraint xsi:type="foreign" referenceId="SMILE_PRODUCTLABEL_OPTION_ID_EAV_ATTRIBUTE_OPTION_OPTION_ID" table="smile_productlabel"
Expand Down

0 comments on commit 4043393

Please sign in to comment.