diff --git a/app/code/Magento/Bundle/Api/Data/LinkInterface.php b/app/code/Magento/Bundle/Api/Data/LinkInterface.php
index 4e2268eae8f9a..694e6227ef25d 100644
--- a/app/code/Magento/Bundle/Api/Data/LinkInterface.php
+++ b/app/code/Magento/Bundle/Api/Data/LinkInterface.php
@@ -7,6 +7,10 @@
namespace Magento\Bundle\Api\Data;
+/**
+ * Interface LinkInterface
+ * @api
+ */
interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{
const PRICE_TYPE_FIXED = 0;
diff --git a/app/code/Magento/Bundle/Api/Data/OptionInterface.php b/app/code/Magento/Bundle/Api/Data/OptionInterface.php
index 47d52ba713c64..52de4e8d65cf7 100644
--- a/app/code/Magento/Bundle/Api/Data/OptionInterface.php
+++ b/app/code/Magento/Bundle/Api/Data/OptionInterface.php
@@ -7,6 +7,10 @@
namespace Magento\Bundle\Api\Data;
+/**
+ * Interface OptionInterface
+ * @api
+ */
interface OptionInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{
/**
diff --git a/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php b/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php
index 9883c8535da83..b86735497f4bf 100644
--- a/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php
+++ b/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php
@@ -6,6 +6,10 @@
*/
namespace Magento\Bundle\Api\Data;
+/**
+ * Interface OptionTypeInterface
+ * @api
+ */
interface OptionTypeInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{
/**
diff --git a/app/code/Magento/Bundle/Api/ProductLinkManagementInterface.php b/app/code/Magento/Bundle/Api/ProductLinkManagementInterface.php
index 0529831f4094f..309084b8137bc 100644
--- a/app/code/Magento/Bundle/Api/ProductLinkManagementInterface.php
+++ b/app/code/Magento/Bundle/Api/ProductLinkManagementInterface.php
@@ -6,6 +6,10 @@
*/
namespace Magento\Bundle\Api;
+/**
+ * Interface for Management of ProductLink
+ * @api
+ */
interface ProductLinkManagementInterface
{
/**
diff --git a/app/code/Magento/Bundle/Api/ProductOptionRepositoryInterface.php b/app/code/Magento/Bundle/Api/ProductOptionRepositoryInterface.php
index 26857e69449cd..b0b8375650150 100644
--- a/app/code/Magento/Bundle/Api/ProductOptionRepositoryInterface.php
+++ b/app/code/Magento/Bundle/Api/ProductOptionRepositoryInterface.php
@@ -6,6 +6,10 @@
*/
namespace Magento\Bundle\Api;
+/**
+ * Interface ProductOptionRepositoryInterface
+ * @api
+ */
interface ProductOptionRepositoryInterface
{
/**
diff --git a/app/code/Magento/Bundle/Api/ProductOptionTypeListInterface.php b/app/code/Magento/Bundle/Api/ProductOptionTypeListInterface.php
index 6df2f3341b6fb..998293c9b937b 100644
--- a/app/code/Magento/Bundle/Api/ProductOptionTypeListInterface.php
+++ b/app/code/Magento/Bundle/Api/ProductOptionTypeListInterface.php
@@ -6,6 +6,10 @@
*/
namespace Magento\Bundle\Api;
+/**
+ * Interface ProductOptionTypeListInterface
+ * @api
+ */
interface ProductOptionTypeListInterface
{
/**
diff --git a/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php b/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php
index ecf2459e85fc6..ed3f39d7ce77e 100644
--- a/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php
+++ b/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php
@@ -110,9 +110,12 @@ public function getOptions()
*/
public function isDisabledField()
{
- return $this->getProduct()->getId() &&
- $this->getAttribute()->getAttributeCode() === 'price' ||
- $this->getElement()->getReadonly();
+ return $this->_getData('is_disabled_field')
+ || ($this->getProduct()->getId()
+ && $this->getAttribute()->getAttributeCode() === 'price'
+ )
+ || $this->getElement()->getReadonly();
+
}
/**
@@ -142,7 +145,9 @@ public function getExtendedElement($switchAttributeCode)
'values' => $this->getOptions(),
'value' => $switchAttributeCode,
'class' => 'required-entry next-toinput',
- 'disabled' => $this->isDisabledField()
+ 'no_span' => true,
+ 'disabled' => $this->isDisabledField(),
+ 'value' => $this->getProduct()->getData($switchAttributeCode),
]
);
}
diff --git a/app/code/Magento/Bundle/Pricing/Price/BundleOptionPriceInterface.php b/app/code/Magento/Bundle/Pricing/Price/BundleOptionPriceInterface.php
index 8239ee0aad8b1..c33b171db6b98 100644
--- a/app/code/Magento/Bundle/Pricing/Price/BundleOptionPriceInterface.php
+++ b/app/code/Magento/Bundle/Pricing/Price/BundleOptionPriceInterface.php
@@ -7,6 +7,7 @@
/**
* Option price interface
+ * @api
*/
interface BundleOptionPriceInterface
{
diff --git a/app/code/Magento/Bundle/Pricing/Price/DiscountProviderInterface.php b/app/code/Magento/Bundle/Pricing/Price/DiscountProviderInterface.php
index 1df557f3a81dc..f17f06e31532a 100644
--- a/app/code/Magento/Bundle/Pricing/Price/DiscountProviderInterface.php
+++ b/app/code/Magento/Bundle/Pricing/Price/DiscountProviderInterface.php
@@ -8,6 +8,7 @@
/**
* Interface DiscountProviderInterface
+ * @api
*/
interface DiscountProviderInterface
{
diff --git a/app/code/Magento/Bundle/Pricing/Price/FinalPriceInterface.php b/app/code/Magento/Bundle/Pricing/Price/FinalPriceInterface.php
index a593809e3da3d..6788132201593 100644
--- a/app/code/Magento/Bundle/Pricing/Price/FinalPriceInterface.php
+++ b/app/code/Magento/Bundle/Pricing/Price/FinalPriceInterface.php
@@ -8,6 +8,7 @@
/**
* Interface FinalPriceInterface
+ * @api
*/
interface FinalPriceInterface extends \Magento\Catalog\Pricing\Price\FinalPriceInterface
{
diff --git a/app/code/Magento/Bundle/Pricing/Price/RegularPriceInterface.php b/app/code/Magento/Bundle/Pricing/Price/RegularPriceInterface.php
index 836144879741e..052f2f4c7ceac 100644
--- a/app/code/Magento/Bundle/Pricing/Price/RegularPriceInterface.php
+++ b/app/code/Magento/Bundle/Pricing/Price/RegularPriceInterface.php
@@ -8,6 +8,7 @@
/**
* Regular price interface
+ * @api
*/
interface RegularPriceInterface extends \Magento\Framework\Pricing\Price\BasePriceProviderInterface
{
diff --git a/app/code/Magento/Bundle/Test/Unit/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/ExtendTest.php b/app/code/Magento/Bundle/Test/Unit/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/ExtendTest.php
new file mode 100644
index 0000000000000..03a3963184b20
--- /dev/null
+++ b/app/code/Magento/Bundle/Test/Unit/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/ExtendTest.php
@@ -0,0 +1,76 @@
+registry = $this->getMockBuilder('Magento\\Framework\\Registry')->disableOriginalConstructor()->getMock(
+ );
+ $this->formFactory = $this->getMockBuilder('Magento\\Framework\\Data\\FormFactory')->disableOriginalConstructor(
+ )->getMock();
+ $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $this->object = $this->objectManagerHelper->getObject(
+ 'Magento\\Bundle\\Block\\Adminhtml\\Catalog\\Product\\Edit\\Tab\\Attributes\\Extend',
+ ['registry' => $this->registry, 'formFactory' => $this->formFactory]
+ );
+ }
+
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
+ public function getProduct()
+ {
+ $product = $this->getMockBuilder(Product::class)->disableOriginalConstructor()->getMock();
+ $this->registry->expects($this->once())
+ ->method('registry')
+ ->with('product')
+ ->will(
+ $this->returnValue($product)
+ );
+ return $product;
+ }
+
+ public function testGetExtendedElement()
+ {
+ $switchAttributeCode = 'test_code';
+ $form = $this->getMockBuilder(\Magento\Framework\Data\Form::class)->disableOriginalConstructor()->getMock();
+ $and = new \PHPUnit_Framework_Constraint_And();
+ $and->setConstraints(
+ [
+ new \PHPUnit_Framework_Constraint_ArrayHasKey('value')
+ ]
+ );
+ $form->expects($this->once())->method('addField')->with(
+ $switchAttributeCode,
+ 'select',
+ $and
+ );
+
+ $this->formFactory->expects($this->once())->method('create')->with()->will($this->returnValue($form));
+ $product = $this->getProduct();
+ $product->expects($this->once())->method('getData')->with($switchAttributeCode)->will(
+ $this->returnValue(123)
+ );
+ $this->object->setIsDisabledField(true);
+ $this->object->getExtendedElement($switchAttributeCode);
+ }
+}
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php
index 168fa5363ab0a..ae190c3b07266 100644
--- a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php
@@ -16,6 +16,14 @@
*/
class TypeTest extends \PHPUnit_Framework_TestCase
{
+ /**
+ * @var \Magento\Bundle\Model\Resource\BundleFactory|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $bundleFactory;
+ /**
+ * @var \Magento\Bundle\Model\SelectionFactory|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $bundleModelSelection;
/**
* @var \Magento\Bundle\Model\Product\Type
*/
@@ -96,19 +104,18 @@ protected function setUp()
->setMethods(['convert'])
->disableOriginalConstructor()
->getMockForAbstractClass();
- $bundleModelSelection = $this->getMockBuilder('\Magento\Bundle\Model\SelectionFactory')
+ $this->bundleModelSelection = $this->getMockBuilder('Magento\Bundle\Model\SelectionFactory')
->disableOriginalConstructor()
->getMock();
- $bundleFactory = $this->getMockBuilder('\Magento\Bundle\Model\Resource\BundleFactory')
+ $this->bundleFactory = $this->getMockBuilder('\Magento\Bundle\Model\Resource\BundleFactory')
->disableOriginalConstructor()
->getMock();
-
$objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->model = $objectHelper->getObject(
'Magento\Bundle\Model\Product\Type',
[
- 'bundleModelSelection' => $bundleModelSelection,
- 'bundleFactory' => $bundleFactory,
+ 'bundleModelSelection' => $this->bundleModelSelection,
+ 'bundleFactory' => $this->bundleFactory,
'bundleCollection' => $this->bundleCollection,
'bundleOption' => $this->bundleOptionFactory,
'catalogData' => $this->catalogData,
@@ -2427,4 +2434,72 @@ protected function parentClass($group, $option, $buyRequest, $product)
->method('getSkipSaleableCheck')
->willReturn(false);
}
+
+ public function testSave()
+ {
+ $options = [
+ 'some_option' => ['option_id' => '', 'delete' => false],
+ ];
+ $selections = [
+ 'some_option' => [
+ 123 => ['selection_id' => '', 'delete' => false],
+ ]
+ ];
+
+ $resource = $this->getMockBuilder('Magento\Bundle\Model\Resource\Bundle')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->bundleFactory->expects($this->once())
+ ->method('create')
+ ->willReturn($resource);
+
+ $product = $this->getMockBuilder('Magento\Catalog\Model\Product')
+ ->setMethods(
+ [
+ 'getStoreId',
+ 'getOrigData',
+ 'getData',
+ 'getBundleOptionsData',
+ 'getBundleSelectionsData'
+ ]
+ )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $product->expects($this->once())
+ ->method('getBundleOptionsData')
+ ->willReturn($options);
+ $product->expects($this->once())
+ ->method('getBundleSelectionsData')
+ ->willReturn($selections);
+ $option = $this->getMockBuilder('Magento\Bundle\Model\Resource\Option\Collection')
+ ->setMethods(['setData', 'setParentId', 'setStoreId', 'isDeleted', 'save', 'getOptionId'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $option->expects($this->once())->method('setData')->willReturnSelf();
+ $option->expects($this->once())->method('setParentId')->willReturnSelf();
+ $option->expects($this->once())->method('setStoreId')->willReturnSelf();
+ $this->bundleOptionFactory->expects($this->once())->method('create')->will($this->returnValue($option));
+
+ $selection = $this->getMockBuilder('Magento\Bundle\Model\Selection')
+ ->setMethods(['setData', 'setOptionId', 'setParentProductId', 'setWebsiteId', 'save'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $selection->expects($this->once())->method('setData')->willReturnSelf();
+ $selection->expects($this->once())->method('setOptionId')->willReturnSelf();
+ $selection->expects($this->once())->method('setParentProductId')->willReturnSelf();
+ $selection->expects($this->once())->method('setWebsiteId')->willReturnSelf();
+ $selection->expects($this->once())->method('setParentProductId')->willReturnSelf();
+ $this->bundleModelSelection->expects($this->once())->method('create')->willReturn($selection);
+ $store = $this->getMockBuilder('Magento\Store\Model\Store')
+ ->setMethods(['getWebsiteId', '__wakeup'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->storeManager->expects($this->once())
+ ->method('getStore')
+ ->will($this->returnValue($store));
+ $store->expects($this->once())
+ ->method('getWebsiteId')
+ ->will($this->returnValue(10));
+ $this->model->save($product);
+ }
}
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Front.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Front.php
index 1f146dcbe254a..837e2ac4f8107 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Front.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Front.php
@@ -11,10 +11,14 @@
*/
namespace Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab;
+use Magento\Backend\Block\Template\Context;
use Magento\Backend\Block\Widget\Form;
use Magento\Backend\Block\Widget\Form\Generic;
use Magento\Config\Model\Config\Source\Yesno;
use Magento\Catalog\Model\Entity\Attribute;
+use Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker;
+use Magento\Framework\Data\FormFactory;
+use Magento\Framework\Registry;
class Front extends Generic
{
@@ -24,28 +28,28 @@ class Front extends Generic
protected $_yesNo;
/**
- * @var array
+ * @var PropertyLocker
*/
- private $disableSearchable;
+ private $propertyLocker;
/**
- * @param \Magento\Backend\Block\Template\Context $context
- * @param \Magento\Framework\Registry $registry
- * @param \Magento\Framework\Data\FormFactory $formFactory
+ * @param Context $context
+ * @param Registry $registry
+ * @param FormFactory $formFactory
* @param Yesno $yesNo
+ * @param PropertyLocker $propertyLocker
* @param array $data
- * @param array $disableSearchable
*/
public function __construct(
- \Magento\Backend\Block\Template\Context $context,
- \Magento\Framework\Registry $registry,
- \Magento\Framework\Data\FormFactory $formFactory,
+ Context $context,
+ Registry $registry,
+ FormFactory $formFactory,
Yesno $yesNo,
- array $data = [],
- array $disableSearchable = []
+ PropertyLocker $propertyLocker,
+ array $data = []
) {
$this->_yesNo = $yesNo;
- $this->disableSearchable = $disableSearchable;
+ $this->propertyLocker = $propertyLocker;
parent::__construct($context, $registry, $formFactory, $data);
}
@@ -71,7 +75,6 @@ protected function _prepareForm()
['legend' => __('Frontend Properties'), 'collapsable' => $this->getRequest()->has('popup')]
);
- $attrCode = $attributeObject->getAttributeCode();
$fieldset->addField(
'is_searchable',
'select',
@@ -80,7 +83,6 @@ protected function _prepareForm()
'label' => __('Use in Search'),
'title' => __('Use in Search'),
'values' => $yesnoSource,
- 'disabled' => isset($this->disableSearchable[$attrCode]) && $this->disableSearchable[$attrCode] ? 1 : 0
]
);
@@ -223,6 +225,7 @@ protected function _prepareForm()
);
$form->setValues($attributeObject->getData());
+ $this->propertyLocker->lock($form);
$this->setForm($form);
return parent::_prepareForm();
}
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Main.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Main.php
index 35155d15e785a..343e9f60273c2 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Main.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Main.php
@@ -61,7 +61,6 @@ protected function _prepareForm()
$response = new \Magento\Framework\Object();
$response->setTypes([]);
$this->_eventManager->dispatch('adminhtml_product_attribute_types', ['response' => $response]);
- $_disabledTypes = [];
$_hiddenFields = [];
foreach ($response->getTypes() as $type) {
$additionalTypes[] = $type;
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Inputtype.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Inputtype.php
index 769a2aeb5a832..7573262af0520 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Inputtype.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Inputtype.php
@@ -53,7 +53,6 @@ public function toOptionArray()
$response = new \Magento\Framework\Object();
$response->setTypes([]);
$this->_eventManager->dispatch('adminhtml_product_attribute_types', ['response' => $response]);
- $_disabledTypes = [];
$_hiddenFields = [];
foreach ($response->getTypes() as $type) {
$inputTypes[] = $type;
diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml
index 31e2f1092287e..29aadc03ae11e 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/di.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml
@@ -66,18 +66,4 @@
-
-
-
- - true
- - true
- - true
- - true
- - true
- - true
- - true
- - true
-
-
-
diff --git a/app/code/Magento/Catalog/etc/eav_attributes.xml b/app/code/Magento/Catalog/etc/eav_attributes.xml
index a7972b6b53113..3ba4dfae9d8b0 100644
--- a/app/code/Magento/Catalog/etc/eav_attributes.xml
+++ b/app/code/Magento/Catalog/etc/eav_attributes.xml
@@ -12,12 +12,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogSearch/Model/Resource/Engine.php b/app/code/Magento/CatalogSearch/Model/Resource/Engine.php
index 8a6d49963700a..15b56ec7b331e 100644
--- a/app/code/Magento/CatalogSearch/Model/Resource/Engine.php
+++ b/app/code/Magento/CatalogSearch/Model/Resource/Engine.php
@@ -37,13 +37,6 @@ class Engine extends AbstractDb implements EngineInterface
*/
protected $_catalogSearchData = null;
- /**
- * Catalog search data
- *
- * @var \Magento\Search\Model\Resource\Helper
- */
- protected $_resourceHelper;
-
/**
* Construct
*
@@ -51,7 +44,6 @@ class Engine extends AbstractDb implements EngineInterface
* @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility
* @param Advanced $searchResource
* @param \Magento\CatalogSearch\Helper\Data $catalogSearchData
- * @param \Magento\Search\Model\Resource\Helper $resourceHelper
* @param string|null $resourcePrefix
*/
public function __construct(
@@ -59,13 +51,11 @@ public function __construct(
\Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
\Magento\CatalogSearch\Model\Resource\Advanced $searchResource,
\Magento\CatalogSearch\Helper\Data $catalogSearchData,
- \Magento\Search\Model\Resource\Helper $resourceHelper,
$resourcePrefix = null
) {
$this->_catalogProductVisibility = $catalogProductVisibility;
$this->_searchResource = $searchResource;
$this->_catalogSearchData = $catalogSearchData;
- $this->_resourceHelper = $resourceHelper;
parent::__construct($context, $resourcePrefix);
}
@@ -118,7 +108,7 @@ public function saveEntityIndexes($storeId, $entityIndexes, $entity = 'product')
}
if ($data) {
- $this->_resourceHelper->insertOnDuplicate($this->getMainTable(), $data, ['data_index']);
+ $this->_getWriteAdapter()->insertOnDuplicate($this->getMainTable(), $data, ['data_index']);
}
return $this;
diff --git a/app/code/Magento/CatalogSearch/Model/Resource/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Resource/Fulltext.php
index 5997b47553eb1..8d2870e9b832d 100644
--- a/app/code/Magento/CatalogSearch/Model/Resource/Fulltext.php
+++ b/app/code/Magento/CatalogSearch/Model/Resource/Fulltext.php
@@ -5,20 +5,11 @@
*/
namespace Magento\CatalogSearch\Model\Resource;
-use Magento\Search\Model\Resource\Helper;
-
/**
* CatalogSearch Fulltext Index resource model
*/
class Fulltext extends \Magento\Framework\Model\Resource\Db\AbstractDb
{
- /**
- * Core string
- *
- * @var \Magento\Framework\Filter\FilterManager
- */
- protected $filter;
-
/**
* Core event manager proxy
*
@@ -26,30 +17,17 @@ class Fulltext extends \Magento\Framework\Model\Resource\Db\AbstractDb
*/
protected $_eventManager;
- /**
- * CatalogSearch resource helper
- *
- * @var \Magento\Search\Model\Resource\Helper
- */
- protected $_resourceHelper;
-
/**
* @param \Magento\Framework\Model\Resource\Db\Context $context
* @param \Magento\Framework\Event\ManagerInterface $eventManager
- * @param \Magento\Framework\Filter\FilterManager $filter
- * @param Helper $resourceHelper
* @param string|null $resourcePrefix
*/
public function __construct(
\Magento\Framework\Model\Resource\Db\Context $context,
\Magento\Framework\Event\ManagerInterface $eventManager,
- \Magento\Framework\Filter\FilterManager $filter,
- \Magento\Search\Model\Resource\Helper $resourceHelper,
$resourcePrefix = null
) {
$this->_eventManager = $eventManager;
- $this->filter = $filter;
- $this->_resourceHelper = $resourceHelper;
parent::__construct($context, $resourcePrefix);
}
@@ -71,7 +49,7 @@ protected function _construct()
public function resetSearchResults()
{
$adapter = $this->_getWriteAdapter();
- $adapter->update($this->getTable('search_query'), ['is_processed' => 0]);
+ $adapter->update($this->getTable('search_query'), ['is_processed' => 0], ['is_processed != 0']);
$this->_eventManager->dispatch('catalogsearch_reset_search_result');
return $this;
}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Resource/FulltextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Resource/FulltextTest.php
new file mode 100644
index 0000000000000..f6e16d3332e7b
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Resource/FulltextTest.php
@@ -0,0 +1,76 @@
+context = $this->getMockBuilder('\Magento\Framework\Model\Resource\Db\Context')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->resource = $this->getMockBuilder('\Magento\Framework\App\Resource')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->context->expects($this->once())
+ ->method('getResources')
+ ->willReturn($this->resource);
+ $this->adapter = $this->getMockBuilder('\Magento\Framework\DB\Adapter\AdapterInterface')
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
+ $this->resource->expects($this->once())
+ ->method('getConnection')
+ ->with('core_write')
+ ->willReturn($this->adapter);
+
+ $objectManager = new ObjectManager($this);
+ $this->target = $objectManager->getObject(
+ '\Magento\CatalogSearch\Model\Resource\Fulltext',
+ [
+ 'context' => $this->context,
+ ]
+ );
+ }
+
+ public function testResetSearchResult()
+ {
+ $this->resource->expects($this->once())
+ ->method('getTableName')
+ ->with('search_query', 'core_read')
+ ->willReturn('table_name_search_query');
+ $this->adapter->expects($this->once())
+ ->method('update')
+ ->with('table_name_search_query', ['is_processed' => 0], ['is_processed != 0'])
+ ->willReturn(10);
+ $result = $this->target->resetSearchResults();
+ $this->assertEquals($this->target, $result);
+ }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/eav_attributes.xml b/app/code/Magento/CatalogUrlRewrite/etc/eav_attributes.xml
index 65818ad4546d1..076ffe0382866 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/eav_attributes.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/eav_attributes.xml
@@ -9,6 +9,7 @@
+
diff --git a/app/code/Magento/ConfigurableProduct/Api/ConfigurableProductManagementInterface.php b/app/code/Magento/ConfigurableProduct/Api/ConfigurableProductManagementInterface.php
index 3588a1ca6a708..66e05cf340d40 100644
--- a/app/code/Magento/ConfigurableProduct/Api/ConfigurableProductManagementInterface.php
+++ b/app/code/Magento/ConfigurableProduct/Api/ConfigurableProductManagementInterface.php
@@ -6,6 +6,10 @@
*/
namespace Magento\ConfigurableProduct\Api;
+/**
+ * Interface ConfigurableProductManagementInterface
+ * @api
+ */
interface ConfigurableProductManagementInterface
{
/**
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionRepositoryTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionRepositoryTest.php
index 34b66ecb320dc..5bf9e0b3106d3 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionRepositoryTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/OptionRepositoryTest.php
@@ -207,4 +207,57 @@ public function testGetListNotConfigurableProduct()
$this->model->getList($productSku);
}
+
+ /**
+ * @param int $attributeId
+ * @param string $label
+ * @param array $optionValues
+ * @param string $msg
+ * @dataProvider validateOptionDataProvider
+ * @throws \Magento\Framework\Exception\InputException
+ */
+ public function testValidateNewOptionData($attributeId, $label, $optionValues, $msg)
+ {
+ $this->setExpectedException('Magento\Framework\Exception\InputException', $msg);
+ $optionValueMock = $this->getMock('\Magento\ConfigurableProduct\Api\Data\OptionValueInterface');
+ $optionValuesMock = [];
+ if (!empty($optionValues)) {
+ $optionValueMock->expects($this->any())
+ ->method('getValueIndex')
+ ->willReturn($optionValues['v']);
+ $optionValueMock->expects($this->any())
+ ->method('getPricingValue')
+ ->willReturn($optionValues['p']);
+ $optionValueMock->expects($this->any())
+ ->method('getIsPercent')
+ ->willReturn($optionValues['r']);
+ $optionValuesMock = [$optionValueMock];
+ }
+
+ $optionMock = $this->getMock('\Magento\ConfigurableProduct\Api\Data\OptionInterface');
+ $optionMock->expects($this->any())
+ ->method('getAttributeId')
+ ->willReturn($attributeId);
+ $optionMock->expects($this->any())
+ ->method('getLabel')
+ ->willReturn($label);
+ $optionMock->expects($this->any())
+ ->method('getValues')
+ ->willReturn($optionValuesMock);
+
+ $this->model->validateNewOptionData($optionMock);
+ }
+
+ public function validateOptionDataProvider()
+ {
+ return [
+ [null, '', ['v' => null, 'p' => null, 'r' => null], 'One or more input exceptions have occurred.'],
+ [1, 'Label', [], 'Option values are not specified.'],
+ [null, 'Label', ['v' => 1, 'p' => 1, 'r' => 1], 'Option attribute ID is not specified.'],
+ [1, '', ['v' => 1, 'p' => 1, 'r' => 1], 'Option label is not specified.'],
+ [1, 'Label', ['v' => null, 'p' => 1, 'r' => 1], 'Value index is not specified for an option.'],
+ [1, 'Label', ['v' => 1, 'p' => null, 'r' => 1], 'Price is not specified for an option.'],
+ [1, 'Label', ['v' => 1, 'p' => 1, 'r' => null], 'Percent/absolute is not specified for an option.'],
+ ];
+ }
}
diff --git a/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php b/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php
index 3a0d8053e4f8d..12b8458cecaec 100644
--- a/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php
+++ b/app/code/Magento/Downloadable/Api/LinkRepositoryInterface.php
@@ -7,31 +7,19 @@
use Magento\Downloadable\Api\Data\LinkInterface;
+/**
+ * Interface LinkRepositoryInterface
+ * @package Magento\Downloadable\Api
+ */
interface LinkRepositoryInterface
{
- /**
- * List of samples for downloadable product
- *
- * @param string $sku
- * @return \Magento\Downloadable\Api\Data\SampleInterface[]
- */
- public function getSamples($sku);
-
- /**
- * List of samples for downloadable product
- *
- * @param \Magento\Catalog\Api\Data\ProductInterface $product
- * @return \Magento\Downloadable\Api\Data\SampleInterface[]
- */
- public function getSamplesByProduct(\Magento\Catalog\Api\Data\ProductInterface $product);
-
/**
* List of links with associated samples
*
* @param string $sku
* @return \Magento\Downloadable\Api\Data\LinkInterface[]
*/
- public function getLinks($sku);
+ public function getList($sku);
/**
* List of links with associated samples
diff --git a/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php b/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php
index 9a52cea8819f4..8aa184795bb3f 100644
--- a/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php
+++ b/app/code/Magento/Downloadable/Api/SampleRepositoryInterface.php
@@ -7,8 +7,28 @@
use Magento\Downloadable\Api\Data\SampleInterface;
+/**
+ * Interface SampleRepositoryInterface
+ * @api
+ */
interface SampleRepositoryInterface
{
+ /**
+ * List of samples for downloadable product
+ *
+ * @param string $sku
+ * @return \Magento\Downloadable\Api\Data\SampleInterface[]
+ */
+ public function getList($sku);
+
+ /**
+ * List of links with associated samples
+ *
+ * @param \Magento\Catalog\Api\Data\ProductInterface $product
+ * @return \Magento\Downloadable\Api\Data\SampleInterface[]
+ */
+ public function getSamplesByProduct(\Magento\Catalog\Api\Data\ProductInterface $product);
+
/**
* Update downloadable sample of the given product
*
diff --git a/app/code/Magento/Downloadable/Model/LinkRepository.php b/app/code/Magento/Downloadable/Model/LinkRepository.php
index bca06682ba718..6f047f4b0a837 100644
--- a/app/code/Magento/Downloadable/Model/LinkRepository.php
+++ b/app/code/Magento/Downloadable/Model/LinkRepository.php
@@ -22,21 +22,11 @@ class LinkRepository implements \Magento\Downloadable\Api\LinkRepositoryInterfac
*/
protected $productRepository;
- /**
- * @var \Magento\Downloadable\Model\Product\Type
- */
- protected $downloadableType;
-
/**
* @var \Magento\Downloadable\Api\Data\LinkInterfaceFactory
*/
protected $linkDataObjectFactory;
- /**
- * @var \Magento\Downloadable\Api\Data\SampleInterfaceFactory
- */
- protected $sampleDataObjectFactory;
-
/**
* @var \Magento\Downloadable\Model\LinkFactory
*/
@@ -61,7 +51,6 @@ class LinkRepository implements \Magento\Downloadable\Api\LinkRepositoryInterfac
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @param \Magento\Downloadable\Model\Product\Type $downloadableType
* @param \Magento\Downloadable\Api\Data\LinkInterfaceFactory $linkDataObjectFactory
- * @param \Magento\Downloadable\Api\Data\SampleInterfaceFactory $sampleDataObjectFactory
* @param LinkFactory $linkFactory
* @param Link\ContentValidator $contentValidator
* @param EncoderInterface $jsonEncoder
@@ -71,7 +60,6 @@ public function __construct(
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Downloadable\Model\Product\Type $downloadableType,
\Magento\Downloadable\Api\Data\LinkInterfaceFactory $linkDataObjectFactory,
- \Magento\Downloadable\Api\Data\SampleInterfaceFactory $sampleDataObjectFactory,
LinkFactory $linkFactory,
Link\ContentValidator $contentValidator,
EncoderInterface $jsonEncoder,
@@ -80,7 +68,6 @@ public function __construct(
$this->productRepository = $productRepository;
$this->downloadableType = $downloadableType;
$this->linkDataObjectFactory = $linkDataObjectFactory;
- $this->sampleDataObjectFactory = $sampleDataObjectFactory;
$this->linkFactory = $linkFactory;
$this->contentValidator = $contentValidator;
$this->jsonEncoder = $jsonEncoder;
@@ -90,7 +77,7 @@ public function __construct(
/**
* {@inheritdoc}
*/
- public function getLinks($sku)
+ public function getList($sku)
{
/** @var \Magento\Catalog\Model\Product $product */
$product = $this->productRepository->get($sku);
@@ -134,10 +121,10 @@ protected function buildLink($resourceData)
}
/**
- * Subroutine for buildLink and buildSample
+ * Subroutine for build link
*
- * @param \Magento\Downloadable\Model\Link|\Magento\Downloadable\Model\Sample $resourceData
- * @param \Magento\Downloadable\Api\Data\LinkInterface|\Magento\Downloadable\Api\Data\SampleInterface $dataObject
+ * @param \Magento\Downloadable\Model\Link $resourceData
+ * @param \Magento\Downloadable\Api\Data\LinkInterface $dataObject
* @return null
*/
protected function setBasicFields($resourceData, $dataObject)
@@ -156,43 +143,6 @@ protected function setBasicFields($resourceData, $dataObject)
$dataObject->setSampleUrl($resourceData->getSampleUrl());
}
- /**
- * {@inheritdoc}
- */
- public function getSamples($sku)
- {
- $product = $this->productRepository->get($sku);
- return $this->getSamplesByProduct($product);
- }
-
- /**
- * @param \Magento\Catalog\Api\Data\ProductInterface $product
- * @return array
- */
- public function getSamplesByProduct(\Magento\Catalog\Api\Data\ProductInterface $product)
- {
- $sampleList = [];
- $samples = $this->downloadableType->getSamples($product);
- /** @var \Magento\Downloadable\Model\Sample $sample */
- foreach ($samples as $sample) {
- $sampleList[] = $this->buildSample($sample);
- }
- return $sampleList;
- }
-
- /**
- * Build a sample data object
- *
- * @param \Magento\Downloadable\Model\Sample $resourceData
- * @return \Magento\Downloadable\Model\Sample
- */
- protected function buildSample($resourceData)
- {
- $sample = $this->sampleDataObjectFactory->create();
- $this->setBasicFields($resourceData, $sample);
- return $sample;
- }
-
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
diff --git a/app/code/Magento/Downloadable/Model/Plugin/AfterProductLoad.php b/app/code/Magento/Downloadable/Model/Plugin/AfterProductLoad.php
index 83466a0fa080f..d8af61297efab 100644
--- a/app/code/Magento/Downloadable/Model/Plugin/AfterProductLoad.php
+++ b/app/code/Magento/Downloadable/Model/Plugin/AfterProductLoad.php
@@ -14,6 +14,11 @@ class AfterProductLoad
*/
protected $linkRepository;
+ /**
+ * @var \Magento\Downloadable\Api\SampleRepositoryInterface
+ */
+ protected $sampleRepository;
+
/**
* @var \Magento\Catalog\Api\Data\ProductExtensionFactory
*/
@@ -21,13 +26,16 @@ class AfterProductLoad
/**
* @param \Magento\Downloadable\Api\LinkRepositoryInterface $linkRepository
+ * @param \Magento\Downloadable\Api\SampleRepositoryInterface $sampleRepository
* @param \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
*/
public function __construct(
\Magento\Downloadable\Api\LinkRepositoryInterface $linkRepository,
+ \Magento\Downloadable\Api\SampleRepositoryInterface $sampleRepository,
\Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
) {
$this->linkRepository = $linkRepository;
+ $this->sampleRepository = $sampleRepository;
$this->productExtensionFactory = $productExtensionFactory;
}
@@ -41,16 +49,13 @@ public function afterLoad(
if ($product->getTypeId() != \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
return $product;
}
-
- $productExtension = $product->getExtensionAttributes();
- if ($productExtension === null) {
- $productExtension = $this->productExtensionFactory->create();
- }
+ $productExtension = $product->getExtensionAttributes()
+ ?: $this->productExtensionFactory->create();
$links = $this->linkRepository->getLinksByProduct($product);
if ($links !== null) {
$productExtension->setDownloadableProductLinks($links);
}
- $samples = $this->linkRepository->getSamplesByProduct($product);
+ $samples = $this->sampleRepository->getSamplesByProduct($product);
if ($samples !== null) {
$productExtension->setDownloadableProductSamples($samples);
}
diff --git a/app/code/Magento/Downloadable/Model/SampleRepository.php b/app/code/Magento/Downloadable/Model/SampleRepository.php
index f357e6a5d8541..71d76e05f40a7 100644
--- a/app/code/Magento/Downloadable/Model/SampleRepository.php
+++ b/app/code/Magento/Downloadable/Model/SampleRepository.php
@@ -6,7 +6,8 @@
namespace Magento\Downloadable\Model;
use Magento\Catalog\Api\ProductRepositoryInterface;
-use Magento\Downloadable\Model\SampleFactory;
+use Magento\Downloadable\Api\Data\SampleInterfaceFactory;
+use Magento\Downloadable\Model\Product\Type;
use Magento\Downloadable\Api\Data\File\ContentUploaderInterface;
use Magento\Downloadable\Api\Data\SampleInterface;
use Magento\Downloadable\Model\Sample\ContentValidator;
@@ -16,7 +17,6 @@
/**
* Class SampleRepository
- * @package Magento\Downloadable\Model
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInterface
@@ -27,14 +27,19 @@ class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInte
protected $productRepository;
/**
- * @var \Magento\Downloadable\Model\Product\Type
+ * @var ContentValidator
+ */
+ protected $contentValidator;
+
+ /**
+ * @var Type
*/
protected $downloadableType;
/**
- * @var ContentValidator
+ * @var SampleInterfaceFactory
*/
- protected $contentValidator;
+ protected $sampleDataObjectFactory;
/**
* @var ContentUploaderInterface
@@ -48,7 +53,8 @@ class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInte
/**
* @param ProductRepositoryInterface $productRepository
- * @param \Magento\Downloadable\Model\Product\Type $downloadableType
+ * @param Type $downloadableType
+ * @param SampleInterfaceFactory $sampleDataObjectFactory
* @param ContentValidator $contentValidator
* @param ContentUploaderInterface $fileContentUploader
* @param EncoderInterface $jsonEncoder
@@ -56,7 +62,8 @@ class SampleRepository implements \Magento\Downloadable\Api\SampleRepositoryInte
*/
public function __construct(
ProductRepositoryInterface $productRepository,
- \Magento\Downloadable\Model\Product\Type $downloadableType,
+ Type $downloadableType,
+ SampleInterfaceFactory $sampleDataObjectFactory,
ContentValidator $contentValidator,
ContentUploaderInterface $fileContentUploader,
EncoderInterface $jsonEncoder,
@@ -68,6 +75,71 @@ public function __construct(
$this->fileContentUploader = $fileContentUploader;
$this->jsonEncoder = $jsonEncoder;
$this->sampleFactory = $sampleFactory;
+ $this->downloadableType = $downloadableType;
+ $this->sampleDataObjectFactory = $sampleDataObjectFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getList($sku)
+ {
+ /** @var \Magento\Catalog\Model\Product $product */
+ $product = $this->productRepository->get($sku);
+ return $this->getSamplesByProduct($product);
+ }
+
+ /**
+ * Build a sample data object
+ *
+ * @param \Magento\Downloadable\Model\Sample $resourceData
+ * @return \Magento\Downloadable\Model\Sample
+ */
+ protected function buildSample($resourceData)
+ {
+ $sample = $this->sampleDataObjectFactory->create();
+ $this->setBasicFields($resourceData, $sample);
+ return $sample;
+ }
+
+ /**
+ * Subroutine for buildLink and buildSample
+ *
+ * @param \Magento\Downloadable\Model\Link|\Magento\Downloadable\Model\Sample $resourceData
+ * @param \Magento\Downloadable\Api\Data\LinkInterface|\Magento\Downloadable\Api\Data\SampleInterface $dataObject
+ * @return null
+ */
+ protected function setBasicFields($resourceData, $dataObject)
+ {
+ $dataObject->setId($resourceData->getId());
+ $storeTitle = $resourceData->getStoreTitle();
+ $title = $resourceData->getTitle();
+ if (!empty($storeTitle)) {
+ $dataObject->setTitle($storeTitle);
+ } else {
+ $dataObject->setTitle($title);
+ }
+ $dataObject->setSortOrder($resourceData->getSortOrder());
+ $dataObject->setSampleType($resourceData->getSampleType());
+ $dataObject->setSampleFile($resourceData->getSampleFile());
+ $dataObject->setSampleUrl($resourceData->getSampleUrl());
+ }
+
+ /**
+ * List of links with associated samples
+ *
+ * @param \Magento\Catalog\Api\Data\ProductInterface $product
+ * @return \Magento\Downloadable\Api\Data\SampleInterface[]
+ */
+ public function getSamplesByProduct(\Magento\Catalog\Api\Data\ProductInterface $product)
+ {
+ $sampleList = [];
+ $samples = $this->downloadableType->getSamples($product);
+ /** @var \Magento\Downloadable\Model\Sample $sample */
+ foreach ($samples as $sample) {
+ $sampleList[] = $this->buildSample($sample);
+ }
+ return $sampleList;
}
/**
@@ -77,7 +149,6 @@ public function __construct(
* @param \Magento\Downloadable\Api\Data\SampleInterface $sample
* @param bool $isGlobalScopeContent
* @return int
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function save(
$sku,
@@ -90,7 +161,7 @@ public function save(
if ($sampleId) {
return $this->updateSample($product, $sample, $isGlobalScopeContent);
} else {
- if ($product->getTypeId() !== \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) {
+ if ($product->getTypeId() !== Type::TYPE_DOWNLOADABLE) {
throw new InputException(__('Product type of the product must be \'downloadable\'.'));
}
if (!$this->contentValidator->isValid($sample)) {
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php
index d4ec184847edc..e030603fd6f3a 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php
@@ -49,10 +49,6 @@ class LinkRepositoryTest extends \PHPUnit_Framework_TestCase
*/
protected $linkDataObjectFactory;
- /**
- * @var \PHPUnit_Framework_MockObject_MockObject
- */
- protected $sampleDataObjectFactory;
/**
* @var LinkRepository
@@ -119,7 +115,6 @@ protected function setUp()
$this->repositoryMock,
$this->productTypeMock,
$this->linkDataObjectFactory,
- $this->sampleDataObjectFactory,
$this->linkFactoryMock,
$this->contentValidatorMock,
$this->jsonEncoderMock,
@@ -487,7 +482,7 @@ public function testDeleteThrowsExceptionIfLinkIdIsNotValid()
$this->service->delete($linkId);
}
- public function testGetLinks()
+ public function testGetList()
{
$productSku = 'downloadable_sku';
@@ -540,58 +535,7 @@ public function testGetLinks()
$this->setLinkAssertions($linkMock, $linkData);
$this->linkDataObjectFactory->expects($this->once())->method('create')->willReturn($linkInterfaceMock);
- $this->assertEquals([$linkInterfaceMock], $this->service->getLinks($productSku));
- }
-
- public function testGetSamples()
- {
- $productSku = 'downloadable_sku';
-
- $sampleData = [
- 'id' => 324,
- 'store_title' => 'rock melody sample',
- 'title' => 'just melody sample',
- 'sort_order' => 21,
- 'sample_type' => 'file',
- 'sample_url' => null,
- 'sample_file' => '/r/o/rock.melody.ogg'
- ];
-
- $sampleMock = $this->getMock(
- '\Magento\Downloadable\Model\Sample',
- [
- 'getId',
- 'getStoreTitle',
- 'getTitle',
- 'getSampleType',
- 'getSampleFile',
- 'getSampleUrl',
- 'getSortOrder',
- 'getData',
- '__wakeup'
- ],
- [],
- '',
- false
- );
-
- $sampleInterfaceMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
-
- $this->repositoryMock->expects($this->once())
- ->method('get')
- ->with($productSku)
- ->will($this->returnValue($this->productMock));
-
- $this->productTypeMock->expects($this->once())
- ->method('getSamples')
- ->with($this->productMock)
- ->will($this->returnValue([$sampleMock]));
-
- $this->setSampleAssertions($sampleMock, $sampleData);
-
- $this->sampleDataObjectFactory->expects($this->once())->method('create')->willReturn($sampleInterfaceMock);
-
- $this->assertEquals([$sampleInterfaceMock], $this->service->getSamples($productSku));
+ $this->assertEquals([$linkInterfaceMock], $this->service->getList($productSku));
}
protected function setLinkAssertions($resource, $inputData)
@@ -622,21 +566,4 @@ protected function setLinkAssertions($resource, $inputData)
$resource->expects($this->any())->method('getLinkUrl')
->will($this->returnValue($inputData['link_url']));
}
-
- protected function setSampleAssertions($resource, $inputData)
- {
- $resource->expects($this->any())->method('getId')->will($this->returnValue($inputData['id']));
- $resource->expects($this->any())->method('getStoreTitle')
- ->will($this->returnValue($inputData['store_title']));
- $resource->expects($this->any())->method('getTitle')
- ->will($this->returnValue($inputData['title']));
- $resource->expects($this->any())->method('getSortOrder')
- ->will($this->returnValue($inputData['sort_order']));
- $resource->expects($this->any())->method('getSampleType')
- ->will($this->returnValue($inputData['sample_type']));
- $resource->expects($this->any())->method('getSampleFile')
- ->will($this->returnValue($inputData['sample_file']));
- $resource->expects($this->any())->method('getSampleUrl')
- ->will($this->returnValue($inputData['sample_url']));
- }
}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AfterProductLoadTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AfterProductLoadTest.php
index 36f21e6fb5f28..305dacc61c95a 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AfterProductLoadTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Plugin/AfterProductLoadTest.php
@@ -36,20 +36,27 @@ class AfterProductLoadTest extends \PHPUnit_Framework_TestCase
*/
protected $productExtensionFactory;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $sampleRepositoryMock;
+
protected function setUp()
{
- $this->linkRepositoryMock = $this->getMock('\Magento\Downloadable\Api\LinkRepositoryInterface');
- $this->productExtensionFactory = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtensionFactory')
+ $this->linkRepositoryMock = $this->getMock('Magento\Downloadable\Api\LinkRepositoryInterface');
+ $this->sampleRepositoryMock = $this->getMock('Magento\Downloadable\Api\SampleRepositoryInterface');
+ $this->productExtensionFactory = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductExtensionFactory')
->disableOriginalConstructor()
->getMock();
$this->model = new \Magento\Downloadable\Model\Plugin\AfterProductLoad(
$this->linkRepositoryMock,
+ $this->sampleRepositoryMock,
$this->productExtensionFactory
);
- $this->productMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+ $this->productMock = $this->getMockBuilder('Magento\Catalog\Model\Product')
->disableOriginalConstructor()
->getMock();
- $this->productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+ $this->productExtensionMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductExtension')
->setMethods(['setDownloadableProductLinks', 'setDownloadableProductSamples'])->getMock();
}
@@ -63,13 +70,13 @@ public function testAfterLoad()
->method('create')
->willReturn($this->productExtensionMock);
- $linkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+ $linkMock = $this->getMock('Magento\Downloadable\Api\Data\LinkInterface');
$this->linkRepositoryMock->expects($this->once())
->method('getLinksByProduct')
->with($this->productMock)
->willReturn([$linkMock]);
- $sampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
- $this->linkRepositoryMock->expects($this->once())
+ $sampleMock = $this->getMock('Magento\Downloadable\Api\Data\SampleInterface');
+ $this->sampleRepositoryMock->expects($this->once())
->method('getSamplesByProduct')
->with($this->productMock)
->willReturn([$sampleMock]);
@@ -104,13 +111,13 @@ public function testAfterLoadWithExistingExtensionAttributes()
$this->productExtensionFactory->expects($this->never())
->method('create');
- $linkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+ $linkMock = $this->getMock('Magento\Downloadable\Api\Data\LinkInterface');
$this->linkRepositoryMock->expects($this->once())
->method('getLinksByProduct')
->with($this->productMock)
->willReturn([$linkMock]);
- $sampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
- $this->linkRepositoryMock->expects($this->once())
+ $sampleMock = $this->getMock('Magento\Downloadable\Api\Data\SampleInterface');
+ $this->sampleRepositoryMock->expects($this->once())
->method('getSamplesByProduct')
->with($this->productMock)
->willReturn([$sampleMock]);
@@ -143,12 +150,12 @@ public function testAfterLoadOnlyLinks()
->method('create')
->willReturn($this->productExtensionMock);
- $linkMock = $this->getMock('\Magento\Downloadable\Api\Data\LinkInterface');
+ $linkMock = $this->getMock('Magento\Downloadable\Api\Data\LinkInterface');
$this->linkRepositoryMock->expects($this->once())
->method('getLinksByProduct')
->with($this->productMock)
->willReturn([$linkMock]);
- $this->linkRepositoryMock->expects($this->once())
+ $this->sampleRepositoryMock->expects($this->once())
->method('getSamplesByProduct')
->with($this->productMock)
->willReturn(null);
@@ -183,8 +190,8 @@ public function testAfterLoadOnlySamples()
->method('getLinksByProduct')
->with($this->productMock)
->willReturn(null);
- $sampleMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
- $this->linkRepositoryMock->expects($this->once())
+ $sampleMock = $this->getMock('Magento\Downloadable\Api\Data\SampleInterface');
+ $this->sampleRepositoryMock->expects($this->once())
->method('getSamplesByProduct')
->with($this->productMock)
->willReturn([$sampleMock]);
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php
index 7e25af50c3f6b..672599aa0e770 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php
@@ -50,6 +50,11 @@ class SampleRepositoryTest extends \PHPUnit_Framework_TestCase
*/
protected $service;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $sampleDataObjectFactory;
+
protected function setUp()
{
$this->productMock = $this->getMock(
@@ -81,10 +86,23 @@ protected function setUp()
'',
false
);
+ $this->productTypeMock = $this->getMockBuilder('\Magento\Downloadable\Model\Product\Type')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->sampleDataObjectFactory = $this->getMockBuilder('\Magento\Downloadable\Api\Data\SampleInterfaceFactory')
+ ->setMethods(
+ [
+ 'create',
+ ]
+ )
+ ->disableOriginalConstructor()
+ ->getMock();
+
$this->service = new \Magento\Downloadable\Model\SampleRepository(
$this->repositoryMock,
$this->productTypeMock,
+ $this->sampleDataObjectFactory,
$this->contentValidatorMock,
$this->contentUploaderMock,
$this->jsonEncoderMock,
@@ -371,4 +389,77 @@ public function testDeleteThrowsExceptionIfSampleIdIsNotValid()
$this->service->delete($sampleId);
}
+
+
+ public function testGetList()
+ {
+ $productSku = 'downloadable_sku';
+
+ $sampleData = [
+ 'id' => 324,
+ 'store_title' => 'rock melody sample',
+ 'title' => 'just melody sample',
+ 'sort_order' => 21,
+ 'sample_type' => 'file',
+ 'sample_url' => null,
+ 'sample_file' => '/r/o/rock.melody.ogg'
+ ];
+
+ $sampleMock = $this->getMock(
+ '\Magento\Downloadable\Model\Sample',
+ [
+ 'getId',
+ 'getStoreTitle',
+ 'getTitle',
+ 'getSampleType',
+ 'getSampleFile',
+ 'getSampleUrl',
+ 'getSortOrder',
+ 'getData',
+ '__wakeup'
+ ],
+ [],
+ '',
+ false
+ );
+
+ $sampleInterfaceMock = $this->getMock('\Magento\Downloadable\Api\Data\SampleInterface');
+
+ $this->repositoryMock->expects($this->once())
+ ->method('get')
+ ->with($productSku)
+ ->will($this->returnValue($this->productMock));
+
+ $this->productTypeMock->expects($this->once())
+ ->method('getSamples')
+ ->with($this->productMock)
+ ->will($this->returnValue([$sampleMock]));
+
+ $this->setSampleAssertions($sampleMock, $sampleData);
+
+ $this->sampleDataObjectFactory->expects($this->once())->method('create')->willReturn($sampleInterfaceMock);
+
+ $this->assertEquals([$sampleInterfaceMock], $this->service->getList($productSku));
+ }
+
+ /**
+ * @param $resource
+ * @param $inputData
+ */
+ protected function setSampleAssertions($resource, $inputData)
+ {
+ $resource->expects($this->any())->method('getId')->will($this->returnValue($inputData['id']));
+ $resource->expects($this->any())->method('getStoreTitle')
+ ->will($this->returnValue($inputData['store_title']));
+ $resource->expects($this->any())->method('getTitle')
+ ->will($this->returnValue($inputData['title']));
+ $resource->expects($this->any())->method('getSortOrder')
+ ->will($this->returnValue($inputData['sort_order']));
+ $resource->expects($this->any())->method('getSampleType')
+ ->will($this->returnValue($inputData['sample_type']));
+ $resource->expects($this->any())->method('getSampleFile')
+ ->will($this->returnValue($inputData['sample_file']));
+ $resource->expects($this->any())->method('getSampleUrl')
+ ->will($this->returnValue($inputData['sample_url']));
+ }
}
diff --git a/app/code/Magento/Downloadable/etc/webapi.xml b/app/code/Magento/Downloadable/etc/webapi.xml
index 7f597119f9e74..4b1f86ead0eaa 100644
--- a/app/code/Magento/Downloadable/etc/webapi.xml
+++ b/app/code/Magento/Downloadable/etc/webapi.xml
@@ -8,13 +8,13 @@
-
+
-
+
diff --git a/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php b/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php
index 597b4f563dd27..0bff79e95a10f 100644
--- a/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php
+++ b/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php
@@ -32,9 +32,9 @@ abstract class AbstractMain extends \Magento\Backend\Block\Widget\Form\Generic
protected $_eavData = null;
/**
- * @var \Magento\Eav\Model\Entity\Attribute\Config
+ * @var \Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker
*/
- protected $_attributeConfig;
+ protected $propertyLocker;
/**
* @var \Magento\Config\Model\Config\Source\YesnoFactory
@@ -53,7 +53,7 @@ abstract class AbstractMain extends \Magento\Backend\Block\Widget\Form\Generic
* @param \Magento\Eav\Helper\Data $eavData
* @param \Magento\Config\Model\Config\Source\YesnoFactory $yesnoFactory
* @param \Magento\Eav\Model\Adminhtml\System\Config\Source\InputtypeFactory $inputTypeFactory
- * @param \Magento\Eav\Model\Entity\Attribute\Config $attributeConfig
+ * @param \Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker $propertyLocker
* @param array $data
*/
public function __construct(
@@ -63,13 +63,13 @@ public function __construct(
\Magento\Eav\Helper\Data $eavData,
\Magento\Config\Model\Config\Source\YesnoFactory $yesnoFactory,
\Magento\Eav\Model\Adminhtml\System\Config\Source\InputtypeFactory $inputTypeFactory,
- \Magento\Eav\Model\Entity\Attribute\Config $attributeConfig,
+ \Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker $propertyLocker,
array $data = []
) {
$this->_eavData = $eavData;
$this->_yesnoFactory = $yesnoFactory;
$this->_inputTypeFactory = $inputTypeFactory;
- $this->_attributeConfig = $attributeConfig;
+ $this->propertyLocker = $propertyLocker;
parent::__construct($context, $registry, $formFactory, $data);
}
@@ -257,6 +257,7 @@ protected function _prepareForm()
}
}
+ $this->propertyLocker->lock($form);
$this->setForm($form);
return parent::_prepareForm();
@@ -277,27 +278,6 @@ protected function _initFormValues()
return parent::_initFormValues();
}
- /**
- * This method is called before rendering HTML
- *
- * @return $this
- */
- protected function _beforeToHtml()
- {
- parent::_beforeToHtml();
- $attributeObject = $this->getAttributeObject();
- if ($attributeObject->getId()) {
- $form = $this->getForm();
- foreach ($this->_attributeConfig->getLockedFields($attributeObject) as $field) {
- if ($element = $form->getElement($field)) {
- $element->setDisabled(1);
- $element->setReadonly(1);
- }
- }
- }
- return $this;
- }
-
/**
* Processing block html after rendering
* Adding js block to the end of this block
diff --git a/app/code/Magento/Eav/Block/Adminhtml/Attribute/PropertyLocker.php b/app/code/Magento/Eav/Block/Adminhtml/Attribute/PropertyLocker.php
new file mode 100644
index 0000000000000..ccaab44afee61
--- /dev/null
+++ b/app/code/Magento/Eav/Block/Adminhtml/Attribute/PropertyLocker.php
@@ -0,0 +1,57 @@
+
+ */
+class PropertyLocker
+{
+ /**
+ * @var Config
+ */
+ private $attributeConfig;
+
+ /**
+ * @var Registry
+ */
+ protected $registry;
+
+ /**
+ * @param Registry $registry
+ * @param Config $attributeConfig
+ */
+ public function __construct(
+ Registry $registry,
+ Config $attributeConfig
+ ) {
+ $this->registry = $registry;
+ $this->attributeConfig = $attributeConfig;
+ }
+
+ /**
+ * @param \Magento\Framework\Data\Form $form
+ * @return void
+ */
+ public function lock(\Magento\Framework\Data\Form $form)
+ {
+ /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attributeObject */
+ $attributeObject = $this->registry->registry('entity_attribute');
+ if ($attributeObject->getId()) {
+ foreach ($this->attributeConfig->getLockedFields($attributeObject) as $field) {
+ if ($element = $form->getElement($field)) {
+ $element->setDisabled(1);
+ $element->setReadonly(1);
+ }
+ }
+ }
+ }
+}
diff --git a/app/code/Magento/Eav/Test/Unit/Block/Adminhtml/Attribute/PropertyLockerTest.php b/app/code/Magento/Eav/Test/Unit/Block/Adminhtml/Attribute/PropertyLockerTest.php
new file mode 100644
index 0000000000000..cf0615c42a7d0
--- /dev/null
+++ b/app/code/Magento/Eav/Test/Unit/Block/Adminhtml/Attribute/PropertyLockerTest.php
@@ -0,0 +1,71 @@
+attributeMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\AbstractAttribute')
+ ->setMethods(['getId'])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $registryMock = $this->getMockBuilder('\Magento\Framework\Registry')
+ ->setMethods(['registry'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $registryMock->expects($this->atLeastOnce())->method('registry')->willReturn($this->attributeMock);
+
+ $this->attributeConfigMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Config')
+ ->setMethods(['getLockedFields'])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->formMock = $this->getMockBuilder('Magento\Framework\Data\Form')
+ ->setMethods(['getElement'])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->object = new PropertyLocker($registryMock, $this->attributeConfigMock);
+ }
+
+ /**
+ * @covers \Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker::lock
+ */
+ public function testLock()
+ {
+ $lockedFields = [
+ 'is_searchable' => 'is_searchable',
+ 'is_filterable' => 'is_filterable'
+ ];
+ $this->attributeMock->expects($this->once())->method('getId')->willReturn(1);
+ $this->attributeConfigMock->expects($this->once())->method('getLockedFields')->willReturn($lockedFields);
+
+ $elementMock = $this->getMockBuilder('\Magento\Framework\Data\Form\Element\AbstractElement')
+ ->setMethods(['setDisabled', 'setReadonly'])
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
+ $elementMock->expects($this->exactly(2))->method('setDisabled');
+ $elementMock->expects($this->exactly(2))->method('setReadonly');
+ $this->formMock->expects($this->exactly(2))->method('getElement')->willReturn($elementMock);
+ $this->object->lock($this->formMock);
+ }
+}
diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
index 5ee51f1ecbfb4..bebfa0435d69f 100644
--- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
@@ -378,7 +378,7 @@ protected function _prepareProduct(\Magento\Framework\Object $buyRequest, $produ
foreach ($associatedProducts as $subProduct) {
$qty = $productsInfo[$subProduct->getId()];
- if (!is_numeric($qty)) {
+ if (!is_numeric($qty) || empty($qty)) {
continue;
}
diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php
index 4cf5af00c0294..aed377242d123 100644
--- a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php
+++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php
@@ -576,4 +576,26 @@ public function testPrepareForCartAdvancedWithProductsStrictTrue()
$this->_model->prepareForCartAdvanced($buyRequest, $this->product)
);
}
+
+ public function testPrepareForCartAdvancedZeroQty()
+ {
+ $expectedMsg = "Please specify the quantity of product(s).";
+ $associatedId = 9384;
+ $associatedProduct = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
+ $associatedProduct->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($associatedId));
+
+ $buyRequest = new \Magento\Framework\Object();
+ $buyRequest->setSuperGroup([$associatedId => 0]);
+
+ $cached = true;
+ $this->product
+ ->expects($this->atLeastOnce())
+ ->method('hasData')
+ ->will($this->returnValue($cached));
+ $this->product
+ ->expects($this->atLeastOnce())
+ ->method('getData')
+ ->will($this->returnValue([$associatedProduct]));
+ $this->assertEquals($expectedMsg, $this->_model->prepareForCartAdvanced($buyRequest, $this->product));
+ }
}
diff --git a/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRenderer.php b/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRenderer.php
index fb4ff5033e26c..11114ba621c51 100644
--- a/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRenderer.php
+++ b/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRenderer.php
@@ -7,16 +7,17 @@
*/
namespace Magento\LayeredNavigation\Block\Navigation;
+use Magento\Catalog\Model\Layer\Filter\FilterInterface;
use Magento\Framework\View\Element\Template;
+use Magento\LayeredNavigation\Block\Navigation\FilterRendererInterface;
-class FilterRenderer extends \Magento\Framework\View\Element\Template implements
- \Magento\LayeredNavigation\Block\Navigation\FilterRendererInterface
+class FilterRenderer extends Template implements FilterRendererInterface
{
/**
- * @param \Magento\Catalog\Model\Layer\Filter\AbstractFilter $filter
+ * @param FilterInterface $filter
* @return string
*/
- public function render(\Magento\Catalog\Model\Layer\Filter\AbstractFilter $filter)
+ public function render(FilterInterface $filter)
{
$this->assign('filterItems', $filter->getItems());
$html = $this->_toHtml();
diff --git a/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRendererInterface.php b/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRendererInterface.php
index c382efa03d5bf..ee4f21d11b1d9 100644
--- a/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRendererInterface.php
+++ b/app/code/Magento/LayeredNavigation/Block/Navigation/FilterRendererInterface.php
@@ -5,13 +5,19 @@
*/
namespace Magento\LayeredNavigation\Block\Navigation;
+use Magento\Catalog\Model\Layer\Filter\FilterInterface;
+
+/**
+ * Interface FilterRendererInterface
+ * @api
+ */
interface FilterRendererInterface
{
/**
* Render filter
*
- * @param \Magento\Catalog\Model\Layer\Filter\AbstractFilter $filter
+ * @param FilterInterface $filter
* @return string
*/
- public function render(\Magento\Catalog\Model\Layer\Filter\AbstractFilter $filter);
+ public function render(FilterInterface $filter);
}
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
index 4226695723fd5..3a31a0555a739 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
@@ -5,12 +5,31 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
-use Magento\Search\Controller\Adminhtml\Term as TermController;
+use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
+use Magento\Search\Model\QueryFactory;
+use Magento\Search\Controller\Adminhtml\Term as TermController;
use Magento\Framework\Exception\LocalizedException;
class Save extends TermController
{
+ /**
+ * @var QueryFactory
+ */
+ private $queryFactory;
+
+ /**
+ * @param Context $context
+ * @param QueryFactory $queryFactory
+ */
+ public function __construct(
+ Context $context,
+ QueryFactory $queryFactory
+ ) {
+ parent::__construct($context);
+ $this->queryFactory = $queryFactory;
+ }
+
/**
* Save search query
*
@@ -19,54 +38,69 @@ class Save extends TermController
*/
public function execute()
{
- $hasError = false;
$data = $this->getRequest()->getPostValue();
- $queryId = $this->getRequest()->getPost('query_id', null);
- /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
- $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
if ($this->getRequest()->isPost() && $data) {
- /* @var $model \Magento\Search\Model\Query */
- $model = $this->_objectManager->create('Magento\Search\Model\Query');
-
- // validate query
- $queryText = $this->getRequest()->getPost('query_text', false);
- $storeId = $this->getRequest()->getPost('store_id', false);
-
try {
- if ($queryText) {
- $model->setStoreId($storeId);
- $model->loadByQueryText($queryText);
- if ($model->getId() && $model->getId() != $queryId) {
- throw new LocalizedException(
- __('You already have an identical search term query.')
- );
- } elseif (!$model->getId() && $queryId) {
- $model->load($queryId);
- }
- } elseif ($queryId) {
- $model->load($queryId);
- }
-
+ $model = $this->loadQuery();
$model->addData($data);
$model->setIsProcessed(0);
$model->save();
$this->messageManager->addSuccess(__('You saved the search term.'));
} catch (LocalizedException $e) {
$this->messageManager->addError($e->getMessage());
- $hasError = true;
+ return $this->proceedToEdit($data);
} catch (\Exception $e) {
$this->messageManager->addException($e, __('Something went wrong while saving the search query.'));
- $hasError = true;
+ return $this->proceedToEdit($data);
}
}
- if ($hasError) {
- $this->_getSession()->setPageData($data);
- $resultRedirect->setPath('search/*/edit', ['id' => $queryId]);
- return $resultRedirect;
- } else {
- $resultRedirect->setPath('search/*');
- return $resultRedirect;
+ /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+ $redirectResult = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+ return $redirectResult->setPath('search/*');
+ }
+
+ /**
+ * Create\Load Query model instance
+ *
+ * @return \Magento\Search\Model\Query
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ private function loadQuery()
+ {
+ //validate query
+ $queryText = $this->getRequest()->getPost('query_text', false);
+ $queryId = $this->getRequest()->getPost('query_id', null);
+
+ /* @var $model \Magento\Search\Model\Query */
+ $model = $this->queryFactory->create();
+ if ($queryText) {
+ $storeId = $this->getRequest()->getPost('store_id', false);
+ $model->setStoreId($storeId);
+ $model->loadByQueryText($queryText);
+ if ($model->getId() && $model->getId() != $queryId) {
+ throw new \Magento\Framework\Exception\LocalizedException(
+ __('You already have an identical search term query.')
+ );
+ }
+ }
+ if ($queryId && !$model->getId()) {
+ $model->load($queryId);
}
+ return $model;
+ }
+
+ /**
+ * Redirect to Edit page
+ *
+ * @param array $data
+ * @return \Magento\Backend\Model\View\Result\Redirect
+ */
+ private function proceedToEdit($data)
+ {
+ $this->_getSession()->setPageData($data);
+ /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+ $redirectResult = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+ return $redirectResult->setPath('search/*/edit', ['id' => $this->getRequest()->getPost('query_id', null)]);
}
}
diff --git a/app/code/Magento/Search/Model/Resource/Helper.php b/app/code/Magento/Search/Model/Resource/Helper.php
deleted file mode 100644
index 3a9ddcf7bb682..0000000000000
--- a/app/code/Magento/Search/Model/Resource/Helper.php
+++ /dev/null
@@ -1,84 +0,0 @@
- words, 1 => terms)
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function prepareTerms($str, $maxWordLength = 0)
- {
- $boolWords = ['+' => '+', '-' => '-', '|' => '|', '<' => '<', '>' => '>', '~' => '~', '*' => '*'];
- $brackets = ['(' => '(', ')' => ')'];
- $words = [0 => ""];
- $terms = [];
- preg_match_all('/([\(\)]|[\"\'][^"\']*[\"\']|[^\s\"\(\)]*)/uis', $str, $matches);
- $isOpenBracket = 0;
- foreach ($matches[1] as $word) {
- $word = trim($word);
- if (strlen($word)) {
- $word = str_replace('"', '', $word);
- $isBool = in_array(strtoupper($word), $boolWords);
- $isBracket = in_array($word, $brackets);
- if (!$isBool && !$isBracket) {
- $terms[$word] = $word;
- $word = '"' . $word . '"';
- $words[] = $word;
- } elseif ($isBracket) {
- if ($word == '(') {
- $isOpenBracket++;
- } else {
- $isOpenBracket--;
- }
- $words[] = $word;
- } elseif ($isBool) {
- $words[] = $word;
- }
- }
- }
- if ($isOpenBracket > 0) {
- $words[] = sprintf("%')" . $isOpenBracket . "s", '');
- } elseif ($isOpenBracket < 0) {
- $words[0] = sprintf("%'(" . $isOpenBracket . "s", '');
- }
- if ($maxWordLength && count($terms) > $maxWordLength) {
- $terms = array_slice($terms, 0, $maxWordLength);
- }
- $result = [$words, $terms];
- return $result;
- }
-
- /**
- * Use sql compatible with Full Text indexes
- *
- * @param string $table The table to insert data into.
- * @param array $data Column-value pairs or array of column-value pairs.
- * @param array $fields update fields pairs or values
- * @return int The number of affected rows.
- */
- public function insertOnDuplicate($table, array $data, array $fields = [])
- {
- return $this->_getWriteAdapter()->insertOnDuplicate($table, $data, $fields);
- }
-}
diff --git a/app/code/Magento/Search/Model/Resource/Query/Collection.php b/app/code/Magento/Search/Model/Resource/Query/Collection.php
index c441ac7b760cc..03772a446b6dd 100644
--- a/app/code/Magento/Search/Model/Resource/Query/Collection.php
+++ b/app/code/Magento/Search/Model/Resource/Query/Collection.php
@@ -30,7 +30,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
/**
* Search resource helper
*
- * @var \Magento\Search\Model\Resource\Helper
+ * @var \Magento\Framework\DB\Helper
*/
protected $_resourceHelper;
@@ -40,7 +40,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
- * @param \Magento\Search\Model\Resource\Helper $resourceHelper
+ * @param \Magento\Framework\DB\Helper $resourceHelper
* @param \Zend_Db_Adapter_Abstract $connection
* @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
*/
@@ -50,7 +50,7 @@ public function __construct(
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Store\Model\StoreManagerInterface $storeManager,
- \Magento\Search\Model\Resource\Helper $resourceHelper,
+ \Magento\Framework\DB\Helper $resourceHelper,
$connection = null,
\Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
) {
diff --git a/app/code/Magento/Search/Setup/UpgradeSchema.php b/app/code/Magento/Search/Setup/UpgradeSchema.php
new file mode 100644
index 0000000000000..461c7fd3d3d23
--- /dev/null
+++ b/app/code/Magento/Search/Setup/UpgradeSchema.php
@@ -0,0 +1,49 @@
+moduleList = $moduleList;
+ }
+
+ /**
+ * Upgrades DB schema for a module
+ *
+ * @param SchemaSetupInterface $setup
+ * @param ModuleContextInterface $context
+ * @return void
+ */
+ public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
+ {
+ if (version_compare($context->getVersion(), '2.0.0.1') < 0) {
+ $setup->startSetup();
+ $connection = $setup->getConnection();
+ $tableName = $setup->getTable('search_query');
+ $idxName = $setup->getIdxName('search_query', ['is_processed']);
+ $connection->addIndex($tableName, $idxName, ['is_processed']);
+ $setup->endSetup();
+ }
+ }
+}
diff --git a/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/SaveTest.php b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/SaveTest.php
new file mode 100644
index 0000000000000..5197e7d83e450
--- /dev/null
+++ b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/SaveTest.php
@@ -0,0 +1,236 @@
+context = $this->getMockBuilder('Magento\Backend\App\Action\Context')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->redirect = $this->getMockBuilder('Magento\Backend\Model\View\Result\Redirect')
+ ->setMethods(['setPath'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $redirectFactory = $this->getMockBuilder('\Magento\Framework\Controller\ResultFactory')
+ ->setMethods(['create'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $redirectFactory->expects($this->any())
+ ->method('create')
+ ->will($this->returnValue($this->redirect));
+ $this->context->expects($this->any())
+ ->method('getResultRedirectFactory')
+ ->willReturn($redirectFactory);
+ $this->context->expects($this->any())
+ ->method('getResultFactory')
+ ->willReturn($redirectFactory);
+
+ $this->request = $this->getMockBuilder('\Magento\Framework\App\RequestInterface')
+ ->disableOriginalConstructor()
+ ->setMethods(['getPostValue', 'isPost', 'getPost'])
+ ->getMockForAbstractClass();
+ $this->context->expects($this->atLeastOnce())
+ ->method('getRequest')
+ ->willReturn($this->request);
+
+ $objectManager = $this->getMockBuilder('\Magento\Framework\ObjectManagerInterface')
+ ->disableOriginalConstructor()
+ ->setMethods(['create'])
+ ->getMockForAbstractClass();
+ $this->context->expects($this->any())
+ ->method('getObjectManager')
+ ->willReturn($objectManager);
+
+ $this->messageManager = $this->getMockBuilder('\Magento\Framework\Message\ManagerInterface')
+ ->disableOriginalConstructor()
+ ->setMethods(['addSuccess', 'addError', 'addException'])
+ ->getMockForAbstractClass();
+ $this->context->expects($this->any())
+ ->method('getMessageManager')
+ ->willReturn($this->messageManager);
+
+ $this->session = $this->getMockBuilder('\Magento\Backend\Model\Session')
+ ->disableOriginalConstructor()
+ ->setMethods(['setPageData'])
+ ->getMock();
+ $this->context->expects($this->any())
+ ->method('getSession')
+ ->willReturn($this->session);
+
+ $this->query = $this->getMockBuilder('Magento\Search\Model\Query')
+ ->disableOriginalConstructor()
+ ->setMethods(['getId', 'load', 'addData', 'setIsProcessed', 'save', 'loadByQueryText', 'setStoreId'])
+ ->getMock();
+ $queryFactory = $this->getMockBuilder('Magento\Search\Model\QueryFactory')
+ ->setMethods(['create'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $queryFactory->expects($this->any())
+ ->method('create')
+ ->will($this->returnValue($this->query));
+
+ $this->controller = $objectManagerHelper->getObject(
+ 'Magento\Search\Controller\Adminhtml\Term\Save',
+ [
+ 'context' => $this->context,
+ 'queryFactory' => $queryFactory,
+ ]
+ );
+ }
+
+ /**
+ * @param bool $isPost
+ * @param array $data
+ * @dataProvider executeIsPostDataDataProvider
+ */
+ public function testExecuteIsPostData($isPost, $data)
+ {
+ $this->request->expects($this->at(0))->method('getPostValue')->willReturn($data);
+ $this->request->expects($this->at(1))->method('isPost')->willReturn($isPost);
+ $this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
+ $this->assertSame($this->redirect, $this->controller->execute());
+ }
+
+ /**
+ * @return array
+ */
+ public function executeIsPostDataDataProvider()
+ {
+ return [
+ [false, ['0' => '0']],
+ [true, []]
+ ];
+ }
+
+ public function testExecuteLoadQueryQueryId()
+ {
+ $queryId = 1;
+ $queryText = '';
+ $this->mockGetRequestData($queryText, $queryId);
+
+ $this->query->expects($this->once())->method('getId')->willReturn(false);
+ $this->query->expects($this->once())->method('load')->with($queryId);
+
+ $this->messageManager->expects($this->once())->method('addSuccess');
+
+ $this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
+ $this->assertSame($this->redirect, $this->controller->execute());
+ }
+
+ public function testExecuteLoadQueryQueryIdQueryText()
+ {
+ $queryId = 1;
+ $queryText = 'search';
+ $this->mockGetRequestData($queryText, $queryId);
+
+ $this->request->expects($this->at(4))->method('getPost')->with('store_id', false)->willReturn(1);
+
+ $this->query->expects($this->once())->method('setStoreId');
+ $this->query->expects($this->once())->method('loadByQueryText')->with($queryText);
+ $this->query->expects($this->any())->method('getId')->willReturn($queryId);
+
+ $this->messageManager->expects($this->once())->method('addSuccess');
+
+ $this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
+ $this->assertSame($this->redirect, $this->controller->execute());
+ }
+
+ public function testExecuteLoadQueryQueryIdQueryText2()
+ {
+ $queryId = 1;
+ $queryText = 'search';
+ $this->mockGetRequestData($queryText, $queryId);
+
+ $this->request->expects($this->at(4))->method('getPost')->with('store_id', false)->willReturn(1);
+
+ $this->query->expects($this->once())->method('setStoreId');
+ $this->query->expects($this->once())->method('loadByQueryText')->with($queryText);
+ $this->query->expects($this->any())->method('getId')->willReturn(false);
+ $this->query->expects($this->once())->method('load')->with($queryId);
+
+ $this->messageManager->expects($this->once())->method('addSuccess');
+
+ $this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
+ $this->assertSame($this->redirect, $this->controller->execute());
+ }
+
+ public function testExecuteLoadQueryQueryIdQueryTextException()
+ {
+ $queryId = 1;
+ $anotherQueryId = 2;
+ $queryText = 'search';
+ $this->mockGetRequestData($queryText, $queryId);
+
+ $this->request->expects($this->at(4))->method('getPost')->with('store_id', false)->willReturn(1);
+
+ $this->query->expects($this->once())->method('setStoreId');
+ $this->query->expects($this->once())->method('loadByQueryText')->with($queryText);
+ $this->query->expects($this->any())->method('getId')->willReturn($anotherQueryId);
+
+ $this->messageManager->expects($this->once())->method('addError');
+ $this->session->expects($this->once())->method('setPageData');
+ $this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
+ $this->assertSame($this->redirect, $this->controller->execute());
+ }
+
+ public function testExecuteException()
+ {
+ $queryId = 1;
+ $queryText = 'search';
+ $this->mockGetRequestData($queryText, $queryId);
+
+ $this->request->expects($this->at(4))->method('getPost')->with('store_id', false)->willReturn(1);
+
+ $this->query->expects($this->once())->method('setStoreId');
+ $this->query->expects($this->once())->method('loadByQueryText')->willThrowException(new \Exception());
+
+ $this->messageManager->expects($this->once())->method('addException');
+ $this->session->expects($this->once())->method('setPageData');
+ $this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
+ $this->assertSame($this->redirect, $this->controller->execute());
+ }
+
+ /**
+ * @param string $queryText
+ * @param int $queryId
+ */
+ private function mockGetRequestData($queryText, $queryId)
+ {
+ $this->request->expects($this->at(0))->method('getPostValue')->willReturn(['0' => '0']);
+ $this->request->expects($this->at(1))->method('isPost')->willReturn(true);
+ $this->request->expects($this->at(2))->method('getPost')->with('query_text', false)->willReturn($queryText);
+ $this->request->expects($this->at(3))->method('getPost')->with('query_id', null)->willReturn($queryId);
+ }
+}
diff --git a/app/code/Magento/Search/etc/module.xml b/app/code/Magento/Search/etc/module.xml
index 8719bbd18c2cf..2648b158b5042 100644
--- a/app/code/Magento/Search/etc/module.xml
+++ b/app/code/Magento/Search/etc/module.xml
@@ -7,7 +7,7 @@
-->
-
+
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php
index 656da53f38e84..4c6ff5ed4465b 100644
--- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php
@@ -920,26 +920,12 @@ public function getListForAbsentProductProvider()
]
];
- $sampleExpectation = [
- 'fields' => [
- 'title' => 'Downloadable Product Sample Title',
- 'sort_order' => 0,
- 'sample_file' => '/f/u/jellyfish_1_4.jpg',
- 'sample_type' => 'file'
- ]
- ];
-
return [
'links' => [
'/downloadable-links',
- 'GetLinks',
+ 'GetList',
$linkExpectation,
],
- 'samples' => [
- '/downloadable-links/samples',
- 'GetSamples',
- $sampleExpectation,
- ],
];
}
}
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php
index 0a1bba69a8989..dfd7ee356eb76 100644
--- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php
@@ -515,4 +515,56 @@ public function testDeleteThrowsExceptionIfThereIsNoDownloadableSampleWithGivenI
$this->_webApiCall($this->deleteServiceInfo, $requestData);
}
+
+ /**
+ * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
+ * @dataProvider getListForAbsentProductProvider
+ */
+ public function testGetList($urlTail, $method, $expectations)
+ {
+ $sku = 'downloadable-product';
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => '/V1/products/' . $sku . $urlTail,
+ 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+ ],
+ 'soap' => [
+ 'service' => 'downloadableSampleRepositoryV1',
+ 'serviceVersion' => 'V1',
+ 'operation' => 'downloadableSampleRepositoryV1' . $method,
+ ],
+ ];
+
+ $requestData = ['sku' => $sku];
+
+ $list = $this->_webApiCall($serviceInfo, $requestData);
+
+ $this->assertEquals(1, count($list));
+
+ $link = reset($list);
+ foreach ($expectations['fields'] as $index => $value) {
+ $this->assertEquals($value, $link[$index]);
+ }
+ }
+
+ public function getListForAbsentProductProvider()
+ {
+ $sampleExpectation = [
+ 'fields' => [
+ 'title' => 'Downloadable Product Sample Title',
+ 'sort_order' => 0,
+ 'sample_file' => '/f/u/jellyfish_1_4.jpg',
+ 'sample_type' => 'file'
+ ]
+ ];
+
+ return [
+ 'samples' => [
+ '/downloadable-links/samples',
+ 'GetList',
+ $sampleExpectation,
+ ],
+ ];
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/FrontTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/FrontTest.php
index 631738f29155b..97fae046b884b 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/FrontTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/FrontTest.php
@@ -37,7 +37,7 @@ public function testToHtml($attributeCode)
{
/** @var \Magento\Catalog\Model\Resource\Eav\Attribute $model */
$model = $this->objectManager->create('Magento\Catalog\Model\Resource\Eav\Attribute');
- $model->load($attributeCode, 'attribute_code');
+ $model->loadByCode(\Magento\Catalog\Model\Product::ENTITY, $attributeCode);
/** @var \Magento\Framework\Registry $coreRegistry */
$coreRegistry = $this->objectManager->get('\Magento\Framework\Registry');
diff --git a/dev/tests/integration/testsuite/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMainTest.php
similarity index 93%
rename from dev/tests/integration/testsuite/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractTest.php
rename to dev/tests/integration/testsuite/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMainTest.php
index 7ab902da2f613..3e8b1f30a0c2a 100644
--- a/dev/tests/integration/testsuite/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMainTest.php
@@ -9,7 +9,7 @@
*/
namespace Magento\Eav\Block\Adminhtml\Attribute\Edit\Main;
-class AbstractTest extends \PHPUnit_Framework_TestCase
+class AbstractMainTest extends \PHPUnit_Framework_TestCase
{
/**
* @magentoAppIsolation enabled
@@ -38,7 +38,7 @@ public function testPrepareForm()
$objectManager->get('Magento\Eav\Helper\Data'),
$objectManager->get('Magento\Config\Model\Config\Source\YesnoFactory'),
$objectManager->get('Magento\Eav\Model\Adminhtml\System\Config\Source\InputtypeFactory'),
- $objectManager->get('Magento\Eav\Model\Entity\Attribute\Config')
+ $objectManager->get('Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker')
]
)->setLayout(
$objectManager->create('Magento\Framework\View\Layout')
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 7f76c862105e0..9be8e1ae1f468 100755
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -3336,4 +3336,5 @@
['Magento\Log\Model\LogFactory\Clean'],
['Magento\Log\Model\Shell\CommandInterface'],
['Magento\Framework\App\Filesystem\DirectoryList\AbstractShell'],
+ ['Magento\Search\Model\Resource\Helper'],
];