Skip to content

Commit

Permalink
Merge pull request #3827 from magento-tsg/2.2-develop-pr80
Browse files Browse the repository at this point in the history
[TSG] Backporting for 2.2 (pr80) (2.2-develop)
  • Loading branch information
xmav authored Mar 2, 2019
2 parents 9f04388 + 2ece592 commit 0982a53
Show file tree
Hide file tree
Showing 44 changed files with 1,078 additions and 249 deletions.
6 changes: 6 additions & 0 deletions app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,19 @@ public function __construct(
}

/**
* Perform action on relation/extension attribute.
*
* @param object $entity
* @param array $arguments
* @return \Magento\Catalog\Api\Data\ProductInterface|object
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function execute($entity, $arguments = [])
{
if ($entity->getOptionsSaved()) {
return $entity;
}

$options = $entity->getOptions();
$optionIds = [];

Expand Down
14 changes: 10 additions & 4 deletions app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
namespace Magento\Catalog\Model\ResourceModel;

use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend;
use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend;
use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
use Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface;

/**
* Catalog entity abstract model
Expand Down Expand Up @@ -39,16 +43,18 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Catalog\Model\Factory $modelFactory
* @param array $data
* @param UniqueValidationInterface|null $uniqueValidator
*/
public function __construct(
\Magento\Eav\Model\Entity\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Catalog\Model\Factory $modelFactory,
$data = []
$data = [],
UniqueValidationInterface $uniqueValidator = null
) {
$this->_storeManager = $storeManager;
$this->_modelFactory = $modelFactory;
parent::__construct($context, $data);
parent::__construct($context, $data, $uniqueValidator);
}

/**
Expand Down Expand Up @@ -88,14 +94,14 @@ protected function _isApplicableAttribute($object, $attribute)
/**
* Check whether attribute instance (attribute, backend, frontend or source) has method and applicable
*
* @param AbstractAttribute|\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend|\Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend|\Magento\Eav\Model\Entity\Attribute\Source\AbstractSource $instance
* @param AbstractAttribute|AbstractBackend|AbstractFrontend|AbstractSource $instance
* @param string $method
* @param array $args array of arguments
* @return boolean
*/
protected function _isCallableAttributeInstance($instance, $method, $args)
{
if ($instance instanceof \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
if ($instance instanceof AbstractBackend
&& ($method == 'beforeSave' || $method == 'afterSave')
) {
$attributeCode = $instance->getAttribute()->getAttributeCode();
Expand Down
23 changes: 17 additions & 6 deletions app/code/Magento/Catalog/Model/ResourceModel/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Magento\Catalog\Model\ResourceModel\Product\Website\Link as ProductWebsiteLink;
use Magento\Framework\App\ObjectManager;
use Magento\Catalog\Model\Indexer\Category\Product\TableMaintainer;
use Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface;

/**
* Product entity resource model
Expand Down Expand Up @@ -101,6 +102,7 @@ class Product extends AbstractResource
* @param \Magento\Catalog\Model\Product\Attribute\DefaultAttributes $defaultAttributes
* @param array $data
* @param TableMaintainer|null $tableMaintainer
* @param UniqueValidationInterface|null $uniqueValidator
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
Expand All @@ -115,7 +117,8 @@ public function __construct(
\Magento\Eav\Model\Entity\TypeFactory $typeFactory,
\Magento\Catalog\Model\Product\Attribute\DefaultAttributes $defaultAttributes,
$data = [],
TableMaintainer $tableMaintainer = null
TableMaintainer $tableMaintainer = null,
UniqueValidationInterface $uniqueValidator = null
) {
$this->_categoryCollectionFactory = $categoryCollectionFactory;
$this->_catalogCategory = $catalogCategory;
Expand All @@ -127,7 +130,8 @@ public function __construct(
$context,
$storeManager,
$modelFactory,
$data
$data,
$uniqueValidator
);
$this->connectionName = 'catalog';
$this->tableMaintainer = $tableMaintainer ?: ObjectManager::getInstance()->get(TableMaintainer::class);
Expand Down Expand Up @@ -289,7 +293,7 @@ protected function _afterSave(\Magento\Framework\DataObject $product)
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function delete($object)
{
Expand Down Expand Up @@ -575,7 +579,7 @@ public function countAll()
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function validate($object)
{
Expand Down Expand Up @@ -615,7 +619,7 @@ public function load($object, $entityId, $attributes = [])
}

/**
* {@inheritdoc}
* @inheritdoc
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
* @since 101.0.0
*/
Expand Down Expand Up @@ -657,6 +661,8 @@ public function save(\Magento\Framework\Model\AbstractModel $object)
}

/**
* Retrieve entity manager object.
*
* @return \Magento\Framework\EntityManager\EntityManager
*/
private function getEntityManager()
Expand All @@ -669,6 +675,8 @@ private function getEntityManager()
}

/**
* Retrieve ProductWebsiteLink object.
*
* @deprecated 101.1.0
* @return ProductWebsiteLink
*/
Expand All @@ -678,6 +686,8 @@ private function getProductWebsiteLink()
}

/**
* Retrieve CategoryLink object.
*
* @deprecated 101.1.0
* @return \Magento\Catalog\Model\ResourceModel\Product\CategoryLink
*/
Expand All @@ -692,9 +702,10 @@ private function getProductCategoryLink()

/**
* Extends parent method to be appropriate for product.
*
* Store id is required to correctly identify attribute value we are working with.
*
* {@inheritdoc}
* @inheritdoc
* @since 101.1.0
*/
protected function getAttributeRow($entity, $object, $attribute)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\Plugin\Model\Product\Option;

/**
* Plugin for updating product 'has_options' and 'required_options' attributes.
*/
class UpdateProductCustomOptionsAttributes
{
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
*/
private $productRepository;

/**
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
*/
public function __construct(\Magento\Catalog\Api\ProductRepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}

/**
* Update product 'has_options' and 'required_options' attributes after option save.
*
* @param \Magento\Catalog\Api\ProductCustomOptionRepositoryInterface $subject
* @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface $option
*
* @return \Magento\Catalog\Api\Data\ProductCustomOptionInterface
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterSave(
\Magento\Catalog\Api\ProductCustomOptionRepositoryInterface $subject,
\Magento\Catalog\Api\Data\ProductCustomOptionInterface $option
) {
$product = $this->productRepository->get($option->getProductSku());
if (!$product->getHasOptions()
|| ($option->getIsRequire()
&& !$product->getRequiredOptions())
) {
$product->setCanSaveCustomOptions(true);
$product->setOptionsSaved(true);
$optionId = $option->getOptionId();
$currentOptions = array_filter($product->getOptions(), function ($optionItem) use ($optionId) {
return $optionId != $optionItem->getOptionId();
});
$currentOptions[] = $option;
$product->setOptions($currentOptions);
$product->save();
}

return $option;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<!--Action to delete product attribute-->
<actionGroup name="DeleteProductAttribute">
<arguments>
<argument name="productAttribute"/>
</arguments>
<amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="goToProductAttributesGridPage"/>
<waitForPageLoad time="30" stepKey="waitForProductAttributesGridPageLoad"/>
<click selector="{{AdminProductAttributeGridSection.resetFilter}}" stepKey="resetFilter"/>
<conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersBeforeDelete"/>
<fillField selector="{{AdminProductAttributeGridSection.gridFilterFrontEndLabel}}"
userInput="{{productAttribute.default_label}}" stepKey="fillAttributeDefaultLabelInput"/>
<click selector="{{AdminProductAttributeGridSection.search}}" stepKey="searchForAttribute"/>
<click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="applyFilters"/>
<click selector="{{AdminProductAttributeGridSection.firstRow}}" stepKey="clickFirstRow"/>
<waitForPageLoad time="30" stepKey="waitForPageLoad"/>
<click selector="{{AdminProductAttributeEditSection.deleteAttribute}}" stepKey="deleteProductAttribute"/>
<click selector="{{AdminMainActionsSection.delete}}" stepKey="deleteProductAttribute"/>
<waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitingForWarningModal"/>
<click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmStoreDelete"/>
<click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete"/>
<see selector="{{AdminMessagesSection.success}}" userInput="You deleted the product attribute." stepKey="seeSuccessMessage"/>
</actionGroup>

<actionGroup name="navigateToProductAttribute">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,38 @@
<click selector="{{AdminDataGridTableSection.row('1')}}" stepKey="clickOnAttributeRow"/>
<waitForPageLoad stepKey="waitForAttributePageLoad" />
</actionGroup>
<actionGroup name="StartCreateProductAttribute">
<arguments>
<argument name="attributeCode" type="string"/>
<argument name="attributeType" type="string" defaultValue="select"/>
</arguments>
<amOnPage url="{{AdminProductAttributeNewPage.url}}" stepKey="goToNewProductAttributePage"/>
<fillField selector="{{AttributePropertiesSection.defaultLabel}}" userInput="{{attributeCode}}" stepKey="fillDefaultLabel"/>
<selectOption selector="{{AttributePropertiesSection.inputType}}" userInput="{{attributeType}}" stepKey="selectInputType"/>
<waitForElementVisible selector="{{AdminNewAttributePanelSection.addOption}}" stepKey="waitForElementVisible"/>
</actionGroup>
<actionGroup name="AddOptionToProductAttribute">
<arguments>
<argument name="optionName" type="string"/>
<argument name="optionNumber" type="string"/>
</arguments>
<click selector="{{AdminNewAttributePanelSection.addOption}}" stepKey="clickAddOption"/>
<waitForElementVisible selector="{{AdminNewAttributePanelSection.optionAdminValue('optionNumber')}}" time="30" stepKey="waitForOptionRow"/>
<fillField selector="{{AdminNewAttributePanelSection.optionAdminValue('optionNumber')}}" userInput="{{optionName}}" stepKey="fillAdminLabel"/>
</actionGroup>
<actionGroup name="SetScopeToProductAttribute">
<arguments>
<argument name="scope" type="string" defaultValue="1"/>
</arguments>
<click selector="{{AttributePropertiesSection.AdvancedProperties}}" stepKey="expandAdvancedProperties"/>
<selectOption selector="{{AttributePropertiesSection.scope}}" userInput="{{scope}}" stepKey="selectGlobalScope"/>
</actionGroup>
<actionGroup name="SetUseInLayeredNavigationToProductAttribute">
<arguments>
<argument name="useInLayeredNavigation" type="string" defaultValue="1"/>
</arguments>
<scrollToTopOfPage stepKey="scrollToTop"/>
<click selector="{{StorefrontPropertiesSection.storefrontPropertiesTab}}" stepKey="goToStorefrontProperties"/>
<selectOption selector="{{AttributePropertiesSection.useInLayeredNavigation}}" userInput="{{useInLayeredNavigation}}" stepKey="selectUseInLayeredNavigation"/>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<entity name="ProductAttributeFrontendLabelThree" type="FrontendLabel">
<data key="store_id">0</data>
<data key="label" unique="suffix">attributeThree</data>
<data key="default_label" unique="suffix">attributeThree</data>
</entity>
<entity name="ColorAttributeFrontandLabel" type="FrontendLabel">
<data key="store_id">0</data>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd">
<page name="AdminProductAttributeNewPage" url="catalog/product_attribute/new/" area="admin" module="Magento_Catalog">
<section name="AttributePropertiesSection"/>
<section name="StorefrontPropertiesSection"/>
<section name="AdvancedAttributePropertiesSection"/>
<section name="AdminAttributeOptionsSection"/>
<section name="AttributeManageSwatchSection"/>
</page>
</pages>
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<element name="attributeSetDropDown" type="select" selector="div[data-index='attribute_set_id'] .action-select.admin__action-multiselect"/>
<element name="requiredNameIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=name]&gt;.admin__field-label span'), ':after').getPropertyValue('content');"/>
<element name="requiredSkuIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=sku]&gt;.admin__field-label span'), ':after').getPropertyValue('content');"/>
<element name="customAttributeDropdownField" type="select" selector="select[name='product[{{attributeCode}}]']" parameterized="true"/>
</section>
<section name="ProductInWebsitesSection">
<element name="sectionHeader" type="button" selector="div[data-index='websites']" timeout="30"/>
Expand Down Expand Up @@ -180,6 +181,7 @@
<element name="applySinglePriceToAllSkus" type="radio" selector=".admin__field-label[for='apply-single-price-radio']"/>
<element name="singlePrice" type="input" selector="#apply-single-price-input"/>
<element name="attributeByName" type="input" selector="//label[text()='{{var}}']/preceding-sibling::input" parameterized="true"/>
<element name="checkboxByName" type="input" selector="//div[text()='{{var}}']//ancestor::tr//input" parameterized="true"/>
</section>
<section name="AdminNewAttributePanel">
<element name="saveAttribute" type="button" selector="#save" timeout="30"/>
Expand Down
3 changes: 3 additions & 0 deletions app/code/Magento/Catalog/etc/webapi_rest/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@
<plugin name="get_catalog_category_product_index_table_name" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\TableResolver"/>
<plugin name="get_catalog_product_price_index_table_name" type="Magento\Catalog\Model\Indexer\Product\Price\Plugin\TableResolver"/>
</type>
<type name="Magento\Catalog\Api\ProductCustomOptionRepositoryInterface">
<plugin name="updateProductCustomOptionsAttributes" type="Magento\Catalog\Plugin\Model\Product\Option\UpdateProductCustomOptionsAttributes"/>
</type>
</config>
3 changes: 3 additions & 0 deletions app/code/Magento/Catalog/etc/webapi_soap/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@
<plugin name="get_catalog_category_product_index_table_name" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\TableResolver"/>
<plugin name="get_catalog_product_price_index_table_name" type="Magento\Catalog\Model\Indexer\Product\Price\Plugin\TableResolver"/>
</type>
<type name="Magento\Catalog\Api\ProductCustomOptionRepositoryInterface">
<plugin name="updateProductCustomOptionsAttributes" type="Magento\Catalog\Plugin\Model\Product\Option\UpdateProductCustomOptionsAttributes"/>
</type>
</config>
Loading

0 comments on commit 0982a53

Please sign in to comment.