diff --git a/app/code/Magento/Backend/Helper/Dashboard/Data.php b/app/code/Magento/Backend/Helper/Dashboard/Data.php
index efaf955675d59..a7fbf36c88863 100644
--- a/app/code/Magento/Backend/Helper/Dashboard/Data.php
+++ b/app/code/Magento/Backend/Helper/Dashboard/Data.php
@@ -14,7 +14,7 @@
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
- * @var \MagentoFrameworkDataCollectionAbstractDb
+ * @var \Magento\Framework\Data\Collection\AbstractDb
*/
protected $_stores;
@@ -48,7 +48,7 @@ public function __construct(
/**
* Retrieve stores configured in system.
*
- * @return \MagentoFrameworkDataCollectionAbstractDb
+ * @return \Magento\Framework\Data\Collection\AbstractDb
*/
public function getStores()
{
diff --git a/app/code/Magento/Bundle/Model/Product/OptionList.php b/app/code/Magento/Bundle/Model/Product/OptionList.php
index c90d6347e6015..7e26305be731b 100644
--- a/app/code/Magento/Bundle/Model/Product/OptionList.php
+++ b/app/code/Magento/Bundle/Model/Product/OptionList.php
@@ -28,22 +28,30 @@ class OptionList
*/
protected $dataObjectHelper;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $extensionAttributesJoinProcessor;
+
/**
* @param Type $type
* @param \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory
* @param LinksList $linkList
* @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
*/
public function __construct(
\Magento\Bundle\Model\Product\Type $type,
\Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory,
\Magento\Bundle\Model\Product\LinksList $linkList,
- \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
+ \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->type = $type;
$this->optionFactory = $optionFactory;
$this->linkList = $linkList;
$this->dataObjectHelper = $dataObjectHelper;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -53,6 +61,7 @@ public function __construct(
public function getItems(\Magento\Catalog\Api\Data\ProductInterface $product)
{
$optionCollection = $this->type->getOptionsCollection($product);
+ $this->extensionAttributesJoinProcessor->process($optionCollection);
$optionList = [];
/** @var \Magento\Bundle\Model\Option $option */
foreach ($optionCollection as $option) {
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/OptionListTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/OptionListTest.php
index 4827a7efd2fda..855c15bc06fd0 100644
--- a/app/code/Magento/Bundle/Test/Unit/Model/Product/OptionListTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/OptionListTest.php
@@ -33,6 +33,16 @@ class OptionListTest extends \PHPUnit_Framework_TestCase
*/
protected $dataObjectHelperMock;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $extensionAttributesFactoryMock;
+
+ /**
+ * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+ */
+ protected $objectManager;
+
protected function setUp()
{
$this->typeMock = $this->getMock('\Magento\Bundle\Model\Product\Type', [], [], '', false);
@@ -43,15 +53,26 @@ protected function setUp()
'',
false
);
- $this->dataObjectHelperMock = $this->getMockBuilder('\Magento\Framework\Api\DataObjectHelper')
- ->disableOriginalConstructor()
- ->getMock();
+ $this->dataObjectHelperMock = $this->getMock('\Magento\Framework\Api\DataObjectHelper', [], [], '', false);
$this->linkListMock = $this->getMock('\Magento\Bundle\Model\Product\LinksList', [], [], '', false);
- $this->model = new \Magento\Bundle\Model\Product\OptionList(
- $this->typeMock,
- $this->optionFactoryMock,
- $this->linkListMock,
- $this->dataObjectHelperMock
+ $this->extensionAttributesFactoryMock = $this->getMock(
+ '\Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
+ [],
+ [],
+ '',
+ false
+ );
+
+ $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $this->model = $this->objectManager->getObject(
+ 'Magento\Bundle\Model\Product\OptionList',
+ [
+ 'type' => $this->typeMock,
+ 'optionFactory' => $this->optionFactoryMock,
+ 'linkList' => $this->linkListMock,
+ 'dataObjectHelper' => $this->dataObjectHelperMock,
+ 'extensionAttributesJoinProcessor' => $this->extensionAttributesFactoryMock
+ ]
);
}
@@ -71,8 +92,7 @@ public function testGetItems()
'',
false
);
- $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
- $optionsCollMock = $objectManager->getCollectionMock(
+ $optionsCollMock = $this->objectManager->getCollectionMock(
'Magento\Bundle\Model\Resource\Option\Collection',
[$optionMock]
);
diff --git a/app/code/Magento/Catalog/Api/Data/ProductCustomOptionInterface.php b/app/code/Magento/Catalog/Api/Data/ProductCustomOptionInterface.php
index ee11f877129b6..f57491b950d33 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductCustomOptionInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductCustomOptionInterface.php
@@ -9,7 +9,7 @@
/**
* @api
*/
-interface ProductCustomOptionInterface
+interface ProductCustomOptionInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{
/**
* Get product SKU
@@ -201,4 +201,21 @@ public function getValues();
* @return $this
*/
public function setValues(array $values = null);
+
+ /**
+ * Retrieve existing extension attributes object or create a new one.
+ *
+ * @return \Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface|null
+ */
+ public function getExtensionAttributes();
+
+ /**
+ * Set an extension attributes object.
+ *
+ * @param \Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface $extensionAttributes
+ * @return $this
+ */
+ public function setExtensionAttributes(
+ \Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface $extensionAttributes
+ );
}
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 32ad8cfb390d3..11ae8402ce6fb 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -317,6 +317,11 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
'group_price',
];
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
@@ -351,6 +356,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
* @param \Magento\Catalog\Api\Data\ProductLinkExtensionFactory $productLinkExtensionFactory
* @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $mediaGalleryEntryFactory
* @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
* @param array $data
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -389,6 +395,7 @@ public function __construct(
\Magento\Catalog\Api\Data\ProductLinkExtensionFactory $productLinkExtensionFactory,
\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $mediaGalleryEntryFactory,
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor,
array $data = []
) {
$this->metadataService = $metadataService;
@@ -417,6 +424,7 @@ public function __construct(
$this->productLinkExtensionFactory = $productLinkExtensionFactory;
$this->mediaGalleryEntryFactory = $mediaGalleryEntryFactory;
$this->dataObjectHelper = $dataObjectHelper;
+ $this->joinProcessor = $joinProcessor;
parent::__construct(
$context,
$registry,
@@ -1961,7 +1969,9 @@ public function getOptionById($optionId)
public function getOptions()
{
if (empty($this->_options) && $this->getHasOptions() && !$this->optionsInitialized) {
- foreach ($this->getProductOptionsCollection() as $option) {
+ $collection = $this->getProductOptionsCollection();
+ $this->joinProcessor->process($collection);
+ foreach ($collection as $option) {
$option->setProduct($this);
$this->addOption($option);
}
diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php
index 8c5d3d25675d9..05ca2bbdf9c98 100644
--- a/app/code/Magento/Catalog/Model/Product/Option.php
+++ b/app/code/Magento/Catalog/Model/Product/Option.php
@@ -12,7 +12,6 @@
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Resource\Product\Option\Value\Collection;
use Magento\Catalog\Pricing\Price\BasePrice;
-use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Exception\LocalizedException;
/**
@@ -26,7 +25,8 @@
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
*/
-class Option extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCustomOptionInterface
+class Option extends \Magento\Framework\Model\AbstractExtensibleModel
+ implements \Magento\Catalog\Api\Data\ProductCustomOptionInterface
{
const OPTION_GROUP_TEXT = 'text';
@@ -116,6 +116,8 @@ class Option extends AbstractModel implements \Magento\Catalog\Api\Data\ProductC
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
+ * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+ * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
* @param Option\Value $productOptionValue
* @param Option\Type\Factory $optionFactory
* @param \Magento\Framework\Stdlib\String $string
@@ -128,6 +130,8 @@ class Option extends AbstractModel implements \Magento\Catalog\Api\Data\ProductC
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
+ \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+ \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
Option\Value $productOptionValue,
\Magento\Catalog\Model\Product\Option\Type\Factory $optionFactory,
\Magento\Framework\Stdlib\String $string,
@@ -143,6 +147,8 @@ public function __construct(
parent::__construct(
$context,
$registry,
+ $extensionFactory,
+ $customAttributeFactory,
$resource,
$resourceCollection,
$data
@@ -406,7 +412,7 @@ public function saveOptions()
}
/**
- * @return AbstractModel
+ * @return \Magento\Framework\Model\AbstractModel
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function afterSave()
@@ -845,5 +851,27 @@ public function setValues(array $values = null)
$this->_values = $values;
return $this;
}
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return \Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface|null
+ */
+ public function getExtensionAttributes()
+ {
+ return $this->_getExtensionAttributes();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param \Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface $extensionAttributes
+ * @return $this
+ */
+ public function setExtensionAttributes(
+ \Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface $extensionAttributes
+ ) {
+ return $this->_setExtensionAttributes($extensionAttributes);
+ }
//@codeCoverageIgnoreEnd
}
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index 79f26720fff4d..33ef608575c92 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -11,7 +11,6 @@
use Magento\Catalog\Model\Resource\Product\Collection;
use Magento\Framework\Api\Data\ImageContentInterface;
use Magento\Framework\Api\Data\ImageContentInterfaceFactory;
-use Magento\Framework\Api\ExtensionAttributesFactory;
use Magento\Framework\Api\ImageContentValidatorInterface;
use Magento\Framework\Api\ImageProcessorInterface;
use Magento\Framework\Api\SearchCriteriaInterface;
@@ -137,9 +136,9 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
protected $imageProcessor;
/**
- * @var ExtensionAttributesFactory
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
*/
- protected $extensionAttributesFactory;
+ protected $extensionAttributesJoinProcessor;
/**
* @param ProductFactory $productFactory
@@ -149,20 +148,20 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
* @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
* @param Resource\Product $resourceModel
- * @param \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer
- * @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
- * @param \Magento\Store\Model\StoreManagerInterface $storeManager ,
+ * @param Product\Initialization\Helper\ProductLinks $linkInitializer
+ * @param Product\LinkTypeProvider $linkTypeProvider
+ * @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\Api\FilterBuilder $filterBuilder
* @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface
* @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter
- * @param \Magento\Eav\Model\Config $eavConfig
- * @param \Magento\Catalog\Model\Product\Option\Converter $optionConverter
+ * @param Product\Option\Converter $optionConverter
* @param \Magento\Framework\Filesystem $fileSystem
* @param ImageContentValidatorInterface $contentValidator
* @param ImageContentInterfaceFactory $contentFactory
* @param MimeTypeExtensionMap $mimeTypeExtensionMap
+ * @param \Magento\Eav\Model\Config $eavConfig
* @param ImageProcessorInterface $imageProcessor
- * @param ExtensionAttributesFactory $extensionAttributesFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
@@ -186,7 +185,7 @@ public function __construct(
MimeTypeExtensionMap $mimeTypeExtensionMap,
\Magento\Eav\Model\Config $eavConfig,
ImageProcessorInterface $imageProcessor,
- ExtensionAttributesFactory $extensionAttributesFactory
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->productFactory = $productFactory;
$this->collectionFactory = $collectionFactory;
@@ -208,7 +207,7 @@ public function __construct(
$this->mimeTypeExtensionMap = $mimeTypeExtensionMap;
$this->eavConfig = $eavConfig;
$this->imageProcessor = $imageProcessor;
- $this->extensionAttributesFactory = $extensionAttributesFactory;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -649,6 +648,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
{
/** @var \Magento\Catalog\Model\Resource\Product\Collection $collection */
$collection = $this->collectionFactory->create();
+ $this->extensionAttributesJoinProcessor->process($collection);
$defaultAttributeSetId = $this->eavConfig
->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE)
->getDefaultAttributeSetId();
@@ -681,8 +681,6 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
}
$collection->setCurPage($searchCriteria->getCurrentPage());
$collection->setPageSize($searchCriteria->getPageSize());
- $productDataClass = 'Magento\Catalog\Model\Product';
- $this->extensionAttributesFactory->process($collection, $productDataClass);
$collection->load();
$searchResult = $this->searchResultsFactory->create();
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
index 545c8d990ed95..da842214bbd80 100755
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
@@ -1277,7 +1277,10 @@ public function priceDataProvider()
public function testGetOptions()
{
- $optionInstanceMock = $this->getMockBuilder('\Magento\Catalog\Model\Product\Option')
+ $optionInstanceMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Option')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $joinProcessorMock = $this->getMockBuilder('Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface')
->disableOriginalConstructor()
->getMock();
@@ -1286,6 +1289,7 @@ public function testGetOptions()
'Magento\Catalog\Model\Product',
[
'catalogProductOption' => $optionInstanceMock,
+ 'joinProcessor' => $joinProcessorMock
]
);
$productModel->setHasOptions(true);
@@ -1315,12 +1319,19 @@ public function testGetOptions()
->method('setProduct')
->with($productModel)
->willReturn($option1Id);
- $options = [$optionMock1, $optionMock2];
+ $optionColl = $this->objectManagerHelper->getCollectionMock(
+ 'Magento\Catalog\Model\Resource\Product\Option\Collection',
+ [$optionMock1, $optionMock2]
+ );
$optionInstanceMock->expects($this->once())
->method('getProductOptionCollection')
->with($productModel)
- ->willReturn($options);
+ ->willReturn($optionColl);
+
+ $joinProcessorMock->expects($this->once())
+ ->method('process')
+ ->with($this->isInstanceOf('Magento\Catalog\Model\Resource\Product\Option\Collection'));
$expectedOptions = [
$option1Id => $optionMock1,
diff --git a/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php b/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php
index 90a67c71146c5..299e027ac248a 100644
--- a/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php
+++ b/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php
@@ -5,7 +5,7 @@
*/
namespace Magento\CheckoutAgreements\Api\Data;
-interface AgreementInterface
+interface AgreementInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{
/**#@+
* Constants for keys of data array. Identical to the name of the getter in snake case
@@ -128,4 +128,21 @@ public function getIsHtml();
* @return $this
*/
public function setIsHtml($isHtml);
+
+ /**
+ * Retrieve existing extension attributes object or create a new one.
+ *
+ * @return \Magento\CheckoutAgreements\Api\Data\AgreementExtensionInterface|null
+ */
+ public function getExtensionAttributes();
+
+ /**
+ * Set an extension attributes object.
+ *
+ * @param \Magento\CheckoutAgreements\Api\Data\AgreementExtensionInterface $extensionAttributes
+ * @return $this
+ */
+ public function setExtensionAttributes(
+ \Magento\CheckoutAgreements\Api\Data\AgreementExtensionInterface $extensionAttributes
+ );
}
diff --git a/app/code/Magento/CheckoutAgreements/Model/Agreement.php b/app/code/Magento/CheckoutAgreements/Model/Agreement.php
index 6f951c12d5b62..98b1b36b153c1 100644
--- a/app/code/Magento/CheckoutAgreements/Model/Agreement.php
+++ b/app/code/Magento/CheckoutAgreements/Model/Agreement.php
@@ -8,7 +8,7 @@
use Magento\CheckoutAgreements\Api\Data\AgreementInterface;
use Magento\Framework\Model\AbstractModel;
-class Agreement extends AbstractModel implements AgreementInterface
+class Agreement extends \Magento\Framework\Model\AbstractExtensibleModel implements AgreementInterface
{
/**
* Allowed CSS units for height field
@@ -176,5 +176,27 @@ public function setIsHtml($isHtml)
{
return $this->setData(self::IS_HTML, $isHtml);
}
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return \Magento\CheckoutAgreements\Api\Data\AgreementExtensionInterface|null
+ */
+ public function getExtensionAttributes()
+ {
+ return $this->_getExtensionAttributes();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param \Magento\CheckoutAgreements\Api\Data\AgreementExtensionInterface $extensionAttributes
+ * @return $this
+ */
+ public function setExtensionAttributes(
+ \Magento\CheckoutAgreements\Api\Data\AgreementExtensionInterface $extensionAttributes
+ ) {
+ return $this->_setExtensionAttributes($extensionAttributes);
+ }
//@codeCoverageIgnoreEnd
}
diff --git a/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php b/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php
index eae3f09c667a9..845bb2a9d2c74 100644
--- a/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php
+++ b/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php
@@ -10,6 +10,7 @@
use Magento\CheckoutAgreements\Model\Resource\Agreement\CollectionFactory as AgreementCollectionFactory;
use Magento\CheckoutAgreements\Model\Resource\Agreement\Collection as AgreementCollection;
+use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Store\Model\ScopeInterface;
@@ -56,6 +57,11 @@ class CheckoutAgreementsRepository implements CheckoutAgreementsRepositoryInterf
*/
private $agreementFactory;
+ /**
+ * @var JoinProcessorInterface
+ */
+ private $extensionAttributesJoinProcessor;
+
/**
* Constructs a checkout agreement data object.
*
@@ -64,19 +70,22 @@ class CheckoutAgreementsRepository implements CheckoutAgreementsRepositoryInterf
* @param ScopeConfigInterface $scopeConfig Scope config.
* @param AgreementResource $agreementResource
* @param AgreementFactory $agreementFactory
+ * @param JoinProcessorInterface $extensionAttributesJoinProcessor
*/
public function __construct(
AgreementCollectionFactory $collectionFactory,
StoreManagerInterface $storeManager,
ScopeConfigInterface $scopeConfig,
AgreementResource $agreementResource,
- AgreementFactory $agreementFactory
+ AgreementFactory $agreementFactory,
+ JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->collectionFactory = $collectionFactory;
$this->storeManager = $storeManager;
$this->scopeConfig = $scopeConfig;
$this->resourceModel = $agreementResource;
$this->agreementFactory = $agreementFactory;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -92,9 +101,9 @@ public function getList()
$storeId = $this->storeManager->getStore()->getId();
/** @var $agreementCollection AgreementCollection */
$agreementCollection = $this->collectionFactory->create();
+ $this->extensionAttributesJoinProcessor->process($agreementCollection);
$agreementCollection->addStoreFilter($storeId);
$agreementCollection->addFieldToFilter('is_active', 1);
-
$agreementDataObjects = [];
foreach ($agreementCollection as $agreement) {
$agreementDataObjects[] = $agreement;
diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php
index 9d27e3e471e23..04543777e3470 100644
--- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php
+++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php
@@ -56,6 +56,11 @@ class CheckoutAgreementsRepositoryTest extends \PHPUnit_Framework_TestCase
*/
private $storeMock;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $extensionAttributesJoinProcessorMock;
+
protected function setUp()
{
$this->objectManager = new ObjectManager($this);
@@ -81,17 +86,28 @@ protected function setUp()
$this->agreementMock =
$this->getMock('\Magento\CheckoutAgreements\Model\Agreement', $methods, [], '', false);
$this->storeMock = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+ $this->extensionAttributesJoinProcessorMock = $this->getMock(
+ '\Magento\Framework\Api\ExtensionAttribute\JoinProcessor',
+ ['process'],
+ [],
+ '',
+ false
+ );
+
$this->model = new \Magento\CheckoutAgreements\Model\CheckoutAgreementsRepository(
$this->factoryMock,
$this->storeManagerMock,
$this->scopeConfigMock,
$this->resourceMock,
- $this->agrFactoryMock
+ $this->agrFactoryMock,
+ $this->extensionAttributesJoinProcessorMock
);
}
public function testGetListReturnsEmptyListIfCheckoutAgreementsAreDisabledOnFrontend()
{
+ $this->extensionAttributesJoinProcessorMock->expects($this->never())
+ ->method('process');
$this->scopeConfigMock->expects($this->once())
->method('isSetFlag')
->with('checkout/options/enable_agreements', ScopeInterface::SCOPE_STORE, null)
@@ -102,6 +118,10 @@ public function testGetListReturnsEmptyListIfCheckoutAgreementsAreDisabledOnFron
public function testGetListReturnsTheListOfActiveCheckoutAgreements()
{
+ $this->extensionAttributesJoinProcessorMock->expects($this->once())
+ ->method('process')
+ ->with($this->isInstanceOf('Magento\CheckoutAgreements\Model\Resource\Agreement\Collection'));
+
$this->scopeConfigMock->expects($this->once())
->method('isSetFlag')
->with('checkout/options/enable_agreements', ScopeInterface::SCOPE_STORE, null)
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index c1fb0b41ef427..20d861e695135 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -158,6 +158,11 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
*/
protected $jsonHelper;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $extensionAttributesJoinProcessor;
+
/**
* @codingStandardsIgnoreStart/End
*
@@ -181,6 +186,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
* @param \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable $catalogProductTypeConfigurable
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\Catalog\Model\ProductFactory $productFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
@@ -205,7 +211,8 @@ public function __construct(
\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable $catalogProductTypeConfigurable,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
- \Magento\Catalog\Model\ProductFactory $productFactory
+ \Magento\Catalog\Model\ProductFactory $productFactory,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->_typeConfigurableFactory = $typeConfigurableFactory;
$this->_entityFactory = $entityFactory;
@@ -218,6 +225,7 @@ public function __construct(
$this->_scopeConfig = $scopeConfig;
$this->stockConfiguration = $stockConfiguration;
$this->jsonHelper = $jsonHelper;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
parent::__construct(
$catalogProductOption,
$eavConfig,
@@ -370,7 +378,9 @@ public function getConfigurableAttributes($product)
['group' => 'CONFIGURABLE', 'method' => __METHOD__]
);
if (!$product->hasData($this->_configurableAttributes)) {
- $configurableAttributes = $this->getConfigurableAttributeCollection($product)->orderByPosition()->load();
+ $configurableAttributes = $this->getConfigurableAttributeCollection($product);
+ $this->extensionAttributesJoinProcessor->process($configurableAttributes);
+ $configurableAttributes->orderByPosition()->load();
$product->setData($this->_configurableAttributes, $configurableAttributes);
}
\Magento\Framework\Profiler::stop('CONFIGURABLE:' . __METHOD__);
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php
index 4ca090adef44b..a4fcb50da0362 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php
@@ -83,6 +83,11 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
*/
protected $_objectHelper;
+ /**
+ * @var JoinProcessorInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $extensionAttributesJoinProcessorMock;
+
/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
@@ -169,6 +174,14 @@ protected function setUp()
'',
false
);
+ $this->extensionAttributesJoinProcessorMock = $this->getMock(
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
+ [],
+ [],
+ '',
+ false
+ );
+
$this->_model = $this->_objectHelper->getObject(
'Magento\ConfigurableProduct\Model\Product\Type\Configurable',
[
@@ -186,7 +199,8 @@ protected function setUp()
'filesystem' => $filesystem,
'coreRegistry' => $coreRegistry,
'logger' => $logger,
- 'stockConfiguration' => $this->_stockConfiguration
+ 'stockConfiguration' => $this->_stockConfiguration,
+ 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock
]
);
}
@@ -202,9 +216,20 @@ public function testHasWeightTrue()
public function testSave()
{
$product = $this->getMockBuilder('\Magento\Catalog\Model\Product')
- ->setMethods(['getIsDuplicate', 'dataHasChangedFor', 'getConfigurableAttributesData', 'getStoreId',
- 'getId', 'getData', 'hasData', 'getAssociatedProductIds', '__wakeup', '__sleep',
- ])->disableOriginalConstructor()
+ ->setMethods(
+ [
+ 'getIsDuplicate',
+ 'dataHasChangedFor',
+ 'getConfigurableAttributesData',
+ 'getStoreId',
+ 'getId',
+ 'getData',
+ 'hasData',
+ 'getAssociatedProductIds',
+ '__wakeup',
+ '__sleep',
+ ]
+ )->disableOriginalConstructor()
->getMock();
$product->expects($this->any())->method('dataHasChangedFor')->will($this->returnValue('false'));
$product->expects($this->any())->method('getConfigurableAttributesData')
@@ -297,9 +322,19 @@ public function testGetUsedProducts()
$this->_attributeCollectionFactory->expects($this->any())->method('create')
->will($this->returnValue($attributeCollection));
$product = $this->getMockBuilder('\Magento\Catalog\Model\Product')
- ->setMethods(['dataHasChangedFor', 'getConfigurableAttributesData', 'getStoreId',
- 'getId', 'getData', 'hasData', 'getAssociatedProductIds', '__wakeup', '__sleep',
- ])->disableOriginalConstructor()
+ ->setMethods(
+ [
+ 'dataHasChangedFor',
+ 'getConfigurableAttributesData',
+ 'getStoreId',
+ 'getId',
+ 'getData',
+ 'hasData',
+ 'getAssociatedProductIds',
+ '__wakeup',
+ '__sleep',
+ ]
+ )->disableOriginalConstructor()
->getMock();
$product->expects($this->any())->method('getConfigurableAttributesData')
->will($this->returnValue($this->attributeData));
@@ -307,18 +342,28 @@ public function testGetUsedProducts()
$product->expects($this->any())->method('getId')->will($this->returnValue(1));
$product->expects($this->any())->method('getAssociatedProductIds')->will($this->returnValue([2]));
$product->expects($this->any())->method('hasData')
- ->will($this->returnValueMap([
- ['_cache_instance_used_product_attribute_ids', 1],
- ['_cache_instance_products', 0],
- ['_cache_instance_configurable_attributes', 1],
- ]));
+ ->will(
+ $this->returnValueMap(
+ [
+ ['_cache_instance_used_product_attribute_ids', 1],
+ ['_cache_instance_products', 0],
+ ['_cache_instance_configurable_attributes', 1],
+ ]
+ )
+ );
$product->expects($this->any())->method('getData')
->will($this->returnValue(1));
$productCollection = $this->getMockBuilder(
'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Product\Collection'
)->setMethods(
- ['setFlag', 'setProductFilter', 'addStoreFilter', 'addAttributeToSelect', 'addFilterByRequiredOptions',
- 'setStoreId', ]
+ [
+ 'setFlag',
+ 'setProductFilter',
+ 'addStoreFilter',
+ 'addAttributeToSelect',
+ 'addFilterByRequiredOptions',
+ 'setStoreId',
+ ]
)->disableOriginalConstructor()
->getMock();
$productCollection->expects($this->any())->method('addAttributeToSelect')->will($this->returnSelf());
@@ -385,13 +430,21 @@ public function testGetConfigurableAttributesAsArray($productStore, $attributeSt
->getMock();
$product->expects($this->any())->method('getStoreId')->will($this->returnValue($productStore));
$product->expects($this->any())->method('hasData')
- ->will($this->returnValueMap([
- ['_cache_instance_configurable_attributes', 1],
- ]));
+ ->will(
+ $this->returnValueMap(
+ [
+ ['_cache_instance_configurable_attributes', 1],
+ ]
+ )
+ );
$product->expects($this->any())->method('getData')
- ->will($this->returnValueMap([
- ['_cache_instance_configurable_attributes', null, [$attribute]],
- ]));
+ ->will(
+ $this->returnValueMap(
+ [
+ ['_cache_instance_configurable_attributes', null, [$attribute]],
+ ]
+ )
+ );
$result = $this->_model->getConfigurableAttributesAsArray($product);
$this->assertCount(1, $result);
@@ -408,6 +461,41 @@ public function getConfigurableAttributesAsArrayDataProvider()
];
}
+ public function testGetConfigurableAttributes()
+ {
+ $expectedData = [1];
+ $configurableAttributes = '_cache_instance_configurable_attributes';
+
+ /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */
+ $product = $this->getMockBuilder('Magento\Catalog\Model\Product')
+ ->setMethods(['getData', 'hasData', 'setData'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $product->expects($this->once())->method('hasData')->with($configurableAttributes)->willReturn(false);
+ $product->expects($this->once())->method('setData')->willReturnSelf();
+ $product->expects($this->once())->method('getData')->with($configurableAttributes)->willReturn($expectedData);
+
+ $attributeCollection = $this->getMockBuilder(
+ 'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Collection'
+ )
+ ->setMethods(['setProductFilter', 'orderByPosition', 'load'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $attributeCollection->expects($this->any())->method('setProductFilter')->will($this->returnSelf());
+ $attributeCollection->expects($this->any())->method('orderByPosition')->will($this->returnSelf());
+ $this->_attributeCollectionFactory->expects($this->any())->method('create')->willReturn($attributeCollection);
+
+ $this->extensionAttributesJoinProcessorMock->expects($this->once())
+ ->method('process')
+ ->with(
+ $this->isInstanceOf(
+ 'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Collection'
+ )
+ );
+
+ $this->assertEquals($expectedData, $this->_model->getConfigurableAttributes($product));
+ }
+
public function testResetConfigurableAttributes()
{
$product = $this->getMockBuilder('\Magento\Catalog\Model\Product')
diff --git a/app/code/Magento/Customer/Model/Resource/AddressRepository.php b/app/code/Magento/Customer/Model/Resource/AddressRepository.php
index 1a97ba112fbcf..833cf68fd70b8 100644
--- a/app/code/Magento/Customer/Model/Resource/AddressRepository.php
+++ b/app/code/Magento/Customer/Model/Resource/AddressRepository.php
@@ -56,6 +56,11 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf
*/
protected $addressCollectionFactory;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $extensionAttributesJoinProcessor;
+
/**
* @param \Magento\Customer\Model\AddressFactory $addressFactory
* @param \Magento\Customer\Model\AddressRegistry $addressRegistry
@@ -64,6 +69,7 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf
* @param \Magento\Directory\Helper\Data $directoryData
* @param \Magento\Customer\Api\Data\AddressSearchResultsInterfaceFactory $addressSearchResultsFactory
* @param \Magento\Customer\Model\Resource\Address\CollectionFactory $addressCollectionFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
*/
public function __construct(
\Magento\Customer\Model\AddressFactory $addressFactory,
@@ -72,7 +78,8 @@ public function __construct(
\Magento\Customer\Model\Resource\Address $addressResourceModel,
\Magento\Directory\Helper\Data $directoryData,
\Magento\Customer\Api\Data\AddressSearchResultsInterfaceFactory $addressSearchResultsFactory,
- \Magento\Customer\Model\Resource\Address\CollectionFactory $addressCollectionFactory
+ \Magento\Customer\Model\Resource\Address\CollectionFactory $addressCollectionFactory,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->addressFactory = $addressFactory;
$this->addressRegistry = $addressRegistry;
@@ -81,6 +88,7 @@ public function __construct(
$this->directoryData = $directoryData;
$this->addressSearchResultsFactory = $addressSearchResultsFactory;
$this->addressCollectionFactory = $addressCollectionFactory;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -146,6 +154,7 @@ public function getList(SearchCriteriaInterface $searchCriteria)
/** @var Collection $collection */
$collection = $this->addressCollectionFactory->create();
+ $this->extensionAttributesJoinProcessor->process($collection, 'Magento\Customer\Api\Data\AddressInterface');
// Add filters from root filter group to the collection
foreach ($searchCriteria->getFilterGroups() as $group) {
$this->addFilterGroupToCollection($group, $collection);
diff --git a/app/code/Magento/Customer/Model/Resource/CustomerRepository.php b/app/code/Magento/Customer/Model/Resource/CustomerRepository.php
index b20ce2bb0d599..bd3064d2f9317 100644
--- a/app/code/Magento/Customer/Model/Resource/CustomerRepository.php
+++ b/app/code/Magento/Customer/Model/Resource/CustomerRepository.php
@@ -13,7 +13,6 @@
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\NoSuchEntityException;
-use Magento\Framework\Api\ExtensionAttributesFactory;
/**
* Customer repository.
@@ -82,9 +81,9 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte
protected $imageProcessor;
/**
- * @var ExtensionAttributesFactory
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
*/
- protected $extensionAttributesFactory;
+ protected $extensionAttributesJoinProcessor;
/**
* @param \Magento\Customer\Model\CustomerFactory $customerFactory
@@ -99,7 +98,7 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte
* @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter
* @param DataObjectHelper $dataObjectHelper
* @param ImageProcessorInterface $imageProcessor
- * @param ExtensionAttributesFactory $extensionAttributesFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
@@ -115,7 +114,7 @@ public function __construct(
\Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter,
DataObjectHelper $dataObjectHelper,
ImageProcessorInterface $imageProcessor,
- ExtensionAttributesFactory $extensionAttributesFactory
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->customerFactory = $customerFactory;
$this->customerSecureFactory = $customerSecureFactory;
@@ -129,7 +128,7 @@ public function __construct(
$this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
$this->dataObjectHelper = $dataObjectHelper;
$this->imageProcessor = $imageProcessor;
- $this->extensionAttributesFactory = $extensionAttributesFactory;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -250,6 +249,7 @@ public function getList(SearchCriteriaInterface $searchCriteria)
$searchResults->setSearchCriteria($searchCriteria);
/** @var \Magento\Customer\Model\Resource\Customer\Collection $collection */
$collection = $this->customerFactory->create()->getCollection();
+ $this->extensionAttributesJoinProcessor->process($collection, 'Magento\Customer\Api\Data\CustomerInterface');
// This is needed to make sure all the attributes are properly loaded
foreach ($this->customerMetadata->getAllAttributesMetadata() as $metadata) {
$collection->addAttributeToSelect($metadata->getAttributeCode());
@@ -279,7 +279,6 @@ public function getList(SearchCriteriaInterface $searchCriteria)
}
$collection->setCurPage($searchCriteria->getCurrentPage());
$collection->setPageSize($searchCriteria->getPageSize());
- $this->extensionAttributesFactory->process($collection, 'Magento\Customer\Model\Data\Customer');
$customers = [];
/** @var \Magento\Customer\Model\Customer $customerModel */
foreach ($collection as $customerModel) {
diff --git a/app/code/Magento/Customer/Model/Resource/GroupRepository.php b/app/code/Magento/Customer/Model/Resource/GroupRepository.php
index fe0d52ca471ef..2b87df95a55bd 100644
--- a/app/code/Magento/Customer/Model/Resource/GroupRepository.php
+++ b/app/code/Magento/Customer/Model/Resource/GroupRepository.php
@@ -14,6 +14,8 @@
use Magento\Framework\Exception\State\InvalidTransitionException;
use Magento\Tax\Api\Data\TaxClassInterface;
use Magento\Tax\Api\TaxClassManagementInterface;
+use Magento\Framework\Api\ExtensibleDataInterface;
+use Magento\Customer\Api\Data\GroupExtensionInterface;
/**
* Customer group CRUD class
@@ -62,6 +64,11 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface
*/
private $taxClassRepository;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $extensionAttributesJoinProcessor;
+
/**
* @param \Magento\Customer\Model\GroupRegistry $groupRegistry
* @param \Magento\Customer\Model\GroupFactory $groupFactory
@@ -70,6 +77,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface
* @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
* @param \Magento\Customer\Api\Data\GroupSearchResultsInterfaceFactory $searchResultsFactory
* @param \Magento\Tax\Api\TaxClassRepositoryInterface $taxClassRepositoryInterface
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
*/
public function __construct(
\Magento\Customer\Model\GroupRegistry $groupRegistry,
@@ -78,7 +86,8 @@ public function __construct(
\Magento\Customer\Model\Resource\Group $groupResourceModel,
\Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor,
\Magento\Customer\Api\Data\GroupSearchResultsInterfaceFactory $searchResultsFactory,
- \Magento\Tax\Api\TaxClassRepositoryInterface $taxClassRepositoryInterface
+ \Magento\Tax\Api\TaxClassRepositoryInterface $taxClassRepositoryInterface,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->groupRegistry = $groupRegistry;
$this->groupFactory = $groupFactory;
@@ -87,6 +96,7 @@ public function __construct(
$this->dataObjectProcessor = $dataObjectProcessor;
$this->searchResultsFactory = $searchResultsFactory;
$this->taxClassRepository = $taxClassRepositoryInterface;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -164,6 +174,8 @@ public function getList(SearchCriteriaInterface $searchCriteria)
/** @var \Magento\Customer\Model\Resource\Group\Collection $collection */
$collection = $this->groupFactory->create()->getCollection();
+ $groupInterfaceName = 'Magento\Customer\Api\Data\GroupInterface';
+ $this->extensionAttributesJoinProcessor->process($collection, $groupInterfaceName);
$collection->addTaxClass();
//Add filters from root filter group to the collection
@@ -171,7 +183,6 @@ public function getList(SearchCriteriaInterface $searchCriteria)
foreach ($searchCriteria->getFilterGroups() as $group) {
$this->addFilterGroupToCollection($group, $collection);
}
- $searchResults->setTotalCount($collection->getSize());
$sortOrders = $searchCriteria->getSortOrders();
/** @var \Magento\Framework\Api\SortOrder $sortOrder */
if ($sortOrders) {
@@ -182,6 +193,11 @@ public function getList(SearchCriteriaInterface $searchCriteria)
($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
);
}
+ } else {
+ // set a default sorting order since this method is used constantly in many
+ // different blocks
+ $field = $this->translateField('id');
+ $collection->addOrder($field, 'ASC');
}
$collection->setCurPage($searchCriteria->getCurrentPage());
$collection->setPageSize($searchCriteria->getPageSize());
@@ -190,13 +206,22 @@ public function getList(SearchCriteriaInterface $searchCriteria)
$groups = [];
/** @var \Magento\Customer\Model\Group $group */
foreach ($collection as $group) {
+ /** @var \Magento\Customer\Api\Data\GroupInterface $groupDataObject */
$groupDataObject = $this->groupDataFactory->create()
->setId($group->getId())
->setCode($group->getCode())
->setTaxClassId($group->getTaxClassId())
->setTaxClassName($group->getTaxClassName());
+ $data = $group->getData();
+ $data = $this->extensionAttributesJoinProcessor->extractExtensionAttributes($groupInterfaceName, $data);
+ if (isset($data[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY])
+ && ($data[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY] instanceof GroupExtensionInterface)
+ ) {
+ $groupDataObject->setExtensionAttributes($data[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]);
+ }
$groups[] = $groupDataObject;
}
+ $searchResults->setTotalCount($collection->getSize());
return $searchResults->setItems($groups);
}
diff --git a/app/code/Magento/Downloadable/Model/Product/Type.php b/app/code/Magento/Downloadable/Model/Product/Type.php
index c25d6886e20ab..e34c9bdf1b576 100644
--- a/app/code/Magento/Downloadable/Model/Product/Type.php
+++ b/app/code/Magento/Downloadable/Model/Product/Type.php
@@ -6,6 +6,7 @@
namespace Magento\Downloadable\Model\Product;
use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
/**
* Downloadable product type model
@@ -59,6 +60,11 @@ class Type extends \Magento\Catalog\Model\Product\Type\Virtual
*/
private $typeHandler;
+ /**
+ * @var JoinProcessorInterface
+ */
+ private $extensionAttributesJoinProcessor;
+
/**
* Construct
*
@@ -78,6 +84,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\Virtual
* @param \Magento\Downloadable\Model\SampleFactory $sampleFactory
* @param \Magento\Downloadable\Model\LinkFactory $linkFactory
* @param TypeHandler\TypeHandlerInterface $typeHandler
+ * @param JoinProcessorInterface $extensionAttributesJoinProcessor
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
@@ -96,7 +103,8 @@ public function __construct(
\Magento\Downloadable\Model\Resource\Sample\CollectionFactory $samplesFactory,
\Magento\Downloadable\Model\SampleFactory $sampleFactory,
\Magento\Downloadable\Model\LinkFactory $linkFactory,
- \Magento\Downloadable\Model\Product\TypeHandler\TypeHandlerInterface $typeHandler
+ \Magento\Downloadable\Model\Product\TypeHandler\TypeHandlerInterface $typeHandler,
+ JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->_sampleResFactory = $sampleResFactory;
$this->_linkResource = $linkResource;
@@ -105,6 +113,7 @@ public function __construct(
$this->_sampleFactory = $sampleFactory;
$this->_linkFactory = $linkFactory;
$this->typeHandler = $typeHandler;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
parent::__construct(
$catalogProductOption,
$eavConfig,
@@ -127,17 +136,18 @@ public function __construct(
public function getLinks($product)
{
if ($product->getDownloadableLinks() === null) {
- $_linkCollection = $this->_linksFactory->create()->addProductToFilter(
+ /** @var \Magento\Downloadable\Model\Resource\Link\Collection $linkCollection */
+ $linkCollection = $this->_linksFactory->create()->addProductToFilter(
$product->getId()
)->addTitleToResult(
$product->getStoreId()
)->addPriceToResult(
$product->getStore()->getWebsiteId()
);
+ $this->extensionAttributesJoinProcessor->process($linkCollection);
$linksCollectionById = [];
- foreach ($_linkCollection as $link) {
+ foreach ($linkCollection as $link) {
/* @var \Magento\Downloadable\Model\Link $link */
-
$link->setProduct($product);
$linksCollectionById[$link->getId()] = $link;
}
@@ -203,12 +213,13 @@ public function getLinkSelectionRequired($product)
public function getSamples($product)
{
if ($product->getDownloadableSamples() === null) {
- $_sampleCollection = $this->_samplesFactory->create()->addProductToFilter(
+ $sampleCollection = $this->_samplesFactory->create()->addProductToFilter(
$product->getId()
)->addTitleToResult(
$product->getStoreId()
);
- $product->setDownloadableSamples($_sampleCollection);
+ $this->extensionAttributesJoinProcessor->process($sampleCollection);
+ $product->setDownloadableSamples($sampleCollection);
}
return $product->getDownloadableSamples();
diff --git a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php
index 5b1b7d539d930..bfa5952bdbfc6 100644
--- a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php
+++ b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php
@@ -37,25 +37,33 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf
*/
protected $searchResultsFactory;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @param \Magento\Eav\Model\Resource\Entity\Attribute\Group $groupResource
* @param \Magento\Eav\Model\Resource\Entity\Attribute\Group\CollectionFactory $groupListFactory
* @param \Magento\Eav\Model\Entity\Attribute\GroupFactory $groupFactory
* @param \Magento\Eav\Api\AttributeSetRepositoryInterface $setRepository
* @param \Magento\Eav\Api\Data\AttributeGroupSearchResultsInterfaceFactory $searchResultsFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
*/
public function __construct(
\Magento\Eav\Model\Resource\Entity\Attribute\Group $groupResource,
\Magento\Eav\Model\Resource\Entity\Attribute\Group\CollectionFactory $groupListFactory,
\Magento\Eav\Model\Entity\Attribute\GroupFactory $groupFactory,
\Magento\Eav\Api\AttributeSetRepositoryInterface $setRepository,
- \Magento\Eav\Api\Data\AttributeGroupSearchResultsInterfaceFactory $searchResultsFactory
+ \Magento\Eav\Api\Data\AttributeGroupSearchResultsInterfaceFactory $searchResultsFactory,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
) {
$this->groupResource = $groupResource;
$this->groupListFactory = $groupListFactory;
$this->groupFactory = $groupFactory;
$this->setRepository = $setRepository;
$this->searchResultsFactory = $searchResultsFactory;
+ $this->joinProcessor = $joinProcessor;
}
/**
@@ -108,6 +116,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
}
$collection = $this->groupListFactory->create();
+ $this->joinProcessor->process($collection);
$collection->setAttributeSetFilter($attributeSetId);
$collection->setSortOrder();
diff --git a/app/code/Magento/Eav/Model/AttributeRepository.php b/app/code/Magento/Eav/Model/AttributeRepository.php
index e325fea2f4717..a308bcf630f49 100644
--- a/app/code/Magento/Eav/Model/AttributeRepository.php
+++ b/app/code/Magento/Eav/Model/AttributeRepository.php
@@ -42,25 +42,33 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa
*/
protected $attributeFactory;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @param Config $eavConfig
* @param Resource\Entity\Attribute $eavResource
* @param Resource\Entity\Attribute\CollectionFactory $attributeCollectionFactory
* @param \Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory $searchResultsFactory
* @param Entity\AttributeFactory $attributeFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
*/
public function __construct(
\Magento\Eav\Model\Config $eavConfig,
\Magento\Eav\Model\Resource\Entity\Attribute $eavResource,
\Magento\Eav\Model\Resource\Entity\Attribute\CollectionFactory $attributeCollectionFactory,
\Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory $searchResultsFactory,
- \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory
+ \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
) {
$this->eavConfig = $eavConfig;
$this->eavResource = $eavResource;
$this->attributeCollectionFactory = $attributeCollectionFactory;
$this->searchResultsFactory = $searchResultsFactory;
$this->attributeFactory = $attributeFactory;
+ $this->joinProcessor = $joinProcessor;
}
/**
@@ -87,6 +95,7 @@ public function getList($entityTypeCode, \Magento\Framework\Api\SearchCriteriaIn
/** @var \Magento\Eav\Model\Resource\Entity\Attribute\Collection $attributeCollection */
$attributeCollection = $this->attributeCollectionFactory->create();
+ $this->joinProcessor->process($attributeCollection);
$attributeCollection->addFieldToFilter('entity_type_code', ['eq' => $entityTypeCode]);
$attributeCollection->join(
['entity_type' => $attributeCollection->getTable('eav_entity_type')],
diff --git a/app/code/Magento/Eav/Model/AttributeSetRepository.php b/app/code/Magento/Eav/Model/AttributeSetRepository.php
index 2e0d4457eb293..3cc9a46867910 100644
--- a/app/code/Magento/Eav/Model/AttributeSetRepository.php
+++ b/app/code/Magento/Eav/Model/AttributeSetRepository.php
@@ -46,25 +46,33 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface
*/
private $searchResultsFactory;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @param AttributeSetResource $attributeSetResource
* @param AttributeSetFactory $attributeSetFactory
* @param CollectionFactory $collectionFactory
* @param Config $eavConfig
* @param \Magento\Eav\Api\Data\AttributeSetSearchResultsInterfaceFactory $searchResultFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
*/
public function __construct(
AttributeSetResource $attributeSetResource,
AttributeSetFactory $attributeSetFactory,
CollectionFactory $collectionFactory,
EavConfig $eavConfig,
- \Magento\Eav\Api\Data\AttributeSetSearchResultsInterfaceFactory $searchResultFactory
+ \Magento\Eav\Api\Data\AttributeSetSearchResultsInterfaceFactory $searchResultFactory,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
) {
$this->attributeSetResource = $attributeSetResource;
$this->attributeSetFactory = $attributeSetFactory;
$this->collectionFactory = $collectionFactory;
$this->eavConfig = $eavConfig;
$this->searchResultsFactory = $searchResultFactory;
+ $this->joinProcessor = $joinProcessor;
}
/**
@@ -87,6 +95,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
{
/** @var \Magento\Eav\Model\Resource\Entity\Attribute\Set\Collection $collection */
$collection = $this->collectionFactory->create();
+ $this->joinProcessor->process($collection);
/** The only possible/meaningful search criteria for attribute set is entity type code */
$entityTypeCode = $this->getEntityTypeCode($searchCriteria);
diff --git a/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php b/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php
index 5975bf3b5f422..56d56b6035d23 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php
@@ -42,6 +42,11 @@ class AttributeSetRepositoryTest extends \PHPUnit_Framework_TestCase
*/
private $resultFactoryMock;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $extensionAttributesJoinProcessorMock;
+
/**
* @return void
*/
@@ -76,12 +81,20 @@ protected function setUp()
'',
false
);
+ $this->extensionAttributesJoinProcessorMock = $this->getMock(
+ '\Magento\Framework\Api\ExtensionAttribute\JoinProcessor',
+ ['process'],
+ [],
+ '',
+ false
+ );
$this->model = new \Magento\Eav\Model\AttributeSetRepository(
$this->resourceMock,
$this->setFactoryMock,
$this->collectionFactoryMock,
$this->eavConfigMock,
- $this->resultFactoryMock
+ $this->resultFactoryMock,
+ $this->extensionAttributesJoinProcessorMock
);
}
diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php
index 9cc216d09012c..95fa91f6c6c5c 100644
--- a/app/code/Magento/Quote/Model/Quote.php
+++ b/app/code/Magento/Quote/Model/Quote.php
@@ -16,6 +16,7 @@
use Magento\Sales\Model\Resource;
use Magento\Sales\Model\Status;
use Magento\Framework\Api\AttributeValueFactory;
+use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
/**
* Quote model
@@ -322,6 +323,11 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
*/
protected $dataObjectHelper;
+ /**
+ * @var JoinProcessorInterface
+ */
+ protected $extensionAttributesJoinProcessor;
+
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
@@ -355,6 +361,7 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
* @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
* @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter
* @param Cart\CurrencyFactory $currencyFactory
+ * @param JoinProcessorInterface $extensionAttributesJoinProcessor
* @param \Magento\Framework\Model\Resource\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param array $data
@@ -393,6 +400,7 @@ public function __construct(
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
\Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter,
\Magento\Quote\Model\Cart\CurrencyFactory $currencyFactory,
+ JoinProcessorInterface $extensionAttributesJoinProcessor,
\Magento\Framework\Model\Resource\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
@@ -425,6 +433,7 @@ public function __construct(
$this->dataObjectHelper = $dataObjectHelper;
$this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
$this->currencyFactory = $currencyFactory;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
parent::__construct(
$context,
$registry,
@@ -1323,6 +1332,7 @@ public function getItemsCollection($useCache = true)
}
if (null === $this->_items) {
$this->_items = $this->_quoteItemCollectionFactory->create();
+ $this->extensionAttributesJoinProcessor->process($this->_items);
$this->_items->setQuote($this);
}
return $this->_items;
diff --git a/app/code/Magento/Quote/Model/QuoteRepository.php b/app/code/Magento/Quote/Model/QuoteRepository.php
index b54652e7fd8ed..6fa9bca5e4e33 100644
--- a/app/code/Magento/Quote/Model/QuoteRepository.php
+++ b/app/code/Magento/Quote/Model/QuoteRepository.php
@@ -12,6 +12,7 @@
use Magento\Framework\Api\Search\FilterGroup;
use Magento\Quote\Model\Resource\Quote\Collection as QuoteCollection;
use Magento\Framework\Exception\InputException;
+use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface
{
@@ -45,22 +46,30 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface
*/
protected $searchResultsDataFactory;
+ /**
+ * @var JoinProcessorInterface
+ */
+ private $extensionAttributesJoinProcessor;
+
/**
* @param QuoteFactory $quoteFactory
* @param StoreManagerInterface $storeManager
* @param \Magento\Quote\Model\Resource\Quote\Collection $quoteCollection
* @param \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory $searchResultsDataFactory
+ * @param JoinProcessorInterface $extensionAttributesJoinProcessor
*/
public function __construct(
QuoteFactory $quoteFactory,
StoreManagerInterface $storeManager,
\Magento\Quote\Model\Resource\Quote\Collection $quoteCollection,
- \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory $searchResultsDataFactory
+ \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory $searchResultsDataFactory,
+ JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->quoteFactory = $quoteFactory;
$this->storeManager = $storeManager;
$this->searchResultsDataFactory = $searchResultsDataFactory;
$this->quoteCollection = $quoteCollection;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -220,6 +229,7 @@ public function getList(\Magento\Framework\Api\SearchCriteria $searchCriteria)
}
$this->quoteCollection->setCurPage($searchCriteria->getCurrentPage());
$this->quoteCollection->setPageSize($searchCriteria->getPageSize());
+ $this->extensionAttributesJoinProcessor->process($this->quoteCollection);
$searchData->setItems($this->quoteCollection->getItems());
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
index 3690aa6cbf310..872cfa989fbda 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
@@ -10,6 +10,7 @@
use \Magento\Quote\Model\QuoteRepository;
use Magento\Framework\Api\SearchCriteria;
+use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
{
@@ -19,35 +20,40 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
protected $model;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Quote\Model\QuoteFactory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $quoteFactoryMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $storeManagerMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject
*/
protected $storeMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Quote\Model\Quote|\PHPUnit_Framework_MockObject_MockObject
*/
protected $quoteMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $searchResultsDataFactory;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Quote\Model\Resource\Quote\Collection|\PHPUnit_Framework_MockObject_MockObject
*/
protected $quoteCollectionMock;
+ /**
+ * @var JoinProcessorInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $extensionAttributesJoinProcessorMock;
+
protected function setUp()
{
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -56,8 +62,17 @@ protected function setUp()
$this->storeManagerMock = $this->getMock('\Magento\Store\Model\StoreManagerInterface');
$this->quoteMock = $this->getMock(
'\Magento\Quote\Model\Quote',
- ['load', 'loadByCustomer', 'getIsActive', 'getId', '__wakeup', 'setSharedStoreIds', 'save', 'delete',
- 'getCustomerId'],
+ [
+ 'load',
+ 'loadByCustomer',
+ 'getIsActive',
+ 'getId',
+ '__wakeup',
+ 'setSharedStoreIds',
+ 'save',
+ 'delete',
+ 'getCustomerId'
+ ],
[],
'',
false
@@ -73,6 +88,14 @@ protected function setUp()
$this->quoteCollectionMock = $this->getMock('Magento\Quote\Model\Resource\Quote\Collection', [], [], '', false);
+ $this->extensionAttributesJoinProcessorMock = $this->getMock(
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
+ [],
+ [],
+ '',
+ false
+ );
+
$this->model = $objectManager->getObject(
'Magento\Quote\Model\QuoteRepository',
[
@@ -80,6 +103,7 @@ protected function setUp()
'storeManager' => $this->storeManagerMock,
'searchResultsDataFactory' => $this->searchResultsDataFactory,
'quoteCollection' => $this->quoteCollectionMock,
+ 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock
]
);
}
@@ -362,6 +386,11 @@ public function testGetListSuccess($direction, $expectedDirection)
$this->quoteCollectionMock->expects($this->once())->method('setCurPage')->with(1);
$this->quoteCollectionMock->expects($this->once())->method('setPageSize')->with(10);
+ $this->extensionAttributesJoinProcessorMock->expects($this->once())
+ ->method('process')
+ ->with(
+ $this->isInstanceOf('\Magento\Quote\Model\Resource\Quote\Collection')
+ );
$this->quoteCollectionMock->expects($this->once())->method('getItems')->willReturn([$cartMock]);
$searchResult->expects($this->once())->method('setItems')->with([$cartMock]);
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
index 96815ef257fa1..4412f8fc3669e 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
@@ -12,6 +12,7 @@
use Magento\Store\Model\ScopeInterface;
use Magento\Quote\Api\Data\CartInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
/**
* Test class for \Magento\Quote\Model
@@ -131,6 +132,11 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
*/
protected $objectCopyServiceMock;
+ /**
+ * @var JoinProcessorInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $extensionAttributesJoinProcessorMock;
+
/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
@@ -260,6 +266,14 @@ protected function setUp()
->disableOriginalConstructor()
->getMock();
+ $this->extensionAttributesJoinProcessorMock = $this->getMock(
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
+ [],
+ [],
+ '',
+ false
+ );
+
$this->quote = (new ObjectManager($this))
->getObject(
'Magento\Quote\Model\Quote',
@@ -280,7 +294,8 @@ protected function setUp()
'scopeConfig' => $this->scopeConfig,
'extensibleDataObjectConverter' => $this->extensibleDataObjectConverterMock,
'customerRepository' => $this->customerRepositoryMock,
- 'objectCopyService' => $this->objectCopyServiceMock
+ 'objectCopyService' => $this->objectCopyServiceMock,
+ 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock
]
);
}
@@ -1123,7 +1138,6 @@ public function testBeforeSaveIsVirtualQuote(array $productTypes, $expected)
$this->assertEquals($expected, $this->quote->getDataByKey(CartInterface::KEY_IS_VIRTUAL));
}
-
/**
* @return array
*/
@@ -1137,4 +1151,24 @@ public function dataProviderForTestBeforeSaveIsVirtualQuote()
[[false, false], 0]
];
}
+
+ public function testGetItemsCollection()
+ {
+ $itemCollectionMock = $this->getMockBuilder('Magento\Quote\Model\Resource\Quote\Collection')
+ ->disableOriginalConstructor()
+ ->setMethods(['setQuote'])
+ ->getMock();
+ $this->quoteItemCollectionFactoryMock->expects($this->once())
+ ->method('create')
+ ->willReturn($itemCollectionMock);
+
+ $this->extensionAttributesJoinProcessorMock->expects($this->once())
+ ->method('process')
+ ->with(
+ $this->isInstanceOf('Magento\Quote\Model\Resource\Quote\Collection')
+ );
+ $itemCollectionMock->expects($this->once())->method('setQuote')->with($this->quote);
+
+ $this->quote->getItemsCollection();
+ }
}
diff --git a/app/code/Magento/Sales/Api/Data/OrderSearchResultInterface.php b/app/code/Magento/Sales/Api/Data/OrderSearchResultInterface.php
index b11a2c04de8d3..a7c67652dd7a4 100644
--- a/app/code/Magento/Sales/Api/Data/OrderSearchResultInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderSearchResultInterface.php
@@ -18,7 +18,7 @@ interface OrderSearchResultInterface
/**
* Gets collection items.
*
- * @return \Magento\Sales\Api\Data\OrderSearchResultInterface[] Array of collection items.
+ * @return \Magento\Sales\Api\Data\OrderInterface[] Array of collection items.
*/
public function getItems();
}
diff --git a/app/code/Magento/Sales/Api/InvoiceCommentRepositoryInterface.php b/app/code/Magento/Sales/Api/InvoiceCommentRepositoryInterface.php
index c7e2d8cfb759c..f256bb88af2ab 100644
--- a/app/code/Magento/Sales/Api/InvoiceCommentRepositoryInterface.php
+++ b/app/code/Magento/Sales/Api/InvoiceCommentRepositoryInterface.php
@@ -18,7 +18,7 @@ interface InvoiceCommentRepositoryInterface
* Lists invoice comments that match specified search criteria.
*
* @param \Magento\Framework\Api\SearchCriteria $criteria The search criteria.
- * @return \Magento\Sales\Api\Data\InvoiceSearchResultInterface Invoice search result interface.
+ * @return \Magento\Sales\Api\Data\InvoiceCommentSearchResultInterface Invoice search result interface.
*/
public function getList(\Magento\Framework\Api\SearchCriteria $criteria);
diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php
index 6f099ea27ae35..d124469768d16 100644
--- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php
+++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php
@@ -65,6 +65,11 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface
*/
protected $resourceModel;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @param Converter $converter
* @param RateRegistry $rateRegistry
@@ -73,6 +78,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface
* @param CountryFactory $countryFactory
* @param RegionFactory $regionFactory
* @param \Magento\Tax\Model\Resource\Calculation\Rate $rateResource
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
*/
public function __construct(
Converter $converter,
@@ -81,7 +87,8 @@ public function __construct(
RateFactory $rateFactory,
CountryFactory $countryFactory,
RegionFactory $regionFactory,
- \Magento\Tax\Model\Resource\Calculation\Rate $rateResource
+ \Magento\Tax\Model\Resource\Calculation\Rate $rateResource,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
) {
$this->converter = $converter;
$this->rateRegistry = $rateRegistry;
@@ -90,6 +97,7 @@ public function __construct(
$this->countryFactory = $countryFactory;
$this->regionFactory = $regionFactory;
$this->resourceModel = $rateResource;
+ $this->joinProcessor = $joinProcessor;
}
/**
@@ -146,6 +154,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
{
/** @var \Magento\Tax\Model\Resource\Calculation\Rate\Collection $collection */
$collection = $this->rateFactory->create()->getCollection();
+ $this->joinProcessor->process($collection);
$collection->joinRegionTable();
//Add filters from root filter group to the collection
diff --git a/app/code/Magento/Tax/Model/TaxClass/Repository.php b/app/code/Magento/Tax/Model/TaxClass/Repository.php
index 01dd656b0d5e5..54b92c00c6633 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Repository.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Repository.php
@@ -62,6 +62,11 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface
*/
protected $taxClassResource;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @param FilterBuilder $filterBuilder
@@ -69,6 +74,7 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface
* @param \Magento\Tax\Api\Data\TaxClassSearchResultsInterfaceFactory $searchResultsFactory
* @param ClassModelRegistry $classModelRegistry
* @param \Magento\Tax\Model\Resource\TaxClass $taxClassResource
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
*/
public function __construct(
SearchCriteriaBuilder $searchCriteriaBuilder,
@@ -76,7 +82,8 @@ public function __construct(
TaxClassCollectionFactory $taxClassCollectionFactory,
\Magento\Tax\Api\Data\TaxClassSearchResultsInterfaceFactory $searchResultsFactory,
ClassModelRegistry $classModelRegistry,
- \Magento\Tax\Model\Resource\TaxClass $taxClassResource
+ \Magento\Tax\Model\Resource\TaxClass $taxClassResource,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
) {
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->filterBuilder = $filterBuilder;
@@ -84,6 +91,7 @@ public function __construct(
$this->searchResultsFactory = $searchResultsFactory;
$this->classModelRegistry = $classModelRegistry;
$this->taxClassResource = $taxClassResource;
+ $this->joinProcessor = $joinProcessor;
}
/**
@@ -195,6 +203,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
$searchResults->setSearchCriteria($searchCriteria);
/** @var TaxClassCollection $collection */
$collection = $this->taxClassCollectionFactory->create();
+ $this->joinProcessor->process($collection);
foreach ($searchCriteria->getFilterGroups() as $group) {
$this->addFilterGroupToCollection($group, $collection);
}
diff --git a/app/code/Magento/Tax/Model/TaxRuleRepository.php b/app/code/Magento/Tax/Model/TaxRuleRepository.php
index d186c79b562aa..28ff8015b9a66 100644
--- a/app/code/Magento/Tax/Model/TaxRuleRepository.php
+++ b/app/code/Magento/Tax/Model/TaxRuleRepository.php
@@ -52,25 +52,33 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface
*/
protected $resource;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @param TaxRuleRegistry $taxRuleRegistry
* @param TaxRuleSearchResultsInterfaceFactory $searchResultsFactory
* @param RuleFactory $ruleFactory
* @param CollectionFactory $collectionFactory
* @param Resource $resource
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
*/
public function __construct(
TaxRuleRegistry $taxRuleRegistry,
TaxRuleSearchResultsInterfaceFactory $searchResultsFactory,
RuleFactory $ruleFactory,
CollectionFactory $collectionFactory,
- Resource $resource
+ Resource $resource,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
) {
$this->taxRuleRegistry = $taxRuleRegistry;
$this->taxRuleSearchResultsFactory = $searchResultsFactory;
$this->taxRuleModelFactory = $ruleFactory;
$this->collectionFactory = $collectionFactory;
$this->resource = $resource;
+ $this->joinProcessor = $joinProcessor;
}
/**
@@ -133,6 +141,7 @@ public function getList(\Magento\Framework\Api\SearchCriteria $searchCriteria)
$fields = [];
$collection = $this->collectionFactory->create();
+ $this->joinProcessor->process($collection);
//Add filters from root filter group to the collection
foreach ($searchCriteria->getFilterGroups() as $group) {
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
index 7feff54990150..f2d8b4b17d164 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
@@ -59,6 +59,11 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase
*/
private $rateResourceMock;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $joinProcessorMock;
+
public function setUp()
{
$this->rateConverterMock = $this->getMock(
@@ -117,6 +122,13 @@ public function setUp()
'',
false
);
+ $this->joinProcessorMock = $this->getMock(
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
+ [],
+ [],
+ '',
+ false
+ );
$this->model = new RateRepository(
$this->rateConverterMock,
$this->rateRegistryMock,
@@ -124,7 +136,8 @@ public function setUp()
$this->rateFactoryMock,
$this->countryFactoryMock,
$this->regionFactoryMock,
- $this->rateResourceMock
+ $this->rateResourceMock,
+ $this->joinProcessorMock
);
}
@@ -256,6 +269,8 @@ public function testGetList()
->willReturnSelf();
$this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultMock);
+ $this->joinProcessorMock->expects($this->once())->method('process')->with($collectionMock);
+
$this->model->getList($searchCriteriaMock);
}
@@ -402,6 +417,8 @@ public function testGetListWhenFilterGroupExists()
->willReturnSelf();
$this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultMock);
+ $this->joinProcessorMock->expects($this->once())->method('process')->with($collectionMock);
+
$this->model->getList($searchCriteriaMock);
}
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php
index 80894cab62e2a..bfab6b77acc7f 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php
@@ -47,6 +47,11 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
*/
protected $taxClassCollectionFactory;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $extensionAttributesJoinProcessorMock;
+
/**
* @return void
*/
@@ -85,13 +90,23 @@ protected function setUp()
);
$this->taxClassResourceMock = $this->getMock('\Magento\Tax\Model\Resource\TaxClass', [], [], '', false);
+
+ $this->extensionAttributesJoinProcessorMock = $this->getMock(
+ '\Magento\Framework\Api\ExtensionAttribute\JoinProcessor',
+ ['process'],
+ [],
+ '',
+ false
+ );
+
$this->model = $this->objectManager->getObject(
'Magento\Tax\Model\TaxClass\Repository',
[
'classModelRegistry' => $this->classModelRegistryMock,
'taxClassResource' => $this->taxClassResourceMock,
'searchResultsFactory' => $this->searchResultFactory,
- 'taxClassCollectionFactory' => $this->taxClassCollectionFactory
+ 'taxClassCollectionFactory' => $this->taxClassCollectionFactory,
+ 'joinProcessor' => $this->extensionAttributesJoinProcessorMock
]
);
}
@@ -187,6 +202,10 @@ public function testGetList()
$collection = $this->getMock('\Magento\Tax\Model\Resource\TaxClass\Collection', [], [], '', false);
$sortOrder = $this->getMock('\Magento\Framework\Api\SortOrder', [], [], '', false);
+ $this->extensionAttributesJoinProcessorMock->expects($this->once())
+ ->method('process')
+ ->with($collection);
+
$searchCriteria->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroup]);
$filterGroup->expects($this->once())->method('getFilters')->willReturn([$filter]);
$filter->expects($this->atLeastOnce())->method('getConditionType')->willReturn('eq');
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
index 435fa82bbe9e4..3225be5242f8a 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
@@ -46,6 +46,11 @@ class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase
*/
protected $resource;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $extensionAttributesJoinProcessorMock;
+
/**
* @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
*/
@@ -78,13 +83,21 @@ protected function setUp()
false
);
$this->resource = $this->getMock('\Magento\Tax\Model\Resource\Calculation\Rule', [], [], '', false);
+ $this->extensionAttributesJoinProcessorMock = $this->getMock(
+ '\Magento\Framework\Api\ExtensionAttribute\JoinProcessor',
+ ['process'],
+ [],
+ '',
+ false
+ );
$this->model = new TaxRuleRepository(
$this->taxRuleRegistry,
$this->searchResultFactory,
$this->ruleFactory,
$this->collectionFactory,
- $this->resource
+ $this->resource,
+ $this->extensionAttributesJoinProcessorMock
);
}
@@ -181,6 +194,10 @@ public function testGetList()
$filterMock = $this->getMock('\Magento\Framework\Api\Filter', [], [], '', false);
$sortOrderMock = $this->getMock('\Magento\Framework\Api\SortOrder', [], [], '', false);
+ $this->extensionAttributesJoinProcessorMock->expects($this->once())
+ ->method('process')
+ ->with($collectionMock);
+
$this->searchResultsMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteriaMock);
$this->collectionFactory->expects($this->once())->method('create')->willReturn($collectionMock);
$searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroupMock]);
diff --git a/app/code/Magento/User/Model/UserInterface.php b/app/code/Magento/User/Api/Data/UserInterface.php
similarity index 91%
rename from app/code/Magento/User/Model/UserInterface.php
rename to app/code/Magento/User/Api/Data/UserInterface.php
index 4b4cecf569a01..c5de7bd1bc5e8 100644
--- a/app/code/Magento/User/Model/UserInterface.php
+++ b/app/code/Magento/User/Api/Data/UserInterface.php
@@ -3,7 +3,7 @@
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-namespace Magento\User\Model;
+namespace Magento\User\Api\Data;
/**
* Admin user interface.
@@ -14,119 +14,119 @@ interface UserInterface
{
/**
* Get ID.
- *
+ *
* @return int
*/
public function getId();
-
+
/**
* Set ID.
- *
+ *
* @param int $id
* @return $this
*/
public function setId($id);
-
+
/**
* Get first name.
- *
+ *
* @return string
*/
public function getFirstName();
-
+
/**
* Set first name.
- *
+ *
* @param string $firstName
* @return $this
*/
public function setFirstName($firstName);
-
+
/**
* Get last name.
- *
+ *
* @return string
*/
public function getLastName();
-
+
/**
* Set last name.
- *
+ *
* @param string $lastName
* @return $this
*/
public function setLastName($lastName);
-
+
/**
* Get email.
- *
+ *
* @return string
*/
public function getEmail();
-
+
/**
* Set email.
- *
+ *
* @param string $email
* @return $this
*/
public function setEmail($email);
-
+
/**
* Get user name.
- *
+ *
* @return string
*/
public function getUserName();
-
+
/**
* Set user name.
- *
+ *
* @param string $userName
* @return $this
*/
public function setUserName($userName);
-
+
/**
* Get password or password hash.
- *
+ *
* @return string
*/
public function getPassword();
-
+
/**
* Set password or password hash.
- *
+ *
* @param string $password
* @return $this
*/
public function setPassword($password);
-
+
/**
* Get user record creation date.
- *
+ *
* @return string
*/
public function getCreated();
-
+
/**
* Set user record creation date.
- *
+ *
* @param string $created
* @return $this
*/
public function setCreated($created);
-
+
/**
* Get user record modification date.
- *
+ *
* @return string
*/
public function getModified();
-
+
/**
* Set user record modification date.
- *
+ *
* @param string $modified
* @return $this
*/
diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php
index 9ab8a1039fcfb..b152509226ddb 100644
--- a/app/code/Magento/User/Model/User.php
+++ b/app/code/Magento/User/Model/User.php
@@ -8,6 +8,7 @@
use Magento\Backend\Model\Auth\Credential\StorageInterface;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Exception\AuthenticationException;
+use Magento\User\Api\Data\UserInterface;
/**
* Admin user model
diff --git a/app/code/Magento/User/etc/di.xml b/app/code/Magento/User/etc/di.xml
index f76198da27e60..962ccc2aa632a 100644
--- a/app/code/Magento/User/etc/di.xml
+++ b/app/code/Magento/User/etc/di.xml
@@ -14,5 +14,5 @@
-
+
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 02cd1c358cb7e..87986caa2ba5a 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -34,6 +34,8 @@
system/currency/installed
+
+
diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/Api/TestRepositoryInterface.php b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/Api/TestRepositoryInterface.php
new file mode 100644
index 0000000000000..fd70ae4b5fb01
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/Api/TestRepositoryInterface.php
@@ -0,0 +1,20 @@
+quoteCollectionFactory = $quoteCollectionFactory;
+ $this->searchResultsDataFactory = $searchResultsDataFactory;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getList(\Magento\Framework\Api\SearchCriteria $searchCriteria)
+ {
+ $quoteCollection = $this->quoteCollectionFactory->create();
+ $this->extensionAttributesJoinProcessor->process($quoteCollection);
+ $searchData = $this->searchResultsDataFactory->create();
+ $searchData->setSearchCriteria($searchCriteria);
+ $searchData->setItems($quoteCollection->getItems());
+ return $searchData;
+ }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/composer.json b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/composer.json
new file mode 100644
index 0000000000000..72d19bcf34cfb
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/composer.json
@@ -0,0 +1,20 @@
+{
+ "name": "magento/module-test-join-directives",
+ "description": "test integration for join directives",
+ "require": {
+ "php": "~5.5.0|~5.6.0",
+ "magento/framework": "0.42.0-beta8",
+ "magento/module-sales": "0.42.0-beta8",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-module",
+ "version": "1.0",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/TestModuleJoinDirectives"
+ ]
+ ]
+ }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/acl.xml
new file mode 100644
index 0000000000000..ad548566ba7d1
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/acl.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/di.xml
new file mode 100644
index 0000000000000..a3633a8adf41f
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/di.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/extension_attributes.xml b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/extension_attributes.xml
new file mode 100644
index 0000000000000..e20f73c0d237f
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/extension_attributes.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ firstname
+ lastname
+ email
+
+
+
+
+
+
+ firstname
+ lastname
+ email
+
+
+
+
diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/module.xml
new file mode 100644
index 0000000000000..7f91223ddc7d2
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/module.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/webapi.xml
new file mode 100644
index 0000000000000..741e134c76d7e
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/webapi.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php
index fa8be5fc2dcc2..722dfb6770135 100644
--- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php
@@ -863,16 +863,16 @@ private function createGroup($group)
public function testSearchGroupsDataProvider()
{
return [
- ['tax_class_id', '3', []],
- ['tax_class_id', '0', null],
+ ['tax_class_id', 3, []],
+ ['tax_class_id', 0, null],
['code', md5(mt_rand(0, 10000000000) . time()), null],
[
'id',
- '0',
+ 0,
[
- 'id' => '0',
+ 'id' => 0,
'code' => 'NOT LOGGED IN',
- 'tax_class_id' => '3',
+ 'tax_class_id' => 3,
'tax_class_name' => 'Retail Customer'
]
],
@@ -880,19 +880,19 @@ public function testSearchGroupsDataProvider()
'code',
'General',
[
- 'id' => '1',
+ 'id' => 1,
'code' => 'General',
- 'tax_class_id' => '3',
+ 'tax_class_id' => 3,
'tax_class_name' => 'Retail Customer'
]
],
[
'id',
- '2',
+ 2,
[
- 'id' => '2',
+ 'id' => 2,
'code' => 'Wholesale',
- 'tax_class_id' => '3',
+ 'tax_class_id' => 3,
'tax_class_name' => 'Retail Customer'
]
],
@@ -900,9 +900,9 @@ public function testSearchGroupsDataProvider()
'code',
'Retailer',
[
- 'id' => '3',
+ 'id' => 3,
'code' => 'Retailer',
- 'tax_class_id' => '3',
+ 'tax_class_id' => 3,
'tax_class_name' => 'Retail Customer'
]
]
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php
new file mode 100644
index 0000000000000..142283fa8ac35
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php
@@ -0,0 +1,136 @@
+searchBuilder = $objectManager->create('Magento\Framework\Api\SearchCriteriaBuilder');
+ $this->sortOrderBuilder = $objectManager->create('Magento\Framework\Api\SortOrderBuilder');
+ $this->filterBuilder = $objectManager->create('Magento\Framework\Api\FilterBuilder');
+ $this->user = $objectManager->create('Magento\User\Model\User');
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Sales/_files/quote.php
+ */
+ public function testGetList()
+ {
+ /** @var SortOrder $sortOrder */
+ $sortOrder = $this->sortOrderBuilder->setField('store_id')->setDirection(SearchCriteria::SORT_ASC)->create();
+ $this->searchBuilder->setSortOrders([$sortOrder]);
+ $searchCriteria = $this->searchBuilder->create()->__toArray();
+ $requestData = ['searchCriteria' => $searchCriteria];
+
+ $restResourcePath = '/V1/TestJoinDirectives/';
+ $soapService = 'testJoinDirectivesTestRepositoryV1';
+ $expectedExtensionAttributes = $this->getExpectedExtensionAttributes();
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => $restResourcePath . '?' . http_build_query($requestData),
+ 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+ ],
+ 'soap' => [
+ 'service' => $soapService,
+ 'operation' => $soapService . 'GetList',
+ ],
+ ];
+ $searchResult = $this->_webApiCall($serviceInfo, $requestData);
+
+ $this->assertArrayHasKey('items', $searchResult);
+ $itemData = array_pop($searchResult['items']);
+ $this->assertArrayHasKey('extension_attributes', $itemData);
+ $this->assertArrayHasKey('quote_api_test_attribute', $itemData['extension_attributes']);
+ $testAttribute = $itemData['extension_attributes']['quote_api_test_attribute'];
+ $this->assertEquals($expectedExtensionAttributes['firstname'], $testAttribute['first_name']);
+ $this->assertEquals($expectedExtensionAttributes['lastname'], $testAttribute['last_name']);
+ $this->assertEquals($expectedExtensionAttributes['email'], $testAttribute['email']);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+ */
+ public function testAutoGeneratedGetList()
+ {
+ $this->getExpectedExtensionAttributes();
+ /** @var SortOrder $sortOrder */
+ $sortOrder = $this->sortOrderBuilder->setField('store_id')->setDirection(SearchCriteria::SORT_ASC)->create();
+ $this->searchBuilder->setSortOrders([$sortOrder]);
+ $this->searchBuilder->addFilter([$this->filterBuilder->setField('state')->setValue(2)->create()]);
+ $searchCriteria = $this->searchBuilder->create()->__toArray();
+ $requestData = ['criteria' => $searchCriteria];
+
+ $restResourcePath = '/V1/invoices/';
+ $soapService = 'salesInvoiceRepositoryV1';
+ $expectedExtensionAttributes = $this->getExpectedExtensionAttributes();
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => $restResourcePath . '?' . http_build_query($requestData),
+ 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+ ],
+ 'soap' => [
+ 'service' => $soapService,
+ 'operation' => $soapService . 'GetList',
+ ],
+ ];
+ $searchResult = $this->_webApiCall($serviceInfo, $requestData);
+
+ $this->assertArrayHasKey('items', $searchResult);
+ $itemData = array_pop($searchResult['items']);
+ $this->assertArrayHasKey('extension_attributes', $itemData);
+ $this->assertArrayHasKey('invoice_api_test_attribute', $itemData['extension_attributes']);
+ $testAttribute = $itemData['extension_attributes']['invoice_api_test_attribute'];
+ $this->assertEquals($expectedExtensionAttributes['firstname'], $testAttribute['first_name']);
+ $this->assertEquals($expectedExtensionAttributes['lastname'], $testAttribute['last_name']);
+ $this->assertEquals($expectedExtensionAttributes['email'], $testAttribute['email']);
+ }
+
+ /**
+ * Retrieve the admin user's information.
+ *
+ * @return array
+ */
+ private function getExpectedExtensionAttributes()
+ {
+ $this->user->load(1);
+ return [
+ 'firstname' => $this->user->getFirstname(),
+ 'lastname' => $this->user->getLastname(),
+ 'email' => $this->user->getEmail()
+ ];
+ }
+}
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php
index 13aefd3cb0531..e5d71b3055b8f 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php
@@ -122,6 +122,13 @@ class Application
*/
private $globalConfigFile;
+ /**
+ * Defines whether load test extension attributes or not
+ *
+ * @var bool
+ */
+ private $loadTestExtensionAttributes;
+
/**
* Constructor
*
@@ -132,6 +139,7 @@ class Application
* @param string $globalConfigDir
* @param string $appMode
* @param AutoloaderInterface $autoloadWrapper
+ * @param bool|null $loadTestExtensionAttributes
*/
public function __construct(
\Magento\Framework\Shell $shell,
@@ -140,7 +148,8 @@ public function __construct(
$globalConfigFile,
$globalConfigDir,
$appMode,
- AutoloaderInterface $autoloadWrapper
+ AutoloaderInterface $autoloadWrapper,
+ $loadTestExtensionAttributes = false
) {
if (getcwd() != BP . '/dev/tests/integration') {
chdir(BP . '/dev/tests/integration');
@@ -150,6 +159,7 @@ public function __construct(
$this->_globalConfigDir = realpath($globalConfigDir);
$this->_appMode = $appMode;
$this->installDir = $installDir;
+ $this->loadTestExtensionAttributes = $loadTestExtensionAttributes;
$customDirs = $this->getCustomDirs();
$this->dirList = new \Magento\Framework\App\Filesystem\DirectoryList(BP, $customDirs);
@@ -323,25 +333,28 @@ public function initialize($overriddenParams = [])
$objectManager->addSharedInstance($logger, 'Magento\Framework\Logger\Monolog');
$sequenceBuilder = $objectManager->get('\Magento\TestFramework\Db\Sequence\Builder');
$objectManager->addSharedInstance($sequenceBuilder, 'Magento\SalesSequence\Model\Builder');
-
Helper\Bootstrap::setObjectManager($objectManager);
-
- $objectManager->configure(
- [
- 'preferences' => [
- 'Magento\Framework\App\State' => 'Magento\TestFramework\App\State',
- 'Magento\Framework\Mail\TransportInterface' => 'Magento\TestFramework\Mail\TransportInterfaceMock',
- 'Magento\Framework\Mail\Template\TransportBuilder'
- => 'Magento\TestFramework\Mail\Template\TransportBuilderMock',
- ],
- 'Magento\Framework\Api\ExtensionAttribute\Config\Reader' => [
- 'arguments' => [
- 'fileResolver' => ['instance' => 'Magento\TestFramework\Api\Config\Reader\FileResolver'],
- ],
- ],
+ $objectManagerConfiguration = [
+ 'preferences' => [
+ 'Magento\Framework\App\State' => 'Magento\TestFramework\App\State',
+ 'Magento\Framework\Mail\TransportInterface' => 'Magento\TestFramework\Mail\TransportInterfaceMock',
+ 'Magento\Framework\Mail\Template\TransportBuilder'
+ => 'Magento\TestFramework\Mail\Template\TransportBuilderMock',
]
- );
-
+ ];
+ if ($this->loadTestExtensionAttributes) {
+ $objectManagerConfiguration = array_merge(
+ $objectManagerConfiguration,
+ [
+ 'Magento\Framework\Api\ExtensionAttribute\Config\Reader' => [
+ 'arguments' => [
+ 'fileResolver' => ['instance' => 'Magento\TestFramework\Api\Config\Reader\FileResolver'],
+ ],
+ ],
+ ]
+ );
+ }
+ $objectManager->configure($objectManagerConfiguration);
/** Register event observer of Integration Framework */
/** @var \Magento\Framework\Event\Config\Data $eventConfigData */
$eventConfigData = $objectManager->get('Magento\Framework\Event\Config\Data');
@@ -356,7 +369,6 @@ public function initialize($overriddenParams = [])
]
]
);
-
$this->loadArea(\Magento\TestFramework\Application::DEFAULT_APP_AREA);
\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->configure(
$objectManager->get('Magento\Framework\ObjectManager\DynamicConfigInterface')->getConfiguration()
diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php
index 2f607671fe773..e39836e58dd5b 100644
--- a/dev/tests/integration/framework/bootstrap.php
+++ b/dev/tests/integration/framework/bootstrap.php
@@ -52,7 +52,8 @@
$globalConfigFile,
$settings->get('TESTS_GLOBAL_CONFIG_DIR'),
$settings->get('TESTS_MAGENTO_MODE'),
- AutoloaderRegistry::getAutoloader()
+ AutoloaderRegistry::getAutoloader(),
+ true
);
$bootstrap = new \Magento\TestFramework\Bootstrap(
@@ -71,7 +72,7 @@
if (!$application->isInstalled()) {
$application->install();
}
- $application->initialize();
+ $application->initialize([]);
\Magento\TestFramework\Helper\Bootstrap::setInstance(new \Magento\TestFramework\Helper\Bootstrap($bootstrap));
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/OptionListTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/OptionListTest.php
new file mode 100644
index 0000000000000..62f5cff1ff52e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/OptionListTest.php
@@ -0,0 +1,44 @@
+objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ }
+
+ /**
+ * @magentoDataFixture Magento/Bundle/_files/product.php
+ */
+ public function testGetItems()
+ {
+ $this->product = $this->objectManager->get('Magento\Catalog\Model\Product');
+ $this->product->load(3);
+ /**
+ * @var \Magento\Bundle\Model\Product\OptionList $optionList
+ */
+ $optionList = $this->objectManager->create('\Magento\Bundle\Model\Product\OptionList');
+ $options = $optionList->getItems($this->product);
+ $this->assertEquals(1, count($options));
+ $this->assertEquals('Bundle Product Items', $options[0]->getTitle());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
index db9cfaa872bda..cbd558ed2f3e0 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
@@ -419,4 +419,15 @@ public function testValidate()
$this->assertTrue($error);
}
}
+
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+ * @magentoAppIsolation enabled
+ */
+ public function testGetOptions()
+ {
+ $this->_model->load(1);
+ $options = $this->_model->getOptions();
+ $this->assertEquals(4, count($options));
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/OptionRepositoryTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/OptionRepositoryTest.php
new file mode 100644
index 0000000000000..dfe06c0deefe3
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/OptionRepositoryTest.php
@@ -0,0 +1,33 @@
+create('Magento\ConfigurableProduct\Api\OptionRepositoryInterface');
+
+ $options = $optionRepository->getList($productSku);
+ $this->assertCount(1, $options, "Invalid number of option.");
+ $this->assertNotNull($options[0]->getExtensionAttributes(), "Extension attributes not loaded");
+ /** @var \Magento\Eav\Model\Entity\Attribute $joinedEntity */
+ $joinedEntity = $objectManager->create('Magento\Eav\Model\Entity\Attribute');
+ $joinedEntity->load($options[0]->getId());
+ $joinedExtensionAttributeValue = $joinedEntity->getAttributeCode();
+ $this->assertEquals(
+ $joinedExtensionAttributeValue,
+ $options[0]->getExtensionAttributes()->getTestDummyAttribute(),
+ "Extension attributes were not loaded correctly"
+ );
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/etc/extension_attributes.xml b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/etc/extension_attributes.xml
new file mode 100644
index 0000000000000..dbf00dbc8c5b0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/etc/extension_attributes.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ attribute_code
+
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
index 16cfa26b08873..438de55ed11d1 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
@@ -316,7 +316,7 @@ public function testSearchAddresses($filters, $filterGroup, $expectedResult)
$this->assertEquals(count($expectedResult), $searchResults->getTotalCount());
- /** @var \Magento\Customer\Api\Data\AddressInterface $item*/
+ /** @var \Magento\Customer\Api\Data\AddressInterface $item */
foreach ($searchResults->getItems() as $item) {
$this->assertEquals(
$expectedResult[$item->getId()]['city'],
diff --git a/dev/tests/integration/testsuite/Magento/Customer/etc/extension_attributes.xml b/dev/tests/integration/testsuite/Magento/Customer/etc/extension_attributes.xml
new file mode 100644
index 0000000000000..6c210f6f4125f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Customer/etc/extension_attributes.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ group_id
+
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php
index 2628c9c0e2880..cb06602f2c2a5 100644
--- a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php
@@ -69,6 +69,7 @@ public function testDeleteTypeSpecificData()
/**
* @magentoDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
* @magentoAppArea adminhtml
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testSaveTypeSpecificData()
{
@@ -129,12 +130,21 @@ public function testSaveTypeSpecificData()
'title' => 'Updated downloadable link #1',
'website_price' => '15.0000',
];
-
-
+ $expectedExtensionAttributes = [
+ 'firstname' => 'firstname',
+ 'lastname' => 'lastname',
+ 'email' => 'admin@example.com'
+ ];
$links = $this->_model->getLinks($product);
$this->assertNotEmpty($links);
$this->assertCount(1, $links);
+ /** @var \Magento\Downloadable\Model\Link $link */
$link = reset($links);
+ /** @var \Magento\User\Api\Data\UserInterface $testAttribute */
+ $testAttribute = $link->getExtensionAttributes()->getTestAttribute();
+ $this->assertEquals($expectedExtensionAttributes['firstname'], $testAttribute->getFirstName());
+ $this->assertEquals($expectedExtensionAttributes['lastname'], $testAttribute->getLastName());
+ $this->assertEquals($expectedExtensionAttributes['email'], $testAttribute->getEmail());
foreach ($expectedLink as $key => $value) {
$this->assertTrue($link->hasData($key), 'Key ' . $key . ' not exist!');
$this->assertArrayHasKey($key, $link);
@@ -157,6 +167,11 @@ public function testSaveTypeSpecificData()
$this->assertEquals(1, $samples->count());
/** @var \Magento\Downloadable\Model\Sample $sample */
$sample = $samples->getFirstItem()->getData();
+ /** @var \Magento\User\Api\Data\UserInterface $testAttribute */
+ $testAttribute = $sample['extension_attributes']->getTestAttribute();
+ $this->assertEquals($expectedExtensionAttributes['firstname'], $testAttribute->getFirstName());
+ $this->assertEquals($expectedExtensionAttributes['lastname'], $testAttribute->getLastName());
+ $this->assertEquals($expectedExtensionAttributes['email'], $testAttribute->getEmail());
foreach ($expectedSample as $key => $value) {
$this->assertArrayHasKey($key, $sample);
$this->assertEquals($value, $sample[$key]);
diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/etc/extension_attributes.xml b/dev/tests/integration/testsuite/Magento/Downloadable/etc/extension_attributes.xml
new file mode 100644
index 0000000000000..e120bbea99bcf
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Downloadable/etc/extension_attributes.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ firstname
+ lastname
+ email
+
+
+
+
+
+
+ firstname
+ lastname
+ email
+
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttribute/JoinProcessorTest.php b/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttribute/JoinProcessorTest.php
new file mode 100644
index 0000000000000..10be075426201
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttribute/JoinProcessorTest.php
@@ -0,0 +1,404 @@
+config = $this->getMockBuilder('Magento\Framework\Api\ExtensionAttribute\Config')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->extensionAttributeJoinDataFactory = $this
+ ->getMockBuilder('Magento\Framework\Api\ExtensionAttribute\JoinDataInterfaceFactory')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->extensionAttributeJoinDataFactory = $this
+ ->getMockBuilder('Magento\Framework\Api\ExtensionAttribute\JoinDataInterfaceFactory')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->typeProcessor = $this->getMockBuilder('Magento\Framework\Reflection\TypeProcessor')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ /** @var \Magento\Framework\ObjectManagerInterface */
+ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+ $this->appResource = $objectManager->get('Magento\Framework\App\Resource');
+
+ $this->joinProcessor = $objectManager->create(
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessor',
+ [
+ 'objectManager' => $objectManager,
+ 'config' => $this->config,
+ 'extensionAttributeJoinDataFactory' => $this->extensionAttributeJoinDataFactory,
+ 'typeProcessor' => $this->typeProcessor
+ ]
+ );
+ }
+
+ /**
+ * Test the processing of the join config for a particular type
+ */
+ public function testProcess()
+ {
+ $this->config->expects($this->once())
+ ->method('get')
+ ->will($this->returnValue($this->getConfig()));
+
+ $collection = $this->getMockBuilder('Magento\Framework\Data\Collection\AbstractDb')
+ ->setMethods(['joinExtensionAttribute'])
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
+
+ $extensionAttributeJoinData = new JoinData();
+ $this->extensionAttributeJoinDataFactory
+ ->expects($this->once())
+ ->method('create')
+ ->willReturn($extensionAttributeJoinData);
+
+ $collection->expects($this->once())->method('joinExtensionAttribute')->with($extensionAttributeJoinData);
+
+ $this->joinProcessor->process($collection, 'Magento\Catalog\Api\Data\ProductInterface');
+ $expectedTableName = 'reviews';
+ $this->assertEquals($expectedTableName, $extensionAttributeJoinData->getReferenceTable());
+ $this->assertEquals('extension_attribute_review_id', $extensionAttributeJoinData->getReferenceTableAlias());
+ $this->assertEquals('product_id', $extensionAttributeJoinData->getReferenceField());
+ $this->assertEquals('id', $extensionAttributeJoinData->getJoinField());
+ $this->assertEquals(
+ [
+ [
+ 'external_alias' => 'review_id',
+ 'internal_alias' => 'extension_attribute_review_id_db_review_id',
+ 'with_db_prefix' => 'extension_attribute_review_id.db_review_id',
+ 'setter' => 'setReviewId',
+ ]
+ ],
+ $extensionAttributeJoinData->getSelectFields()
+ );
+ }
+
+ private function getConfig()
+ {
+ return [
+ 'Magento\Catalog\Api\Data\ProductInterface' => [
+ 'review_id' => [
+ Converter::DATA_TYPE => 'string',
+ Converter::RESOURCE_PERMISSIONS => [],
+ Converter::JOIN_DIRECTIVE => [
+ Converter::JOIN_REFERENCE_TABLE => "reviews",
+ Converter::JOIN_REFERENCE_FIELD => "product_id",
+ Converter::JOIN_FIELDS => [
+ [
+ Converter::JOIN_FIELD => "review_id",
+ Converter::JOIN_FIELD_COLUMN => "db_review_id",
+ ],
+ ],
+ Converter::JOIN_ON_FIELD => "id",
+ ],
+ ],
+ ],
+ 'Magento\Customer\Api\Data\CustomerInterface' => [
+ 'library_card_id' => [
+ Converter::DATA_TYPE => 'string',
+ Converter::RESOURCE_PERMISSIONS => [],
+ Converter::JOIN_DIRECTIVE => [
+ Converter::JOIN_REFERENCE_TABLE => "library_account",
+ Converter::JOIN_FIELDS => [
+ [
+ Converter::JOIN_FIELD => "library_card_id",
+ Converter::JOIN_FIELD_COLUMN => "",
+ ],
+ ],
+ Converter::JOIN_ON_FIELD => "customer_id",
+ ],
+ ],
+ 'reviews' => [
+ Converter::DATA_TYPE => 'Magento\Reviews\Api\Data\Reviews[]',
+ Converter::RESOURCE_PERMISSIONS => [],
+ Converter::JOIN_DIRECTIVE => [
+ Converter::JOIN_REFERENCE_TABLE => "reviews",
+ Converter::JOIN_FIELDS => [
+ [
+ Converter::JOIN_FIELD => "comment",
+ Converter::JOIN_FIELD_COLUMN => "",
+ ],
+ [
+ Converter::JOIN_FIELD => "rating",
+ Converter::JOIN_FIELD_COLUMN => "",
+ ],
+ ],
+ Converter::JOIN_ON_FIELD => "customer_id",
+ ],
+ ],
+ ],
+ ];
+ }
+
+ public function testProcessSqlSelectVerification()
+ {
+ /** @var \Magento\Framework\ObjectManagerInterface */
+ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ /** @var \Magento\Framework\Api\ExtensionAttribute\Config $config */
+ $config = $objectManager->get('Magento\Framework\Api\ExtensionAttribute\Config');
+ $config->reset();
+
+ $extensionConfigFileResolverMock = $this->getMockBuilder('Magento\Framework\Config\FileResolverInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $extensionConfigFilePath = __DIR__ . '/../_files/extension_attributes.xml';
+ $extensionConfigFileContent = file_get_contents($extensionConfigFilePath);
+ $extensionConfigFileResolverMock->expects($this->any())
+ ->method('get')
+ ->willReturn([$extensionConfigFilePath => $extensionConfigFileContent]);
+ $configReader = $objectManager->create(
+ 'Magento\Framework\Api\ExtensionAttribute\Config\Reader',
+ ['fileResolver' => $extensionConfigFileResolverMock]
+ );
+ /** @var \Magento\Framework\Api\ExtensionAttribute\Config $config */
+ $config = $objectManager->create(
+ 'Magento\Framework\Api\ExtensionAttribute\Config',
+ ['reader' => $configReader]
+ );
+ /** @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessor $extensionAttributesProcessor */
+ $extensionAttributesProcessor = $objectManager->create(
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessor',
+ ['config' => $config]
+ );
+ /** @var \Magento\Catalog\Model\Resource\Product\Collection $collection */
+ $collection = $objectManager->create('Magento\Catalog\Model\Resource\Product\Collection');
+ $extensionAttributesProcessor->process($collection);
+ $config->reset();
+
+ $catalogProductEntity = $this->appResource->getTableName('catalog_product_entity');
+ $catalogInventoryStockItem = $this->appResource->getTableName('cataloginventory_stock_item');
+ $reviews = $this->appResource->getTableName('reviews');
+ $expectedSql = <<getSelectSql(true);
+ $formattedResultSql = str_replace(',', ",\n ", $resultSql);
+ $this->assertEquals($expectedSql, $formattedResultSql);
+ }
+
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/products.php
+ */
+ public function testGetListWithExtensionAttributesAbstractModel()
+ {
+ $firstProductId = 1;
+ $firstProductQty = 11;
+ $secondProductId = 2;
+ $secondProductQty = 22;
+ /** @var \Magento\Framework\ObjectManagerInterface */
+ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+ $productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
+ /** @var \Magento\CatalogInventory\Api\StockItemRepositoryInterface $stockItemRepository */
+ $stockItemRepository = $objectManager->get('Magento\CatalogInventory\Api\StockItemRepositoryInterface');
+
+ /** Prepare stock items */
+ $firstStockItem = $productRepository->getById($firstProductId)->getExtensionAttributes()->getStockItem();
+ $firstStockItem->setQty($firstProductQty);
+ $stockItemRepository->save($firstStockItem);
+ $this->assertEquals(
+ $firstProductQty,
+ $productRepository->getById($firstProductId)->getExtensionAttributes()->getStockItem()->getQty(),
+ 'Precondition failed.'
+ );
+ $secondStockItem = $productRepository->getById($secondProductId)->getExtensionAttributes()->getStockItem();
+ $secondStockItem->setQty($secondProductQty);
+ $stockItemRepository->save($secondStockItem);
+ $this->assertEquals(
+ $secondProductQty,
+ $productRepository->getById($secondProductId)->getExtensionAttributes()->getStockItem()->getQty(),
+ 'Precondition failed.'
+ );
+
+ /** @var \Magento\Framework\Api\Search\FilterGroup $searchCriteriaGroup */
+ $searchCriteriaGroup = $objectManager->create('Magento\Framework\Api\Search\FilterGroup');
+ /** @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria */
+ $searchCriteria = $objectManager->create('Magento\Framework\Api\SearchCriteriaInterface');
+ $searchCriteria->setFilterGroups([$searchCriteriaGroup]);
+ $products = $productRepository->getList($searchCriteria)->getItems();
+
+ /** Ensure that simple extension attributes were populated correctly */
+ $this->assertEquals(
+ $firstProductQty,
+ $products[$firstProductId]->getExtensionAttributes()->getTestStockItemQty()
+ );
+ $this->assertEquals(
+ $secondProductQty,
+ $products[$secondProductId]->getExtensionAttributes()->getTestStockItemQty()
+ );
+
+ /** Check population of complex extension attributes */
+ $this->assertEquals(
+ $firstProductQty,
+ $products[$firstProductId]->getExtensionAttributes()->getTestStockItem()->getQty()
+ );
+ $this->assertNotEmpty($products[$firstProductId]->getExtensionAttributes()->getTestStockItem()->getItemId());
+
+ $this->assertArrayNotHasKey(
+ 'extension_attribute_test_stock_item_qty_qty',
+ $products[$firstProductId]->getData(),
+ "Selected extension field should be unset after it is added to extension attributes object."
+ );
+ }
+
+ /**
+ * @magentoDataFixture Magento/Customer/_files/customer.php
+ * @magentoDataFixture Magento/Customer/_files/customer_group.php
+ */
+ public function testGetListWithExtensionAttributesAbstractObject()
+ {
+ $customerId = 1;
+ $customerGroupName = 'General';
+ $taxClassId = 3;
+ /** @var \Magento\Framework\ObjectManagerInterface */
+ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+ /** @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository */
+ $customerRepository = $objectManager->get('Magento\Customer\Api\CustomerRepositoryInterface');
+ /** @var \Magento\Framework\Api\Search\FilterGroup $searchCriteriaGroup */
+ $searchCriteriaGroup = $objectManager->create('Magento\Framework\Api\Search\FilterGroup');
+ /** @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria */
+ $searchCriteria = $objectManager->create('Magento\Framework\Api\SearchCriteriaInterface');
+ $searchCriteria->setFilterGroups([$searchCriteriaGroup]);
+ $customers = $customerRepository->getList($searchCriteria)->getItems();
+
+ /** Ensure that simple extension attributes were populated correctly */
+ $customer = $customers[0];
+ $this->assertEquals($customerId, $customer->getId(), 'Precondition failed');
+ $this->assertEquals($customerGroupName, $customer->getExtensionAttributes()->getTestGroupCode());
+
+ /** Check population of complex extension attributes */
+ $this->assertEquals($taxClassId, $customer->getExtensionAttributes()->getTestGroup()->getTaxClassId());
+ $this->assertEquals($customerGroupName, $customer->getExtensionAttributes()->getTestGroup()->getCode());
+ }
+
+ public function testGetListWithFilterBySimpleDummyAttributeWithMapping()
+ {
+ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ $groupRepository = $objectManager->create('Magento\Customer\Api\GroupRepositoryInterface');
+ $searchCriteriaBuilder = $objectManager->create('Magento\Framework\Api\SearchCriteriaBuilder');
+ $builder = $objectManager->create('Magento\Framework\Api\FilterBuilder');
+ $joinedExtensionAttribute = 'test_dummy_attribute';
+ $joinedExtensionAttributeValue = 'website_id';
+ $filter = $builder->setField($joinedExtensionAttribute)
+ ->setValue($joinedExtensionAttributeValue)
+ ->create();
+ $searchCriteriaBuilder->addFilter([$filter]);
+ $searchResults = $groupRepository->getList($searchCriteriaBuilder->create());
+ $items = $searchResults->getItems();
+ $this->assertCount(1, $items, 'Filtration by extension attribute does not work.');
+ $expectedGroupCode = 'General';
+ $this->assertEquals($expectedGroupCode, $items[0]->getCode(), 'Invalid group loaded.');
+ $this->assertNotNull($items[0]->getExtensionAttributes(), "Extension attributes not loaded");
+ $this->assertEquals(
+ $joinedExtensionAttributeValue,
+ $items[0]->getExtensionAttributes()->getTestDummyAttribute(),
+ "Extension attributes were not loaded correctly"
+ );
+ }
+
+ public function testGetListWithFilterByComplexDummyAttributeWithSetterMapping()
+ {
+ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ $groupRepository = $objectManager->create('Magento\Customer\Api\GroupRepositoryInterface');
+ $searchCriteriaBuilder = $objectManager->create('Magento\Framework\Api\SearchCriteriaBuilder');
+ $builder = $objectManager->create('Magento\Framework\Api\FilterBuilder');
+ $joinedExtensionAttribute = 'test_complex_dummy_attribute.frontend_label';
+ $joinedExtensionAttributeValue = 'firstname';
+ $filter = $builder->setField($joinedExtensionAttribute)
+ ->setValue($joinedExtensionAttributeValue)
+ ->create();
+ $searchCriteriaBuilder->addFilter([$filter]);
+ $searchResults = $groupRepository->getList($searchCriteriaBuilder->create());
+ $items = $searchResults->getItems();
+ $this->assertCount(1, $items, 'Filtration by extension attribute does not work.');
+ $expectedGroupCode = 'General';
+ $this->assertEquals($expectedGroupCode, $items[0]->getCode(), 'Invalid group loaded.');
+ $this->assertNotNull($items[0]->getExtensionAttributes(), "Extension attributes not loaded");
+ $this->assertNotNull(
+ $items[0]->getExtensionAttributes()->getTestComplexDummyAttribute(),
+ "Complex extension attribute not loaded"
+ );
+ $this->assertEquals(
+ 'user',
+ $items[0]->getExtensionAttributes()->getTestComplexDummyAttribute()->getAttributeCode(),
+ "Extension attributes were not loaded correctly"
+ );
+ $this->assertEquals(
+ $joinedExtensionAttributeValue,
+ $items[0]->getExtensionAttributes()->getTestComplexDummyAttribute()->getFrontendLabel(),
+ "Extension attributes were not loaded correctly"
+ );
+ }
+
+ /**
+ * @magentoDataFixture Magento/Sales/_files/invoice.php
+ */
+ public function testGetListWithExtensionAttributesAutoGeneratedRepository()
+ {
+ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ $searchCriteriaBuilder = $objectManager->create('Magento\Framework\Api\SearchCriteriaBuilder');
+ /** @var \Magento\Sales\Api\InvoiceRepositoryInterface $invoiceRepository */
+ $invoiceRepository = $objectManager->create('Magento\Sales\Api\InvoiceRepositoryInterface');
+ $invoices = $invoiceRepository->getList($searchCriteriaBuilder->create())->getItems();
+ $this->assertCount(1, $invoices, "Invalid number of loaded invoices.");
+ $invoice = reset($invoices);
+
+ /** @var \Magento\Eav\Model\Entity\Attribute $joinedEntity */
+ $joinedEntity = $objectManager->create('Magento\Eav\Model\Entity\Attribute');
+ $joinedEntity->load($invoice->getId());
+ $joinedExtensionAttributeValue = $joinedEntity->getAttributeCode();
+
+ $this->assertNotNull($invoice->getExtensionAttributes(), "Extension attributes not loaded");
+ $this->assertEquals(
+ $joinedExtensionAttributeValue,
+ $invoice->getExtensionAttributes()->getTestDummyAttribute(),
+ "Extension attributes were not loaded correctly"
+ );
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttributesFactoryTest.php b/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttributesFactoryTest.php
index 674fc1432f0ef..faec140dbdab7 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttributesFactoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttributesFactoryTest.php
@@ -5,70 +5,21 @@
*/
namespace Magento\Framework\Api;
-use Magento\Framework\Api\ExtensionAttribute\Config\Converter;
-use Magento\Framework\Api\ExtensionAttribute\Config\Reader;
-use Magento\Framework\Api\ExtensionAttribute\JoinData;
-use Magento\Framework\Api\ExtensionAttribute\JoinDataFactory;
-use Magento\Framework\Reflection\TypeProcessor;
-use Magento\Framework\App\Resource;
-
class ExtensionAttributesFactoryTest extends \PHPUnit_Framework_TestCase
{
/** @var \Magento\Framework\Api\ExtensionAttributesFactory */
private $factory;
- /**
- * @var Reader|\PHPUnit_Framework_MockObject_MockObject
- */
- private $config;
-
- /**
- * @var JoinDataFactory|\PHPUnit_Framework_MockObject_MockObject
- */
- private $extensionAttributeJoinDataFactory;
-
- /**
- * @var TypeProcessor|\PHPUnit_Framework_MockObject_MockObject
- */
- private $typeProcessor;
-
- /**
- * @var AppResource|\PHPUnit_Framework_MockObject_MockObject
- */
- private $appResource;
-
protected function setUp()
{
- $this->config = $this->getMockBuilder('Magento\Framework\Api\ExtensionAttribute\Config')
- ->disableOriginalConstructor()
- ->getMock();
- $this->extensionAttributeJoinDataFactory = $this
- ->getMockBuilder('Magento\Framework\Api\ExtensionAttribute\JoinDataFactory')
- ->disableOriginalConstructor()
- ->getMock();
- $this->extensionAttributeJoinDataFactory = $this
- ->getMockBuilder('Magento\Framework\Api\ExtensionAttribute\JoinDataFactory')
- ->disableOriginalConstructor()
- ->getMock();
- $this->typeProcessor = $this->getMockBuilder('Magento\Framework\Reflection\TypeProcessor')
- ->disableOriginalConstructor()
- ->getMock();
-
$autoloadWrapper = \Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader();
$autoloadWrapper->addPsr4('Magento\\Wonderland\\', realpath(__DIR__ . '/_files/Magento/Wonderland'));
/** @var \Magento\Framework\ObjectManagerInterface */
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
- $this->appResource = $objectManager->get('Magento\Framework\App\Resource');
-
$this->factory = $objectManager->create(
'Magento\Framework\Api\ExtensionAttributesFactory',
- [
- 'objectManager' => $objectManager,
- 'config' => $this->config,
- 'extensionAttributeJoinDataFactory' => $this->extensionAttributeJoinDataFactory,
- 'typeProcessor' => $this->typeProcessor
- ]
+ ['objectManager' => $objectManager]
);
}
@@ -104,240 +55,6 @@ public function testCreate()
);
}
- /**
- * Test the processing of the join config for a particular type
- */
- public function testProcess()
- {
- $this->config->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->getConfig()));
-
- $collection = $this->getMockBuilder('Magento\Framework\Data\Collection\AbstractDb')
- ->setMethods(['joinExtensionAttribute'])
- ->disableOriginalConstructor()
- ->getMockForAbstractClass();
-
- $extensionAttributeJoinData = new JoinData();
- $this->extensionAttributeJoinDataFactory
- ->expects($this->once())
- ->method('create')
- ->willReturn($extensionAttributeJoinData);
-
- $collection->expects($this->once())->method('joinExtensionAttribute')->with($extensionAttributeJoinData);
-
- $this->factory->process($collection, 'Magento\Catalog\Api\Data\ProductInterface');
- $expectedTableName = 'reviews';
- $this->assertEquals($expectedTableName, $extensionAttributeJoinData->getReferenceTable());
- $this->assertEquals('extension_attribute_review_id', $extensionAttributeJoinData->getReferenceTableAlias());
- $this->assertEquals('product_id', $extensionAttributeJoinData->getReferenceField());
- $this->assertEquals('id', $extensionAttributeJoinData->getJoinField());
- $this->assertEquals(['review_id'], $extensionAttributeJoinData->getSelectFields());
- }
-
- private function getConfig()
- {
- return [
- 'Magento\Catalog\Api\Data\ProductInterface' => [
- 'review_id' => [
- Converter::DATA_TYPE => 'string',
- Converter::RESOURCE_PERMISSIONS => [],
- Converter::JOIN_DIRECTIVE => [
- Converter::JOIN_REFERENCE_TABLE => "reviews",
- Converter::JOIN_REFERENCE_FIELD => "product_id",
- Converter::JOIN_SELECT_FIELDS => [
- [
- Converter::JOIN_SELECT_FIELD => "review_id",
- ],
- ],
- Converter::JOIN_JOIN_ON_FIELD => "id",
- ],
- ],
- ],
- 'Magento\Customer\Api\Data\CustomerInterface' => [
- 'library_card_id' => [
- Converter::DATA_TYPE => 'string',
- Converter::RESOURCE_PERMISSIONS => [],
- Converter::JOIN_DIRECTIVE => [
- Converter::JOIN_REFERENCE_TABLE => "library_account",
- Converter::JOIN_SELECT_FIELDS => [
- [
- Converter::JOIN_SELECT_FIELD => "library_card_id",
- ],
- ],
- Converter::JOIN_JOIN_ON_FIELD => "customer_id",
- ],
- ],
- 'reviews' => [
- Converter::DATA_TYPE => 'Magento\Reviews\Api\Data\Reviews[]',
- Converter::RESOURCE_PERMISSIONS => [],
- Converter::JOIN_DIRECTIVE => [
- Converter::JOIN_REFERENCE_TABLE => "reviews",
- Converter::JOIN_SELECT_FIELDS => [
- [
- Converter::JOIN_SELECT_FIELD => "comment",
- ],
- [
- Converter::JOIN_SELECT_FIELD => "rating",
- ],
- ],
- Converter::JOIN_JOIN_ON_FIELD => "customer_id",
- ],
- ],
- ],
- ];
- }
-
- public function testProcessSqlSelectVerification()
- {
- /** @var \Magento\Framework\ObjectManagerInterface */
- $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
- /** @var \Magento\Framework\Api\ExtensionAttribute\Config $config */
- $config = $objectManager->get('Magento\Framework\Api\ExtensionAttribute\Config');
- $config->reset();
-
- $extensionConfigFileResolverMock = $this->getMockBuilder('Magento\Framework\Config\FileResolverInterface')
- ->disableOriginalConstructor()
- ->getMock();
- $extensionConfigFilePath = __DIR__ . '/_files/extension_attributes.xml';
- $extensionConfigFileContent = file_get_contents($extensionConfigFilePath);
- $extensionConfigFileResolverMock->expects($this->any())
- ->method('get')
- ->willReturn([$extensionConfigFilePath => $extensionConfigFileContent]);
- $configReader = $objectManager->create(
- 'Magento\Framework\Api\ExtensionAttribute\Config\Reader',
- ['fileResolver' => $extensionConfigFileResolverMock]
- );
- /** @var \Magento\Framework\Api\ExtensionAttribute\Config $config */
- $config = $objectManager->create(
- 'Magento\Framework\Api\ExtensionAttribute\Config',
- ['reader' => $configReader]
- );
- /** @var \Magento\Framework\Api\ExtensionAttributesFactory $extensionAttributesFactory */
- $extensionAttributesFactory = $objectManager->create(
- 'Magento\Framework\Api\ExtensionAttributesFactory',
- ['config' => $config]
- );
- $productClassName = 'Magento\Catalog\Model\Product';
- /** @var \Magento\Catalog\Model\Resource\Product\Collection $collection */
- $collection = $objectManager->create('Magento\Catalog\Model\Resource\Product\Collection');
-
- $extensionAttributesFactory->process($collection, $productClassName);
- $config->reset();
-
- $catalogProductEntity = $this->appResource->getTableName('catalog_product_entity');
- $catalogInventoryStockItem = $this->appResource->getTableName('cataloginventory_stock_item');
- $reviews = $this->appResource->getTableName('reviews');
- $expectedSql = <<getSelectSql(true);
- $formattedResultSql = str_replace(',', ",\n ", $resultSql);
- $this->assertEquals($expectedSql, $formattedResultSql);
- }
-
- /**
- * @magentoDataFixture Magento/Catalog/_files/products.php
- */
- public function testGetListWithExtensionAttributesAbstractModel()
- {
- $firstProductId = 1;
- $firstProductQty = 11;
- $secondProductId = 2;
- $secondProductQty = 22;
- /** @var \Magento\Framework\ObjectManagerInterface */
- $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
- /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
- $productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
- /** @var \Magento\CatalogInventory\Api\StockItemRepositoryInterface $stockItemRepository */
- $stockItemRepository = $objectManager->get('Magento\CatalogInventory\Api\StockItemRepositoryInterface');
-
- /** Prepare stock items */
- $firstStockItem = $productRepository->getById($firstProductId)->getExtensionAttributes()->getStockItem();
- $firstStockItem->setQty($firstProductQty);
- $stockItemRepository->save($firstStockItem);
- $this->assertEquals(
- $firstProductQty,
- $productRepository->getById($firstProductId)->getExtensionAttributes()->getStockItem()->getQty(),
- 'Precondition failed.'
- );
- $secondStockItem = $productRepository->getById($secondProductId)->getExtensionAttributes()->getStockItem();
- $secondStockItem->setQty($secondProductQty);
- $stockItemRepository->save($secondStockItem);
- $this->assertEquals(
- $secondProductQty,
- $productRepository->getById($secondProductId)->getExtensionAttributes()->getStockItem()->getQty(),
- 'Precondition failed.'
- );
-
- /** @var \Magento\Framework\Api\Search\FilterGroup $searchCriteriaGroup */
- $searchCriteriaGroup = $objectManager->create('Magento\Framework\Api\Search\FilterGroup');
- /** @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria */
- $searchCriteria = $objectManager->create('Magento\Framework\Api\SearchCriteriaInterface');
- $searchCriteria->setFilterGroups([$searchCriteriaGroup]);
- $products = $productRepository->getList($searchCriteria)->getItems();
-
- /** Ensure that simple extension attributes were populated correctly */
- $this->assertEquals(
- $firstProductQty,
- $products[$firstProductId]->getExtensionAttributes()->getTestStockItemQty()
- );
- $this->assertEquals(
- $secondProductQty,
- $products[$secondProductId]->getExtensionAttributes()->getTestStockItemQty()
- );
-
- /** Check population of complex extension attributes */
- $this->assertEquals(
- $firstProductQty,
- $products[$firstProductId]->getExtensionAttributes()->getTestStockItem()->getQty()
- );
- $this->assertNotEmpty($products[$firstProductId]->getExtensionAttributes()->getTestStockItem()->getItemId());
-
- $this->assertArrayNotHasKey(
- 'extension_attribute_test_stock_item_qty_qty',
- $products[$firstProductId]->getData(),
- "Selected extension field should be unset after it is added to extension attributes object."
- );
- }
-
- /**
- * @magentoDataFixture Magento/Customer/_files/customer.php
- * @magentoDataFixture Magento/Customer/_files/customer_group.php
- */
- public function testGetListWithExtensionAttributesAbstractObject()
- {
- $customerId = 1;
- $customerGroupName = 'General';
- $taxClassId = 3;
- /** @var \Magento\Framework\ObjectManagerInterface */
- $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
- /** @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository */
- $customerRepository = $objectManager->get('Magento\Customer\Api\CustomerRepositoryInterface');
- /** @var \Magento\Framework\Api\Search\FilterGroup $searchCriteriaGroup */
- $searchCriteriaGroup = $objectManager->create('Magento\Framework\Api\Search\FilterGroup');
- /** @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria */
- $searchCriteria = $objectManager->create('Magento\Framework\Api\SearchCriteriaInterface');
- $searchCriteria->setFilterGroups([$searchCriteriaGroup]);
- $customers = $customerRepository->getList($searchCriteria)->getItems();
-
- /** Ensure that simple extension attributes were populated correctly */
- $customer = $customers[0];
- $this->assertEquals($customerId, $customer->getId(), 'Precondition failed');
- $this->assertEquals($customerGroupName, $customer->getExtensionAttributes()->getTestGroupCode());
-
- /** Check population of complex extension attributes */
- $this->assertEquals($taxClassId, $customer->getExtensionAttributes()->getTestGroup()->getTaxClassId());
- $this->assertEquals($customerGroupName, $customer->getExtensionAttributes()->getTestGroup()->getCode());
- }
-
public function testCreateWithLogicException()
{
$this->setExpectedException(
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/extension_attributes.xml b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/extension_attributes.xml
index 4b47d317898ab..6b79d122ab836 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/extension_attributes.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/extension_attributes.xml
@@ -16,7 +16,7 @@
join_on_field="id"
reference_field="id"
>
- qty
+ qty
@@ -24,9 +24,9 @@
reference_field="product_id"
join_on_field="id"
>
- comment
- rating
- date
+ comment
+ rating
+ date
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/etc/extension_attributes.xml b/dev/tests/integration/testsuite/Magento/Framework/Api/etc/extension_attributes.xml
index 68bc09b6590be..6f5910737fe47 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/etc/extension_attributes.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/etc/extension_attributes.xml
@@ -16,8 +16,8 @@
join_on_field="entity_id"
reference_field="product_id"
>
- qty
- item_id
+ qty
+ item_id
@@ -28,17 +28,18 @@
join_on_field="entity_id"
reference_field="product_id"
>
- qty
+ qty
+
- customer_group_code
+ customer_group_code
@@ -46,8 +47,39 @@
join_on_field="group_id"
reference_field="customer_group_id"
>
- tax_class_id
- customer_group_code
+ tax_class_id
+ code
+
+
+
+
+
+
+
+ attribute_code
+
+
+
+
+ attribute_code
+ frontend_label
+
+
+
+
+
+
+
+ attribute_code
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php b/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php
index 17eaeb9c4eb94..bd9f8528bc1d7 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php
@@ -11,7 +11,13 @@ class RemoveTest extends \PHPUnit_Framework_TestCase
{
public function testRemove()
{
- $composerApp = $this->getMock('Composer\Console\Application', [], [], '', false);
+ $composerApp = $this->getMock(
+ 'Composer\Console\Application',
+ ['setAutoExit', 'resetComposer', 'run'],
+ [],
+ '',
+ false
+ );
$directoryList = $this->getMock('Magento\Framework\App\Filesystem\DirectoryList', [], [], '', false);
$directoryList->expects($this->once())->method('getRoot');
$directoryList->expects($this->once())
diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/Quote/Item/RepositoryTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/Quote/Item/RepositoryTest.php
new file mode 100644
index 0000000000000..b7e78e977191f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Quote/Model/Quote/Item/RepositoryTest.php
@@ -0,0 +1,40 @@
+ 'firstname',
+ 'lastname' => 'lastname',
+ 'email' => 'admin@example.com'
+ ];
+
+ /** @var \Magento\Quote\Model\Quote\Item\Repository $quoteItemRepository */
+ $quoteItemRepository = Bootstrap::getObjectManager()->create('Magento\Quote\Model\Quote\Item\Repository');
+ /** @var \Magento\Quote\Model\Quote $quote */
+ $quote = Bootstrap::getObjectManager()->create('Magento\Quote\Model\Quote');
+ $quoteId = $quote->load('test01', 'reserved_order_id')->getId();
+
+ /** @var \Magento\Quote\Api\Data\CartItemInterface[] $quoteItems */
+ $quoteItems = $quoteItemRepository->getList($quoteId);
+ /** @var \Magento\Quote\Api\Data\CartItemInterface $actualQuoteItem */
+ $actualQuoteItem = array_pop($quoteItems);
+ $this->assertInstanceOf('Magento\Quote\Api\Data\CartItemInterface', $actualQuoteItem);
+ /** @var \Magento\User\Api\Data\UserInterface $testAttribute */
+ $testAttribute = $actualQuoteItem->getExtensionAttributes()->getQuoteItemTestAttribute();
+ $this->assertEquals($expectedExtensionAttributes['firstname'], $testAttribute->getFirstName());
+ $this->assertEquals($expectedExtensionAttributes['lastname'], $testAttribute->getLastName());
+ $this->assertEquals($expectedExtensionAttributes['email'], $testAttribute->getEmail());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php
new file mode 100644
index 0000000000000..0d7b1ea35f3b7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php
@@ -0,0 +1,40 @@
+ 'firstname',
+ 'lastname' => 'lastname',
+ 'email' => 'admin@example.com'
+ ];
+
+ /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder */
+ $searchCriteriaBuilder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\SearchCriteriaBuilder');
+
+ /** @var \Magento\Quote\Model\QuoteRepository $quoteRepository */
+ $quoteRepository = Bootstrap::getObjectManager()->create('Magento\Quote\Model\QuoteRepository');
+ $searchResult = $quoteRepository->getList($searchCriteriaBuilder->create());
+ $items = $searchResult->getItems();
+ /** @var \Magento\Quote\Api\Data\CartInterface $actualQuote */
+ $actualQuote = array_pop($items);
+ $this->assertInstanceOf('Magento\Quote\Api\Data\CartInterface', $actualQuote);
+ $this->assertEquals('test01', $actualQuote->getReservedOrderId());
+ /** @var \Magento\User\Api\Data\UserInterface $testAttribute */
+ $testAttribute = $actualQuote->getExtensionAttributes()->getQuoteTestAttribute();
+ $this->assertEquals($expectedExtensionAttributes['firstname'], $testAttribute->getFirstName());
+ $this->assertEquals($expectedExtensionAttributes['lastname'], $testAttribute->getLastName());
+ $this->assertEquals($expectedExtensionAttributes['email'], $testAttribute->getEmail());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Quote/etc/extension_attributes.xml b/dev/tests/integration/testsuite/Magento/Quote/etc/extension_attributes.xml
new file mode 100644
index 0000000000000..b71757a71adde
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Quote/etc/extension_attributes.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ firstname
+ lastname
+ email
+
+
+
+
+
+
+ firstname
+ lastname
+ email
+
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/RepositoryTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/RepositoryTest.php
index b9c4925d392fa..a38ef69ab30ed 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/RepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/RepositoryTest.php
@@ -112,6 +112,29 @@ public function testGet()
$this->assertEquals(TaxClassManagementInterface::TYPE_CUSTOMER, $data->getClassType());
}
+ /**
+ * @magentoDbIsolation enabled
+ */
+ public function testGetList()
+ {
+ $taxClassName = 'Get Me';
+ $taxClassDataObject = $this->taxClassFactory->create();
+ $taxClassDataObject->setClassName($taxClassName)
+ ->setClassType(TaxClassManagementInterface::TYPE_CUSTOMER);
+ $taxClassId = $this->taxClassRepository->save($taxClassDataObject);
+ /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder */
+ $searchCriteriaBuilder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\SearchCriteriaBuilder');
+ /** @var \Magento\Tax\Api\Data\TaxClassSearchResultsInterface */
+ $searchResult = $this->taxClassRepository->getList($searchCriteriaBuilder->create());
+ $items = $searchResult->getItems();
+ /** @var \Magento\Tax\Api\Data\TaxClassInterface */
+ $taxClass = array_pop($items);
+ $this->assertInstanceOf('Magento\Tax\Api\Data\TaxClassInterface', $taxClass);
+ $this->assertEquals($taxClassName, $taxClass->getClassName());
+ $this->assertEquals($taxClassId, $taxClass->getClassId());
+ $this->assertEquals(TaxClassManagementInterface::TYPE_CUSTOMER, $taxClass->getClassType());
+ }
+
/**
* @expectedException \Magento\Framework\Exception\NoSuchEntityException
* @expectedExceptionMessage No such entity with class_id = -9999
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index 6ab58f1aa7740..ac58d760d24f1 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -2123,6 +2123,16 @@
'Magento\Customer\Controller\Account\LoginPost',
'Magento\Customer\Model\Account\Redirect::getRedirect',
],
+ [
+ 'process',
+ 'Magento\Framework\Api\ExtensionAttributesFactory',
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessor::process'
+ ],
+ [
+ 'extractExtensionAttributes',
+ 'Magento\Framework\Api\ExtensionAttributesFactory',
+ 'Magento\Framework\Api\ExtensionAttribute\JoinProcessor::extractExtensionAttributes'
+ ],
['isReviewOwner', 'Magento\Review\Block\Customer\View'],
['getRegistration', 'Magento\Customer\Block\Form\Login', 'Magento\Customer\Block\Form\Login\Info::getRegistration'],
['getCreateAccountUrl', 'Magento\Customer\Block\Form\Login', 'Magento\Customer\Block\Form\Login\Info::getCreateAccountUrl'],
diff --git a/lib/internal/Magento/Framework/Api/DataObjectHelper.php b/lib/internal/Magento/Framework/Api/DataObjectHelper.php
index 80e8587315bd5..2fb75d5f84161 100644
--- a/lib/internal/Magento/Framework/Api/DataObjectHelper.php
+++ b/lib/internal/Magento/Framework/Api/DataObjectHelper.php
@@ -35,6 +35,11 @@ class DataObjectHelper
*/
protected $extensionFactory;
+ /**
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $joinProcessor;
+
/**
* @var MethodsMap
*/
@@ -45,6 +50,7 @@ class DataObjectHelper
* @param \Magento\Framework\Reflection\DataObjectProcessor $objectProcessor
* @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor
* @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
* @param MethodsMap $methodsMapProcessor
*/
public function __construct(
@@ -52,16 +58,20 @@ public function __construct(
\Magento\Framework\Reflection\DataObjectProcessor $objectProcessor,
\Magento\Framework\Reflection\TypeProcessor $typeProcessor,
\Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor,
MethodsMap $methodsMapProcessor
) {
$this->objectFactory = $objectFactory;
$this->objectProcessor = $objectProcessor;
$this->typeProcessor = $typeProcessor;
$this->extensionFactory = $extensionFactory;
+ $this->joinProcessor = $joinProcessor;
$this->methodsMapProcessor = $methodsMapProcessor;
}
/**
+ * Populate data object using data in array format.
+ *
* @param mixed $dataObject
* @param array $data
* @param string $interfaceName
@@ -70,7 +80,7 @@ public function __construct(
public function populateWithArray($dataObject, array $data, $interfaceName)
{
if ($dataObject instanceof ExtensibleDataInterface) {
- $data = $this->extensionFactory->extractExtensionAttributes(get_class($dataObject), $data);
+ $data = $this->joinProcessor->extractExtensionAttributes(get_class($dataObject), $data);
}
$this->_setDataValues($dataObject, $data, $interfaceName);
return $this;
diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttribute/Config/Converter.php b/lib/internal/Magento/Framework/Api/ExtensionAttribute/Config/Converter.php
index f4e9df7cd643a..64fb32ecdf166 100644
--- a/lib/internal/Magento/Framework/Api/ExtensionAttribute/Config/Converter.php
+++ b/lib/internal/Magento/Framework/Api/ExtensionAttribute/Config/Converter.php
@@ -9,13 +9,15 @@ class Converter implements \Magento\Framework\Config\ConverterInterface
{
const RESOURCE_PERMISSIONS = "resourceRefs";
const DATA_TYPE = "type";
+
const JOIN_DIRECTIVE = "join";
const JOIN_REFERENCE_TABLE = "join_reference_table";
const JOIN_REFERENCE_FIELD = "join_reference_field";
- const JOIN_SELECT_FIELDS = "join_select_fields";
- const JOIN_SELECT_FIELD = "select_field";
- const JOIN_SELECT_FIELD_SETTER = "setter_name";
- const JOIN_JOIN_ON_FIELD= "join_join_on_field";
+ const JOIN_ON_FIELD= "join_on_field";
+
+ const JOIN_FIELDS = "fields";
+ const JOIN_FIELD = "field";
+ const JOIN_FIELD_COLUMN = "column";
/**
* Convert dom node tree to array
@@ -83,16 +85,15 @@ private function processJoinElement($joinElement, $attribute)
$joinAttributes = $joinElement->attributes;
$join = [
self::JOIN_REFERENCE_TABLE => $joinAttributes->getNamedItem('reference_table')->nodeValue,
- self::JOIN_JOIN_ON_FIELD => $joinAttributes->getNamedItem('join_on_field')->nodeValue,
+ self::JOIN_ON_FIELD => $joinAttributes->getNamedItem('join_on_field')->nodeValue,
self::JOIN_REFERENCE_FIELD => $joinAttributes->getNamedItem('reference_field')->nodeValue,
];
- $selectElements = $attribute->getElementsByTagName('select_field');
- foreach ($selectElements as $selectElement) {
- $selectField = $selectElement->nodeValue;
- $setterName = $selectElement->getAttribute('setter_name');
- $join[self::JOIN_SELECT_FIELDS][] = [
- self::JOIN_SELECT_FIELD => $selectField,
- self::JOIN_SELECT_FIELD_SETTER => $setterName
+ $fields = $attribute->getElementsByTagName('field');
+ foreach ($fields as $field) {
+ $column = $field->getAttribute('column');
+ $join[self::JOIN_FIELDS][] = [
+ self::JOIN_FIELD => $field->nodeValue,
+ self::JOIN_FIELD_COLUMN => $column
];
}
}
diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinData.php b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinData.php
index 6457c79d1e145..27200762555b6 100644
--- a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinData.php
+++ b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinData.php
@@ -11,8 +11,13 @@
*
* @codeCoverageIgnore
*/
-class JoinData
+class JoinData implements JoinDataInterface
{
+ /**
+ * @var string
+ */
+ private $attributeCode;
+
/**
* @var string
*/
@@ -39,9 +44,24 @@ class JoinData
private $selectFields;
/**
- * Get reference table name.
- *
- * @return string
+ * {@inheritdoc}
+ */
+ public function getAttributeCode()
+ {
+ return $this->attributeCode;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAttributeCode($attributeCode)
+ {
+ $this->attributeCode = $attributeCode;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
*/
public function getReferenceTable()
{
@@ -49,10 +69,7 @@ public function getReferenceTable()
}
/**
- * Set reference table name.
- *
- * @param string $referenceTable
- * @return $this
+ * {@inheritdoc}
*/
public function setReferenceTable($referenceTable)
{
@@ -61,9 +78,7 @@ public function setReferenceTable($referenceTable)
}
/**
- * Get reference table alias.
- *
- * @return string
+ * {@inheritdoc}
*/
public function getReferenceTableAlias()
{
@@ -71,10 +86,7 @@ public function getReferenceTableAlias()
}
/**
- * Set reference table alias.
- *
- * @param string $referenceTableAlias
- * @return $this
+ * {@inheritdoc}
*/
public function setReferenceTableAlias($referenceTableAlias)
{
@@ -83,9 +95,7 @@ public function setReferenceTableAlias($referenceTableAlias)
}
/**
- * Get reference field.
- *
- * @return string
+ * {@inheritdoc}
*/
public function getReferenceField()
{
@@ -93,10 +103,7 @@ public function getReferenceField()
}
/**
- * Set reference field.
- *
- * @param string $referenceField
- * @return $this
+ * {@inheritdoc}
*/
public function setReferenceField($referenceField)
{
@@ -105,9 +112,7 @@ public function setReferenceField($referenceField)
}
/**
- * Get join field.
- *
- * @return string
+ * {@inheritdoc}
*/
public function getJoinField()
{
@@ -115,10 +120,7 @@ public function getJoinField()
}
/**
- * Set join field.
- *
- * @param string $joinField
- * @return $this
+ * {@inheritdoc}
*/
public function setJoinField($joinField)
{
@@ -127,9 +129,7 @@ public function setJoinField($joinField)
}
/**
- * Get select fields.
- *
- * @return string[]
+ * {@inheritdoc}
*/
public function getSelectFields()
{
@@ -137,10 +137,7 @@ public function getSelectFields()
}
/**
- * Set select field.
- *
- * @param string[] $selectFields
- * @return $this
+ * {@inheritdoc}
*/
public function setSelectFields(array $selectFields)
{
diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinDataInterface.php b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinDataInterface.php
new file mode 100644
index 0000000000000..91000c4e62e29
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinDataInterface.php
@@ -0,0 +1,108 @@
+_objectManager = $objectManager;
$this->_instanceName = $instanceName;
diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessor.php b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessor.php
new file mode 100644
index 0000000000000..dbe83d1d343a2
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessor.php
@@ -0,0 +1,258 @@
+objectManager = $objectManager;
+ $this->config = $config;
+ $this->extensionAttributeJoinDataFactory = $extensionAttributeJoinDataFactory;
+ $this->typeProcessor = $typeProcessor;
+ $this->extensionAttributesFactory = $extensionAttributesFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function process(DbCollection $collection, $extensibleEntityClass = null)
+ {
+ $extensibleEntityClass = $extensibleEntityClass ?: $collection->getItemObjectClass();
+ $joinDirectives = $this->getJoinDirectivesForType($extensibleEntityClass);
+ foreach ($joinDirectives as $attributeCode => $directive) {
+ /** @var JoinDataInterface $joinData */
+ $joinData = $this->extensionAttributeJoinDataFactory->create();
+ $joinData->setAttributeCode($attributeCode)
+ ->setReferenceTable($directive[Converter::JOIN_REFERENCE_TABLE])
+ ->setReferenceTableAlias($this->getReferenceTableAlias($attributeCode))
+ ->setReferenceField($directive[Converter::JOIN_REFERENCE_FIELD])
+ ->setJoinField($directive[Converter::JOIN_ON_FIELD]);
+ $joinData->setSelectFields(
+ $this->getSelectFieldsMap($attributeCode, $directive[Converter::JOIN_FIELDS])
+ );
+ $collection->joinExtensionAttribute($joinData, $this);
+ }
+ }
+
+ /**
+ * Generate a list of select fields with mapping of client facing attribute names to field names used in SQL select.
+ *
+ * @param string $attributeCode
+ * @param array $selectFields
+ * @return array
+ */
+ private function getSelectFieldsMap($attributeCode, $selectFields)
+ {
+ $referenceTableAlias = $this->getReferenceTableAlias($attributeCode);
+ $useFieldInAlias = (count($selectFields) > 1);
+ $selectFieldsAliases = [];
+ foreach ($selectFields as $selectField) {
+ $internalFieldName = $selectField[Converter::JOIN_FIELD_COLUMN]
+ ? $selectField[Converter::JOIN_FIELD_COLUMN]
+ : $selectField[Converter::JOIN_FIELD];
+ $setterName = 'set'
+ . ucfirst(SimpleDataObjectConverter::snakeCaseToCamelCase($selectField[Converter::JOIN_FIELD]));
+ $selectFieldsAliases[] = [
+ JoinDataInterface::SELECT_FIELD_EXTERNAL_ALIAS => $attributeCode
+ . ($useFieldInAlias ? '.' . $selectField[Converter::JOIN_FIELD] : ''),
+ JoinDataInterface::SELECT_FIELD_INTERNAL_ALIAS => $referenceTableAlias . '_' . $internalFieldName,
+ JoinDataInterface::SELECT_FIELD_WITH_DB_PREFIX => $referenceTableAlias . '.' . $internalFieldName,
+ JoinDataInterface::SELECT_FIELD_SETTER => $setterName
+ ];
+ }
+ return $selectFieldsAliases;
+ }
+
+ /**
+ * Generate reference table alias.
+ *
+ * @param string $attributeCode
+ * @return string
+ */
+ private function getReferenceTableAlias($attributeCode)
+ {
+ return 'extension_attribute_' . $attributeCode;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function extractExtensionAttributes($extensibleEntityClass, array $data)
+ {
+ if (!$this->isExtensibleAttributesImplemented($extensibleEntityClass)) {
+ /* do nothing as there are no extension attributes */
+ return $data;
+ }
+
+ $joinDirectives = $this->getJoinDirectivesForType($extensibleEntityClass);
+ $extensionData = [];
+ foreach ($joinDirectives as $attributeCode => $directive) {
+ $this->populateAttributeCodeWithDirective(
+ $attributeCode,
+ $directive,
+ $data,
+ $extensionData,
+ $extensibleEntityClass
+ );
+ }
+ if (!empty($extensionData)) {
+ $extensionAttributes = $this->extensionAttributesFactory->create($extensibleEntityClass, $extensionData);
+ $data[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY] = $extensionAttributes;
+ }
+ return $data;
+ }
+
+ /**
+ * Populate a specific attribute code with join directive instructions.
+ *
+ * @param string $attributeCode
+ * @param array $directive
+ * @param array &$data
+ * @param array &$extensionData
+ * @param string $extensibleEntityClass
+ * @return void
+ */
+ private function populateAttributeCodeWithDirective(
+ $attributeCode,
+ $directive,
+ &$data,
+ &$extensionData,
+ $extensibleEntityClass
+ ) {
+ $attributeType = $directive[Converter::DATA_TYPE];
+ $selectFields = $this->getSelectFieldsMap($attributeCode, $directive[Converter::JOIN_FIELDS]);
+ foreach ($selectFields as $selectField) {
+ $internalAlias = $selectField[JoinDataInterface::SELECT_FIELD_INTERNAL_ALIAS];
+ if (isset($data[$internalAlias])) {
+ if ($this->typeProcessor->isArrayType($attributeType)) {
+ throw new \LogicException(
+ sprintf(
+ 'Join directives cannot be processed for attribute (%s) of extensible entity (%s),'
+ . ' which has an Array type (%s).',
+ $attributeCode,
+ $this->extensionAttributesFactory->getExtensibleInterfaceName($extensibleEntityClass),
+ $attributeType
+ )
+ );
+ } elseif ($this->typeProcessor->isTypeSimple($attributeType)) {
+ $extensionData['data'][$attributeCode] = $data[$internalAlias];
+ unset($data[$internalAlias]);
+ break;
+ } else {
+ if (!isset($extensionData['data'][$attributeCode])) {
+ $extensionData['data'][$attributeCode] = $this->objectManager->create($attributeType);
+ }
+ $setterName = $selectField[JoinDataInterface::SELECT_FIELD_SETTER];
+ $extensionData['data'][$attributeCode]->$setterName($data[$internalAlias]);
+ unset($data[$internalAlias]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the internal join directive config for a given type.
+ *
+ * Array returned has all of the \Magento\Framework\Api\ExtensionAttribute\Config\Converter JOIN* fields set.
+ *
+ * @param string $extensibleEntityClass
+ * @return array
+ */
+ private function getJoinDirectivesForType($extensibleEntityClass)
+ {
+ $extensibleInterfaceName = $this->extensionAttributesFactory
+ ->getExtensibleInterfaceName($extensibleEntityClass);
+ $extensibleInterfaceName = ltrim($extensibleInterfaceName, '\\');
+ $config = $this->config->get();
+ if (!isset($config[$extensibleInterfaceName])) {
+ return [];
+ }
+
+ $typeAttributesConfig = $config[$extensibleInterfaceName];
+ $joinDirectives = [];
+ foreach ($typeAttributesConfig as $attributeCode => $attributeConfig) {
+ if (isset($attributeConfig[Converter::JOIN_DIRECTIVE])) {
+ $joinDirectives[$attributeCode] = $attributeConfig[Converter::JOIN_DIRECTIVE];
+ $joinDirectives[$attributeCode][Converter::DATA_TYPE] = $attributeConfig[Converter::DATA_TYPE];
+ }
+ }
+
+ return $joinDirectives;
+ }
+
+ /**
+ * Determine if the type is an actual extensible data interface.
+ *
+ * @param string $typeName
+ * @return bool
+ */
+ private function isExtensibleAttributesImplemented($typeName)
+ {
+ try {
+ $this->extensionAttributesFactory->getExtensibleInterfaceName($typeName);
+ return true;
+ } catch (\LogicException $e) {
+ return false;
+ }
+ }
+}
diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessorInterface.php b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessorInterface.php
new file mode 100644
index 0000000000000..6b9c47b6d10fc
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessorInterface.php
@@ -0,0 +1,38 @@
+objectManager = $objectManager;
- $this->config = $config;
- $this->extensionAttributeJoinDataFactory = $extensionAttributeJoinDataFactory;
- $this->typeProcessor = $typeProcessor;
}
/**
@@ -110,155 +77,13 @@ public function create($extensibleClassName, $data = [])
return $extensionFactory->create($data);
}
- /**
- * Processes join instructions to add to the collection for a data interface.
- *
- * @param DbCollection $collection
- * @param string $extensibleEntityClass
- * @return void
- */
- public function process(DbCollection $collection, $extensibleEntityClass)
- {
- $joinDirectives = $this->getJoinDirectivesForType($extensibleEntityClass);
- foreach ($joinDirectives as $attributeCode => $directive) {
- /** @var JoinData $joinData */
- $joinData = $this->extensionAttributeJoinDataFactory->create();
- $joinData->setReferenceTable($directive[Converter::JOIN_REFERENCE_TABLE])
- ->setReferenceTableAlias('extension_attribute_' . $attributeCode)
- ->setReferenceField($directive[Converter::JOIN_REFERENCE_FIELD])
- ->setJoinField($directive[Converter::JOIN_JOIN_ON_FIELD]);
- $selectFieldsMapper = function ($selectFieldData) {
- return $selectFieldData[Converter::JOIN_SELECT_FIELD];
- };
- $joinData->setSelectFields(array_map($selectFieldsMapper, $directive[Converter::JOIN_SELECT_FIELDS]));
- $collection->joinExtensionAttribute($joinData, [$this, 'extractExtensionAttributes']);
- }
- }
-
- /**
- * Extract extension attributes into separate extension object.
- *
- * @param string $extensibleEntityClass
- * @param array $data
- * @return array
- * @throws \LogicException
- */
- public function extractExtensionAttributes($extensibleEntityClass, array $data)
- {
- if (!$this->isExtensibleAttributesImplemented($extensibleEntityClass)) {
- /* do nothing as there are no extension attributes */
- return $data;
- }
-
- $joinDirectives = $this->getJoinDirectivesForType($extensibleEntityClass);
- $extensionData = [];
- foreach ($joinDirectives as $attributeCode => $directive) {
- $this->populateAttributeCodeWithDirective(
- $attributeCode,
- $directive,
- $data,
- $extensionData,
- $extensibleEntityClass
- );
- }
- if (!empty($extensionData)) {
- $extensionAttributes = $this->create($extensibleEntityClass, $extensionData);
- $data[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY] = $extensionAttributes;
- }
- return $data;
- }
-
- /**
- * Populate a specific attribute code with join directive instructions.
- *
- * @param string $attributeCode
- * @param array $directive
- * @param array &$data
- * @param array &$extensionData
- * @param string $extensibleEntityClass
- * @return void
- */
- private function populateAttributeCodeWithDirective(
- $attributeCode,
- $directive,
- &$data,
- &$extensionData,
- $extensibleEntityClass
- ) {
- $attributeType = $directive[Converter::DATA_TYPE];
- $selectFields = $directive[Converter::JOIN_SELECT_FIELDS];
- foreach ($selectFields as $selectField) {
- $selectFieldAlias = 'extension_attribute_' . $attributeCode
- . '_' . $selectField[Converter::JOIN_SELECT_FIELD];
- if (isset($data[$selectFieldAlias])) {
- if ($this->typeProcessor->isArrayType($attributeType)) {
- throw new \LogicException(
- sprintf(
- 'Join directives cannot be processed for attribute (%s) of extensible entity (%s),'
- . ' which has an Array type (%s).',
- $attributeCode,
- $this->getExtensibleInterfaceName($extensibleEntityClass),
- $attributeType
- )
- );
- } elseif ($this->typeProcessor->isTypeSimple($attributeType)) {
- $extensionData['data'][$attributeCode] = $data[$selectFieldAlias];
- unset($data[$selectFieldAlias]);
- break;
- } else {
- if (!isset($extensionData['data'][$attributeCode])) {
- $extensionData['data'][$attributeCode] = $this->objectManager->create($attributeType);
- }
- $setterName = $selectField[Converter::JOIN_SELECT_FIELD_SETTER]
- ? $selectField[Converter::JOIN_SELECT_FIELD_SETTER]
- :'set' . ucfirst(
- SimpleDataObjectConverter::snakeCaseToCamelCase(
- $selectField[Converter::JOIN_SELECT_FIELD]
- )
- );
- $extensionData['data'][$attributeCode]->$setterName($data[$selectFieldAlias]);
- unset($data[$selectFieldAlias]);
- }
- }
- }
- }
-
- /**
- * Returns the internal join directive config for a given type.
- *
- * Array returned has all of the \Magento\Framework\Api\ExtensionAttribute\Config\Converter JOIN* fields set.
- *
- * @param string $extensibleEntityClass
- * @return array
- */
- private function getJoinDirectivesForType($extensibleEntityClass)
- {
- $extensibleInterfaceName = $this->getExtensibleInterfaceName($extensibleEntityClass);
- $extensibleInterfaceName = ltrim($extensibleInterfaceName, '\\');
- $config = $this->config->get();
- if (!isset($config[$extensibleInterfaceName])) {
- return [];
- }
-
- $typeAttributesConfig = $config[$extensibleInterfaceName];
- $joinDirectives = [];
- foreach ($typeAttributesConfig as $attributeCode => $attributeConfig) {
- if (isset($attributeConfig[Converter::JOIN_DIRECTIVE])) {
- $joinDirectives[$attributeCode] = $attributeConfig[Converter::JOIN_DIRECTIVE];
- $joinDirectives[$attributeCode][Converter::DATA_TYPE] = $attributeConfig[Converter::DATA_TYPE];
- }
- }
-
- return $joinDirectives;
- }
-
/**
* Identify concrete extensible interface name based on the class name.
*
* @param string $extensibleClassName
* @return string
*/
- private function getExtensibleInterfaceName($extensibleClassName)
+ public function getExtensibleInterfaceName($extensibleClassName)
{
$exceptionMessage = "Class '{$extensibleClassName}' must implement an interface, "
. "which extends from '" . self::EXTENSIBLE_INTERFACE_NAME . "'";
@@ -289,20 +114,4 @@ private function getExtensibleInterfaceName($extensibleClassName)
$this->classInterfaceMap[$extensibleClassName] = $notExtensibleClassFlag;
throw new \LogicException($exceptionMessage);
}
-
- /**
- * Determine if the type is an actual extensible data interface.
- *
- * @param string $typeName
- * @return bool
- */
- private function isExtensibleAttributesImplemented($typeName)
- {
- try {
- $this->getExtensibleInterfaceName($typeName);
- return true;
- } catch (\LogicException $e) {
- return false;
- }
- }
}
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
index 079ebbaec7832..484920c2a6740 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
@@ -44,14 +44,14 @@ class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
protected $attributeValueFactoryMock;
/**
- * @var \Magento\Framework\Api\ExtensionAttributesFactory|\PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Framework\Reflection\MethodsMap|\PHPUnit_Framework_MockObject_MockObject
*/
- protected $extensionFactoryMock;
+ protected $methodsMapProcessor;
/**
- * @var \Magento\Framework\Reflection\MethodsMap|\PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessor|\PHPUnit_Framework_MockObject_MockObject
*/
- protected $methodsMapProcessor;
+ protected $joinProcessorMock;
public function setUp()
{
@@ -69,22 +69,23 @@ public function setUp()
$this->attributeValueFactoryMock = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
->disableOriginalConstructor()
->getMock();
- $this->extensionFactoryMock = $this->getMockBuilder('Magento\Framework\Api\ExtensionAttributesFactory')
+ $this->joinProcessorMock = $this->getMockBuilder('\Magento\Framework\Api\ExtensionAttribute\JoinProcessor')
->setMethods(['extractExtensionAttributes'])
->disableOriginalConstructor()
->getMock();
- $this->extensionFactoryMock->expects($this->any())
+ $this->joinProcessorMock->expects($this->any())
->method('extractExtensionAttributes')
->willReturnArgument(1);
$this->typeProcessor = $this->objectManager->getObject('Magento\Framework\Reflection\TypeProcessor');
+
$this->dataObjectHelper = $this->objectManager->getObject(
'Magento\Framework\Api\DataObjectHelper',
[
'objectFactory' => $this->objectFactoryMock,
'typeProcessor' => $this->typeProcessor,
'objectProcessor' => $this->objectProcessorMock,
- 'extensionFactory' => $this->extensionFactoryMock,
'methodsMapProcessor' => $this->methodsMapProcessor,
+ 'joinProcessor' => $this->joinProcessorMock
]
);
}
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/ConverterTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/ConverterTest.php
index 46b46456c828a..dca3d3af4382f 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/ConverterTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/ConverterTest.php
@@ -105,13 +105,13 @@ public function testConvertWithJoinDirectives()
Converter::RESOURCE_PERMISSIONS => [],
Converter::JOIN_DIRECTIVE => [
Converter::JOIN_REFERENCE_TABLE => "library_account",
- Converter::JOIN_SELECT_FIELDS => [
+ Converter::JOIN_FIELDS => [
[
- Converter::JOIN_SELECT_FIELD => "library_card_id",
- Converter::JOIN_SELECT_FIELD_SETTER => ""
+ Converter::JOIN_FIELD => "library_card_id",
+ Converter::JOIN_FIELD_COLUMN => ""
]
],
- Converter::JOIN_JOIN_ON_FIELD => "id",
+ Converter::JOIN_ON_FIELD => "id",
Converter::JOIN_REFERENCE_FIELD => "customer_id",
],
],
@@ -120,17 +120,17 @@ public function testConvertWithJoinDirectives()
Converter::RESOURCE_PERMISSIONS => [],
Converter::JOIN_DIRECTIVE => [
Converter::JOIN_REFERENCE_TABLE => "reviews",
- Converter::JOIN_SELECT_FIELDS => [
+ Converter::JOIN_FIELDS => [
[
- Converter::JOIN_SELECT_FIELD => "comment",
- Converter::JOIN_SELECT_FIELD_SETTER => ""
+ Converter::JOIN_FIELD => "comment",
+ Converter::JOIN_FIELD_COLUMN => ""
],
[
- Converter::JOIN_SELECT_FIELD => "rating",
- Converter::JOIN_SELECT_FIELD_SETTER => ""
+ Converter::JOIN_FIELD => "rating",
+ Converter::JOIN_FIELD_COLUMN => ""
]
],
- Converter::JOIN_JOIN_ON_FIELD => "customer_id",
+ Converter::JOIN_ON_FIELD => "customer_id",
Converter::JOIN_REFERENCE_FIELD => "customer_id",
],
],
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/XsdTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/XsdTest.php
index c599760f5934f..9dab40a9ad26c 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/XsdTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/XsdTest.php
@@ -89,7 +89,7 @@ public function exemplarXmlDataProvider()
reference_field="customer_id"
join_on_field="id"
>
- library_card_id
+ library_card_id
@@ -107,7 +107,7 @@ public function exemplarXmlDataProvider()
reference_field="customer_id"
join_on_field="id"
>
- library_card_id
+ library_card_id
@@ -142,7 +142,7 @@ public function exemplarXmlDataProvider()
"Element 'join': The attribute 'reference_table' is required but missing.",
"Element 'join': The attribute 'join_on_field' is required but missing.",
"Element 'join': The attribute 'reference_field' is required but missing.",
- "Element 'join': Missing child element(s). Expected is ( select_field ).",
+ "Element 'join': Missing child element(s). Expected is ( field ).",
],
],
];
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/_files/extension_attributes_with_join_directives.xml b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/_files/extension_attributes_with_join_directives.xml
index bdf8f3920bb19..baacb34779535 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/_files/extension_attributes_with_join_directives.xml
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/_files/extension_attributes_with_join_directives.xml
@@ -12,7 +12,7 @@
reference_field="customer_id"
join_on_field="id"
>
- library_card_id
+ library_card_id
@@ -20,8 +20,8 @@
reference_field="customer_id"
join_on_field="customer_id"
>
- comment
- rating
+ comment
+ rating
diff --git a/lib/internal/Magento/Framework/Api/etc/extension_attributes.xsd b/lib/internal/Magento/Framework/Api/etc/extension_attributes.xsd
index 6bccd9b1643b0..ef21443cec8b4 100644
--- a/lib/internal/Magento/Framework/Api/etc/extension_attributes.xsd
+++ b/lib/internal/Magento/Framework/Api/etc/extension_attributes.xsd
@@ -41,13 +41,13 @@
-
+
-
+
diff --git a/lib/internal/Magento/Framework/Composer/Test/Unit/DependencyCheckerTest.php b/lib/internal/Magento/Framework/Composer/Test/Unit/DependencyCheckerTest.php
index 75b6239c776dd..46279d8fb1065 100644
--- a/lib/internal/Magento/Framework/Composer/Test/Unit/DependencyCheckerTest.php
+++ b/lib/internal/Magento/Framework/Composer/Test/Unit/DependencyCheckerTest.php
@@ -11,7 +11,13 @@ class DependencyCheckerTest extends \PHPUnit_Framework_TestCase
{
public function testCheckDependencies()
{
- $composerApp = $this->getMock('Composer\Console\Application', [], [], '', false);
+ $composerApp = $this->getMock(
+ 'Composer\Console\Application',
+ ['setAutoExit', 'resetComposer', 'run'],
+ [],
+ '',
+ false
+ );
$directoryList = $this->getMock('Magento\Framework\App\Filesystem\DirectoryList', [], [], '', false);
$directoryList->expects($this->exactly(2))->method('getRoot');
$composerApp->expects($this->once())->method('setAutoExit')->with(false);
@@ -44,7 +50,13 @@ function ($input, $buffer) {
public function testCheckDependenciesExcludeSelf()
{
- $composerApp = $this->getMock('Composer\Console\Application', [], [], '', false);
+ $composerApp = $this->getMock(
+ 'Composer\Console\Application',
+ ['setAutoExit', 'resetComposer', 'run'],
+ [],
+ '',
+ false
+ );
$directoryList = $this->getMock('Magento\Framework\App\Filesystem\DirectoryList', [], [], '', false);
$directoryList->expects($this->exactly(3))->method('getRoot');
$composerApp->expects($this->once())->method('setAutoExit')->with(false);
diff --git a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php
index e745a916a8092..3573fdb87f541 100755
--- a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php
+++ b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php
@@ -8,7 +8,8 @@
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;
-use Magento\Framework\Api\ExtensionAttribute\JoinData;
+use Magento\Framework\Api\ExtensionAttribute\JoinDataInterface;
+use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Psr\Log\LoggerInterface as Logger;
/**
@@ -87,11 +88,11 @@ abstract class AbstractDb extends \Magento\Framework\Data\Collection
private $_fetchStrategy;
/**
- * Flag which determines if extension attributes were joined before the collection was loaded.
+ * Join processor is set only if extension attributes were joined before the collection was loaded.
*
- * @var callable|null
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface|null
*/
- protected $extensionAttributesExtractorCallback;
+ protected $extensionAttributesJoinProcessor;
/**
* @param EntityFactoryInterface $entityFactory
@@ -743,7 +744,7 @@ protected function _reset()
$this->_setIsLoaded(false);
$this->_items = [];
$this->_data = null;
- $this->extensionAttributesExtractorCallback = null;
+ $this->extensionAttributesJoinProcessor = null;
return $this;
}
@@ -756,11 +757,11 @@ protected function _reset()
protected function _fetchAll(\Zend_Db_Select $select)
{
$data = $this->_fetchStrategy->fetchAll($select, $this->_bindParams);
- if ($this->extensionAttributesExtractorCallback && is_callable($this->extensionAttributesExtractorCallback)) {
+ if ($this->extensionAttributesJoinProcessor) {
foreach ($data as $key => $dataItem) {
- $data[$key] = call_user_func_array(
- $this->extensionAttributesExtractorCallback,
- [$this->_itemObjectClass, $dataItem]
+ $data[$key] = $this->extensionAttributesJoinProcessor->extractExtensionAttributes(
+ $this->_itemObjectClass,
+ $dataItem
);
}
}
@@ -812,32 +813,46 @@ protected function _initSelect()
/**
* Join extension attribute.
*
- * @param \Magento\Framework\Api\ExtensionAttribute\JoinData $join
- * @param callable $extensionAttributesExtractorCallback
+ * @param JoinDataInterface $join
+ * @param JoinProcessorInterface $extensionAttributesJoinProcessor
* @return $this
*/
- public function joinExtensionAttribute($join, $extensionAttributesExtractorCallback)
- {
+ public function joinExtensionAttribute(
+ JoinDataInterface $join,
+ JoinProcessorInterface $extensionAttributesJoinProcessor
+ ) {
$selectFrom = $this->getSelect()->getPart(\Zend_Db_Select::FROM);
$joinRequired = !isset($selectFrom[$join->getReferenceTableAlias()]);
if ($joinRequired) {
+ $joinOn = $this->getMainTableAlias() . '.' . $join->getJoinField()
+ . ' = ' . $join->getReferenceTableAlias() . '.' . $join->getReferenceField();
$this->getSelect()->joinLeft(
[$join->getReferenceTableAlias() => $this->getResource()->getTable($join->getReferenceTable())],
- $this->getMainTableAlias() . '.' . $join->getJoinField()
- . ' = ' . $join->getReferenceTableAlias() . '.' . $join->getReferenceField(),
+ $joinOn,
[]
);
}
$columns = [];
foreach ($join->getSelectFields() as $selectField) {
- $fieldAlias = $join->getReferenceTableAlias() . '_' . $selectField;
- $columns[$fieldAlias] = $join->getReferenceTableAlias() . '.' . $selectField;
+ $fieldWIthDbPrefix = $selectField[JoinDataInterface::SELECT_FIELD_WITH_DB_PREFIX];
+ $columns[$selectField[JoinDataInterface::SELECT_FIELD_INTERNAL_ALIAS]] = $fieldWIthDbPrefix;
+ $this->addFilterToMap($selectField[JoinDataInterface::SELECT_FIELD_EXTERNAL_ALIAS], $fieldWIthDbPrefix);
}
$this->getSelect()->columns($columns);
- $this->extensionAttributesExtractorCallback = $extensionAttributesExtractorCallback;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
return $this;
}
+ /**
+ * Get collection item object class name.
+ *
+ * @return string
+ */
+ public function getItemObjectClass()
+ {
+ return $this->_itemObjectClass;
+ }
+
/**
* Identify main table alias or its name if alias is not defined.
*
diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
index 22857fcf9bcfa..496ba2e8d173a 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
@@ -73,6 +73,19 @@ protected function _getClassProperties()
],
]
],
+ [
+ 'name' => 'extensionAttributesJoinProcessor',
+ 'visibility' => 'protected',
+ 'docblock' => [
+ 'shortDescription' => 'Extension attributes join processor.',
+ 'tags' => [
+ [
+ 'name' => 'var',
+ 'description' => '\Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
+ ],
+ ],
+ ]
+ ],
];
return $properties;
}
@@ -138,13 +151,18 @@ protected function _getDefaultConstructorDefinition()
'name' => $this->_getSourceCollectionFactoryPropertyName(),
'type' => $this->_getCollectionFactoryClassName(),
],
+ [
+ 'name' => 'extensionAttributesJoinProcessor',
+ 'type' => '\Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
+ ],
],
'body' => "\$this->"
. $this->_getSourcePersistorPropertyName()
. " = \$" . $this->_getSourcePersistorPropertyName() . ";\n"
. "\$this->"
. $this->_getSourceCollectionFactoryPropertyName()
- . " = \$" . $this->_getSourceCollectionFactoryPropertyName() . ";"
+ . " = \$" . $this->_getSourceCollectionFactoryPropertyName() . ";\n"
+ . "\$this->extensionAttributesJoinProcessor = \$extensionAttributesJoinProcessor;"
,
'docblock' => [
'shortDescription' => ucfirst(static::ENTITY_TYPE) . ' constructor',
@@ -158,6 +176,11 @@ protected function _getDefaultConstructorDefinition()
'description' => $this->_getCollectionFactoryClassName()
. " \$" . $this->_getSourceCollectionFactoryPropertyName()
],
+ [
+ 'name' => 'param',
+ 'description' => '\Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface'
+ . " \$extensionAttributesJoinProcessor"
+ ],
],
]
];
@@ -362,6 +385,10 @@ protected function _getDeleteMethod()
'name' => 'param',
'description' => $this->getSourceClassName() . ' $entity',
],
+ [
+ 'name' => 'return',
+ 'description' => 'bool',
+ ],
],
]
];
@@ -393,6 +420,10 @@ protected function _getDeleteByIdMethod()
'name' => 'param',
'description' => 'int $id',
],
+ [
+ 'name' => 'return',
+ 'description' => 'bool',
+ ],
],
]
];
@@ -428,14 +459,15 @@ protected function _getRemoveMethod()
}
/**
- * Returns find() method
+ * Returns getList() method
*
* @return string
*/
protected function _getGetListMethod()
{
$body = "\$collection = \$this->" . $this->_getSourceCollectionFactoryPropertyName() . "->create();\n"
- . "foreach(\$criteria->getFilterGroups() as \$filterGroup) {\n"
+ . "\$this->extensionAttributesJoinProcessor->process(\$collection);\n"
+ . "foreach (\$criteria->getFilterGroups() as \$filterGroup) {\n"
. " foreach (\$filterGroup->getFilters() as \$filter) {\n"
. " \$condition = \$filter->getConditionType() ? \$filter->getConditionType() : 'eq';\n"
. " \$collection->addFieldToFilter(\$filter->getField(), [\$condition => \$filter->getValue()]);\n"
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/GenerateRepositoryTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/GenerateRepositoryTest.php
index 33ff3368e02de..a2744ca17becd 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/GenerateRepositoryTest.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/GenerateRepositoryTest.php
@@ -58,8 +58,12 @@ public function testGenerate()
->with('\Magento\Framework\ObjectManager\Code\Generator\SampleRepository')
->willReturn('SampleRepository.php');
+ $repositoryCode = file_get_contents(__DIR__ . '/_files/SampleRepository.txt');
+ $this->ioObjectMock->expects($this->once())->method('writeResultFile')
+ ->with('SampleRepository.php', $repositoryCode);
+
$model->expects($this->once())->method('_validateData')->willReturn(true);
- $this->assertEquals('SampleRepository.php', $model->generate());
+ $this->assertEquals('SampleRepository.php', $model->generate(), "Generated repository is invalid.");
}
/**
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt
index 4b1ee7b010837..d135ca64dd1fc 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt
@@ -1,7 +1,7 @@
namespace Magento\Framework\ObjectManager\Code\Generator;
/**
- * Repository class for
+ * Repository class for @see
* \Magento\Framework\ObjectManager\Code\Generator\SampleInterface
*/
class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generator\SampleRepositoryInterface
@@ -22,7 +22,7 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato
protected $sampleInterfaceSearchResultFactory = null;
/**
- * Magento\Framework\ObjectManager\Code\Generator\SampleInterface[]
+ * \Magento\Framework\ObjectManager\Code\Generator\SampleInterface[]
*
* @var array
*/
@@ -30,6 +30,13 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato
);
+ /**
+ * Extension attributes join processor.
+ *
+ * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ */
+ protected $extensionAttributesJoinProcessor = null;
+
/**
* Repository constructor
*
@@ -38,11 +45,14 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato
* @param
* \Magento\Framework\ObjectManager\Code\Generator\SampleSearchResultInterfaceFactory
* $sampleInterfaceSearchResultFactory
+ * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
+ * $extensionAttributesJoinProcessor
*/
- public function __construct(\Magento\Framework\ObjectManager\Code\Generator\SampleInterfacePersistor $sampleInterfacePersistor, \Magento\Framework\ObjectManager\Code\Generator\SampleSearchResultInterfaceFactory $sampleInterfaceSearchResultFactory)
+ public function __construct(\Magento\Framework\ObjectManager\Code\Generator\SampleInterfacePersistor $sampleInterfacePersistor, \Magento\Framework\ObjectManager\Code\Generator\SampleSearchResultInterfaceFactory $sampleInterfaceSearchResultFactory, \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor)
{
$this->sampleInterfacePersistor = $sampleInterfacePersistor;
$this->sampleInterfaceSearchResultFactory = $sampleInterfaceSearchResultFactory;
+ $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}
/**
@@ -53,13 +63,13 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
- public function get($id, $arguments = array())
+ public function get($id)
{
if (!$id) {
throw new \Magento\Framework\Exception\InputException('ID required');
}
if (!isset($this->registry[$id])) {
- $entity = $this->sampleInterfacePersistor->loadEntity($id, $arguments);
+ $entity = $this->sampleInterfacePersistor->loadEntity($id);
if (!$entity->getId()) {
throw new \Magento\Framework\Exception\NoSuchEntityException('Requested entity doesn\'t exist');
}
@@ -94,13 +104,13 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato
* Find entities by criteria
*
* @param \Magento\Framework\Api\SearchCriteria $criteria
- * @param array $arguments
- * @return \Magento\Framework\ObjectManager\Code\Generator\Sample[]
+ * @return \Magento\Framework\ObjectManager\Code\Generator\SampleInterface[]
*/
- public function find(\Magento\Framework\Api\SearchCriteria $criteria, $arguments = array())
+ public function getList(\Magento\Framework\Api\SearchCriteria $criteria)
{
$collection = $this->sampleInterfaceSearchResultFactory->create();
- foreach($criteria->getFilterGroups() as $filterGroup) {
+ $this->extensionAttributesJoinProcessor->process($collection);
+ foreach ($criteria->getFilterGroups() as $filterGroup) {
foreach ($filterGroup->getFilters() as $filter) {
$condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
$collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]);
@@ -125,11 +135,25 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato
* Register entity to delete
*
* @param \Magento\Framework\ObjectManager\Code\Generator\SampleInterface $entity
+ * @return bool
+ */
+ public function delete(\Magento\Framework\ObjectManager\Code\Generator\SampleInterface $entity)
+ {
+ $this->sampleInterfacePersistor->registerDeleted($entity);
+ return $this->sampleInterfacePersistor->doPersistEntity($entity);
+ }
+
+ /**
+ * Delete entity by Id
+ *
+ * @param int $id
+ * @return bool
*/
- public function delete(\Magento\Framework\ObjectManager\Code\Generator\SampleInterface $entity, $arguments = array())
+ public function deleteById($id)
{
+ $entity = $this->get($id);
$this->sampleInterfacePersistor->registerDeleted($entity);
- $this->sampleInterfacePersistor->save($entity);
+ return $this->sampleInterfacePersistor->doPersistEntity($entity);
}
/**
@@ -147,9 +171,11 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato
* Perform persist operations for one entity
*
* @param \Magento\Framework\ObjectManager\Code\Generator\SampleInterface $entity
+ * @return \Magento\Framework\ObjectManager\Code\Generator\SampleInterface
*/
- public function save(\Magento\Framework\ObjectManager\Code\Generator\SampleInterface $entity, $arguments = array())
+ public function save(\Magento\Framework\ObjectManager\Code\Generator\SampleInterface $entity)
{
- return $this->sampleInterfacePersistor->doPersistEntity($entity);
+ $this->sampleInterfacePersistor->doPersistEntity($entity);
+ return $entity;
}
}