diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js index f843de02f9037..1c7b36b9178be 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js @@ -21,10 +21,10 @@ define( "paymentMethod": methodData }; - var shippingMethodCode = quote.getSelectedShippingMethod()().split("_"), + var shippingMethodCode = quote.getSelectedShippingMethod()().slice(0).split("_"), shippingMethodData = { - "shippingCarrierCode" : shippingMethodCode[0], - "shippingMethodCode" : shippingMethodCode[1] + "shippingCarrierCode" : shippingMethodCode.shift(), + "shippingMethodCode" : shippingMethodCode.join('_') }, serviceUrl; if (quote.getCheckoutMethod()() === 'guest') { diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js index d30ef8da186de..8bb0366111a7a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js @@ -2,11 +2,11 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -/*jshint browser:true jquery:true*/ -/*global alert*/ +/*global define*/ define( ['ko', 'jquery'], function (ko, $) { + "use strict"; var rates = ko.observable([]); return { shippingRates: ko.observableArray([]), @@ -30,29 +30,34 @@ define( return this.shippingRates; }, getTitleByCode: function(methodCodeParts) { - var shippingMethodTitle = ''; - if (methodCodeParts) { - $.each(rates(), function (key, entity) { - if (entity['carrier_code'] == methodCodeParts[0] - && entity['method_code'] == methodCodeParts[1]) { - shippingMethodTitle = entity['carrier_title'] + " - " + entity['method_title']; - } - }); + var shippingMethodTitle = '', shippingMethodCode, carrierCode, methodCode; + if (!methodCodeParts) { + return shippingMethodTitle; } + shippingMethodCode = methodCodeParts.slice(0); + carrierCode = shippingMethodCode.shift(); + methodCode = shippingMethodCode.join('_'); + $.each(rates(), function (key, entity) { + if (entity['carrier_code'] === carrierCode && entity['method_code'] === methodCode) { + shippingMethodTitle = entity['carrier_title'] + " - " + entity['method_title']; + } + }); return shippingMethodTitle; }, getRateByCode : function(methodCodeParts) { - var shippingRates = []; + var shippingRates = [], + shippingMethodCode = methodCodeParts.slice(0), + carrierCode = shippingMethodCode.shift(), + methodCode = shippingMethodCode.join('_'); if (methodCodeParts) { $.each(rates(), function (key, entity) { - if (entity['carrier_code'] == methodCodeParts[0] - && entity['method_code'] == methodCodeParts[1]) { + if (entity['carrier_code'] === carrierCode && entity['method_code'] === methodCode) { shippingRates.push(entity); } }); } return shippingRates; } - } + }; } ); diff --git a/app/code/Magento/CheckoutAgreements/Api/CheckoutAgreementsRepositoryInterface.php b/app/code/Magento/CheckoutAgreements/Api/CheckoutAgreementsRepositoryInterface.php index 3d528c2a3969d..670b7683b0c03 100644 --- a/app/code/Magento/CheckoutAgreements/Api/CheckoutAgreementsRepositoryInterface.php +++ b/app/code/Magento/CheckoutAgreements/Api/CheckoutAgreementsRepositoryInterface.php @@ -5,12 +5,55 @@ */ namespace Magento\CheckoutAgreements\Api; +/** + * Interface CheckoutAgreementsRepositoryInterface + * @api + */ interface CheckoutAgreementsRepositoryInterface { + /** + * Return data object for specified checkout agreement ID and store. + * + * @param int $id + * @param int $storeId + * @return \Magento\CheckoutAgreements\Api\Data\AgreementInterface + */ + public function get($id, $storeId = null); + /** * Lists active checkout agreements. * * @return \Magento\CheckoutAgreements\Api\Data\AgreementInterface[] */ public function getList(); + + /** + * Create/Update new checkout agreements with data object values + * + * @param \Magento\CheckoutAgreements\Api\Data\AgreementInterface $data + * @param int $storeId + * @return \Magento\CheckoutAgreements\Api\Data\AgreementInterface + * @throws \Magento\Framework\Exception\CouldNotSaveException If there is a problem with the input + * @throws \Magento\Framework\Exception\NoSuchEntityException If a ID is sent but the entity does not exist + */ + public function save(\Magento\CheckoutAgreements\Api\Data\AgreementInterface $data, $storeId = null); + + /** + * Delete checkout agreement + * + * @param \Magento\CheckoutAgreements\Api\Data\AgreementInterface $data + * @return bool + * @throws \Magento\Framework\Exception\CouldNotDeleteException If there is a problem with the input + */ + public function delete(\Magento\CheckoutAgreements\Api\Data\AgreementInterface $data); + + /** + * Delete checkout agreement by id + * + * @param int $id + * @return bool + * @throws \Magento\Framework\Exception\NoSuchEntityException If a ID is sent but the entity does not exist + * @throws \Magento\Framework\Exception\CouldNotDeleteException If there is a problem with the input + */ + public function deleteById($id); } diff --git a/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php b/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php index 892e1599241f3..eae3f09c667a9 100644 --- a/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php +++ b/app/code/Magento/CheckoutAgreements/Model/CheckoutAgreementsRepository.php @@ -14,9 +14,14 @@ use Magento\Store\Model\StoreManagerInterface; use Magento\Store\Model\ScopeInterface; use Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface; +use Magento\CheckoutAgreements\Model\Resource\Agreement as AgreementResource; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Store\Model\Store; /** * Checkout agreement repository. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class CheckoutAgreementsRepository implements CheckoutAgreementsRepositoryInterface { @@ -41,21 +46,37 @@ class CheckoutAgreementsRepository implements CheckoutAgreementsRepositoryInterf */ private $scopeConfig; + /** + * @var AgreementResource + */ + private $resourceModel; + + /** + * @var AgreementFactory + */ + private $agreementFactory; + /** * Constructs a checkout agreement data object. * * @param AgreementCollectionFactory $collectionFactory Collection factory. * @param \Magento\Store\Model\StoreManagerInterface $storeManager Store manager. * @param ScopeConfigInterface $scopeConfig Scope config. + * @param AgreementResource $agreementResource + * @param AgreementFactory $agreementFactory */ public function __construct( AgreementCollectionFactory $collectionFactory, StoreManagerInterface $storeManager, - ScopeConfigInterface $scopeConfig + ScopeConfigInterface $scopeConfig, + AgreementResource $agreementResource, + AgreementFactory $agreementFactory ) { $this->collectionFactory = $collectionFactory; $this->storeManager = $storeManager; $this->scopeConfig = $scopeConfig; + $this->resourceModel = $agreementResource; + $this->agreementFactory = $agreementFactory; } /** @@ -81,4 +102,67 @@ public function getList() return $agreementDataObjects; } + + /** + * {@inheritdoc} + */ + public function save(\Magento\CheckoutAgreements\Api\Data\AgreementInterface $data, $storeId = null) + { + $id = $data->getAgreementId(); + + if ($id) { + $data = $this->get($id, $storeId)->addData($data->getData()); + } + if ($storeId === null) { + $storeId = $this->storeManager->getStore()->getId(); + } + $data->setStores($storeId); + try { + $this->resourceModel->save($data); + } catch (\Exception $e) { + throw new \Magento\Framework\Exception\CouldNotSaveException( + __('Unable to save checkout agreement %1', $data->getAgreementId()) + ); + } + return $data; + } + + /** + * {@inheritdoc} + */ + public function delete(\Magento\CheckoutAgreements\Api\Data\AgreementInterface $data) + { + try { + $this->resourceModel->delete($data); + } catch (\Exception $e) { + throw new \Magento\Framework\Exception\CouldNotDeleteException( + __('Unable to remove checkout agreement %1', $data->getAgreementId()) + ); + } + return true; + } + + /** + * {@inheritdoc} + */ + public function deleteById($id) + { + $model = $this->get($id); + $this->delete($model); + return true; + } + + /** + * {@inheritdoc} + */ + public function get($id, $storeId = null) + { + /** @var AgreementFactory $agreement */ + $agreement = $this->agreementFactory->create(); + $this->resourceModel->load($agreement, $id); + if (!$agreement->getId()) { + throw new NoSuchEntityException(__('Checkout agreement with specified ID "%1" not found.', $id)); + } + return $agreement; + } } diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php index 1751b99c5c632..9d27e3e471e23 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php +++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/CheckoutAgreementsRepositoryTest.php @@ -36,6 +36,26 @@ class CheckoutAgreementsRepositoryTest extends \PHPUnit_Framework_TestCase */ private $objectManager; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $resourceMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $agrFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $agreementMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + protected function setUp() { $this->objectManager = new ObjectManager($this); @@ -49,10 +69,24 @@ protected function setUp() ); $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManagerInterface'); $this->scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + $this->resourceMock = $this->getMock('Magento\CheckoutAgreements\Model\Resource\Agreement', [], [], '', false); + $this->agrFactoryMock = $this->getMock( + 'Magento\CheckoutAgreements\Model\AgreementFactory', + ['create'], + [], + '', + false + ); + $methods = ['addData', 'getData', 'setStores', 'getAgreementId', 'getId']; + $this->agreementMock = + $this->getMock('\Magento\CheckoutAgreements\Model\Agreement', $methods, [], '', false); + $this->storeMock = $this->getMock('Magento\Store\Model\Store', [], [], '', false); $this->model = new \Magento\CheckoutAgreements\Model\CheckoutAgreementsRepository( $this->factoryMock, $this->storeManagerMock, - $this->scopeConfigMock + $this->scopeConfigMock, + $this->resourceMock, + $this->agrFactoryMock ); } @@ -73,14 +107,6 @@ public function testGetListReturnsTheListOfActiveCheckoutAgreements() ->with('checkout/options/enable_agreements', ScopeInterface::SCOPE_STORE, null) ->will($this->returnValue(true)); - $agreementDataObject = $this->getMock( - 'Magento\CheckoutAgreements\Model\Agreement', - [], - [], - '', - false - ); - $storeId = 1; $storeMock = $this->getMock('Magento\Store\Model\Store', [], [], '', false); $storeMock->expects($this->any())->method('getId')->will($this->returnValue($storeId)); @@ -88,12 +114,92 @@ public function testGetListReturnsTheListOfActiveCheckoutAgreements() $collectionMock = $this->objectManager->getCollectionMock( 'Magento\CheckoutAgreements\Model\Resource\Agreement\Collection', - [$agreementDataObject] + [$this->agreementMock] ); $this->factoryMock->expects($this->once())->method('create')->will($this->returnValue($collectionMock)); $collectionMock->expects($this->once())->method('addStoreFilter')->with($storeId); $collectionMock->expects($this->once())->method('addFieldToFilter')->with('is_active', 1); - $this->assertEquals([$agreementDataObject], $this->model->getList()); + $this->assertEquals([$this->agreementMock], $this->model->getList()); + } + + public function testSave() + { + $this->agreementMock->expects($this->once())->method('getAgreementId')->willReturn(null); + $this->agrFactoryMock->expects($this->never())->method('create'); + $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn('storeId'); + $this->agreementMock->expects($this->once())->method('setStores'); + $this->resourceMock->expects($this->once())->method('save')->with($this->agreementMock); + $this->model->save($this->agreementMock); + } + + public function testUpdate() + { + $agreementId = 1; + $this->agreementMock->expects($this->once())->method('getAgreementId')->willReturn($agreementId); + $this->agrFactoryMock->expects($this->once())->method('create')->willReturn($this->agreementMock); + $this->resourceMock + ->expects($this->once()) + ->method('load') + ->with($this->agreementMock, $agreementId); + $this->storeManagerMock->expects($this->never())->method('getStore'); + $this->agreementMock->expects($this->once())->method('setStores'); + $this->agreementMock->expects($this->once())->method('getId')->willReturn($agreementId); + $this->agreementMock->expects($this->any())->method('getData')->willReturn(['data']); + $this->agreementMock + ->expects($this->once()) + ->method('addData')->with(['data']) + ->willReturn($this->agreementMock); + $this->resourceMock->expects($this->once())->method('save')->with($this->agreementMock); + $this->assertEquals($this->agreementMock, $this->model->save($this->agreementMock, 1)); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testSaveWithException() + { + $this->agreementMock->expects($this->exactly(2))->method('getAgreementId')->willReturn(null); + $this->agrFactoryMock->expects($this->never())->method('create'); + $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn('storeId'); + $this->agreementMock->expects($this->once())->method('setStores'); + $this->resourceMock + ->expects($this->once()) + ->method('save') + ->with($this->agreementMock)->willThrowException(new \Exception()); + $this->model->save($this->agreementMock); + } + + public function testDeleteById() + { + $agreementId = 1; + $this->agrFactoryMock->expects($this->once())->method('create')->willReturn($this->agreementMock); + $this->resourceMock + ->expects($this->once()) + ->method('load') + ->with($this->agreementMock, $agreementId) + ->willReturn($this->agreementMock); + $this->agreementMock->expects($this->once())->method('getId')->willReturn($agreementId); + $this->resourceMock->expects($this->once())->method('delete'); + $this->assertTrue($this->model->deleteById(1)); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotDeleteException + */ + public function testDeleteByIdWithException() + { + $agreementId = 1; + $this->agrFactoryMock->expects($this->once())->method('create')->willReturn($this->agreementMock); + $this->resourceMock + ->expects($this->once()) + ->method('load') + ->with($this->agreementMock, $agreementId) + ->willReturn($this->agreementMock); + $this->agreementMock->expects($this->once())->method('getId')->willReturn($agreementId); + $this->resourceMock->expects($this->once())->method('delete')->willThrowException(new \Exception()); + $this->assertTrue($this->model->deleteById(1)); } } diff --git a/app/code/Magento/Eav/Api/AttributeGroupRepositoryInterface.php b/app/code/Magento/Eav/Api/AttributeGroupRepositoryInterface.php index 9519950004b42..4edcecdb0fff9 100644 --- a/app/code/Magento/Eav/Api/AttributeGroupRepositoryInterface.php +++ b/app/code/Magento/Eav/Api/AttributeGroupRepositoryInterface.php @@ -6,6 +6,10 @@ */ namespace Magento\Eav\Api; +/** + * Interface AttributeGroupRepositoryInterface + * @api + */ interface AttributeGroupRepositoryInterface { /** diff --git a/app/code/Magento/Eav/Api/AttributeManagementInterface.php b/app/code/Magento/Eav/Api/AttributeManagementInterface.php index d311c8fdbceef..07e2474c54f56 100644 --- a/app/code/Magento/Eav/Api/AttributeManagementInterface.php +++ b/app/code/Magento/Eav/Api/AttributeManagementInterface.php @@ -6,6 +6,10 @@ */ namespace Magento\Eav\Api; +/** + * Interface AttributeManagementInterface + * @api + */ interface AttributeManagementInterface { /** diff --git a/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php b/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php index f7eae770ac527..d8b306cca79e4 100644 --- a/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php +++ b/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php @@ -7,6 +7,7 @@ /** * Interface AttributeOptionManagementInterface + * @api */ interface AttributeOptionManagementInterface { diff --git a/app/code/Magento/Eav/Api/AttributeRepositoryInterface.php b/app/code/Magento/Eav/Api/AttributeRepositoryInterface.php index 2cfca10832ee0..ebf0c4b784ddc 100644 --- a/app/code/Magento/Eav/Api/AttributeRepositoryInterface.php +++ b/app/code/Magento/Eav/Api/AttributeRepositoryInterface.php @@ -6,6 +6,10 @@ */ namespace Magento\Eav\Api; +/** + * Interface AttributeRepositoryInterface + * @api + */ interface AttributeRepositoryInterface { /** diff --git a/app/code/Magento/Eav/Api/AttributeSetManagementInterface.php b/app/code/Magento/Eav/Api/AttributeSetManagementInterface.php index 23b34f148b443..102fcb2c6cbb3 100644 --- a/app/code/Magento/Eav/Api/AttributeSetManagementInterface.php +++ b/app/code/Magento/Eav/Api/AttributeSetManagementInterface.php @@ -6,6 +6,10 @@ */ namespace Magento\Eav\Api; +/** + * Interface AttributeSetManagementInterface + * @api + */ interface AttributeSetManagementInterface { /** diff --git a/app/code/Magento/Eav/Api/AttributeSetRepositoryInterface.php b/app/code/Magento/Eav/Api/AttributeSetRepositoryInterface.php index 986cbcbc03b28..323ddc2fd6ea6 100644 --- a/app/code/Magento/Eav/Api/AttributeSetRepositoryInterface.php +++ b/app/code/Magento/Eav/Api/AttributeSetRepositoryInterface.php @@ -6,6 +6,10 @@ */ namespace Magento\Eav\Api; +/** + * Interface AttributeSetRepositoryInterface + * @api + */ interface AttributeSetRepositoryInterface { /** diff --git a/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php index 7e34c18ed0d65..6cc1bc5ec088c 100644 --- a/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php +++ b/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php @@ -5,6 +5,10 @@ */ namespace Magento\GiftMessage\Api; +/** + * Interface CartRepositoryInterface + * @api + */ interface CartRepositoryInterface { /** diff --git a/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php index 3e2f771fad133..eacb52d5e1c09 100644 --- a/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php +++ b/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php @@ -5,6 +5,10 @@ */ namespace Magento\GiftMessage\Api; +/** + * Interface ItemRepositoryInterface + * @api + */ interface ItemRepositoryInterface { /** diff --git a/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php index 4b94af3ce5f61..8e66c7922c939 100644 --- a/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php +++ b/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php @@ -5,6 +5,10 @@ */ namespace Magento\GiftMessage\Api; +/** + * Interface OrderItemRepositoryInterface + * @api + */ interface OrderItemRepositoryInterface { /** diff --git a/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php index 28f5b54dde526..564577e49b786 100644 --- a/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php +++ b/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php @@ -5,6 +5,10 @@ */ namespace Magento\GiftMessage\Api; +/** + * Interface OrderRepositoryInterface + * @api + */ interface OrderRepositoryInterface { /** diff --git a/app/code/Magento/Persistent/Model/Session.php b/app/code/Magento/Persistent/Model/Session.php index 3a61917fbd56d..78c0fb856a495 100644 --- a/app/code/Magento/Persistent/Model/Session.php +++ b/app/code/Magento/Persistent/Model/Session.php @@ -278,6 +278,7 @@ public function deleteByCustomerId($customerId, $clearCookie = true) * Remove persistent cookie * * @return $this + * @api */ public function removePersistentCookie() { @@ -293,6 +294,7 @@ public function removePersistentCookie() * @param int $duration Time in seconds. * @param string $path * @return $this + * @api */ public function setPersistentCookie($duration, $path) { diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index 8236627a40caf..9c75faf07f034 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -101,6 +101,9 @@ protected function execute(InputInterface $input, OutputInterface $output) 'application' => '#^' . $appCodePath . '/[\\w]+/[\\w]+/Test#', 'framework' => '#^' . $libraryPath . '/[\\w]+/[\\w]+/([\\w]+/)?Test#' ]; + $dataAttributesIncludePattern = [ + 'service_data_attributes' => '/\/etc\/([a-zA-Z_]*\/service_data_attributes|service_data_attributes)\.xml$/' + ]; $this->configureObjectManager($output); $operations = [ @@ -108,6 +111,10 @@ protected function execute(InputInterface $input, OutputInterface $output) 'path' => $compiledPathsList['application'], 'filePatterns' => ['di' => '/\/etc\/([a-zA-Z_]*\/di|di)\.xml$/'] ], + OperationFactory::DATA_ATTRIBUTES_GENERATOR => [ + 'path' => $compiledPathsList['application'], + 'filePatterns' => $dataAttributesIncludePattern + ], OperationFactory::APPLICATION_CODE_GENERATOR => [ $compiledPathsList['application'], $compiledPathsList['library'], diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php new file mode 100644 index 0000000000000..eed75e7e329ea --- /dev/null +++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php @@ -0,0 +1,67 @@ +directoryScanner = $directoryScanner; + $this->serviceDataAttributesScanner = $repositoryScanner; + $this->data = $data; + } + + /** + * Processes operation task + * + * @return void + */ + public function doOperation() + { + if (array_diff(array_keys($this->data), ['filePatterns', 'path']) + !== array_diff(['filePatterns', 'path'], array_keys($this->data))) { + return; + } + + $files = $this->directoryScanner->scan($this->data['path'], $this->data['filePatterns']); + $repositories = $this->serviceDataAttributesScanner->collectEntities($files['service_data_attributes']); + foreach ($repositories as $entityName) { + class_exists($entityName); + } + } +} diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/OperationFactory.php b/setup/src/Magento/Setup/Module/Di/App/Task/OperationFactory.php index a2505bad47a0e..69406279ccab9 100644 --- a/setup/src/Magento/Setup/Module/Di/App/Task/OperationFactory.php +++ b/setup/src/Magento/Setup/Module/Di/App/Task/OperationFactory.php @@ -32,6 +32,11 @@ class OperationFactory */ const REPOSITORY_GENERATOR = 'repository_generator'; + /** + * Service data attributes generator + */ + const DATA_ATTRIBUTES_GENERATOR = 'service_data_attributes_generator'; + /** * Application code generator */ @@ -43,6 +48,7 @@ class OperationFactory * @var array */ private $operationsDefinitions = [ + self::DATA_ATTRIBUTES_GENERATOR => 'Magento\Setup\Module\Di\App\Task\Operation\ServiceDataAttributesGenerator', self::AREA_CONFIG_GENERATOR => 'Magento\Setup\Module\Di\App\Task\Operation\Area', self::APPLICATION_CODE_GENERATOR => 'Magento\Setup\Module\Di\App\Task\Operation\ApplicationCodeGenerator', self::INTERCEPTION => 'Magento\Setup\Module\Di\App\Task\Operation\Interception', diff --git a/setup/src/Magento/Setup/Module/Di/Code/Scanner/ServiceDataAttributesScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Scanner/ServiceDataAttributesScanner.php new file mode 100644 index 0000000000000..6fc9e34100810 --- /dev/null +++ b/setup/src/Magento/Setup/Module/Di/Code/Scanner/ServiceDataAttributesScanner.php @@ -0,0 +1,35 @@ +loadXML(file_get_contents($fileName)); + $xpath = new \DOMXPath($dom); + /** @var $node \DOMNode */ + foreach ($xpath->query('//extension_attributes') as $node) { + $forType = $node->attributes->getNamedItem('for')->nodeValue; + $extensionClasses[] = str_replace('Interface', 'ExtensionInterface', $forType); + $extensionClasses[] = str_replace('Interface', 'Extension', $forType); + } + } + return $extensionClasses; + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php index b2c5e9a65254d..f307af40de473 100644 --- a/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php @@ -73,7 +73,7 @@ public function testExecute() { $this->deploymentConfig->expects($this->once())->method('isAvailable')->willReturn(true); $this->objectManager->expects($this->once())->method('configure'); - $this->manager->expects($this->exactly(5))->method('addOperation'); + $this->manager->expects($this->exactly(6))->method('addOperation'); $this->manager->expects($this->once())->method('process'); $tester = new CommandTester($this->command); $tester->execute([]); diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ServiceDataAttributesGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ServiceDataAttributesGeneratorTest.php new file mode 100644 index 0000000000000..dc11cccd59662 --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ServiceDataAttributesGeneratorTest.php @@ -0,0 +1,99 @@ +directoryScannerMock = $this->getMock( + 'Magento\Setup\Module\Di\Code\Scanner\DirectoryScanner', + [], + [], + '', + false + ); + $this->serviceDataAttributesScannerMock = $this->getMock( + 'Magento\Setup\Module\Di\Code\Scanner\ServiceDataAttributesScanner', + [], + [], + '', + false + ); + } + + /** + * @param $data array + * @dataProvider doOperationDataProvider + */ + public function testDoOperationEmptyData($data) + { + $model = new ServiceDataAttributesGenerator( + $this->directoryScannerMock, + $this->serviceDataAttributesScannerMock, + $data + ); + $this->directoryScannerMock->expects($this->never())->method('scan'); + + $model->doOperation(); + } + + /** + * @return array + */ + public function doOperationDataProvider() + { + return [ + [[]], + [['filePatterns' => ['php' => '*.php']]], + [['path' => 'path']] + ]; + } + + public function testDoOperation() + { + $data = [ + 'path' => 'path/to/app', + 'filePatterns' => ['di' => 'di.xml'], + ]; + $files = ['service_data_attributes' => []]; + $model = new ServiceDataAttributesGenerator( + $this->directoryScannerMock, + $this->serviceDataAttributesScannerMock, + $data + ); + + $this->directoryScannerMock->expects($this->once()) + ->method('scan') + ->with( + $data['path'], + $data['filePatterns'] + )->willReturn($files); + $this->serviceDataAttributesScannerMock->expects($this->once()) + ->method('collectEntities') + ->with($files['service_data_attributes']) + ->willReturn([]); + + $model->doOperation(); + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/ServiceDataAttributesScannerTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/ServiceDataAttributesScannerTest.php new file mode 100644 index 0000000000000..e96951ab59e9d --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/ServiceDataAttributesScannerTest.php @@ -0,0 +1,45 @@ +model = new ServiceDataAttributesScanner(); + $this->testFile = str_replace('\\', '/', realpath(__DIR__ . '/../../') . '/_files/service_data_attributes.xml'); + } + + public function testCollectEntities() + { + $files = [$this->testFile]; + $expectedResult = [ + 'Magento\Sales\Api\Data\OrderExtensionInterface', + 'Magento\Sales\Api\Data\OrderExtension', + 'Magento\Sales\Api\Data\OrderItemExtensionInterface', + 'Magento\Sales\Api\Data\OrderItemExtension', + 'Magento\GiftMessage\Api\Data\MessageExtensionInterface', + 'Magento\GiftMessage\Api\Data\MessageExtension', + 'Magento\Quote\Api\Data\TotalsAdditionalDataExtensionInterface', + 'Magento\Quote\Api\Data\TotalsAdditionalDataExtension' + ]; + + $this->assertSame($expectedResult, $this->model->collectEntities($files)); + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/_files/service_data_attributes.xml b/setup/src/Magento/Setup/Test/Unit/Module/Di/_files/service_data_attributes.xml new file mode 100644 index 0000000000000..bc8a926dfb86f --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/_files/service_data_attributes.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + +