diff --git a/CHANGELOG.md b/CHANGELOG.md index 72d11b49ba5d716aea1f9f023b77e8192cf59065..921226d21170a79bc56228703d426cb2d775e26d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +0.74.0-beta3 +============= +* API + * The orders were extended with the gift messages + * The page and block data and repository interfaces + * Updated the public API list +* Framework improvements + * Improved the profile generator + * Introduced the new environment for Jasmine tests +* Design + * Inverted the new admin area styles scope, clean up the old styles + * New Side Panels on Admin Area +* Various + * Asynchronous indexing for sales grids + * Advanced Mini Cart + * The HTML minification management on Admin Area + * Minor UI improvements + * The GitHub contribution process was updated in the README.md file +* Fixed bugs + * Fixed the assets deployment tool with the minification + * Fixed the JMeter scenario for the performance toolkit + * Fixed the static files caching on Varnish + * Fixed Admin user creation with the duplicated email or name (incorrect URL) + * Fixed the link on Reset password email for secure URL case + * Fixed the configured product adding from the wish-list to shopping cart + * Fixed the long labels display on Admin Area + * Fixed the Navigation Menu items on Admin Area + * Various unit and integration tests bugs +* GitHub issues and requests + [#675] (https://github.com/magento/magento2/issues/675) -- Fix for Textarea element cols and rows #675 + 0.74.0-beta2 ============= * Fixed bugs diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json index 4bdbc07cfbd7e9bb30713dafc8291546c9b0ea60..4fb447cbea3a01021a5814b7af1475e5adf8bc43 100644 --- a/app/code/Magento/AdminNotification/composer.json +++ b/app/code/Magento/AdminNotification/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json index 41cca87deaa066a7e119c190d49aa72f09d4d8a9..511ee7948da9fa8c83d615cf1a911c5aa8aac0c2 100644 --- a/app/code/Magento/Authorization/composer.json +++ b/app/code/Magento/Authorization/composer.json @@ -3,12 +3,12 @@ "description": "Authorization module provides access to Magento ACL functionality.", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index 639122ecc702064bc2ceda23e59f32b21fd19f8f..bb64b58db804677f56b192fba0e12919f3e00b98 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -3,27 +3,27 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-developer": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-cron": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-reports": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-user": "0.74.0-beta2", - "magento/module-backup": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-translation": "0.74.0-beta2", - "magento/module-require-js": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-developer": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-cron": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-reports": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-user": "0.74.0-beta3", + "magento/module-backup": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-translation": "0.74.0-beta3", + "magento/module-require-js": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 6dd6d3ea9d992df5b4907094abebd2127827a41a..614c5a507892140d30e0e691d5270bd09052d6f3 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -154,13 +154,6 @@ <label>Developer</label> <tab>advanced</tab> <resource>Magento_Backend::dev</resource> - <group id="restrict" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> - <label>Developer Client Restrictions</label> - <field id="allow_ips" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> - <label>Allowed IPs (comma separated)</label> - <comment>Leave empty for access from any location.</comment> - </field> - </group> <group id="debug" translate="label" type="text" sortOrder="20" showInDefault="0" showInWebsite="1" showInStore="1"> <label>Debug</label> <field id="template_hints" translate="label" type="select" sortOrder="20" showInDefault="0" showInWebsite="1" showInStore="1"> diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json index 2c9f59ec6320c18d224d40af33aa6d20c546a5d7..8e68c52d358e3b9a72e8c520b659158bcd196181 100644 --- a/app/code/Magento/Backup/composer.json +++ b/app/code/Magento/Backup/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-cron": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-cron": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Bundle/Model/Product/Price.php b/app/code/Magento/Bundle/Model/Product/Price.php index b2b70b3a55c027f644f494a15dfe3dd411a99b2e..9c0163fcc4cb9081e24c487ecb055ade1900d3c0 100644 --- a/app/code/Magento/Bundle/Model/Product/Price.php +++ b/app/code/Magento/Bundle/Model/Product/Price.php @@ -47,7 +47,12 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param PriceCurrencyInterface $priceCurrency * @param GroupManagementInterface $groupManagement + * @param \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory $groupPriceFactory + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config * @param \Magento\Catalog\Helper\Data $catalogData + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\CatalogRule\Model\Resource\RuleFactory $ruleFactory, @@ -57,6 +62,9 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price \Magento\Framework\Event\ManagerInterface $eventManager, PriceCurrencyInterface $priceCurrency, GroupManagementInterface $groupManagement, + \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory $groupPriceFactory, + \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory, + \Magento\Framework\App\Config\ScopeConfigInterface $config, \Magento\Catalog\Helper\Data $catalogData ) { $this->_catalogData = $catalogData; @@ -67,7 +75,10 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price $customerSession, $eventManager, $priceCurrency, - $groupManagement + $groupManagement, + $groupPriceFactory, + $tierPriceFactory, + $config ); } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php index 8db5283f5b38d2b0048695c64c0897b33b2316b6..3d107771e79d05c084c087368e04478aabe2d45e 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Bundle\Test\Unit\Model\Product; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + class PriceTest extends \PHPUnit_Framework_TestCase { /** @@ -75,16 +77,26 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->priceCurrency = $this->getMockBuilder('Magento\Framework\Pricing\PriceCurrencyInterface')->getMock(); $this->groupManagement = $this->getMockBuilder('Magento\Customer\Api\GroupManagementInterface') ->getMockForAbstractClass(); - - $this->model = new \Magento\Bundle\Model\Product\Price( - $this->ruleFactoryMock, - $this->storeManagerMock, - $this->localeDateMock, - $this->customerSessionMock, - $this->eventManagerMock, - $this->priceCurrency, - $this->groupManagement, - $this->catalogHelperMock + $gpFactory = $this->getMock('Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory', [], [], '', false); + $tpFactory = $this->getMock('Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory', [], [], '', false); + $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + + $objectManagerHelper = new ObjectManagerHelper($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Bundle\Model\Product\Price', + [ + 'ruleFactory' => $this->ruleFactoryMock, + 'storeManager' => $this->storeManagerMock, + 'localeDate' => $this->localeDateMock, + 'customerSession' => $this->customerSessionMock, + 'eventManager' => $this->eventManagerMock, + 'priceCurrency' => $this->priceCurrency, + 'groupManagement' => $this->groupManagement, + 'groupPriceFactory' => $gpFactory, + 'tierPriceFactory' => $tpFactory, + 'config' => $scopeConfig, + 'catalogData' => $this->catalogHelperMock + ] ); } diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index 172bf912af2924d869d8f763c172729ae41920a6..f3cff9f22559898a0f0c118cee162b010b6b6123 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-catalog-rule": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-gift-message": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-catalog-rule": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-gift-message": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-webapi": "0.74.0-beta2" + "magento/module-webapi": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json index ee220a5e9b3af383185d71694704c4cb25b72f53..8689919efe734fcd05efb9f1458ca498003661f3 100644 --- a/app/code/Magento/Captcha/composer.json +++ b/app/code/Magento/Captcha/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Catalog/Api/Data/CategoryInterface.php b/app/code/Magento/Catalog/Api/Data/CategoryInterface.php index 8ca5780579cf2f6062e9ba8df686e1f0eba56463..8e4327cd95f976fba1f64865cf1d4d7bc4c3a96d 100644 --- a/app/code/Magento/Catalog/Api/Data/CategoryInterface.php +++ b/app/code/Magento/Catalog/Api/Data/CategoryInterface.php @@ -106,6 +106,12 @@ interface CategoryInterface extends \Magento\Framework\Api\CustomAttributesDataI */ public function getCreatedAt(); + /** + * @param string $createdAt + * @return $this + */ + public function setCreatedAt($createdAt); + /** * @return string|null */ diff --git a/app/code/Magento/Catalog/Api/Data/ProductInterface.php b/app/code/Magento/Catalog/Api/Data/ProductInterface.php index 34eed7fdf7bab210c1ff8c75a6690973bcc1cbca..9903fef8d1a4e8f132182406d8102c3d8b21d188 100644 --- a/app/code/Magento/Catalog/Api/Data/ProductInterface.php +++ b/app/code/Magento/Catalog/Api/Data/ProductInterface.php @@ -229,4 +229,79 @@ interface ProductInterface extends \Magento\Framework\Api\CustomAttributesDataIn * @return $this */ public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes); + + /** + * Get product links info + * + * @return \Magento\Catalog\Api\Data\ProductLinkInterface[]|null + */ + public function getProductLinks(); + + /** + * Set product links info + * + * @param \Magento\Catalog\Api\Data\ProductLinkInterface[] $links + * @return $this + */ + public function setProductLinks(array $links = null); + + /** + * Get list of product options + * + * @return \Magento\Catalog\Api\Data\ProductCustomOptionInterface[]|null + */ + public function getOptions(); + + /** + * Set list of product options + * + * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $options + * @return $this + */ + public function setOptions(array $options = null); + + /** + * Get media gallery entries + * + * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]|null + */ + public function getMediaGalleryEntries(); + + /** + * Set media gallery entries + * + * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[] $mediaGalleryEntries + * @return $this + */ + public function setMediaGalleryEntries(array $mediaGalleryEntries = null); + + /** + * Gets list of product group prices + * + * @return \Magento\Catalog\Api\Data\ProductGroupPriceInterface[]|null + */ + public function getGroupPrices(); + + /** + * Sets list of product group prices + * + * @param \Magento\Catalog\Api\Data\ProductGroupPriceInterface[] $groupPrices + * @return $this + */ + public function setGroupPrices(array $groupPrices = null); + + /** + * Gets list of product tier prices + * + * @return \Magento\Catalog\Api\Data\ProductTierPriceInterface[]|null + */ + public function getTierPrices(); + + /** + * Sets list of product tier prices + * + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface[] $tierPrices + * @return $this + */ + public function setTierPrices(array $tierPrices = null); } diff --git a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php index bee553af0f504824cb8c85b50d2a4c0fa485f9fe..984379ba9877320841661a01f5df90c5c4be759a 100644 --- a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php +++ b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php @@ -9,15 +9,29 @@ namespace Magento\Catalog\Api\Data; use Magento\Framework\Api\ExtensibleDataInterface; -/** - * @todo remove this interface if framework support return array - */ interface ProductTierPriceInterface extends ExtensibleDataInterface { const QTY = 'qty'; const VALUE = 'value'; + const CUSTOMER_GROUP_ID = 'customer_group_id'; + + /** + * Retrieve customer group id + * + * @return int + */ + public function getCustomerGroupId(); + + /** + * Set customer group id + * + * @param int $customerGroupId + * @return $this + */ + public function setCustomerGroupId($customerGroupId); + /** * Retrieve tier qty * diff --git a/app/code/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterface.php b/app/code/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterface.php index 2dfe8e5a30976dfeb65d37dd337bf73382d81093..f14ead9d77c3cf9689584e40a0e6da7873730351 100644 --- a/app/code/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterface.php +++ b/app/code/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterface.php @@ -16,13 +16,19 @@ interface ProductAttributeMediaGalleryManagementInterface /** * Create new gallery entry * - * @param \Magento\Catalog\Api\Data\ProductInterface $product + * @param string $sku + * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface $entry + * @param int $storeId * @return int gallery entry ID * @throws \Magento\Framework\Exception\InputException * @throws \Magento\Framework\Exception\NoSuchEntityException * @throws \Magento\Framework\Exception\StateException */ - public function create($product); + public function create( + $sku, + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface $entry, + $storeId = 0 + ); /** * Update gallery entry diff --git a/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php b/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php index c8e3a5361e72acfe0ca9e68ac64ed934037e52df..01d67c30390596159830ca33bbe68705513fab74 100644 --- a/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php +++ b/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php @@ -12,7 +12,7 @@ interface ProductTierPriceManagementInterface * Create tier price for product * * @param string $sku - * @param string $customerGroupId + * @param string $customerGroupId 'all' can be used to specify 'ALL GROUPS' * @param float $price * @param float $qty * @return boolean @@ -22,10 +22,10 @@ interface ProductTierPriceManagementInterface public function add($sku, $customerGroupId, $price, $qty); /** - * Remove tire price from product + * Remove tier price from product * * @param string $sku - * @param string $customerGroupId + * @param string $customerGroupId 'all' can be used to specify 'ALL GROUPS' * @param float $qty * @return boolean * @throws \Magento\Framework\Exception\NoSuchEntityException @@ -34,10 +34,10 @@ interface ProductTierPriceManagementInterface public function remove($sku, $customerGroupId, $qty); /** - * Get tire price of product + * Get tier price of product * * @param string $sku - * @param string $customerGroupId + * @param string $customerGroupId 'all' can be used to specify 'ALL GROUPS' * @return \Magento\Catalog\Api\Data\ProductTierPriceInterface[] * @throws \Magento\Framework\Exception\NoSuchEntityException */ diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Option.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Option.php index 088cc75846d5e136cba16d11f81dbb2889bda6cd..ae97a87ac96ca199098f62f95443d65e4a886082 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Option.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Option.php @@ -278,6 +278,9 @@ class Option extends Widget public function getOptionValues() { $optionsArr = $this->getProduct()->getOptions(); + if ($optionsArr == null) { + $optionsArr = []; + } if (!$this->_values || $this->getIgnoreCaching()) { $showPrice = $this->getCanReadPrice(); diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php index 6ac1774c0bbd03d31873e28155dd10222b9fec5f..16bdd17ffd3060776c5b3bcc8de0b17a5879248b 100644 --- a/app/code/Magento/Catalog/Model/Category.php +++ b/app/code/Magento/Catalog/Model/Category.php @@ -65,6 +65,7 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements const KEY_POSITION = 'position'; const KEY_LEVEL = 'level'; const KEY_UPDATED_AT = 'updated_at'; + const KEY_CREATED_AT = 'created_at'; const KEY_PATH = 'path'; const KEY_AVAILABLE_SORT_BY = 'available_sort_by'; const KEY_INCLUDE_IN_MENU = 'include_in_menu'; @@ -128,6 +129,25 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements 'custom_apply_to_products', ]; + /** + * Attributes are that part of interface + * + * @var array + */ + protected $interfaceAttributes = [ + 'id', + self::KEY_PARENT_ID, + self::KEY_NAME, + self::KEY_IS_ACTIVE, + self::KEY_POSITION, + self::KEY_LEVEL, + self::KEY_UPDATED_AT, + self::KEY_CREATED_AT, + self::KEY_AVAILABLE_SORT_BY, + self::KEY_INCLUDE_IN_MENU, + self::KEY_CHILDREN_DATA, + ]; + /** * Category tree model * @@ -289,6 +309,7 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements { if ($this->customAttributesCodes === null) { $this->customAttributesCodes = $this->getEavAttributesCodes($this->metadataService); + $this->customAttributesCodes = array_diff($this->customAttributesCodes, $this->interfaceAttributes); } return $this->customAttributesCodes; } @@ -1296,6 +1317,15 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements return $this->setData(self::KEY_UPDATED_AT, $updatedAt); } + /** + * @param string $createdAt + * @return $this + */ + public function setCreatedAt($createdAt) + { + return $this->setData(self::KEY_CREATED_AT, $createdAt); + } + /** * @param string $path * @return $this diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index e6a8912b1c6668a4cd4b561c4ea25f1a5059012d..ebd9494fe1f842f7e42eba21cdb0c3da4cbd1325 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -11,6 +11,8 @@ use Magento\Framework\Api\AttributeValueFactory; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Object\IdentityInterface; use Magento\Framework\Pricing\Object\SaleableInterface; +use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface; +use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface; /** * Catalog product model @@ -124,6 +126,11 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements */ protected $_options = []; + /** + * @var array + */ + protected $_links = null; + /** * Flag for available duplicate function * @@ -242,11 +249,47 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements */ protected $metadataService; + /* + * @param \Magento\Catalog\Model\ProductLink\ProductLinkManagementInterface + */ + protected $linkManagement; + + /* + * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory + */ + protected $productLinkFactory; + + /** + * @var \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory + */ + protected $mediaGalleryEntryFactory; + /** * @var \Magento\Framework\Api\DataObjectHelper */ protected $dataObjectHelper; + /** + * List of attributes in ProductInterface + * @var array + */ + protected $interfaceAttributes = [ + ProductInterface::SKU, + ProductInterface::NAME, + ProductInterface::PRICE, + ProductInterface::WEIGHT, + ProductInterface::STATUS, + ProductInterface::VISIBILITY, + ProductInterface::ATTRIBUTE_SET_ID, + ProductInterface::TYPE_ID, + ProductInterface::CREATED_AT, + ProductInterface::UPDATED_AT, + ProductInterface::STORE_ID, + 'media_gallery', + 'tier_price', + 'group_price', + ]; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -275,6 +318,9 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements * @param Indexer\Product\Eav\Processor $productEavIndexerProcessor * @param CategoryRepositoryInterface $categoryRepository * @param Product\Image\CacheFactory $imageCacheFactory + * @param \Magento\Catalog\Model\ProductLink\Management $linkManagement + * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory, + * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $mediaGalleryEntryFactory * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * @param array $data * @@ -308,6 +354,9 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor, CategoryRepositoryInterface $categoryRepository, Product\Image\CacheFactory $imageCacheFactory, + \Magento\Catalog\Model\ProductLink\Management $linkManagement, + \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory, + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $mediaGalleryEntryFactory, \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, array $data = [] ) { @@ -331,6 +380,9 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements $this->_productEavIndexerProcessor = $productEavIndexerProcessor; $this->categoryRepository = $categoryRepository; $this->imageCacheFactory = $imageCacheFactory; + $this->linkManagement = $linkManagement; + $this->productLinkFactory = $productLinkFactory; + $this->mediaGalleryEntryFactory = $mediaGalleryEntryFactory; $this->dataObjectHelper = $dataObjectHelper; parent::__construct( $context, @@ -361,6 +413,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements { if ($this->customAttributesCodes === null) { $this->customAttributesCodes = $this->getEavAttributesCodes($this->metadataService); + $this->customAttributesCodes = array_diff($this->customAttributesCodes, $this->interfaceAttributes); } return $this->customAttributesCodes; } @@ -749,7 +802,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements $websiteIds = $this->_getResource()->getWebsiteIds($this); $this->setOrigData('website_ids', $websiteIds); } - parent::beforeSave(); } @@ -911,7 +963,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements $this->addOption($option); } } - return $this; } @@ -950,7 +1001,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements } /** - * Get product group price + * Get product group price for the customer * * @return float */ @@ -960,7 +1011,51 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements } /** - * Get product tier price by qty + * Gets list of product group prices + * + * @return \Magento\Catalog\Api\Data\ProductGroupPriceInterface[]|null + */ + public function getGroupPrices() + { + return $this->getPriceModel()->getGroupPrices($this); + } + + /** + * Sets list of product group prices + * + * @param \Magento\Catalog\Api\Data\ProductGroupPriceInterface[] $groupPrices + * @return $this + */ + public function setGroupPrices(array $groupPrices = null) + { + $this->getPriceModel()->setGroupPrices($this, $groupPrices); + return $this; + } + + /** + * Gets list of product tier prices + * + * @return \Magento\Catalog\Api\Data\ProductTierPriceInterface[]|null + */ + public function getTierPrices() + { + return $this->getPriceModel()->getTierPrices($this); + } + + /** + * Sets list of product tier prices + * + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface[] $tierPrices + * @return $this + */ + public function setTierPrices(array $tierPrices = null) + { + $this->getPriceModel()->setTierPrices($this, $tierPrices); + return $this; + } + + /** + * Get product tier price for the customer, based on qty of this product * * @param float $qty * @return float|array @@ -1249,6 +1344,57 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements return $collection; } + /** + * Get product links info + * + * @return \Magento\Catalog\Api\Data\ProductLinkInterface[]|null + */ + public function getProductLinks() + { + if (empty($this->_links)) { + $productLinks = []; + + $productLinks['related'] = $this->getRelatedProducts(); + $productLinks['upsell'] = $this->getUpSellProducts(); + $productLinks['crosssell'] = $this->getCrossSellProducts(); + + $output = []; + foreach ($productLinks as $type => $linkTypeArray) { + foreach ($linkTypeArray as $link) { + /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */ + $productLink = $this->productLinkFactory->create(); + $productLink->setProductSku($this->getSku()) + ->setLinkType($type) + ->setLinkedProductSku($link['sku']) + ->setLinkedProductType($link['type_id']) + ->setPosition($link['position']); + + $output[] = $productLink; + } + } + $this->_links = $output; + } + + return $this->_links; + } + + /** + * Set product links info + * + * @param \Magento\Catalog\Api\Data\ProductLinkInterface[] $links + * @return this + */ + public function setProductLinks(array $links = null) + { + if ($links === null) { + $this->setData('ignore_links_flag', true); + } else { + $this->setData('ignore_links_flag', false); + } + $this->_links = $links; + return $this; + } + /******************************************************************************* ** Media API */ @@ -1271,6 +1417,21 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements return $this->getData('media_attributes'); } + /** + * Retrieve assoc array that contains media attribute values of the product + * + * @return array + */ + public function getMediaAttributeValues() + { + $mediaAttributeCodes = array_keys($this->getMediaAttributes()); + $mediaAttributeValues = []; + foreach ($mediaAttributeCodes as $attributeCode) { + $mediaAttributeValues[$attributeCode] = $this->getData($attributeCode); + } + return $mediaAttributeValues; + } + /** * Retrieve media gallery images * @@ -1296,6 +1457,25 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements return $this->getData('media_gallery_images'); } + /** + * Retrieve backend model of product media gallery attribute, return null if the product + * does not support images + * + * @return \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend|null + */ + public function getGalleryAttributeBackend() + { + $attributes = $this->getAttributes(); + if (!isset($attributes['media_gallery']) + || !($attributes['media_gallery'] instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute) + ) { + return null; + } + /** @var $galleryAttribute \Magento\Eav\Model\Entity\Attribute\AbstractAttribute */ + $galleryAttribute = $attributes['media_gallery']; + return $galleryAttribute->getBackend(); + } + /** * Add image to media gallery * @@ -1714,13 +1894,26 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements /** * Get all options of product * - * @return array + * @return \Magento\Catalog\Api\Data\ProductCustomOptionInterface[]|null */ public function getOptions() { return $this->_options; } + /** + * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $options + * @return $this + */ + public function setOptions(array $options = null) + { + $this->_options = $options; + if (is_array($options) && empty($options)) { + $this->setData('is_delete_options', true); + } + return $this; + } + /** * Retrieve is a virtual product * @@ -2256,4 +2449,99 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements return $this->_setExtensionAttributes($extensionAttributes); } //@codeCoverageIgnoreEnd + + /** + * @param array $mediaGallery + * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[] + */ + protected function convertToMediaGalleryInterface(array $mediaGallery) + { + $productImages = $this->getMediaAttributeValues(); + + $entries = []; + foreach ($mediaGallery as $image) { + if (!isset($image['types'])) { + $image['types'] = array_keys($productImages, $image['file']); + } + $entry = $this->mediaGalleryEntryFactory->create(); + $this->dataObjectHelper->populateWithArray( + $entry, + $image, + '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface' + ); + if (isset($image['value_id'])) { + $entry->setId($image['value_id']); + } + $entries[] = $entry; + } + return $entries; + } + + /** + * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]|null + */ + public function getMediaGalleryEntries() + { + $mediaGallery = $this->getMediaGallery('images'); + if ($mediaGallery === null) { + return null; + } + //convert the data + $convertedEntries = $this->convertToMediaGalleryInterface($mediaGallery); + return $convertedEntries; + } + + /** + * @param ProductAttributeMediaGalleryEntryContentInterface $content + * @return array + */ + protected function convertFromMediaGalleryEntryContentInterface( + ProductAttributeMediaGalleryEntryContentInterface $content = null + ) { + if ($content == null) { + return null; + } else { + return [ + "entry_data" => $content->getEntryData(), + "mime_type" => $content->getMimeType(), + "name" => $content->getName(), + ]; + } + } + + /** + * @param ProductAttributeMediaGalleryEntryInterface $entry + * @return array + */ + protected function convertFromMediaGalleryInterface(ProductAttributeMediaGalleryEntryInterface $entry) + { + $entryArray = [ + "value_id" => $entry->getId(), + "file" => $entry->getFile(), + "label" => $entry->getLabel(), + "position" => $entry->getPosition(), + "disabled" => $entry->isDisabled(), + "types" => $entry->getTypes(), + "content" => $this->convertFromMediaGalleryEntryContentInterface($entry->getContent()), + ]; + + return $entryArray; + } + + /** + * @param ProductAttributeMediaGalleryEntryInterface[] $mediaGalleryEntries + * @return $this + */ + public function setMediaGalleryEntries(array $mediaGalleryEntries = null) + { + if ($mediaGalleryEntries !== null) { + $images = []; + foreach ($mediaGalleryEntries as $entry) { + $images[] = $this->convertFromMediaGalleryInterface($entry); + } + $this->setData('media_gallery', ['images' => $images]); + + } + return $this; + } } diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index f5337a699139fe3e6e8c46aa007be00b7c738355..9f1271ae8c7c1975f14e5df3e439814fa65e74f1 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -300,12 +300,7 @@ abstract class AbstractGroupPrice extends Price $isGlobal = $this->getAttribute()->isScopeGlobal() || $websiteId == 0; $priceRows = $object->getData($this->getAttribute()->getName()); - if (empty($priceRows)) { - if ($isGlobal) { - $this->_getResource()->deletePriceData($object->getId()); - } else { - $this->_getResource()->deletePriceData($object->getId(), $websiteId); - } + if ($priceRows === null) { return $this; } diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 4297b2692b5089f3c7350a13ec7da2dcb50c1120..cd4c2d3cf4b6fa209475d7e70c06e18ede5a5907 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -8,8 +8,6 @@ namespace Magento\Catalog\Model\Product\Gallery; use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface; use Magento\Catalog\Api\Data\ProductInterface as Product; -use Magento\Catalog\Model\Product\Media\Config as MediaConfig; -use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; @@ -19,18 +17,6 @@ use Magento\Framework\Exception\StateException; */ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface { - /** - * MIME type/extension map - * - * @var array - */ - protected $mimeTypeExtensionMap = [ - 'image/jpg' => 'jpg', - 'image/jpeg' => 'jpg', - 'image/gif' => 'gif', - 'image/png' => 'png', - ]; - /** * @var \Magento\Store\Model\StoreManagerInterface */ @@ -41,77 +27,26 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal */ protected $productRepository; - /** - * @var MediaConfig - */ - protected $mediaConfig; - /** * @var \Magento\Catalog\Model\Product\Gallery\ContentValidator */ protected $contentValidator; - /** - * @var \Magento\Framework\Filesystem - */ - protected $filesystem; - - /** - * @var \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory - */ - protected $entryFactory; - - /** - * @var \Magento\Catalog\Model\Resource\Product\Attribute\Backend\Media - */ - protected $mediaGallery; - - /** - * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface - */ - protected $attributeRepository; - - /** - * @var \Magento\Framework\Api\DataObjectHelper - */ - protected $dataObjectHelper; - /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository - * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository - * @param MediaConfig $mediaConfig * @param ContentValidator $contentValidator - * @param \Magento\Framework\Filesystem $filesystem - * @param EntryResolver $entryResolver - * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $entryFactory - * @param \Magento\Catalog\Model\Resource\Product\Attribute\Backend\Media $mediaGallery - * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Api\ProductRepositoryInterface $productRepository, - \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository, - MediaConfig $mediaConfig, - \Magento\Catalog\Model\Product\Gallery\ContentValidator $contentValidator, - \Magento\Framework\Filesystem $filesystem, - EntryResolver $entryResolver, - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory $entryFactory, - \Magento\Catalog\Model\Resource\Product\Attribute\Backend\Media $mediaGallery, - \Magento\Framework\Api\DataObjectHelper $dataObjectHelper + \Magento\Catalog\Model\Product\Gallery\ContentValidator $contentValidator ) { $this->productRepository = $productRepository; $this->storeManager = $storeManager; - $this->attributeRepository = $attributeRepository; - $this->mediaConfig = $mediaConfig; $this->contentValidator = $contentValidator; - $this->filesystem = $filesystem; - $this->entryResolver = $entryResolver; - $this->entryFactory = $entryFactory; - $this->mediaGallery = $mediaGallery; - $this->dataObjectHelper = $dataObjectHelper; } /** @@ -123,93 +58,56 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal */ protected function getGalleryAttributeBackend(Product $product) { - $attributes = $product->getTypeInstance()->getSetAttributes($product); - if (!isset($attributes['media_gallery']) - || !($attributes['media_gallery'] instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute) - ) { + $galleryAttributeBackend = $product->getGalleryAttributeBackend(); + if ($galleryAttributeBackend == null) { throw new StateException(__('Requested product does not support images.')); } - /** @var $galleryAttribute \Magento\Eav\Model\Entity\Attribute\AbstractAttribute */ - $galleryAttribute = $attributes['media_gallery']; - return $galleryAttribute->getBackend(); - } - - /** - * Retrieve assoc array that contains media attribute values of the given product - * - * @param Product $product - * @return array - */ - protected function getMediaAttributeValues(Product $product) - { - $mediaAttributeCodes = array_keys($product->getMediaAttributes()); - $mediaAttributeValues = []; - foreach ($mediaAttributeCodes as $attributeCode) { - $mediaAttributeValues[$attributeCode] = $product->getData($attributeCode); - } - return $mediaAttributeValues; + return $galleryAttributeBackend; } /** * {@inheritdoc} */ - public function create($product) + public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry, $storeId = 0) { try { - $this->storeManager->getStore($product->getStoreId()); + $this->storeManager->getStore($storeId); } catch (\Exception $exception) { throw new NoSuchEntityException(__('There is no store with provided ID.')); } /** @var $entry ProductAttributeMediaGalleryEntryInterface */ - $entry = $product->getCustomAttribute('media_gallery')->getValue(); $entryContent = $entry->getContent(); if (!$this->contentValidator->isValid($entryContent)) { throw new InputException(__('The image content is not valid.')); } - $product = $this->productRepository->get($product->getSku()); - - $fileContent = @base64_decode($entryContent->getEntryData(), true); - $mediaTmpPath = $this->mediaConfig->getBaseTmpMediaPath(); - $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); - $mediaDirectory->create($mediaTmpPath); - $fileName = $entryContent->getName() . '.' . $this->mimeTypeExtensionMap[$entryContent->getMimeType()]; - $relativeFilePath = $mediaTmpPath . DIRECTORY_SEPARATOR . $fileName; - $absoluteFilePath = $mediaDirectory->getAbsolutePath($relativeFilePath); - $mediaDirectory->writeFile($relativeFilePath, $fileContent); - - /** @var $productMediaGallery \Magento\Catalog\Model\Product\Attribute\Backend\Media */ - $productMediaGallery = $this->getGalleryAttributeBackend($product); - $imageFileUri = $productMediaGallery->addImage( - $product, - $absoluteFilePath, - $entry->getTypes(), - true, - $entry->isDisabled() - ); - // Update additional fields that are still empty after addImage call - $productMediaGallery->updateImage( - $product, - $imageFileUri, - [ - 'label' => $entry->getLabel(), - 'position' => $entry->getPosition(), - 'disabled' => $entry->isDisabled(), - ] - ); + $product = $this->productRepository->get($sku); + $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); + $existingEntryIds = []; + if ($existingMediaGalleryEntries == null) { + $existingMediaGalleryEntries = [$entry]; + } else { + foreach ($existingMediaGalleryEntries as $existingEntries) { + $existingEntryIds[$existingEntries->getId()] = $existingEntries->getId(); + } + $existingMediaGalleryEntries[] = $entry; + } + $product->setMediaGalleryEntries($existingMediaGalleryEntries); try { - $this->productRepository->save($product); + $product = $this->productRepository->save($product); + } catch (InputException $inputException) { + throw $inputException; } catch (\Exception $e) { throw new StateException(__('Cannot save product.')); } - // Remove all temporary files - $mediaDirectory->delete($relativeFilePath); - // File could change its name during the move from tmp dir - return $this->entryResolver->getEntryIdByFilePath( - $product, - $productMediaGallery->getRenamedImage($imageFileUri) - ); + + foreach ($product->getMediaGalleryEntries() as $entry) { + if (!isset($existingEntryIds[$entry->getId()])) { + return $entry->getId(); + } + } + throw new StateException(__('Failed to save new media gallery entry.')); } /** @@ -223,24 +121,22 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal throw new NoSuchEntityException(__('There is no store with provided ID.')); } $product = $this->productRepository->get($sku); - /** @var $productMediaGallery \Magento\Catalog\Model\Product\Attribute\Backend\Media */ - $productMediaGallery = $this->getGalleryAttributeBackend($product); - $filePath = $this->entryResolver->getEntryFilePathById($product, $entry->getId()); - if ($filePath === null) { + $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); + if ($existingMediaGalleryEntries == null) { throw new NoSuchEntityException(__('There is no image with provided ID.')); } - - $productMediaGallery->updateImage( - $product, - $filePath, - [ - 'label' => $entry->getLabel(), - 'position' => $entry->getPosition(), - 'disabled' => $entry->isDisabled(), - ] - ); - $productMediaGallery->clearMediaAttribute($product, array_keys($product->getMediaAttributes())); - $productMediaGallery->setMediaAttribute($product, $entry->getTypes(), $filePath); + $found = false; + foreach ($existingMediaGalleryEntries as $key => $existingEntry) { + if ($existingEntry->getId() == $entry->getId()) { + $found = true; + $existingMediaGalleryEntries[$key] = $entry; + break; + } + } + if (!$found) { + throw new NoSuchEntityException(__('There is no image with provided ID.')); + } + $product->setMediaGalleryEntries($existingMediaGalleryEntries); $product->setStoreId($storeId); try { @@ -257,14 +153,22 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal public function remove($sku, $entryId) { $product = $this->productRepository->get($sku); - /** @var $productMediaGallery \Magento\Catalog\Model\Product\Attribute\Backend\Media */ - $productMediaGallery = $this->getGalleryAttributeBackend($product); - $filePath = $this->entryResolver->getEntryFilePathById($product, $entryId); - if ($filePath === null) { + $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); + if ($existingMediaGalleryEntries == null) { throw new NoSuchEntityException(__('There is no image with provided ID.')); } - - $productMediaGallery->removeImage($product, $filePath); + $found = false; + foreach ($existingMediaGalleryEntries as $key => $entry) { + if ($entry->getId() == $entryId) { + unset($existingMediaGalleryEntries[$key]); + $found = true; + break; + } + } + if (!$found) { + throw new NoSuchEntityException(__('There is no image with provided ID.')); + } + $product->setMediaGalleryEntries($existingMediaGalleryEntries); $this->productRepository->save($product); return true; } @@ -280,25 +184,14 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal throw new NoSuchEntityException(__('Such product doesn\'t exist')); } - $output = null; - $productImages = $this->getMediaAttributeValues($product); - foreach ((array)$product->getMediaGallery('images') as $image) { - if (intval($image['value_id']) == intval($imageId)) { - $image['types'] = array_keys($productImages, $image['file']); - $output = $this->entryFactory->create(); - $this->dataObjectHelper->populateWithArray( - $output, - $image, - '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface' - ); - break; + $mediaGalleryEntries = $product->getMediaGalleryEntries(); + foreach ($mediaGalleryEntries as $entry) { + if ($entry->getId() == $imageId) { + return $entry; } } - if ($output === null) { - throw new NoSuchEntityException(__('Such image doesn\'t exist')); - } - return $output; + throw new NoSuchEntityException(__('Such image doesn\'t exist')); } /** @@ -306,29 +199,9 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal */ public function getList($sku) { - $result = []; /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productRepository->get($sku); - /** @var \Magento\Catalog\Api\Data\ProductAttributeInterface $galleryAttribute */ - $galleryAttribute = $this->attributeRepository->get('media_gallery'); - - $container = new \Magento\Framework\Object(['attribute' => $galleryAttribute]); - $gallery = $this->mediaGallery->loadGallery($product, $container); - - $productImages = $this->getMediaAttributeValues($product); - - foreach ($gallery as $image) { - /** @var \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface $entry */ - $entry = $this->entryFactory->create(); - $entry->setId($image['value_id']) - ->setLabel($image['label_default']) - ->setTypes(array_keys($productImages, $image['file'])) - ->setDisabled($image['disabled_default']) - ->setPosition($image['position_default']) - ->setFile($image['file']); - $result[] = $entry; - } - return $result; + return $product->getMediaGalleryEntries(); } } diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/MimeTypeExtensionMap.php b/app/code/Magento/Catalog/Model/Product/Gallery/MimeTypeExtensionMap.php new file mode 100644 index 0000000000000000000000000000000000000000..2142c860eea96e87edc67a3b242adb85015fcc35 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Gallery/MimeTypeExtensionMap.php @@ -0,0 +1,38 @@ +<?php +/** + * + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\Product\Gallery; + +use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface; +use Magento\Framework\Exception\InputException; + +class MimeTypeExtensionMap +{ + /** + * MIME type/extension map + * + * @var array + */ + protected $mimeTypeExtensionMap = [ + 'image/jpg' => 'jpg', + 'image/jpeg' => 'jpg', + 'image/gif' => 'gif', + 'image/png' => 'png', + ]; + + /** + * @param string $mimeType + * @return string + */ + public function getMimeTypeExtension($mimeType) + { + if (isset($this->mimeTypeExtensionMap[$mimeType])) { + return $this->mimeTypeExtensionMap[$mimeType]; + } else { + return ""; + } + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php index 3afdf86af8f964579c65ced1115c779102f3a8c7..5b9211099d6549f308ca1e3edd1f49f68a7380fb 100644 --- a/app/code/Magento/Catalog/Model/Product/Option.php +++ b/app/code/Magento/Catalog/Model/Product/Option.php @@ -87,7 +87,7 @@ class Option extends AbstractModel implements \Magento\Catalog\Api\Data\ProductC /** * @var array */ - protected $_values = []; + protected $_values = null; /** * Catalog product option value @@ -557,7 +557,7 @@ class Option extends AbstractModel implements \Magento\Catalog\Api\Data\ProductC protected function _clearData() { $this->_data = []; - $this->_values = []; + $this->_values = null; return $this; } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Converter.php b/app/code/Magento/Catalog/Model/Product/Option/Converter.php index ac59498ccb58c323e6ce629bb0e2639b8e33b6db..783afd93a2a13f41030a047349d10e93ef3135ec 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Converter.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Converter.php @@ -9,20 +9,6 @@ namespace Magento\Catalog\Model\Product\Option; class Converter { - /** - * @var \Magento\Catalog\Api\ProductRepositoryInterface - */ - protected $productRepository; - - /** - * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository - */ - public function __construct( - \Magento\Catalog\Api\ProductRepositoryInterface $productRepository - ) { - $this->productRepository = $productRepository; - } - /** * Convert option data to array * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface $option diff --git a/app/code/Magento/Catalog/Model/Product/Option/Repository.php b/app/code/Magento/Catalog/Model/Product/Option/Repository.php index fe12e17d73de04fcd54ca6545c5e955593eace78..159e6eac1884b3f8cd6c1a404e6d80f14c23407d 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Repository.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Repository.php @@ -103,8 +103,12 @@ class Repository implements \Magento\Catalog\Api\ProductCustomOptionRepositoryIn $product = $this->productRepository->get($sku, true); if (!$option->getOptionId()) { $currentOptions = $product->getOptions(); + if ($existingOptions == null) { + $newID = array_keys($currentOptions); + } else { + $newID = array_diff(array_keys($currentOptions), array_keys($existingOptions)); + } - $newID = array_diff(array_keys($currentOptions), array_keys($existingOptions)); if (empty($newID)) { throw new CouldNotSaveException(__('Could not save product option')); } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php index 3074ed6fdf26e803747f172091c3508b90496908..41dfc06bd23febd38920595676bd5851ef2e9133 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php @@ -359,23 +359,26 @@ class DefaultType extends \Magento\Framework\Object public function getProductOptions() { if (!isset($this->_productOptions[$this->getProduct()->getId()])) { - foreach ($this->getProduct()->getOptions() as $_option) { - /* @var $option \Magento\Catalog\Model\Product\Option */ - $this->_productOptions[$this->getProduct()->getId()][$_option->getTitle()] = [ - 'option_id' => $_option->getId(), - ]; - if ($_option->getGroupByType() == \Magento\Catalog\Model\Product\Option::OPTION_GROUP_SELECT) { - $optionValues = []; - foreach ($_option->getValues() as $_value) { - /* @var $value \Magento\Catalog\Model\Product\Option\Value */ - $optionValues[$_value->getTitle()] = $_value->getId(); + $options = $this->getProduct()->getOptions(); + if ($options != null) { + foreach ($options as $_option) { + /* @var $option \Magento\Catalog\Model\Product\Option */ + $this->_productOptions[$this->getProduct()->getId()][$_option->getTitle()] = [ + 'option_id' => $_option->getId(), + ]; + if ($_option->getGroupByType() == \Magento\Catalog\Model\Product\Option::OPTION_GROUP_SELECT) { + $optionValues = []; + foreach ($_option->getValues() as $_value) { + /* @var $value \Magento\Catalog\Model\Product\Option\Value */ + $optionValues[$_value->getTitle()] = $_value->getId(); + } + $this->_productOptions[$this + ->getProduct() + ->getId()][$_option + ->getTitle()]['values'] = $optionValues; + } else { + $this->_productOptions[$this->getProduct()->getId()][$_option->getTitle()]['values'] = []; } - $this->_productOptions[$this - ->getProduct() - ->getId()][$_option - ->getTitle()]['values'] = $optionValues; - } else { - $this->_productOptions[$this->getProduct()->getId()][$_option->getTitle()]['values'] = []; } } } diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index 4f28981a036f82c1da0c118483cd3f1bc5a1fb8f..6f8c0395a31585df207430a83fd46b6f323c1c7d 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -55,6 +55,27 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme return $this->setData(self::VALUE, $value); } + /** + * Retrieve customer group id + * + * @return int + */ + public function getCustomerGroupId() + { + return $this->getData(self::CUSTOMER_GROUP_ID); + } + + /** + * Set customer group id + * + * @param int $customerGroupId + * @return $this + */ + public function setCustomerGroupId($customerGroupId) + { + return $this->setData(self::CUSTOMER_GROUP_ID, $customerGroupId); + } + /** * {@inheritdoc} * diff --git a/app/code/Magento/Catalog/Model/Product/TierPriceManagement.php b/app/code/Magento/Catalog/Model/Product/TierPriceManagement.php index 73ae4f96ea9becf98147146a80eb2b87286b2695..534e7b1781ddd63e52fa406d72a4930d1bbb389b 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPriceManagement.php +++ b/app/code/Magento/Catalog/Model/Product/TierPriceManagement.php @@ -170,6 +170,10 @@ class TierPriceManagement implements \Magento\Catalog\Api\ProductTierPriceManage $priceKey = 'price'; } + $cgi = ($customerGroupId === 'all' + ? $this->groupManagement->getAllCustomersGroup()->getId() + : $customerGroupId); + $prices = []; foreach ($product->getData('tier_price') as $price) { if ((is_numeric($customerGroupId) && intval($price['cust_group']) === intval($customerGroupId)) @@ -178,7 +182,8 @@ class TierPriceManagement implements \Magento\Catalog\Api\ProductTierPriceManage /** @var \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice */ $tierPrice = $this->priceFactory->create(); $tierPrice->setValue($price[$priceKey]) - ->setQty($price['price_qty']); + ->setQty($price['price_qty']) + ->setCustomerGroupId($cgi); $prices[] = $tierPrice; } } diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index bb2306e2ab15577630cac22c481d3cdcc335d174..10414b85e006a28e23ea850b9fcfe5e622245925 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -13,6 +13,7 @@ use Magento\Store\Model\Store; /** * Product type price model + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Price { @@ -69,6 +70,21 @@ class Price */ protected $_groupManagement; + /** + * @var \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory + */ + protected $groupPriceFactory; + + /** + * @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory + */ + protected $tierPriceFactory; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface + */ + protected $config; + /** * @param \Magento\CatalogRule\Model\Resource\RuleFactory $ruleFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -77,6 +93,11 @@ class Price * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param PriceCurrencyInterface $priceCurrency * @param GroupManagementInterface $groupManagement + * @param \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory $groupPriceFactory + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\CatalogRule\Model\Resource\RuleFactory $ruleFactory, @@ -85,7 +106,10 @@ class Price \Magento\Customer\Model\Session $customerSession, \Magento\Framework\Event\ManagerInterface $eventManager, PriceCurrencyInterface $priceCurrency, - GroupManagementInterface $groupManagement + GroupManagementInterface $groupManagement, + \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory $groupPriceFactory, + \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory, + \Magento\Framework\App\Config\ScopeConfigInterface $config ) { $this->_ruleFactory = $ruleFactory; $this->_storeManager = $storeManager; @@ -94,6 +118,9 @@ class Price $this->_eventManager = $eventManager; $this->priceCurrency = $priceCurrency; $this->_groupManagement = $groupManagement; + $this->groupPriceFactory = $groupPriceFactory; + $this->tierPriceFactory = $tierPriceFactory; + $this->config = $config; } /** @@ -181,25 +208,118 @@ class Price } /** - * Get product group price + * Gets list of product group prices * * @param Product $product - * @return float - * @deprecated see \Magento\Catalog\Pricing\Price\GroupPrice (MAGETWO-31468) + * @return \Magento\Catalog\Api\Data\ProductGroupPriceInterface[] */ - public function getGroupPrice($product) + public function getGroupPrices($product) { - $groupPrices = $product->getData('group_price'); + $prices = []; + $groupPrices = $this->getExistingPrices($product, 'group_price'); + foreach ($groupPrices as $price) { + /** @var \Magento\Catalog\Api\Data\ProductGroupPriceInterface $groupPrice */ + $groupPrice = $this->groupPriceFactory->create(); + $groupPrice->setCustomerGroupId($price['cust_group']); + if (array_key_exists('website_price', $price)) { + $value = $price['website_price']; + } else { + $value = $price['price']; + } + $groupPrice->setValue($value); + $prices[] = $groupPrice; + } + return $prices; + } - if ($groupPrices === null) { - $attribute = $product->getResource()->getAttribute('group_price'); + /** + * Gets the 'group_price' array from the product + * + * @param Product $product + * @param string $key + * @param bool $returnRawData + * @return array + */ + protected function getExistingPrices($product, $key, $returnRawData = false) + { + $prices = $product->getData($key); + + if ($prices === null) { + $attribute = $product->getResource()->getAttribute($key); if ($attribute) { $attribute->getBackend()->afterLoad($product); - $groupPrices = $product->getData('group_price'); + $prices = $product->getData($key); } } - if ($groupPrices === null || !is_array($groupPrices)) { + if ($prices === null || !is_array($prices)) { + return ($returnRawData ? $prices : []); + } + + return $prices; + } + + /** + * Sets list of product group prices + * + * @param Product $product + * @param \Magento\Catalog\Api\Data\ProductGroupPriceInterface[] $groupPrices + * @return $this + */ + public function setGroupPrices($product, array $groupPrices = null) + { + // null array means leave everything as is + if ($groupPrices === null) { + return $this; + } + + $websiteId = $this->getWebsiteForPriceScope(); + $allGroupsId = $this->getAllCustomerGroupsId(); + + // build the new array of group prices + $prices = []; + foreach ($groupPrices as $price) { + $prices[] = [ + 'website_id' => $websiteId, + 'cust_group' => $price->getCustomerGroupId(), + 'website_price' => $price->getValue(), + 'price' => $price->getValue(), + 'all_groups' => ($price->getCustomerGroupId() == $allGroupsId) + ]; + } + $product->setData('group_price', $prices); + + return $this; + } + + /** + * Returns the website to use for group or tier prices, based on the price scope setting + * + * @return int|mixed + */ + protected function getWebsiteForPriceScope() + { + $websiteId = 0; + $value = $this->config->getValue('catalog/price/scope', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE); + if ($value != 0) { + // use the website associated with the current store + $websiteId = $this->_storeManager->getWebsite()->getId(); + } + return $websiteId; + } + + /** + * Get product group price for the customer + * + * @param Product $product + * @return float + * @deprecated see \Magento\Catalog\Pricing\Price\GroupPrice (MAGETWO-31468) + */ + public function getGroupPrice($product) + { + $groupPrices = $this->getGroupPrices($product); + + if (empty($groupPrices)) { return $product->getPrice(); } @@ -207,8 +327,9 @@ class Price $matchedPrice = $product->getPrice(); foreach ($groupPrices as $groupPrice) { - if ($groupPrice['cust_group'] == $customerGroup && $groupPrice['website_price'] < $matchedPrice) { - $matchedPrice = $groupPrice['website_price']; + /** @var \Magento\Catalog\Api\Data\ProductGroupPriceInterface $groupPrice */ + if ($groupPrice->getCustomerGroupId() == $customerGroup && $groupPrice->getValue() < $matchedPrice) { + $matchedPrice = $groupPrice->getValue(); break; } } @@ -249,39 +370,32 @@ class Price */ public function getTierPrice($qty, $product) { - $allGroups = $this->_groupManagement->getAllCustomersGroup()->getId(); - $prices = $product->getData('tier_price'); - - if ($prices === null) { - $attribute = $product->getResource()->getAttribute('tier_price'); - if ($attribute) { - $attribute->getBackend()->afterLoad($product); - $prices = $product->getData('tier_price'); - } - } + $allGroupsId = $this->getAllCustomerGroupsId(); + $prices = $this->getExistingPrices($product, 'tier_price', true); if ($prices === null || !is_array($prices)) { if ($qty !== null) { return $product->getPrice(); + } else { + return [ + [ + 'price' => $product->getPrice(), + 'website_price' => $product->getPrice(), + 'price_qty' => 1, + 'cust_group' => $allGroupsId, + ] + ]; } - return [ - [ - 'price' => $product->getPrice(), - 'website_price' => $product->getPrice(), - 'price_qty' => 1, - 'cust_group' => $allGroups, - ] - ]; } $custGroup = $this->_getCustomerGroupId($product); if ($qty) { $prevQty = 1; $prevPrice = $product->getPrice(); - $prevGroup = $allGroups; + $prevGroup = $allGroupsId; foreach ($prices as $price) { - if ($price['cust_group'] != $custGroup && $price['cust_group'] != $allGroups) { + if ($price['cust_group'] != $custGroup && $price['cust_group'] != $allGroupsId) { // tier not for current customer group nor is for all groups continue; } @@ -293,8 +407,9 @@ class Price // higher tier qty already found continue; } - if ($price['price_qty'] == $prevQty && $prevGroup != $allGroups && $price['cust_group'] == $allGroups - ) { + if ($price['price_qty'] == $prevQty && + $prevGroup != $allGroupsId && + $price['cust_group'] == $allGroupsId) { // found tier qty is same as current tier qty but current tier group is ALL_GROUPS continue; } @@ -308,7 +423,7 @@ class Price } else { $qtyCache = []; foreach ($prices as $priceKey => $price) { - if ($price['cust_group'] != $custGroup && $price['cust_group'] != $allGroups) { + if ($price['cust_group'] != $custGroup && $price['cust_group'] != $allGroupsId) { unset($prices[$priceKey]); } elseif (isset($qtyCache[$price['price_qty']])) { $priceQty = $qtyCache[$price['price_qty']]; @@ -327,6 +442,77 @@ class Price return $prices ? $prices : []; } + /** + * Gets the CUST_GROUP_ALL id + * + * @return int + */ + protected function getAllCustomerGroupsId() + { + // ex: 32000 + return $this->_groupManagement->getAllCustomersGroup()->getId(); + } + + /** + * Gets list of product tier prices + * + * @param Product $product + * @return \Magento\Catalog\Api\Data\ProductTierPriceInterface[] + */ + public function getTierPrices($product) + { + $prices = []; + $tierPrices = $this->getExistingPrices($product, 'tier_price'); + foreach ($tierPrices as $price) { + /** @var \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice */ + $tierPrice = $this->tierPriceFactory->create(); + $tierPrice->setCustomerGroupId($price['cust_group']); + if (array_key_exists('website_price', $price)) { + $value = $price['website_price']; + } else { + $value = $price['price']; + } + $tierPrice->setValue($value); + $tierPrice->setQty($price['price_qty']); + $prices[] = $tierPrice; + } + return $prices; + } + + /** + * Sets list of product tier prices + * + * @param Product $product + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface[] $tierPrices + * @return $this + */ + public function setTierPrices($product, array $tierPrices = null) + { + // null array means leave everything as is + if ($tierPrices === null) { + return $this; + } + + $websiteId = $this->getWebsiteForPriceScope(); + $allGroupsId = $this->getAllCustomerGroupsId(); + + // build the new array of tier prices + $prices = []; + foreach ($tierPrices as $price) { + $prices[] = [ + 'website_id' => $websiteId, + 'cust_group' => $price->getCustomerGroupId(), + 'website_price' => $price->getValue(), + 'price' => $price->getValue(), + 'all_groups' => ($price->getCustomerGroupId() == $allGroupsId), + 'price_qty' => $price->getQty() + ]; + } + $product->setData('tier_price', $prices); + + return $this; + } + /** * @param Product $product * @return int diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index ae3fd0df2e6c8a4f5963957eead7caff999ba57f..43fa06093960b8abab062c90bb649cde53164d96 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -10,9 +10,18 @@ use Magento\Catalog\Model\Resource\Product\Collection; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Api\SortOrder; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Framework\Exception\InputException; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\StateException; +use Magento\Catalog\Model\Product\Gallery\ContentValidator; +use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterfaceFactory; +use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface; +use Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterface { @@ -61,6 +70,11 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa */ protected $resourceModel; + /* + * @var \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks + */ + protected $linkInitializer; + /** * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface */ @@ -81,6 +95,31 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa */ protected $extensibleDataObjectConverter; + /** + * @var \Magento\Catalog\Model\Product\Option\Converter + */ + protected $optionConverter; + + /** + * @var \Magento\Framework\Filesystem + */ + protected $fileSystem; + + /** + * @var ContentValidator + */ + protected $contentValidator; + + /** + * @var ProductAttributeMediaGalleryEntryContentInterfaceFactory + */ + protected $contentFactory; + + /** + * @var MimeTypeExtensionMap + */ + protected $mimeTypeExtensionMap; + /** * @param ProductFactory $productFactory * @param \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $initializationHelper @@ -89,10 +128,16 @@ 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\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 \Magento\Framework\Filesystem $fileSystem + * @param ContentValidator $contentValidator + * @param ProductAttributeMediaGalleryEntryContentInterfaceFactory $contentFactory + * @param MimeTypeExtensionMap $mimeTypeExtensionMap * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -103,9 +148,15 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository, \Magento\Catalog\Model\Resource\Product $resourceModel, + \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer, \Magento\Framework\Api\FilterBuilder $filterBuilder, \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface, \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter, + \Magento\Catalog\Model\Product\Option\Converter $optionConverter, + \Magento\Framework\Filesystem $fileSystem, + ContentValidator $contentValidator, + ProductAttributeMediaGalleryEntryContentInterfaceFactory $contentFactory, + MimeTypeExtensionMap $mimeTypeExtensionMap, \Magento\Eav\Model\Config $eavConfig ) { $this->productFactory = $productFactory; @@ -114,10 +165,16 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa $this->searchResultsFactory = $searchResultsFactory; $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->resourceModel = $resourceModel; + $this->linkInitializer = $linkInitializer; $this->attributeRepository = $attributeRepository; $this->filterBuilder = $filterBuilder; $this->metadataService = $metadataServiceInterface; $this->extensibleDataObjectConverter = $extensibleDataObjectConverter; + $this->optionConverter = $optionConverter; + $this->fileSystem = $fileSystem; + $this->contentValidator = $contentValidator; + $this->contentFactory = $contentFactory; + $this->mimeTypeExtensionMap = $mimeTypeExtensionMap; $this->eavConfig = $eavConfig; } @@ -203,6 +260,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa if ($createNew) { $product = $this->productFactory->create(); } else { + unset($this->instances[$productData['sku']]); $product = $this->get($productData['sku']); $this->initializationHelper->initialize($product); } @@ -213,21 +271,287 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa return $product; } + /** + * Process product options, creating new options, updating and deleting existing options + * + * @param \Magento\Catalog\Api\Data\ProductInterface $product + * @param array $newOptions + * @return $this + * @throws NoSuchEntityException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + private function processOptions(\Magento\Catalog\Api\Data\ProductInterface $product, $newOptions) + { + //existing options by option_id + /** @var \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $existingOptions */ + $existingOptions = $product->getOptions(); + if ($existingOptions === null) { + $existingOptions = []; + } + + $newOptionIds = []; + foreach ($newOptions as $key => $option) { + if (isset($option['option_id'])) { + //updating existing option + $optionId = $option['option_id']; + if (!isset($existingOptions[$optionId])) { + throw new NoSuchEntityException(__('Product option with id %1 does not exist', $optionId)); + } + $existingOption = $existingOptions[$optionId]; + $newOptionIds[] = $option['option_id']; + if (isset($option['values'])) { + //updating option values + $optionValues = $option['values']; + $valueIds = []; + foreach ($optionValues as $optionValue) { + if (isset($optionValue['option_type_id'])) { + $valueIds[] = $optionValue['option_type_id']; + } + } + $originalValues = $existingOption->getValues(); + foreach ($originalValues as $originalValue) { + if (!in_array($originalValue->getOptionTypeId(), $valueIds)) { + $originalValue->setData('is_delete', 1); + $optionValues[] = $originalValue->getData(); + } + } + $newOptions[$key]['values'] = $optionValues; + } else { + $existingOptionData = $this->optionConverter->toArray($existingOption); + if (isset($existingOptionData['values'])) { + $newOptions[$key]['values'] = $existingOptionData['values']; + } + } + } + } + + $optionIdsToDelete = array_diff(array_keys($existingOptions), $newOptionIds); + foreach ($optionIdsToDelete as $optionId) { + $optionToDelete = $existingOptions[$optionId]; + $optionDataArray = $this->optionConverter->toArray($optionToDelete); + $optionDataArray['is_delete'] = 1; + $newOptions[] = $optionDataArray; + } + $product->setProductOptions($newOptions); + return $this; + } + + /** + * Process product links, creating new links, updating and deleting existing links + * + * @param \Magento\Catalog\Api\Data\ProductInterface $product + * @param \Magento\Catalog\Api\Data\ProductLinkInterface[] $newLinks + * @return $this + * @throws NoSuchEntityException + */ + private function processLinks(\Magento\Catalog\Api\Data\ProductInterface $product, $newLinks) + { + if ($newLinks === null) { + // If product links were not specified, don't do anything + return $this; + } + + // Clear all existing product links and then set the ones we want + $this->linkInitializer->initializeLinks($product, ['related' => []]); + $this->linkInitializer->initializeLinks($product, ['upsell' => []]); + $this->linkInitializer->initializeLinks($product, ['crosssell' => []]); + + // Gather each linktype info + if (!empty($newLinks)) { + $productLinks = []; + foreach ($newLinks as $link) { + $productLinks[$link->getLinkType()][] = $link; + } + + foreach ($productLinks as $type => $linksByType) { + $assignedSkuList = []; + /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $link */ + foreach ($linksByType as $link) { + $assignedSkuList[] = $link->getLinkedProductSku(); + } + $linkedProductIds = $this->resourceModel->getProductsIdsBySkus($assignedSkuList); + + $linksToInitialize = []; + foreach ($linksByType as $link) { + $linkDataArray = $this->extensibleDataObjectConverter + ->toNestedArray($link, [], 'Magento\Catalog\Api\Data\ProductLinkInterface'); + $linkedSku = $link->getLinkedProductSku(); + if (!isset($linkedProductIds[$linkedSku])) { + throw new NoSuchEntityException( + __('Product with SKU "%1" does not exist', $linkedSku) + ); + } + $linkDataArray['product_id'] = $linkedProductIds[$linkedSku]; + $linksToInitialize[$linkedProductIds[$linkedSku]] = $linkDataArray; + } + + $this->linkInitializer->initializeLinks($product, [$type => $linksToInitialize]); + } + } + + $product->setProductLinks($newLinks); + return $this; + } + + /** + * @param ProductInterface $product + * @param array $newEntry + * @return $this + * @throws InputException + * @throws StateException + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected function processNewMediaGalleryEntry( + ProductInterface $product, + array $newEntry + ) { + /** @var ProductAttributeMediaGalleryEntryContentInterface $contentDataObject */ + $contentDataObject = $newEntry['content']; + if (!$this->contentValidator->isValid($contentDataObject)) { + throw new InputException(__('The image content is not valid.')); + } + + $fileContent = @base64_decode($contentDataObject->getEntryData(), true); + $fileName = $contentDataObject->getName(); + $mimeType = $contentDataObject->getMimeType(); + + /** @var \Magento\Catalog\Model\Product\Media\Config $mediaConfig */ + $mediaConfig = $product->getMediaConfig(); + $mediaTmpPath = $mediaConfig->getBaseTmpMediaPath(); + $mediaDirectory = $this->fileSystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory->create($mediaTmpPath); + $fileName = $fileName . '.' . $this->mimeTypeExtensionMap->getMimeTypeExtension($mimeType); + $relativeFilePath = $mediaTmpPath . DIRECTORY_SEPARATOR . $fileName; + $absoluteFilePath = $mediaDirectory->getAbsolutePath($relativeFilePath); + $mediaDirectory->writeFile($relativeFilePath, $fileContent); + + /** @var \Magento\Catalog\Model\Product\Attribute\Backend\Media $galleryAttributeBackend */ + $galleryAttributeBackend = $product->getGalleryAttributeBackend(); + if ($galleryAttributeBackend == null) { + throw new StateException(__('Requested product does not support images.')); + } + + $imageFileUri = $galleryAttributeBackend->addImage( + $product, + $absoluteFilePath, + isset($newEntry['types']) ? $newEntry['types'] : [], + true, + isset($newEntry['disabled']) ? $newEntry['disabled'] : true + ); + // Update additional fields that are still empty after addImage call + $galleryAttributeBackend->updateImage( + $product, + $imageFileUri, + [ + 'label' => $newEntry['label'], + 'position' => $newEntry['position'], + 'disabled' => $newEntry['disabled'], + ] + ); + return $this; + } + + /** + * @param ProductInterface $product + * @param array $mediaGalleryEntries + * @return $this + * @throws InputException + * @throws StateException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + protected function processMediaGallery(ProductInterface $product, $mediaGalleryEntries) + { + $existingMediaGallery = $product->getMediaGallery('images'); + $newEntries = []; + if (!empty($existingMediaGallery)) { + $entriesById = []; + foreach ($mediaGalleryEntries as $entry) { + if (isset($entry['id'])) { + $entry['value_id'] = $entry['id']; + $entriesById[$entry['value_id']] = $entry; + } else { + $newEntries[] = $entry; + } + } + foreach ($existingMediaGallery as $key => &$existingEntry) { + if (isset($entriesById[$existingEntry['value_id']])) { + $updatedEntry = $entriesById[$existingEntry['value_id']]; + $existingMediaGallery[$key] = array_merge($existingEntry, $updatedEntry); + } else { + //set the removed flag + $existingEntry['removed'] = true; + } + } + $product->setData('media_gallery', ["images" => $existingMediaGallery]); + } else { + $newEntries = $mediaGalleryEntries; + } + + /** @var \Magento\Catalog\Model\Product\Attribute\Backend\Media $galleryAttributeBackend */ + $galleryAttributeBackend = $product->getGalleryAttributeBackend(); + $galleryAttributeBackend->clearMediaAttribute($product, array_keys($product->getMediaAttributes())); + $images = $product->getMediaGallery('images'); + if ($images) { + foreach ($images as $image) { + if (!isset($image['removed']) && !empty($image['types'])) { + $galleryAttributeBackend->setMediaAttribute($product, $image['types'], $image['file']); + } + } + } + + foreach ($newEntries as $newEntry) { + if (!isset($newEntry['content'])) { + throw new InputException(__('The image content is not valid.')); + } + /** @var ProductAttributeMediaGalleryEntryContentInterface $contentDataObject */ + $contentDataObject = $this->contentFactory->create() + ->setName($newEntry['content']['name']) + ->setEntryData($newEntry['content']['entry_data']) + ->setMimeType($newEntry['content']['mime_type']); + $newEntry['content'] = $contentDataObject; + $this->processNewMediaGalleryEntry($product, $newEntry); + } + return $this; + } + /** * {@inheritdoc} + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false) { if ($saveOptions) { $productOptions = $product->getProductOptions(); } + $isDeleteOptions = $product->getIsDeleteOptions(); $groupPrices = $product->getData('group_price'); $tierPrices = $product->getData('tier_price'); $productId = $this->resourceModel->getIdBySku($product->getSku()); + $ignoreLinksFlag = $product->getData('ignore_links_flag'); $productDataArray = $this->extensibleDataObjectConverter ->toNestedArray($product, [], 'Magento\Catalog\Api\Data\ProductInterface'); + + $productLinks = null; + if (!$ignoreLinksFlag && $ignoreLinksFlag !== null) { + $productLinks = $product->getProductLinks(); + } + $product = $this->initializeProductData($productDataArray, empty($productId)); + + if (isset($productDataArray['options'])) { + if (!empty($productDataArray['options']) || $isDeleteOptions) { + $this->processOptions($product, $productDataArray['options']); + $product->setCanSaveCustomOptions(true); + } + } + + $this->processLinks($product, $productLinks); + if (isset($productDataArray['media_gallery_entries'])) { + $this->processMediaGallery($product, $productDataArray['media_gallery_entries']); + } + $validationResult = $this->resourceModel->validate($product); if (true !== $validationResult) { throw new \Magento\Framework\Exception\CouldNotSaveException( @@ -239,8 +563,12 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa $product->setProductOptions($productOptions); $product->setCanSaveCustomOptions(true); } - $product->setData('group_price', $groupPrices); - $product->setData('tier_price', $tierPrices); + if ($groupPrices !== null) { + $product->setData('group_price', $groupPrices); + } + if ($tierPrices !== null) { + $product->setData('tier_price', $tierPrices); + } $this->resourceModel->save($product); } catch (\Magento\Eav\Model\Entity\Attribute\Exception $exception) { throw \Magento\Framework\Exception\InputException::invalidFieldValue( @@ -253,7 +581,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa } unset($this->instances[$product->getSku()]); unset($this->instancesById[$product->getId()]); - return $product; + return $this->get($product->getSku()); } /** diff --git a/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php index 619258746d35e02cb89ac2f8c913853f2d68333e..058e8edb6de1c3e87ba52fa160ad30a8e4a62958 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php @@ -79,6 +79,16 @@ class CategoryTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Indexer\Model\IndexerRegistry|\PHPUnit_Framework_MockObject_MockObject */ protected $indexerRegistry; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $metadataServiceMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $attributeValueFactory; + protected function setUp() { $this->context = $this->getMock( @@ -149,6 +159,10 @@ class CategoryTest extends \PHPUnit_Framework_TestCase ); $this->indexerRegistry = $this->getMock('Magento\Indexer\Model\IndexerRegistry', ['get'], [], '', false); + $this->metadataServiceMock = $this->getMock('\Magento\Catalog\Api\CategoryAttributeRepositoryInterface'); + $this->attributeValueFactory = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory') + ->disableOriginalConstructor()->getMock(); + $this->category = $this->getCategoryModel(); } @@ -308,6 +322,8 @@ class CategoryTest extends \PHPUnit_Framework_TestCase 'urlFinder' => $this->urlFinder, 'resource' => $this->resource, 'indexerRegistry' => $this->indexerRegistry, + 'metadataService' => $this->metadataServiceMock, + 'customAttributeFactory' => $this->attributeValueFactory, ] ); } @@ -397,4 +413,46 @@ class CategoryTest extends \PHPUnit_Framework_TestCase $this->category->reindex(); } + + public function testGetCustomAttributes() + { + $nameAttributeCode = 'name'; + $descriptionAttributeCode = 'description'; + $interfaceAttribute = $this->getMock('\Magento\Framework\Api\MetadataObjectInterface'); + $interfaceAttribute->expects($this->once()) + ->method('getAttributeCode') + ->willReturn($nameAttributeCode); + $descriptionAttribute = $this->getMock('\Magento\Framework\Api\MetadataObjectInterface'); + $descriptionAttribute->expects($this->once()) + ->method('getAttributeCode') + ->willReturn($descriptionAttributeCode); + $customAttributesMetadata = [$interfaceAttribute, $descriptionAttribute]; + + $this->metadataServiceMock->expects($this->once()) + ->method('getCustomAttributesMetadata') + ->willReturn($customAttributesMetadata); + $this->category->setData($nameAttributeCode, "sub"); + + //The color attribute is not set, expect empty custom attribute array + $this->assertEquals([], $this->category->getCustomAttributes()); + + //Set the color attribute; + $this->category->setData($descriptionAttributeCode, "description"); + $attributeValue = new \Magento\Framework\Api\AttributeValue(); + $attributeValue2 = new \Magento\Framework\Api\AttributeValue(); + $this->attributeValueFactory->expects($this->exactly(2))->method('create') + ->willReturnOnConsecutiveCalls($attributeValue, $attributeValue2); + $this->assertEquals(1, count($this->category->getCustomAttributes())); + $this->assertNotNull($this->category->getCustomAttribute($descriptionAttributeCode)); + $this->assertEquals("description", $this->category->getCustomAttribute($descriptionAttributeCode)->getValue()); + + //Change the attribute value, should reflect in getCustomAttribute + $this->category->setData($descriptionAttributeCode, "new description"); + $this->assertEquals(1, count($this->category->getCustomAttributes())); + $this->assertNotNull($this->category->getCustomAttribute($descriptionAttributeCode)); + $this->assertEquals( + "new description", + $this->category->getCustomAttribute($descriptionAttributeCode)->getValue() + ); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php index 8da00cc15b23018240ae436100afdefd3019671e..83da62d4d2cccf02937cfc85959f090e8cddfa9c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php @@ -26,50 +26,20 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase */ protected $productRepositoryMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $mediaConfigMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ protected $contentValidatorMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $filesystemMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $entryFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $mediaGalleryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $attributeRepositoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $entryResolverMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ protected $productMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\DataObjectHelper + * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $dataObjectHelperMock; + protected $mediaGalleryEntryMock; /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\AttributeValue @@ -80,68 +50,28 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase { $this->storeManagerMock = $this->getMock('\Magento\Store\Model\StoreManagerInterface'); $this->productRepositoryMock = $this->getMock('\Magento\Catalog\Api\ProductRepositoryInterface'); - $this->attributeRepositoryMock = $this->getMock('\Magento\Catalog\Api\ProductAttributeRepositoryInterface'); - $this->mediaConfigMock = $this->getMock('\Magento\Catalog\Model\Product\Media\Config', [], [], '', false); - $this->filesystemMock = $this->getMock('\Magento\Framework\Filesystem', [], [], '', false); - $this->contentValidatorMock = $this->getMock( - '\Magento\Catalog\Model\Product\Gallery\ContentValidator', - [], - [], - '', - false - ); - $this->entryResolverMock = $this->getMock( - '\Magento\Catalog\Model\Product\Gallery\EntryResolver', - [], - [], - '', - false - ); - $this->entryFactoryMock = $this->getMock( - '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory', - ['create'], - [], - '', - false - ); - $this->dataObjectHelperMock = $this->getMockBuilder('\Magento\Framework\Api\DataObjectHelper') - ->disableOriginalConstructor() - ->getMock(); - $this->mediaGalleryMock = $this->getMock( - '\Magento\Catalog\Model\Resource\Product\Attribute\Backend\Media', - [], - [], - '', - false - ); + $this->contentValidatorMock = $this->getMock('\Magento\Catalog\Model\Product\Gallery\ContentValidator'); $this->productMock = $this->getMock( '\Magento\Catalog\Model\Product', [ - 'getTypeInstance', - 'getSetAttributes', 'setStoreId', - 'getMediaAttributes', - 'getMediaGallery', 'getData', 'getStoreId', 'getSku', - 'getCustomAttribute' + 'getCustomAttribute', + 'getMediaGalleryEntries', + 'setMediaGalleryEntries', ], [], '', false ); + $this->mediaGalleryEntryMock = + $this->getMock('Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); $this->model = new \Magento\Catalog\Model\Product\Gallery\GalleryManagement( $this->storeManagerMock, $this->productRepositoryMock, - $this->attributeRepositoryMock, - $this->mediaConfigMock, - $this->contentValidatorMock, - $this->filesystemMock, - $this->entryResolverMock, - $this->entryFactoryMock, - $this->mediaGalleryMock, - $this->dataObjectHelperMock + $this->contentValidatorMock ); $this->attributeValueMock = $this->getMockBuilder('\Magento\Framework\Api\AttributeValue') ->disableOriginalConstructor() @@ -156,7 +86,7 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase { $this->storeManagerMock->expects($this->once())->method('getStore') ->willThrowException(new \Exception()); - $this->model->create($this->productMock); + $this->model->create('sku', $this->mediaGalleryEntryMock); } /** @@ -165,78 +95,18 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase */ public function testCreateWithInvalidImageException() { - $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); $entryContentMock = $this->getMock( '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface' ); - $entryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); - $this->attributeValueMock->expects($this->any())->method('getValue')->willReturn($entryMock); + $this->mediaGalleryEntryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); $storeId = 0; - $this->productMock->expects($this->any())->method('getStoreId')->willReturn($storeId); - $this->productMock->expects($this->any()) - ->method('getCustomAttribute') - ->with('media_gallery') - ->willReturn($this->attributeValueMock); $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); $this->contentValidatorMock->expects($this->once())->method('isValid')->with($entryContentMock) ->willReturn(false); - $this->entryResolverMock->expects($this->never())->method('getEntryIdByFilePath'); - $this->model->create($this->productMock); - } - - /** - * @expectedException \Magento\Framework\Exception\StateException - * @expectedExceptionMessage Requested product does not support images. - */ - public function testCreateWithProductWithoutImagesSupport() - { - $productSku = 'mediaProduct'; - $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); - $entryContentMock = $this->getMock( - '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface' - ); - $entryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); - $this->attributeValueMock->expects($this->any())->method('getValue')->willReturn($entryMock); - - $storeId = 0; - $this->productMock->expects($this->any())->method('getStoreId')->willReturn($storeId); - $this->productMock->expects($this->any())->method('getSku')->willReturn($productSku); - $this->productMock->expects($this->any()) - ->method('getCustomAttribute') - ->with('media_gallery') - ->willReturn($this->attributeValueMock); - - $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); - $this->entryResolverMock->expects($this->never())->method('getEntryIdByFilePath'); - - $writeInterfaceMock = $this->getMock('\Magento\Framework\Filesystem\Directory\WriteInterface'); - $entryData = 'entryData'; - $mediaTmpPath = '/media/tmp/path'; - $fileName = 'Image'; - $mimeType = 'image/jpg'; - $relativeFilePath = $mediaTmpPath . DIRECTORY_SEPARATOR . $fileName . '.jpg'; - $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); - $this->contentValidatorMock->expects($this->once())->method('isValid')->with($entryContentMock) - ->willReturn(true); - $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) - ->willReturn($this->productMock); - $entryContentMock->expects($this->once())->method('getEntryData')->willReturn(base64_encode($entryData)); - $this->mediaConfigMock->expects($this->once())->method('getBaseTmpMediaPath')->willReturn($mediaTmpPath); - $this->filesystemMock->expects($this->once())->method('getDirectoryWrite') - ->with(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->willReturn($writeInterfaceMock); - $writeInterfaceMock->expects($this->once())->method('create')->with($mediaTmpPath); - $entryContentMock->expects($this->once())->method('getName')->willReturn($fileName); - $entryContentMock->expects($this->once())->method('getMimeType')->willReturn($mimeType); - $writeInterfaceMock->expects($this->once())->method('getAbsolutePath')->with($relativeFilePath); - $writeInterfaceMock->expects($this->once())->method('writeFile')->with($relativeFilePath, $entryData); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn([]); - $this->entryResolverMock->expects($this->never())->method('getEntryIdByFilePath'); - $this->model->create($this->productMock); + $this->model->create("sku", $this->mediaGalleryEntryMock, $storeId); } /** @@ -246,167 +116,57 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase public function testCreateWithCannotSaveException() { $productSku = 'mediaProduct'; - $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); $entryContentMock = $this->getMock( '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface' ); - $entryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); - $this->attributeValueMock->expects($this->any())->method('getValue')->willReturn($entryMock); + $this->mediaGalleryEntryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); $storeId = 0; - $this->productMock->expects($this->any())->method('getStoreId')->willReturn($storeId); - $this->productMock->expects($this->any())->method('getSku')->willReturn($productSku); - $this->productMock->expects($this->any()) - ->method('getCustomAttribute') - ->with('media_gallery') - ->willReturn($this->attributeValueMock); - - $entryPosition = 'entryPosition'; - $absolutePath = 'absolute/path'; - $productMediaGalleryMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', - ['addImage', 'updateImage'], - [], - '', - false - ); - $attributeMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); - $writeInterfaceMock = $this->getMock('\Magento\Framework\Filesystem\Directory\WriteInterface'); - $entryData = 'entryData'; - $mediaTmpPath = '/media/tmp/path'; - $fileName = 'Image'; - $mimeType = 'image/jpg'; - $imageFileUri = 'http://magento.awesome/image.jpg'; - $relativeFilePath = $mediaTmpPath . DIRECTORY_SEPARATOR . $fileName . '.jpg'; + $this->productRepositoryMock->expects($this->once()) + ->method('get') + ->with($productSku) + ->willReturn($this->productMock); + $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); $this->contentValidatorMock->expects($this->once())->method('isValid')->with($entryContentMock) ->willReturn(true); - $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) - ->willReturn($this->productMock); - $entryContentMock->expects($this->once())->method('getEntryData')->willReturn(base64_encode($entryData)); - $this->mediaConfigMock->expects($this->once())->method('getBaseTmpMediaPath')->willReturn($mediaTmpPath); - $this->filesystemMock->expects($this->once())->method('getDirectoryWrite') - ->with(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->willReturn($writeInterfaceMock); - $writeInterfaceMock->expects($this->once())->method('create')->with($mediaTmpPath); - $entryContentMock->expects($this->once())->method('getName')->willReturn($fileName); - $entryContentMock->expects($this->once())->method('getMimeType')->willReturn($mimeType); - $writeInterfaceMock->expects($this->once())->method('getAbsolutePath')->with($relativeFilePath) - ->willReturn($absolutePath); - $writeInterfaceMock->expects($this->once())->method('writeFile')->with($relativeFilePath, $entryData); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn(['media_gallery' => $attributeMock]); - $attributeMock->expects($this->once())->method('getBackend')->willReturn($productMediaGalleryMock); - $entryMock->expects($this->once())->method('getTypes')->willReturn(['jpg']); - $entryMock->expects($this->exactly(2))->method('isDisabled')->willReturn(false); - $entryMock->expects($this->once())->method('getPosition')->willReturn($entryPosition); - $entryMock->expects($this->once())->method('getLabel')->willReturn('entryLabel'); - $productMediaGalleryMock->expects($this->once())->method('addImage')->with( - $this->productMock, - $absolutePath, - ['jpg'], - true, - false - )->willReturn($imageFileUri); - $productMediaGalleryMock->expects($this->once())->method('updateImage')->with( - $this->productMock, - $imageFileUri, - [ - 'label' => 'entryLabel', - 'position' => $entryPosition, - 'disabled' => false - ] - ); + $this->productRepositoryMock->expects($this->once())->method('save')->with($this->productMock) ->willThrowException(new \Exception()); - $this->entryResolverMock->expects($this->never())->method('getEntryIdByFilePath'); - $this->model->create($this->productMock); + $this->model->create($productSku, $this->mediaGalleryEntryMock, $storeId); } public function testCreate() { $productSku = 'mediaProduct'; - $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); $entryContentMock = $this->getMock( '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface' ); - $entryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); - $this->attributeValueMock->expects($this->any())->method('getValue')->willReturn($entryMock); + $this->mediaGalleryEntryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); $storeId = 0; - $this->productMock->expects($this->any())->method('getStoreId')->willReturn($storeId); - $this->productMock->expects($this->any())->method('getSku')->willReturn($productSku); - $this->productMock->expects($this->any()) - ->method('getCustomAttribute') - ->with('media_gallery') - ->willReturn($this->attributeValueMock); - - $entryPosition = 'entryPosition'; - $absolutePath = 'absolute/path'; - - $productMediaGalleryMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', - ['addImage', 'updateImage', 'getRenamedImage'], - [], - '', - false - ); - $attributeMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); - $writeInterfaceMock = $this->getMock('\Magento\Framework\Filesystem\Directory\WriteInterface'); - $entryData = 'entryData'; - $mediaTmpPath = '/media/tmp/path'; - $fileName = 'Image'; - $mimeType = 'image/jpg'; - $imageFileUri = 'http://magento.awesome/image.jpg'; - $relativeFilePath = $mediaTmpPath . DIRECTORY_SEPARATOR . $fileName . '.jpg'; + + $this->productRepositoryMock->expects($this->once()) + ->method('get') + ->with($productSku) + ->willReturn($this->productMock); + $this->productRepositoryMock->expects($this->once()) + ->method('save') + ->with($this->productMock) + ->willReturn($this->productMock); + $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); $this->contentValidatorMock->expects($this->once())->method('isValid')->with($entryContentMock) ->willReturn(true); - $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) - ->willReturn($this->productMock); - $entryContentMock->expects($this->once())->method('getEntryData')->willReturn(base64_encode($entryData)); - $this->mediaConfigMock->expects($this->once())->method('getBaseTmpMediaPath')->willReturn($mediaTmpPath); - $this->filesystemMock->expects($this->once())->method('getDirectoryWrite') - ->with(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->willReturn($writeInterfaceMock); - $writeInterfaceMock->expects($this->once())->method('create')->with($mediaTmpPath); - $entryContentMock->expects($this->once())->method('getName')->willReturn($fileName); - $entryContentMock->expects($this->once())->method('getMimeType')->willReturn($mimeType); - $writeInterfaceMock->expects($this->once())->method('getAbsolutePath')->with($relativeFilePath) - ->willReturn($absolutePath); - $writeInterfaceMock->expects($this->once())->method('writeFile')->with($relativeFilePath, $entryData); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn(['media_gallery' => $attributeMock]); - $attributeMock->expects($this->once())->method('getBackend')->willReturn($productMediaGalleryMock); - $entryMock->expects($this->once())->method('getTypes')->willReturn(['jpg']); - $entryMock->expects($this->exactly(2))->method('isDisabled')->willReturn(false); - $entryMock->expects($this->once())->method('getPosition')->willReturn($entryPosition); - $entryMock->expects($this->once())->method('getLabel')->willReturn('entryLabel'); - $productMediaGalleryMock->expects($this->once())->method('addImage')->with( - $this->productMock, - $absolutePath, - ['jpg'], - true, - false - )->willReturn($imageFileUri); - $productMediaGalleryMock->expects($this->once())->method('updateImage')->with( - $this->productMock, - $imageFileUri, - [ - 'label' => 'entryLabel', - 'position' => $entryPosition, - 'disabled' => false - ] - ); - $this->productRepositoryMock->expects($this->once())->method('save')->with($this->productMock); - $writeInterfaceMock->expects($this->once())->method('delete')->with($relativeFilePath); - $productMediaGalleryMock->expects($this->once())->method('getRenamedImage')->with($imageFileUri) - ->willReturn('renamed'); - $this->entryResolverMock->expects($this->once())->method('getEntryIdByFilePath')->with( - $this->productMock, - 'renamed' - )->willReturn(42); - $this->assertEquals(42, $this->model->create($this->productMock)); + + $newEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $newEntryMock->expects($this->exactly(2))->method('getId')->willReturn(42); + $this->productMock->expects($this->at(2))->method('getMediaGalleryEntries') + ->willReturn([$newEntryMock]); + $this->productMock->expects($this->once())->method('setMediaGalleryEntries') + ->with([$this->mediaGalleryEntryMock]); + + $this->assertEquals(42, $this->model->create($productSku, $this->mediaGalleryEntryMock, $storeId)); } /** @@ -433,25 +193,14 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); $storeId = 0; $entryId = 42; - $productMediaGalleryMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', - ['addImage', 'updateImage', 'getRenamedImage'], - [], - '', - false - ); - $attributeMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn(['media_gallery' => $attributeMock]); - $attributeMock->expects($this->once())->method('getBackend')->willReturn($productMediaGalleryMock); + $existingEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $existingEntryMock->expects($this->once())->method('getId')->willReturn(43); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$existingEntryMock]); $entryMock->expects($this->once())->method('getId')->willReturn($entryId); - $this->entryResolverMock->expects($this->once())->method('getEntryFilePathById') - ->with($this->productMock, $entryId) - ->willReturn(null); $this->model->update($productSku, $entryMock, $storeId); } @@ -465,49 +214,14 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); $storeId = 0; $entryId = 42; - $filePath = '/path/to/the/file.jpg'; - $entryPosition = 'entryPosition'; - $productMediaGalleryMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', - ['addImage', 'updateImage', 'getRenamedImage', 'clearMediaAttribute', 'setMediaAttribute'], - [], - '', - false - ); - $attributeMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn(['media_gallery' => $attributeMock]); - $attributeMock->expects($this->once())->method('getBackend')->willReturn($productMediaGalleryMock); + $existingEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $existingEntryMock->expects($this->once())->method('getId')->willReturn($entryId); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$existingEntryMock]); $entryMock->expects($this->once())->method('getId')->willReturn($entryId); - $this->entryResolverMock->expects($this->once())->method('getEntryFilePathById') - ->with($this->productMock, $entryId)->willReturn($filePath); - $entryMock->expects($this->once())->method('isDisabled')->willReturn(false); - $entryMock->expects($this->once())->method('getPosition')->willReturn($entryPosition); - $entryMock->expects($this->once())->method('getLabel')->willReturn('entryLabel'); - $productMediaGalleryMock->expects($this->once())->method('updateImage')->with( - $this->productMock, - $filePath, - [ - 'label' => 'entryLabel', - 'position' => $entryPosition, - 'disabled' => false - ] - ); - $this->productMock->expects($this->once())->method('getMediaAttributes')->willReturn([]); - $productMediaGalleryMock->expects($this->once())->method('clearMediaAttribute')->with( - $this->productMock, - [] - ); - $entryMock->expects($this->once())->method('getTypes')->willReturn(['jpg']); - $productMediaGalleryMock->expects($this->once())->method('setMediaAttribute')->with( - $this->productMock, - ['jpg'], - $filePath - ); $this->productMock->expects($this->once())->method('setStoreId')->with($storeId); $this->productRepositoryMock->expects($this->once())->method('save')->with($this->productMock) ->willThrowException(new \Exception()); @@ -520,49 +234,17 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); $storeId = 0; $entryId = 42; - $filePath = '/path/to/the/file.jpg'; - $entryPosition = 'entryPosition'; - $productMediaGalleryMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', - ['addImage', 'updateImage', 'getRenamedImage', 'clearMediaAttribute', 'setMediaAttribute'], - [], - '', - false - ); - $attributeMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId); $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn(['media_gallery' => $attributeMock]); - $attributeMock->expects($this->once())->method('getBackend')->willReturn($productMediaGalleryMock); + $existingEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $existingEntryMock->expects($this->once())->method('getId')->willReturn($entryId); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$existingEntryMock]); $entryMock->expects($this->once())->method('getId')->willReturn($entryId); - $this->entryResolverMock->expects($this->once())->method('getEntryFilePathById') - ->with($this->productMock, $entryId)->willReturn($filePath); - $entryMock->expects($this->once())->method('isDisabled')->willReturn(false); - $entryMock->expects($this->once())->method('getPosition')->willReturn($entryPosition); - $entryMock->expects($this->once())->method('getLabel')->willReturn('entryLabel'); - $productMediaGalleryMock->expects($this->once())->method('updateImage')->with( - $this->productMock, - $filePath, - [ - 'label' => 'entryLabel', - 'position' => $entryPosition, - 'disabled' => false - ] - ); - $this->productMock->expects($this->once())->method('getMediaAttributes')->willReturn([]); - $productMediaGalleryMock->expects($this->once())->method('clearMediaAttribute')->with( - $this->productMock, - [] - ); - $entryMock->expects($this->once())->method('getTypes')->willReturn(['jpg']); - $productMediaGalleryMock->expects($this->once())->method('setMediaAttribute')->with( - $this->productMock, - ['jpg'], - $filePath - ); + + $this->productMock->expects($this->once())->method('setMediaGalleryEntries') + ->willReturn([$entryMock]); $this->productMock->expects($this->once())->method('setStoreId')->with($storeId); $this->productRepositoryMock->expects($this->once())->method('save')->with($this->productMock); $this->assertTrue($this->model->update($productSku, $entryMock, $storeId)); @@ -576,22 +258,12 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase { $productSku = 'testProduct'; $entryId = 42; - $productMediaGalleryMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', - ['addImage', 'updateImage', 'getRenamedImage', 'clearMediaAttribute', 'setMediaAttribute'], - [], - '', - false - ); - $attributeMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn(['media_gallery' => $attributeMock]); - $this->entryResolverMock->expects($this->once())->method('getEntryFilePathById') - ->with($this->productMock, $entryId)->willReturn(null); - $attributeMock->expects($this->once())->method('getBackend')->willReturn($productMediaGalleryMock); + $existingEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $existingEntryMock->expects($this->once())->method('getId')->willReturn(43); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$existingEntryMock]); $this->model->remove($productSku, $entryId); } @@ -599,23 +271,14 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase { $productSku = 'testProduct'; $entryId = 42; - $productMediaGalleryMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', - ['removeImage'], - [], - '', - false - ); - $attributeMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->productMock->expects($this->once())->method('getTypeInstance')->willReturnSelf(); - $this->productMock->expects($this->once())->method('getSetAttributes')->with($this->productMock) - ->willReturn(['media_gallery' => $attributeMock]); - $this->entryResolverMock->expects($this->once())->method('getEntryFilePathById') - ->with($this->productMock, $entryId)->willReturn('/path'); - $attributeMock->expects($this->once())->method('getBackend')->willReturn($productMediaGalleryMock); - $productMediaGalleryMock->expects($this->once())->method('removeImage')->with($this->productMock, '/path'); + $existingEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $existingEntryMock->expects($this->once())->method('getId')->willReturn(42); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$existingEntryMock]); + $this->productMock->expects($this->once())->method('setMediaGalleryEntries') + ->with([]); $this->productRepositoryMock->expects($this->once())->method('save')->with($this->productMock); $this->assertTrue($this->model->remove($productSku, $entryId)); } @@ -641,12 +304,12 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase { $productSku = 'testProduct'; $imageId = 43; - $images = [['value_id' => 42, 'types' => [], 'file' => 'file.jpg']]; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->productMock->expects($this->once())->method('getMediaAttributes')->willReturn(['code' => 0]); - $this->productMock->expects($this->once())->method('getData')->with('code')->willReturn('codeValue'); - $this->productMock->expects($this->once())->method('getMediaGallery')->with('images')->willReturn($images); + $existingEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $existingEntryMock->expects($this->once())->method('getId')->willReturn(44); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$existingEntryMock]); $this->model->get($productSku, $imageId); } @@ -654,54 +317,23 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase { $productSku = 'testProduct'; $imageId = 42; - $images = [['value_id' => 42, 'types' => [], 'file' => 'file.jpg']]; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->productMock->expects($this->once())->method('getMediaAttributes')->willReturn(['code' => 0]); - $this->productMock->expects($this->once())->method('getData')->with('code')->willReturn('codeValue'); - $this->productMock->expects($this->once())->method('getMediaGallery')->with('images')->willReturn($images); - $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); - $this->dataObjectHelperMock->expects($this->once())->method('populateWithArray') - ->with($entryMock, $images[0], '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface') - ->willReturnSelf(); - $this->entryFactoryMock->expects($this->once())->method('create')->willReturn($entryMock); - $this->assertEquals($entryMock, $this->model->get($productSku, $imageId)); + $existingEntryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); + $existingEntryMock->expects($this->once())->method('getId')->willReturn(42); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$existingEntryMock]); + $this->assertEquals($existingEntryMock, $this->model->get($productSku, $imageId)); } public function testGetList() { $productSku = 'testProductSku'; - $attributeMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeInterface'); - $objectMock = new \Magento\Framework\Object(['attribute' => $attributeMock]); - $gallery = [[ - 'value_id' => 42, - 'label_default' => 'defaultLabel', - 'file' => 'code', - 'disabled_default' => false, - 'position_default' => 1, - ]]; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $this->attributeRepositoryMock->expects($this->once())->method('get')->with('media_gallery') - ->willReturn($attributeMock); - $this->mediaGalleryMock->expects($this->once())->method('loadGallery')->with($this->productMock, $objectMock) - ->willReturn($gallery); - $this->productMock->expects($this->once())->method('getMediaAttributes')->willReturn(['code' => 0]); - $this->productMock->expects($this->once())->method('getData')->with('code')->willReturn('codeValue'); $entryMock = $this->getMock('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface'); - $entryMock->expects($this->once())->method('setId') - ->with($gallery[0]['value_id'])->willReturnSelf(); - $entryMock->expects($this->once())->method('setLabel') - ->with($gallery[0]['label_default'])->willReturnSelf(); - $entryMock->expects($this->once())->method('setTypes') - ->with([])->willReturnSelf(); - $entryMock->expects($this->once())->method('setDisabled') - ->with($gallery[0]['disabled_default'])->willReturnSelf(); - $entryMock->expects($this->once())->method('setPosition') - ->with($gallery[0]['position_default'])->willReturnSelf(); - $entryMock->expects($this->once())->method('setFile') - ->with($gallery[0]['file'])->willReturnSelf(); - $this->entryFactoryMock->expects($this->once())->method('create')->willReturn($entryMock); + $this->productMock->expects($this->once())->method('getMediaGalleryEntries') + ->willReturn([$entryMock]); $this->assertEquals([$entryMock], $this->model->getList($productSku)); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/MimeTypeExtensionMapTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/MimeTypeExtensionMapTest.php new file mode 100644 index 0000000000000000000000000000000000000000..99a432e72067a025f86c8f53b70b5e0a2e718d52 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/MimeTypeExtensionMapTest.php @@ -0,0 +1,33 @@ +<?php +/** + * + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +namespace Magento\Catalog\Test\Unit\Model\Product\Gallery; + +class MimeTypeExtensionMapTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap + */ + protected $model; + + protected function setUp() + { + $this->model = new \Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap(); + } + + public function testGetMimeTypeExtension() + { + $this->assertEquals("jpg", $this->model->getMimeTypeExtension("image/jpeg")); + $this->assertEquals("jpg", $this->model->getMimeTypeExtension("image/jpg")); + $this->assertEquals("png", $this->model->getMimeTypeExtension("image/png")); + $this->assertEquals("gif", $this->model->getMimeTypeExtension("image/gif")); + $this->assertEquals("", $this->model->getMimeTypeExtension("unknown")); + $this->assertEquals("", $this->model->getMimeTypeExtension(null)); + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php index 6ed8f131538e4a381ed9569a6d32daf7da135d6a..2dd7d8cc194723ad6a7ec56779c1e8c7fc3d6de8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php @@ -121,6 +121,15 @@ class TierPriceManagementTest extends \PHPUnit_Framework_TestCase */ public function testGetList($configValue, $customerGroupId, $groupData, $expected) { + $group = $this->getMock('\Magento\Customer\Model\Data\Group', + [], + [], + '', + false + ); + $group->expects($this->any())->method('getId')->willReturn(GroupManagement::CUST_GROUP_ALL); + $this->groupManagementMock->expects($this->any())->method('getAllCustomersGroup') + ->will($this->returnValue($group)); $this->repositoryMock->expects($this->once())->method('get')->with('product_sku') ->will($this->returnValue($this->productMock)); $this->productMock diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7ebf31ca906991674a8626f7bad2facb2e00a696 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -0,0 +1,333 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +namespace Magento\Catalog\Test\Unit\Model\Product\Type; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Customer\Model\GroupManagement; + +/** + * Price Test + */ +class PriceTest extends \PHPUnit_Framework_TestCase +{ + const KEY_GROUP_PRICE = 'group_price'; + const KEY_TIER_PRICE = 'tier_price'; + const PRICE_SCOPE_GLOBAL = 0; + const PRICE_SCOPE_WEBSITE = 1; + + /** + * @var \Magento\Catalog\Model\Product\Type\Price + */ + protected $model; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManagerHelper; + + /** + * @var \Magento\Catalog\Model\Product + */ + protected $product; + + /** + * @var \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $gpFactory; + + /** + * @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $tpFactory; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $scopeConfigMock; + + /** + * @var \Magento\Customer\Api\GroupManagementInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $groupManagementMock; + + /** + * @var \Magento\Store\Model\Website|\PHPUnit_Framework_MockObject_MockObject + */ + protected $websiteMock; + + protected function setUp() + { + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->product = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product'); + + $this->gpFactory = $this->getMockForAbstractClass( + 'Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory', + [], + '', + false, + true, + true, + ['create'] + ); + + $this->tpFactory = $this->getMockForAbstractClass( + 'Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory', + [], + '', + false, + true, + true, + ['create'] + ); + + $this->websiteMock = $this->getMock('Magento\Store\Model\Website', ['getId'], [], '', false); + $storeMangerMock = $this->getMockForAbstractClass( + 'Magento\Store\Model\StoreManagerInterface', + [], + '', + false, + true, + true, + ['getWebsite'] + ); + $storeMangerMock->expects($this->any()) + ->method('getWebsite') + ->will($this->returnValue($this->websiteMock)); + + $this->scopeConfigMock = $this->getMockForAbstractClass( + 'Magento\Framework\App\Config\ScopeConfigInterface', + [], + '', + false, + true, + true, + ['getValue'] + ); + + $group = $this->getMock('\Magento\Customer\Model\Data\Group', + [], + [], + '', + false + ); + $group->expects($this->any())->method('getId')->willReturn(GroupManagement::CUST_GROUP_ALL); + $this->groupManagementMock = + $this->getMock('Magento\Customer\Api\GroupManagementInterface', [], [], '', false); + $this->groupManagementMock->expects($this->any())->method('getAllCustomersGroup') + ->will($this->returnValue($group)); + + $this->model = $this->objectManagerHelper->getObject( + 'Magento\Catalog\Model\Product\Type\Price', + [ + 'groupPriceFactory' => $this->gpFactory, + 'tierPriceFactory' => $this->tpFactory, + 'config' => $this->scopeConfigMock, + 'storeManager' => $storeMangerMock, + 'groupManagement' => $this->groupManagementMock + ] + ); + } + + /** + * testGetGroupPricesWithNull + * testGetTierPricesWithNull + * + * @dataProvider nullPricesDataProvider + */ + public function testGetPricesWithNull($key, $getter) + { + // test when we don't send anything in, that no data changes + $someValue = 'any fake value'; + $this->product->setData($key, $someValue); + $this->assertEquals($someValue, $this->product->getData($key)); + + $this->model->$getter($this->product, null); + $this->assertEquals($someValue, $this->product->getData($key)); + } + + /** + * @return array + */ + public function nullPricesDataProvider() + { + return [ + 'testGetGroupPricesWithNull' => [$this::KEY_GROUP_PRICE, 'setGroupPrices'], + 'testGetTierPricesWithNull' => [$this::KEY_TIER_PRICE, 'setTierPrices'] + ]; + } + + /** + * testGetGroupPrices + * testSetGroupPrices + * + * @dataProvider pricesDataProvider + */ + public function testGroupPrices($priceScope, $expectedWebsiteId) + { + // establish the behavior of the mocks + $this->scopeConfigMock->expects($this->any()) + ->method('getValue') + ->will($this->returnValue($priceScope)); + $this->websiteMock->expects($this->any()) + ->method('getId') + ->will($this->returnValue($expectedWebsiteId)); + $this->gpFactory->expects($this->any()) + ->method('create') + ->will($this->returnCallback(function () { + return $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\GroupPrice'); + })); + + // create sample GroupPrice objects that would be coming from a REST call + $gp1 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\GroupPrice'); + $gp1->setValue(10); + $gp1->setCustomerGroupId(1); + $gp2 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\GroupPrice'); + $gp2->setValue(20); + $gp2->setCustomerGroupId(2); + $gps = [$gp1, $gp2]; + + // force the product to have null group prices + $this->product->setData($this::KEY_GROUP_PRICE, null); + $this->assertNull($this->product->getData($this::KEY_GROUP_PRICE)); + + // set the product with the GroupPrice objects + $this->model->setGroupPrices($this->product, $gps); + + // test the data actually set on the product + $gpArray = $this->product->getData($this::KEY_GROUP_PRICE); + $this->assertNotNull($gpArray); + $this->assertTrue(is_array($gpArray)); + $this->assertEquals(sizeof($gps), sizeof($gpArray)); + + for ($i = 0; $i < sizeof($gps); $i++) { + $gpData = $gpArray[$i]; + $this->assertEquals($expectedWebsiteId, $gpData['website_id'], 'Website Id does not match'); + $this->assertEquals($gps[$i]->getValue(), $gpData['price'], 'Price/Value does not match'); + $this->assertEquals($gps[$i]->getValue(), $gpData['website_price'], 'WebsitePrice/Value does not match'); + $this->assertEquals( + $gps[$i]->getCustomerGroupId(), + $gpData['cust_group'], + 'Customer group Id does not match' + ); + } + + // test with the data retrieved as a REST object + $gpRests = $this->model->getGroupPrices($this->product); + $this->assertNotNull($gpRests); + $this->assertTrue(is_array($gpRests)); + $this->assertEquals(sizeof($gps), sizeof($gpRests)); + + for ($i = 0; $i < sizeof($gps); $i++) { + $this->assertEquals( + $gps[$i]->getValue(), + $gpRests[$i]->getValue(), + 'REST: Price/Value does not match' + ); + $this->assertEquals( + $gps[$i]->getCustomerGroupId(), + $gpRests[$i]->getCustomerGroupId(), + 'REST: Customer group Id does not match' + ); + } + } + + /** + * @return array + */ + public function pricesDataProvider() + { + return [ + 'global price scope' => [$this::PRICE_SCOPE_GLOBAL, 0], + 'website price scope' => [$this::PRICE_SCOPE_WEBSITE, 2] + ]; + } + + /** + * testGetTierPrices + * testSetTierPrices + * + * @dataProvider pricesDataProvider + */ + public function testTierPrices($priceScope, $expectedWebsiteId) + { + // establish the behavior of the mocks + $this->scopeConfigMock->expects($this->any()) + ->method('getValue') + ->will($this->returnValue($priceScope)); + $this->websiteMock->expects($this->any()) + ->method('getId') + ->will($this->returnValue($expectedWebsiteId)); + $this->tpFactory->expects($this->any()) + ->method('create') + ->will($this->returnCallback(function () { + return $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); + })); + + // create sample TierPrice objects that would be coming from a REST call + $tp1 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); + $tp1->setValue(10); + $tp1->setCustomerGroupId(1); + $tp1->setQty(11); + $tp2 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); + $tp2->setValue(20); + $tp2->setCustomerGroupId(2); + $tp2->setQty(22); + $tps = [$tp1, $tp2]; + + // force the product to have null tier prices + $this->product->setData($this::KEY_TIER_PRICE, null); + $this->assertNull($this->product->getData($this::KEY_TIER_PRICE)); + + // set the product with the TierPrice objects + $this->model->setTierPrices($this->product, $tps); + + // test the data actually set on the product + $tpArray = $this->product->getData($this::KEY_TIER_PRICE); + $this->assertNotNull($tpArray); + $this->assertTrue(is_array($tpArray)); + $this->assertEquals(sizeof($tps), sizeof($tpArray)); + + for ($i = 0; $i < sizeof($tps); $i++) { + $tpData = $tpArray[$i]; + $this->assertEquals($expectedWebsiteId, $tpData['website_id'], 'Website Id does not match'); + $this->assertEquals($tps[$i]->getValue(), $tpData['price'], 'Price/Value does not match'); + $this->assertEquals($tps[$i]->getValue(), $tpData['website_price'], 'WebsitePrice/Value does not match'); + $this->assertEquals( + $tps[$i]->getCustomerGroupId(), + $tpData['cust_group'], + 'Customer group Id does not match' + ); + $this->assertEquals($tps[$i]->getQty(), $tpData['price_qty'], 'Qty does not match'); + } + + // test with the data retrieved as a REST object + $tpRests = $this->model->getTierPrices($this->product); + $this->assertNotNull($tpRests); + $this->assertTrue(is_array($tpRests)); + $this->assertEquals(sizeof($tps), sizeof($tpRests)); + + for ($i = 0; $i < sizeof($tps); $i++) { + $this->assertEquals( + $tps[$i]->getValue(), + $tpRests[$i]->getValue(), + 'REST: Price/Value does not match' + ); + $this->assertEquals( + $tps[$i]->getCustomerGroupId(), + $tpRests[$i]->getCustomerGroupId(), + 'REST: Customer group Id does not match' + ); + $this->assertEquals( + $tps[$i]->getQty(), + $tpRests[$i]->getQty(), + 'REST: Qty does not match' + ); + } + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index bf60494dae2505f08654308ae2e512d75e277081..d50868fc2306bb0376ba81b02973d51f3c7b42ef 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -11,6 +11,11 @@ namespace Magento\Catalog\Test\Unit\Model; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +/** + * Class ProductRepositoryTest + * @package Magento\Catalog\Test\Unit\Model + * @SuppressWarnings(PHPMD.TooManyFields) + */ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase { /** @@ -18,6 +23,11 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $productMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $initializedProductMock; + /** * @var \Magento\Catalog\Model\ProductRepository */ @@ -81,6 +91,26 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase 'name' => 'existing product', ]; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Filesystem + */ + protected $fileSystemMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap + */ + protected $mimeTypeExtensionMapMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $contentFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product\Gallery\ContentValidator + */ + protected $contentValidatorMock; + /** * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ @@ -90,6 +120,23 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase { $this->productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create'], [], '', false); $this->productMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $this->initializedProductMock = $this->getMock( + 'Magento\Catalog\Model\Product', + [ + 'setProductOptions', + 'load', + 'getOptions', + 'getSku', + 'getGalleryAttributeBackend', + 'getMediaConfig', + 'getMediaAttributes', + 'getProductLinks', + 'setProductLinks', + ], + [], + '', + false + ); $this->filterBuilderMock = $this->getMock('\Magento\Framework\Api\FilterBuilder', [], [], '', false); $this->initializationHelperMock = $this->getMock( '\Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper', @@ -131,13 +178,22 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->eavConfigMock->expects($this->any())->method('getEntityType') ->willReturn(new \Magento\Framework\Object(['default_attribute_set_id' => 4])); $this->objectManager = new ObjectManager($this); - $this->extensibleDataObjectConverterMock = $this ->getMockBuilder('\Magento\Framework\Api\ExtensibleDataObjectConverter') ->setMethods(['toNestedArray']) ->disableOriginalConstructor() ->getMock(); - + $this->fileSystemMock = $this->getMockBuilder('\Magento\Framework\Filesystem') + ->disableOriginalConstructor()->getMock(); + $this->mimeTypeExtensionMapMock = + $this->getMockBuilder('Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap')->getMock(); + $this->contentFactoryMock = $this->getMockBuilder( + 'Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterfaceFactory' + )->disableOriginalConstructor()->setMethods(['create'])->getMockForAbstractClass(); + $this->contentValidatorMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Gallery\ContentValidator') + ->disableOriginalConstructor() + ->getMock(); + $optionConverter = $this->objectManager->getObject('Magento\Catalog\Model\Product\Option\Converter'); $this->model = $this->objectManager->getObject( 'Magento\Catalog\Model\ProductRepository', [ @@ -150,7 +206,12 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase 'metadataServiceInterface' => $this->metadataServiceMock, 'searchResultsFactory' => $this->searchResultsFactoryMock, 'extensibleDataObjectConverter' => $this->extensibleDataObjectConverterMock, + 'optionConverter' => $optionConverter, 'eavConfig' => $this->eavConfigMock, + 'contentValidator' => $this->contentValidatorMock, + 'fileSystem' => $this->fileSystemMock, + 'contentFactory' => $this->contentFactoryMock, + 'mimeTypeExtensionMap' => $this->mimeTypeExtensionMapMock, ] ); } @@ -266,8 +327,8 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase public function testSaveExisting() { - $this->resourceModelMock->expects($this->exactly(2))->method('getIdBySku')->will($this->returnValue(100)); - $this->productFactoryMock->expects($this->once()) + $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100)); + $this->productFactoryMock->expects($this->any()) ->method('create') ->will($this->returnValue($this->productMock)); $this->initializationHelperMock->expects($this->once())->method('initialize')->with($this->productMock); @@ -283,8 +344,9 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase public function testSaveNew() { - $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null)); - $this->productFactoryMock->expects($this->once()) + $this->resourceModelMock->expects($this->at(0))->method('getIdBySku')->will($this->returnValue(null)); + $this->resourceModelMock->expects($this->at(3))->method('getIdBySku')->will($this->returnValue(100)); + $this->productFactoryMock->expects($this->any()) ->method('create') ->will($this->returnValue($this->productMock)); $this->initializationHelperMock->expects($this->never())->method('initialize')->with($this->productMock); @@ -538,4 +600,482 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase ], ]; } + + /** + * @param array $newOptions + * @param array $existingOptions + * @param array $expectedData + * @dataProvider saveExistingWithOptionsDataProvider + */ + public function testSaveExistingWithOptions(array $newOptions, array $existingOptions, array $expectedData) + { + $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100)); + $this->productFactoryMock->expects($this->any()) + ->method('create') + ->will($this->returnValue($this->initializedProductMock)); + $this->initializationHelperMock->expects($this->once())->method('initialize') + ->with($this->initializedProductMock); + $this->resourceModelMock->expects($this->once())->method('validate')->with($this->initializedProductMock) + ->willReturn(true); + $this->resourceModelMock->expects($this->once())->method('save') + ->with($this->initializedProductMock)->willReturn(true); + //option data + $this->productData['options'] = $newOptions; + $this->extensibleDataObjectConverterMock + ->expects($this->once()) + ->method('toNestedArray') + ->will($this->returnValue($this->productData)); + + $this->initializedProductMock->expects($this->once()) + ->method('getOptions') + ->willReturn($existingOptions); + + $this->initializedProductMock->expects($this->once()) + ->method('setProductOptions') + ->with($expectedData); + + $this->assertEquals($this->initializedProductMock, $this->model->save($this->productMock)); + } + + /** + * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function saveExistingWithOptionsDataProvider() + { + $data = []; + + //Scenario 1: new options contains one existing option and one new option + //there are two existing options, one will be updated and one will be deleted + $newOptionsData = [ + [ + "option_id" => 10, + "type" => "drop_down", + "values" => [ + [ + "title" => "DropdownOptions_1", + "option_type_id" => 8, //existing + "price" => 3, + ], + [ //new option value + "title" => "DropdownOptions_3", + "price" => 4, + ] + ] + ], + [//new option + "type" => "checkbox", + "values" => [ + [ + "title" => "CheckBoxValue2", + "price" => 5, + ], + ] + ], + ]; + + /** @var \Magento\Catalog\Model\Product\Option|\PHPUnit_Framework_MockObject_MockObject $existingOption1 */ + $existingOption1 = $this->getMockBuilder('\Magento\Catalog\Model\Product\Option') + ->disableOriginalConstructor() + ->setMethods(null) + ->getMock(); + $existingOption1->setData( + [ + "option_id" => 10, + "type" => "drop_down", + ] + ); + /** @var \Magento\Catalog\Model\Product\Option\Value $existingOptionValue1 */ + $existingOptionValue1 = $this->getMockBuilder('\Magento\Catalog\Model\Product\Option\Value') + ->disableOriginalConstructor() + ->setMethods(null) + ->getMock(); + $existingOptionValue1->setData( + [ + "option_type_id" => "8", + "title" => "DropdownOptions_1", + "price" => 5, + ] + ); + $existingOptionValue2 = $this->getMockBuilder('\Magento\Catalog\Model\Product\Option\Value') + ->disableOriginalConstructor() + ->setMethods(null) + ->getMock(); + $existingOptionValue2->setData( + [ + "option_type_id" => "9", + "title" => "DropdownOptions_2", + "price" => 6, + ] + ); + $existingOption1->setValues( + [ + "8" => $existingOptionValue1, + "9" => $existingOptionValue2, + ] + ); + $existingOption2 = $this->getMockBuilder('Magento\Catalog\Model\Product\Option') + ->disableOriginalConstructor() + ->setMethods(null) + ->getMock(); + $existingOption2->setData( + [ + "option_id" => 11, + "type" => "drop_down", + ] + ); + $data['scenario_1'] = [ + 'new_options' => $newOptionsData, + 'existing_options' => [ + "10" => $existingOption1, + "11" => $existingOption2, + ], + 'expected_data' => [ + [ + "option_id" => 10, + "type" => "drop_down", + "values" => [ + [ + "title" => "DropdownOptions_1", + "option_type_id" => 8, + "price" => 3, + ], + [ + "title" => "DropdownOptions_3", + "price" => 4, + ], + [ + "option_type_id" => 9, + "title" => "DropdownOptions_2", + "price" => 6, + "is_delete" => 1, + ], + ] + ], + [ + "type" => "checkbox", + "values" => [ + [ + "title" => "CheckBoxValue2", + "price" => 5, + ] + ] + ], + [ + "option_id" => 11, + "type" => "drop_down", + "values" => [], + "is_delete" => 1, + + ], + ], + ]; + + return $data; + } + + /** + * @param array $newLinks + * @param array $existingLinks + * @param array $expectedData + * @dataProvider saveWithLinksDataProvider + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + */ + public function testSaveWithLinks(array $newLinks, array $existingLinks, array $expectedData) + { + $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100)); + $this->productFactoryMock->expects($this->any()) + ->method('create') + ->will($this->returnValue($this->initializedProductMock)); + $this->initializationHelperMock->expects($this->once())->method('initialize') + ->with($this->initializedProductMock); + $this->resourceModelMock->expects($this->once())->method('validate')->with($this->initializedProductMock) + ->willReturn(true); + $this->resourceModelMock->expects($this->once())->method('save') + ->with($this->initializedProductMock)->willReturn(true); + + $this->initializedProductMock->setData("product_links", $existingLinks); + + if (!empty($newLinks)) { + $this->initializedProductMock->setData("ignore_links_flag", false); + $this->resourceModelMock + ->expects($this->any())->method('getProductsIdsBySkus') + ->willReturn([$newLinks['linked_product_sku'] => $newLinks['linked_product_sku']]); + + $inputLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link'); + $inputLink->setProductSku($newLinks['product_sku']); + $inputLink->setLinkType($newLinks['link_type']); + $inputLink->setLinkedProductSku($newLinks['linked_product_sku']); + $inputLink->setLinkedProductType($newLinks['linked_product_type']); + $inputLink->setPosition($newLinks['position']); + + $this->productData['product_links'] = [$inputLink]; + + $this->initializedProductMock->expects($this->any()) + ->method('getProductLinks') + ->willReturn([$inputLink]); + } else { + $this->resourceModelMock + ->expects($this->any())->method('getProductsIdsBySkus') + ->willReturn([]); + + $this->productData['product_links'] = []; + + $this->initializedProductMock->setData("ignore_links_flag", true); + $this->initializedProductMock->expects($this->never()) + ->method('getProductLinks') + ->willReturn([]); + } + + $this->extensibleDataObjectConverterMock + ->expects($this->at(0)) + ->method('toNestedArray') + ->will($this->returnValue($this->productData)); + + if (!empty($newLinks)) { + $this->extensibleDataObjectConverterMock + ->expects($this->at(1)) + ->method('toNestedArray') + ->will($this->returnValue($newLinks)); + } + + $outputLinks = []; + if (!empty($expectedData)) { + foreach ($expectedData as $link) { + $outputLink = $this->objectManager->getObject('Magento\Catalog\Model\ProductLink\Link'); + $outputLink->setProductSku($link['product_sku']); + $outputLink->setLinkType($link['link_type']); + $outputLink->setLinkedProductSku($link['linked_product_sku']); + $outputLink->setLinkedProductType($link['linked_product_type']); + $outputLink->setPosition($link['position']); + + $outputLinks[] = $outputLink; + } + } + + $results = $this->model->save($this->initializedProductMock); + $this->assertEquals($this->initializedProductMock, $results); + $this->assertEquals($outputLinks, $results['product_links']); + } + + public function saveWithLinksDataProvider() + { + // Scenario 1 + // No existing, new links + $data['scenario_1'] = [ + 'newLinks' => ["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" => + "Simple Product 2", "linked_product_type" => "simple", "position" => 0], + 'existingLinks' => [], + 'expectedData' => [["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" => + "Simple Product 2", "linked_product_type" => "simple", "position" => 0]] + ]; + + // Scenario 2 + // Existing, no new links + $data['scenario_2'] = [ + 'newLinks' => [], + 'existingLinks' => ["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" => + "Simple Product 2", "linked_product_type" => "simple", "position" => 0], + 'expectedData' => [] + ]; + + // Scenario 3 + // Existing and new links + $data['scenario_3'] = [ + 'newLinks' => ["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" => + "Simple Product 2", "linked_product_type" => "simple", "position" => 0], + 'existingLinks' => ["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" => + "Simple Product 3", "linked_product_type" => "simple", "position" => 0], + 'expectedData' => [ + ["product_sku" => "Simple Product 1", "link_type" => "related", "linked_product_sku" => + "Simple Product 2", "linked_product_type" => "simple", "position" => 0]] + ]; + + return $data; + } + + protected function setupProductMocksForSave() + { + $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100)); + $this->productFactoryMock->expects($this->any()) + ->method('create') + ->will($this->returnValue($this->initializedProductMock)); + $this->initializationHelperMock->expects($this->once())->method('initialize') + ->with($this->initializedProductMock); + $this->resourceModelMock->expects($this->once())->method('validate')->with($this->initializedProductMock) + ->willReturn(true); + $this->resourceModelMock->expects($this->once())->method('save') + ->with($this->initializedProductMock)->willReturn(true); + } + + public function testSaveExistingWithNewMediaGalleryEntries() + { + $newEntriesData = [ + [ + "label" => "label_text", + 'position' => 10, + 'disabled' => false, + 'types' => ['image', 'small_image'], + 'content' => [ + 'name' => 'filename', + 'mime_type' => 'image/jpeg', + 'entry_data' => 'encoded_content', + ], + ], + ]; + + $this->setupProductMocksForSave(); + //media gallery data + $this->productData['media_gallery_entries'] = $newEntriesData; + $this->extensibleDataObjectConverterMock + ->expects($this->once()) + ->method('toNestedArray') + ->will($this->returnValue($this->productData)); + + $this->initializedProductMock->setData('media_gallery', []); + $this->initializedProductMock->expects($this->any()) + ->method('getMediaAttributes') + ->willReturn(["image" => "imageAttribute", "small_image" => "small_image_attribute"]); + + //setup media attribute backend + $mediaTmpPath = '/tmp'; + $relativePath = $mediaTmpPath . DIRECTORY_SEPARATOR . 'filename.jpg'; + $absolutePath = '/a/b/filename.jpg'; + $galleryAttributeBackendMock = $this->getMockBuilder('\Magento\Catalog\Model\Product\Attribute\Backend\Media') + ->disableOriginalConstructor()->getMock(); + $galleryAttributeBackendMock->expects($this->once())->method('clearMediaAttribute') + ->with($this->initializedProductMock, ['image', 'small_image']); + $mediaConfigMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Media\Config') + ->disableOriginalConstructor() + ->getMock(); + $mediaConfigMock->expects($this->once()) + ->method('getBaseTmpMediaPath') + ->willReturn($mediaTmpPath); + $directoryWriteMock = $this->getMockBuilder('\Magento\Framework\Filesystem\Directory\WriteInterface') + ->getMockForAbstractClass(); + $this->fileSystemMock->expects($this->once()) + ->method('getDirectoryWrite') + ->willReturn($directoryWriteMock); + $directoryWriteMock->expects($this->once())->method('create')->with($mediaTmpPath); + $this->mimeTypeExtensionMapMock->expects($this->once())->method('getMimeTypeExtension') + ->with('image/jpeg') + ->willReturn("jpg"); + $directoryWriteMock->expects($this->once())->method('writeFile') + ->with($relativePath, false); //decoded value is false as it contains '_' + $directoryWriteMock->expects($this->once())->method('getAbsolutePath')->willReturn($absolutePath); + $this->initializedProductMock->expects($this->any()) + ->method('getGalleryAttributeBackend') + ->willReturn($galleryAttributeBackendMock); + $this->initializedProductMock->expects($this->once()) + ->method('getMediaConfig') + ->willReturn($mediaConfigMock); + + //verify new entries + $contentDataObject = $this->getMockBuilder('Magento\Catalog\Model\Product\Media\GalleryEntryContent') + ->disableOriginalConstructor() + ->setMethods(null) + ->getMock(); + $this->contentFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($contentDataObject); + + $this->contentValidatorMock->expects($this->once()) + ->method('isValid') + ->willReturn(true); + + $imageFileUri = "imageFileUri"; + $galleryAttributeBackendMock->expects($this->once())->method('addImage') + ->with($this->initializedProductMock, $absolutePath, ['image', 'small_image'], true, false) + ->willReturn($imageFileUri); + $galleryAttributeBackendMock->expects($this->once())->method('updateImage') + ->with( + $this->initializedProductMock, + $imageFileUri, + [ + 'label' => 'label_text', + 'position' => 10, + 'disabled' => false, + ] + ); + + $this->model->save($this->productMock); + } + + public function testSaveExistingWithMediaGalleryEntries() + { + //update one entry, delete one entry + $newEntries = [ + [ + 'id' => 5, + "label" => "new_label_text", + 'file' => 'filename1', + 'position' => 10, + 'disabled' => false, + 'types' => ['image', 'small_image'], + ], + ]; + + $existingMediaGallery = [ + 'images' => [ + [ + 'value_id' => 5, + "label" => "label_text", + 'file' => 'filename1', + 'position' => 10, + 'disabled' => true, + ], + [ + 'value_id' => 6, //will be deleted + 'file' => 'filename2', + ], + ], + ]; + + $expectedResult = [ + [ + 'id' => 5, + 'value_id' => 5, + "label" => "new_label_text", + 'file' => 'filename1', + 'position' => 10, + 'disabled' => false, + 'types' => ['image', 'small_image'], + ], + [ + 'value_id' => 6, //will be deleted + 'file' => 'filename2', + 'removed' => true, + ], + ]; + + $this->setupProductMocksForSave(); + //media gallery data + $this->productData['media_gallery_entries'] = $newEntries; + $this->extensibleDataObjectConverterMock + ->expects($this->once()) + ->method('toNestedArray') + ->will($this->returnValue($this->productData)); + + $this->initializedProductMock->setData('media_gallery', $existingMediaGallery); + $this->initializedProductMock->expects($this->any()) + ->method('getMediaAttributes') + ->willReturn(["image" => "filename1", "small_image" => "filename2"]); + + //setup media attribute backend + $galleryAttributeBackendMock = $this->getMockBuilder('\Magento\Catalog\Model\Product\Attribute\Backend\Media') + ->disableOriginalConstructor()->getMock(); + $galleryAttributeBackendMock->expects($this->once())->method('clearMediaAttribute') + ->with($this->initializedProductMock, ['image', 'small_image']); + $this->initializedProductMock->expects($this->once()) + ->method('getGalleryAttributeBackend') + ->willReturn($galleryAttributeBackendMock); + $galleryAttributeBackendMock->expects($this->once()) + ->method('setMediaAttribute') + ->with($this->initializedProductMock, ['image', 'small_image'], 'filename1'); + + + $this->model->save($this->productMock); + $this->assertEquals($expectedResult, $this->initializedProductMock->getMediaGallery('images')); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php index fb5892f5b30e80ebc16fc60ca4fe2cd94da0adb1..4dcd067721f5bc239c97b1aa0141e694fb8a7f07 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php @@ -121,11 +121,31 @@ class ProductTest extends \PHPUnit_Framework_TestCase */ protected $imageCacheFactory; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $mediaGalleryEntryFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productLinkFactory; + /** * @var \PHPUnit_Framework_MockObject_MockObject */ protected $dataObjectHelperMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $metadataServiceMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $attributeValueFactory; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -249,6 +269,20 @@ class ProductTest extends \PHPUnit_Framework_TestCase ->setMethods(['create']) ->getMock(); + $this->productLinkFactory = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductLinkInterfaceFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->mediaGalleryEntryFactoryMock = + $this->getMockBuilder('Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $this->metadataServiceMock = $this->getMock('\Magento\Catalog\Api\ProductAttributeRepositoryInterface'); + $this->attributeValueFactory = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory') + ->disableOriginalConstructor()->getMock(); $this->objectManagerHelper = new ObjectManagerHelper($this); $this->model = $this->objectManagerHelper->getObject( 'Magento\Catalog\Model\Product', @@ -268,6 +302,10 @@ class ProductTest extends \PHPUnit_Framework_TestCase 'categoryRepository' => $this->categoryRepository, 'catalogProduct' => $this->_catalogProduct, 'imageCacheFactory' => $this->imageCacheFactory, + 'productLinkFactory' => $this->productLinkFactory, + 'mediaGalleryEntryFactory' => $this->mediaGalleryEntryFactoryMock, + 'metadataService' => $this->metadataServiceMock, + 'customAttributeFactory' => $this->attributeValueFactory, 'data' => ['id' => 1] ] ); @@ -693,4 +731,384 @@ class ProductTest extends \PHPUnit_Framework_TestCase ->with(\Magento\Catalog\Model\Indexer\Product\Category::INDEXER_ID) ->will($this->returnValue($this->categoryIndexerMock)); } + + /** + * Test for getProductLinks() + */ + public function testGetProductLinks() + { + $inputLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link'); + $inputLink->setProductSku("Simple Product 1"); + $inputLink->setLinkType("related"); + $inputLink->setData("sku", "Simple Product 2"); + $inputLink->setData("type_id", "simple"); + $inputLink->setPosition(0); + + $outputLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link'); + $outputLink->setProductSku("Simple Product 1"); + $outputLink->setLinkType("related"); + $outputLink->setLinkedProductSku("Simple Product 2"); + $outputLink->setLinkedProductType("simple"); + $outputLink->setPosition(0); + + $productLinks = []; + $this->model->setData('related_products', [$inputLink]); + $productLinks[] = $outputLink; + $outputLink->setLinkType("upsell"); + $inputLink->setLinkType("upsell"); + $this->model->setData('up_sell_products', [$inputLink]); + $productLinks[] = $outputLink; + $outputLink->setLinkType("crosssell"); + $inputLink->setLinkType("crosssell"); + $this->model->setData('cross_sell_products', [$inputLink]); + $productLinks[] = $outputLink; + + $productLink = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link'); + $this->productLinkFactory->expects($this->atLeastOnce()) + ->method('create') + ->willReturn($productLink); + + $typeInstanceMock = $this->getMock( + 'Magento\ConfigurableProduct\Model\Product\Type\Simple', ["getSku"], [], '', false); + $typeInstanceMock + ->expects($this->atLeastOnce()) + ->method('getSku') + ->willReturn("Simple Product 1"); + $this->model->setTypeInstance($typeInstanceMock); + + $links = $this->model->getProductLinks(); + $this->assertEquals($links, $productLinks); + } + + /** + * Test for setProductLinks() + */ + public function testSetProductLinks() + { + $link = $this->objectManagerHelper->getObject('Magento\Catalog\Model\ProductLink\Link'); + $link->setProductSku("Simple Product 1"); + $link->setLinkType("upsell"); + $link->setLinkedProductSku("Simple Product 2"); + $link->setLinkedProductType("simple"); + $link->setPosition(0); + $productLinks = [$link]; + $this->model->setProductLinks($productLinks); + $this->assertEquals($productLinks, $this->model->getProductLinks()); + } + + /** + * Set up two media attributes: image and small_image + */ + protected function setupMediaAttributes() + { + $productType = $this->getMockBuilder('Magento\Catalog\Model\Product\Type\AbstractType') + ->setMethods(['getEditableAttributes']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->productTypeInstanceMock->expects($this->any())->method('factory')->will( + $this->returnValue($productType) + ); + + $frontendMock = $this->getMockBuilder('\Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend') + ->disableOriginalConstructor() + ->setMethods(['getInputType']) + ->getMockForAbstractClass(); + $frontendMock->expects($this->any())->method('getInputType')->willReturn('media_image'); + $attributeImage = $this->getMockBuilder('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute') + ->setMethods(['__wakeup', 'getFrontend', 'getAttributeCode']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $attributeImage->expects($this->any()) + ->method('getFrontend') + ->willReturn($frontendMock); + $attributeImage->expects($this->any())->method('getAttributeCode')->willReturn('image'); + $attributeSmallImage = $this->getMockBuilder('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute') + ->setMethods(['__wakeup', 'getFrontend', 'getAttributeCode']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $attributeSmallImage->expects($this->any()) + ->method('getFrontend') + ->willReturn($frontendMock); + $attributeSmallImage->expects($this->any())->method('getAttributeCode')->willReturn('small_image'); + + $productType->expects($this->any())->method('getEditableAttributes')->will( + $this->returnValue(['image' => $attributeImage, 'small_image' => $attributeSmallImage]) + ); + + return [$attributeImage, $attributeSmallImage]; + } + + public function getMediaAttributes() + { + $expected = []; + $mediaAttributes = $this->setupMediaAttributes(); + foreach ($mediaAttributes as $mediaAttribute) { + $expected[$mediaAttribute->getAttributeCode()] = $mediaAttribute; + } + $this->assertEquals($expected, $this->model->getMediaAttributes()); + } + + public function testGetMediaAttributeValues() + { + $this->setupMediaAttributes(); + + $this->model->setData('image', 'imageValue'); + $this->model->setData('small_image', 'smallImageValue'); + + $expectedMediaAttributeValues = [ + 'image' => 'imageValue', + 'small_image' => 'smallImageValue', + ]; + $this->assertEquals($expectedMediaAttributeValues, $this->model->getMediaAttributeValues()); + } + + public function testGetGalleryAttributeBackendNon() + { + $this->setupMediaAttributes(); + $this->assertNull($this->model->getGalleryAttributeBackend()); + } + + public function testGetGalleryAttributeBackend() + { + $productType = $this->getMockBuilder('Magento\Catalog\Model\Product\Type\AbstractType') + ->setMethods(['getEditableAttributes']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->productTypeInstanceMock->expects($this->any())->method('factory')->will( + $this->returnValue($productType) + ); + + $attributeMediaGallery = $this->getMockBuilder('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute') + ->setMethods(['__wakeup', 'getAttributeCode', 'getBackend']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $attributeMediaGallery->expects($this->any())->method('getAttributeCode')->willReturn('media_gallery'); + $expectedValue = 'expected'; + $attributeMediaGallery->expects($this->once())->method('getBackend')->willReturn($expectedValue); + + $productType->expects($this->once())->method('getEditableAttributes') + ->willReturn(['media_gallery' => $attributeMediaGallery]); + $this->assertEquals($expectedValue, $this->model->getGalleryAttributeBackend()); + } + + public function testGetMediaGalleryEntriesNone() + { + $this->assertNull($this->model->getMediaGalleryEntries()); + } + + public function testGetMediaGalleryEntries() + { + $this->setupMediaAttributes(); + $this->model->setData('image', 'imageFile.jpg'); + $this->model->setData('small_image', 'smallImageFile.jpg'); + + $mediaEntries = [ + 'images' => [ + [ + 'value_id' => 1, + 'file' => 'imageFile.jpg', + ], + [ + 'value_id' => 2, + 'file' => 'smallImageFile.jpg', + ], + ] + ]; + $this->model->setData('media_gallery', $mediaEntries); + + $entry1 = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface') + ->setMethods(['setId']) + ->getMockForAbstractClass(); + $entry1->expects($this->once())->method('setId')->with(1); + $entry2 = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface') + ->setMethods(['setId']) + ->getMockForAbstractClass(); + $entry2->expects($this->once())->method('setId')->with(2); + + $this->mediaGalleryEntryFactoryMock->expects($this->at(0)) + ->method('create') + ->willReturn($entry1); + $this->mediaGalleryEntryFactoryMock->expects($this->at(1)) + ->method('create') + ->willReturn($entry2); + + $this->dataObjectHelperMock->expects($this->at(0)) + ->method('populateWithArray') + ->with( + $entry1, + [ + 'value_id' => 1, + 'file' => 'imageFile.jpg', + 'types' => ['image'], + ], + '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface' + ); + $this->dataObjectHelperMock->expects($this->at(1)) + ->method('populateWithArray') + ->with( + $entry1, + [ + 'value_id' => 2, + 'file' => 'smallImageFile.jpg', + 'types' => ['small_image'], + ], + '\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface' + ); + + $this->assertEquals([$entry1, $entry2], $this->model->getMediaGalleryEntries()); + } + + public function testSetMediaGalleryEntries() + { + $expectedResult = [ + 'images' => [ + [ + "value_id" => 1, + 'file' => 'file1.jpg', + 'label' => 'label_text', + 'position' => 4, + 'disabled' => false, + 'types' => ['image'], + 'content' => [ + 'entry_data' => 'content_data', + 'mime_type' => 'image/jpg', + 'name' => 'product_image', + ] + ] + ], + ]; + + $contentMock = + $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentInterface') + ->setMethods(['getEntryData', 'getMimeType', 'getName']) + ->getMockForAbstractClass(); + $contentMock->expects($this->once())->method('getEntryData') + ->willReturn($expectedResult['images'][0]['content']['entry_data']); + $contentMock->expects($this->once())->method('getMimeType') + ->willReturn($expectedResult['images'][0]['content']['mime_type']); + $contentMock->expects($this->once())->method('getName') + ->willReturn($expectedResult['images'][0]['content']['name']); + + $entryMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface') + ->setMethods(['getId', 'getFile', 'getLabel', 'getPosition', 'isDisabled', 'types', 'getContent']) + ->getMockForAbstractClass(); + $entryMock->expects($this->once())->method('getId') + ->willReturn($expectedResult['images'][0]['value_id']); + $entryMock->expects($this->once())->method('getFile') + ->willReturn($expectedResult['images'][0]['file']); + $entryMock->expects($this->once())->method('getLabel') + ->willReturn($expectedResult['images'][0]['label']); + $entryMock->expects($this->once())->method('getPosition') + ->willReturn($expectedResult['images'][0]['position']); + $entryMock->expects($this->once())->method('isDisabled') + ->willReturn($expectedResult['images'][0]['disabled']); + $entryMock->expects($this->once())->method('getTypes') + ->willReturn($expectedResult['images'][0]['types']); + $entryMock->expects($this->once())->method('getContent') + ->willReturn($contentMock); + + $this->model->setMediaGalleryEntries([$entryMock]); + $this->assertEquals($expectedResult, $this->model->getMediaGallery()); + } + + public function testGetCustomAttributes() + { + $priceCode = 'price'; + $colorAttributeCode = 'color'; + $interfaceAttribute = $this->getMock('\Magento\Framework\Api\MetadataObjectInterface'); + $interfaceAttribute->expects($this->once()) + ->method('getAttributeCode') + ->willReturn($priceCode); + $colorAttribute = $this->getMock('\Magento\Framework\Api\MetadataObjectInterface'); + $colorAttribute->expects($this->once()) + ->method('getAttributeCode') + ->willReturn($colorAttributeCode); + $customAttributesMetadata = [$interfaceAttribute, $colorAttribute]; + + $this->metadataServiceMock->expects($this->once()) + ->method('getCustomAttributesMetadata') + ->willReturn($customAttributesMetadata); + $this->model->setData($priceCode, 10); + + //The color attribute is not set, expect empty custom attribute array + $this->assertEquals([], $this->model->getCustomAttributes()); + + //Set the color attribute; + $this->model->setData($colorAttributeCode, "red"); + $attributeValue = new \Magento\Framework\Api\AttributeValue(); + $attributeValue2 = new \Magento\Framework\Api\AttributeValue(); + $this->attributeValueFactory->expects($this->exactly(2))->method('create') + ->willReturnOnConsecutiveCalls($attributeValue, $attributeValue2); + $this->assertEquals(1, count($this->model->getCustomAttributes())); + $this->assertNotNull($this->model->getCustomAttribute($colorAttributeCode)); + $this->assertEquals("red", $this->model->getCustomAttribute($colorAttributeCode)->getValue()); + + //Change the attribute value, should reflect in getCustomAttribute + $this->model->setData($colorAttributeCode, "blue"); + $this->assertEquals(1, count($this->model->getCustomAttributes())); + $this->assertNotNull($this->model->getCustomAttribute($colorAttributeCode)); + $this->assertEquals("blue", $this->model->getCustomAttribute($colorAttributeCode)->getValue()); + } + + /** + * @dataProvider priceDataProvider + */ + public function testGetGroupPrices($originalGroupPrices) + { + $this->invokeGetGroupOrTierPrices($originalGroupPrices, 'getGroupPrices'); + } + + /** + * @dataProvider priceDataProvider + */ + public function testGetTierPrices($originalGroupPrices) + { + $this->invokeGetGroupOrTierPrices($originalGroupPrices, 'getTierPrices'); + } + + protected function invokeGetGroupOrTierPrices($originalPrices, $getter) + { + // the priceModel's getter method will return the originalPrices + $priceModelMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Type\Price') + ->disableOriginalConstructor() + ->setMethods([$getter]) + ->getMock(); + $priceModelMock->expects($this->any()) + ->method($getter) + ->will($this->returnValue($originalPrices)); + + // the catalogProductType's priceFactory method will return the above priceModel + $catalogProductTypeMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Type') + ->disableOriginalConstructor() + ->setMethods(['priceFactory']) + ->getMock(); + $catalogProductTypeMock->expects(($this->any())) + ->method('priceFactory') + ->will($this->returnValue($priceModelMock)); + + // the productModel + $productModel = $this->objectManagerHelper->getObject( + 'Magento\Catalog\Model\Product', + [ + 'catalogProductType' => $catalogProductTypeMock + ] + ); + + $expectedResultIsEmpty = (empty($originalPrices) ? true : false); + $groupPrices = $productModel->$getter(); + $actualResultIsEmpty = (empty($groupPrices) ? true : false); + $this->assertEquals($expectedResultIsEmpty, $actualResultIsEmpty); + } + + /** + * @return array + */ + public function priceDataProvider() + { + return [ + 'receive empty array' => [[]], + 'receive null' => [null], + 'receive non-empty array' => [['non-empty', 'array', 'of', 'values']] + ]; + } } diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json index b0605d9539855499da59d386f5e106fa32951c96..ade3b473780c2d6a11325438c67f559829be10e1 100644 --- a/app/code/Magento/Catalog/composer.json +++ b/app/code/Magento/Catalog/composer.json @@ -3,37 +3,37 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-indexer": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-log": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-wishlist": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-msrp": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-catalog-rule": "0.74.0-beta2", - "magento/module-product-alert": "0.74.0-beta2", - "magento/module-url-rewrite": "0.74.0-beta2", - "magento/module-catalog-url-rewrite": "0.74.0-beta2", - "magento/module-page-cache": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-indexer": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-log": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-wishlist": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-msrp": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-catalog-rule": "0.74.0-beta3", + "magento/module-product-alert": "0.74.0-beta3", + "magento/module-url-rewrite": "0.74.0-beta3", + "magento/module-catalog-url-rewrite": "0.74.0-beta3", + "magento/module-page-cache": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta2" + "magento/module-cookie": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Catalog/etc/webapi.xml b/app/code/Magento/Catalog/etc/webapi.xml index 88bc0f93a6ec32002356446962220f48422f1fce..b86beded162cfd7ced4da7d5869e7efccf1d01cf 100644 --- a/app/code/Magento/Catalog/etc/webapi.xml +++ b/app/code/Magento/Catalog/etc/webapi.xml @@ -202,7 +202,7 @@ <resource ref="anonymous"/> </resources> </route> - <route url="/V1/products/media" method="POST"> + <route url="/V1/products/:sku/media" method="POST"> <service class="Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface" method="create"/> <resources> <resource ref="Magento_Catalog::catalog"/> @@ -247,7 +247,7 @@ </resources> </route> - <!-- Tear Price --> + <!-- Tier Price --> <route url="/V1/products/:sku/group-prices/:customerGroupId/tiers" method="GET"> <service class="Magento\Catalog\Api\ProductTierPriceManagementInterface" method="getList"/> <resources> diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index 3d648c064b3abec3b79a9ebf0ce4675582bece41..b2bfd622ed51b55d7f574584879e517fe41e2f48 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-import-export": "0.74.0-beta2", - "magento/module-indexer": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-import-export": "0.74.0-beta3", + "magento/module-indexer": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "ext-ctype": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index a08100c30935a41452a6cdcbbca3a6fba2b62d9e..9aea0a4ff684e90c76502d07aaf6a61cfde42cd8 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-indexer": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-indexer": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json index 527f58c05615f46d3c9348c710cb8f5ce65b8777..d17af7fe568758d9649f218b06bcb4430706bdf6 100644 --- a/app/code/Magento/CatalogRule/composer.json +++ b/app/code/Magento/CatalogRule/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-rule": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-indexer": "0.74.0-beta2", - "magento/module-import-export": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-rule": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-indexer": "0.74.0-beta3", + "magento/module-import-export": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index d0d4169d006ce4208d00d09dc1b3dc3c87a907c5..d63877cd7db705ae88eb120cabf43443e3a9628c 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-search": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-indexer": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-search": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-indexer": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index 730aec4c662dca3ff93602e6ecfcc12d33594130..0aa8692bb79f8f10ad0365c6e47ccc12b2d8adb2 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-catalog-import-export": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-import-export": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-url-rewrite": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-catalog-import-export": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-import-export": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-url-rewrite": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json index 772427302289cc7e94adf038c5620c8751c04d20..40f135631b704123ed56b5ba17071607650bf207 100644 --- a/app/code/Magento/CatalogWidget/composer.json +++ b/app/code/Magento/CatalogWidget/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-rule": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-wishlist": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-rule": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-wishlist": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Centinel/composer.json b/app/code/Magento/Centinel/composer.json index 497c1378422053931b3f7c2580aeb4f9843162c5..0319dbc0c07255d79394def57c25b14d2c8b3b0d 100644 --- a/app/code/Magento/Centinel/composer.json +++ b/app/code/Magento/Centinel/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json index a92572b3680b6c80688bc383ec8b5f72ea1a0cde..feb965971203a87ea928880f843010f8bf48e063 100644 --- a/app/code/Magento/Checkout/composer.json +++ b/app/code/Magento/Checkout/composer.json @@ -3,31 +3,31 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-payment": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-gift-message": "0.74.0-beta2", - "magento/module-wishlist": "0.74.0-beta2", - "magento/module-page-cache": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-msrp": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-ui": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-payment": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-gift-message": "0.74.0-beta3", + "magento/module-wishlist": "0.74.0-beta3", + "magento/module-page-cache": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-msrp": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-ui": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta2" + "magento/module-cookie": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json index 564eb787401ac173b467a9dc1a741c80188af697..8b1f2694c65e8826c554c5430f4fb1e92d7a0fb5 100644 --- a/app/code/Magento/CheckoutAgreements/composer.json +++ b/app/code/Magento/CheckoutAgreements/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json index d98e7df4c6fc084b82a8279bf5d69c2d4c25d446..f815637ee05812e01c32d2339e57f01e4a44cfca 100644 --- a/app/code/Magento/Cms/composer.json +++ b/app/code/Magento/Cms/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-email": "0.74.0-beta2", - "magento/module-ui": "0.74.0-beta2", - "magento/module-variable": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-email": "0.74.0-beta3", + "magento/module-ui": "0.74.0-beta3", + "magento/module-variable": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json index 9d32b3444bbb28713fdb769c65b01506cb3dd1ae..7023997c9a8593469758e6f746125d913c786186 100644 --- a/app/code/Magento/CmsUrlRewrite/composer.json +++ b/app/code/Magento/CmsUrlRewrite/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-url-rewrite": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-url-rewrite": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json index 72d17066f3299561cd531e7a1a27f32330c58830..5086021783bbf257b5a5aa0f5198e51e2be856eb 100644 --- a/app/code/Magento/Config/composer.json +++ b/app/code/Magento/Config/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-cron": "0.74.0-beta2", - "magento/module-email": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-cron": "0.74.0-beta3", + "magento/module-email": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json index 159d501aab3926c6ea08cb36613de2f915b90960..f8f63bb9e83eaca139ca56683442015184b14b0f 100644 --- a/app/code/Magento/ConfigurableImportExport/composer.json +++ b/app/code/Magento/ConfigurableImportExport/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-catalog-import-export": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-import-export": "0.74.0-beta2", - "magento/module-configurable-product": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-catalog-import-export": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-import-export": "0.74.0-beta3", + "magento/module-configurable-product": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php index 4947b0fc6088e5bd20e8b7b15c7d00cc20592abd..003ce2871eaca469fc3ffddf57aa34a0b6892271 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php @@ -25,7 +25,12 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param PriceCurrencyInterface $priceCurrency * @param \Magento\Customer\Api\GroupManagementInterface $groupManagement + * @param \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory $groupPriceFactory + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config * @param PriceModifierInterface $priceModifier + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\CatalogRule\Model\Resource\RuleFactory $ruleFactory, @@ -35,6 +40,9 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price \Magento\Framework\Event\ManagerInterface $eventManager, PriceCurrencyInterface $priceCurrency, \Magento\Customer\Api\GroupManagementInterface $groupManagement, + \Magento\Catalog\Api\Data\ProductGroupPriceInterfaceFactory $groupPriceFactory, + \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory, + \Magento\Framework\App\Config\ScopeConfigInterface $config, PriceModifierInterface $priceModifier ) { $this->priceModifier = $priceModifier; @@ -45,7 +53,10 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price $customerSession, $eventManager, $priceCurrency, - $groupManagement + $groupManagement, + $groupPriceFactory, + $tierPriceFactory, + $config ); } diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index 1b82ecacc37d54c27ecdd6a2bfee6e625b40a939..f58f91b35edc5057dfc36b479912b54e94e8234b 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -3,26 +3,26 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-catalog-rule": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-catalog-rule": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-webapi": "0.74.0-beta2" + "magento/module-webapi": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json index 57b5f1fb07d116c5a6def7ee13b40e6bd8efe874..e9471a079220d77129387f3f82ace215a90be5f0 100644 --- a/app/code/Magento/Contact/composer.json +++ b/app/code/Magento/Contact/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json index 6eb0244da272a35850eaeeb2aede214145e1fea6..c58ab6c0d63d185a5483cbab51e64f1aeff3d024 100644 --- a/app/code/Magento/Cookie/composer.json +++ b/app/code/Magento/Cookie/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.4.11|~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-backend": "0.74.0-beta2" + "magento/module-backend": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json index a5f2fd8de55aa27542811c9361cfac9e3d3ba001..16ae3ade8e573c7af86c8d1cdfd28b7acbea4fd9 100644 --- a/app/code/Magento/Cron/composer.json +++ b/app/code/Magento/Cron/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json index 7010fffc07b1b69be0f4e47d1f7cb164ee2009d7..3d8249ed4493abdff40658d8c95b94fe10359dbc 100644 --- a/app/code/Magento/CurrencySymbol/composer.json +++ b/app/code/Magento/CurrencySymbol/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-page-cache": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-page-cache": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php b/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php index 7c480a164ec834b8c56f411db93f8c5c6d096166..ddcd8755b30977399ae4103c27ac1a5ad64ea5c9 100644 --- a/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php +++ b/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php @@ -5,7 +5,7 @@ */ namespace Magento\Customer\Block\Address\Renderer; -use Magento\Customer\Model\Address\AbstractAddress; +use Magento\Customer\Model\Address\AddressModelInterface; use Magento\Customer\Model\Address\Mapper; use Magento\Customer\Model\Metadata\ElementFactory; use Magento\Framework\View\Element\AbstractBlock; @@ -111,7 +111,7 @@ class DefaultRenderer extends AbstractBlock implements RendererInterface * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function render(AbstractAddress $address, $format = null) + public function render(AddressModelInterface $address, $format = null) { $address = $address->getDataModel(0, 0); return $this->renderArray($this->addressMapper->toFlatArray($address), $format); diff --git a/app/code/Magento/Customer/Block/Address/Renderer/RendererInterface.php b/app/code/Magento/Customer/Block/Address/Renderer/RendererInterface.php index c906af48f091179fa76f90de0332794c5d409f1b..837ec1036fb46e54a17e410178b7b2a484fb5deb 100644 --- a/app/code/Magento/Customer/Block/Address/Renderer/RendererInterface.php +++ b/app/code/Magento/Customer/Block/Address/Renderer/RendererInterface.php @@ -6,6 +6,7 @@ namespace Magento\Customer\Block\Address\Renderer; use Magento\Directory\Model\Country\Format; +use Magento\Customer\Model\Address\AddressModelInterface; /** * Address renderer interface @@ -32,12 +33,12 @@ interface RendererInterface /** * Render address * - * @param \Magento\Customer\Model\Address\AbstractAddress $address + * @param AddressModelInterface $address * @param string|null $format * @return mixed * @deprecated All new code should use renderArray based on Metadata service */ - public function render(\Magento\Customer\Model\Address\AbstractAddress $address, $format = null); + public function render(AddressModelInterface $address, $format = null); /** * Get a format object for a given address attributes, based on the type set earlier. diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 32c5402bbb60f7dfd4c2933809cf873a704b27b6..0d227ae85ed6eddd5eee12a7feff43601e76a168 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -29,7 +29,7 @@ use Magento\Framework\Model\AbstractExtensibleModel; * @method bool getShouldIgnoreValidation() * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class AbstractAddress extends AbstractExtensibleModel +class AbstractAddress extends AbstractExtensibleModel implements AddressModelInterface { /** * Possible customer address types diff --git a/app/code/Magento/Customer/Model/Address/AddressModelInterface.php b/app/code/Magento/Customer/Model/Address/AddressModelInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..0b190b41d3ba4ca63cbd7ab37d2167951ce69e1f --- /dev/null +++ b/app/code/Magento/Customer/Model/Address/AddressModelInterface.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Customer\Model\Address; + +/** + * Interface AddressInterface + */ +interface AddressModelInterface +{ + /** + * Get steet line by number + * + * @param int $number + * @return string + */ + public function getStreetLine($number); + + /** + * Create fields street1, street2, etc. + * + * To be used in controllers for views data + * + * @return $this + */ + public function explodeStreetAddress(); +} diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json index aa814c3b434f9ca4becb84a524e2daaff6ac6154..fb5b280cb24f3a50789cd233e8faee1b28d8b577 100644 --- a/app/code/Magento/Customer/composer.json +++ b/app/code/Magento/Customer/composer.json @@ -3,33 +3,33 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-newsletter": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-wishlist": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-review": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-page-cache": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-authorization": "0.74.0-beta2", - "magento/module-integration": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/module-ui": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-newsletter": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-wishlist": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-review": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-page-cache": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-authorization": "0.74.0-beta3", + "magento/module-integration": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/module-ui": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta2" + "magento/module-cookie": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json index 6163121f930528b81563fcbfd5166c6fbd3e75cb..5a1540c2f131655a23515803e3c41580e47d6f60 100644 --- a/app/code/Magento/CustomerImportExport/composer.json +++ b/app/code/Magento/CustomerImportExport/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-import-export": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-import-export": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/DesignEditor/composer.json b/app/code/Magento/DesignEditor/composer.json index 35909f252fa2800b842cd827b53d96d23e21a3f0..01fb407315b6aded0f6bd301e877d22abdcdc68b 100644 --- a/app/code/Magento/DesignEditor/composer.json +++ b/app/code/Magento/DesignEditor/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-translation": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-translation": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Developer/Model/Config/Backend/AllowedIps.php b/app/code/Magento/Developer/Model/Config/Backend/AllowedIps.php new file mode 100644 index 0000000000000000000000000000000000000000..48656d5729843a386c95c1ce5da9fdf975e12032 --- /dev/null +++ b/app/code/Magento/Developer/Model/Config/Backend/AllowedIps.php @@ -0,0 +1,80 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Developer\Model\Config\Backend; + +/** + * Backend model for validating ip addresses entered in Developer Client Restrictions + * + * Class AllowedIps + */ +class AllowedIps extends \Magento\Framework\App\Config\Value +{ + /** + * @var \Magento\Framework\Message\ManagerInterface + */ + private $messageManager; + + /** + * Constructor + * + * @param \Magento\Framework\Model\Context $context + * @param \Magento\Framework\Registry $registry + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config + * @param \Magento\Framework\Message\ManagerInterface $messageManager + * @param \Magento\Framework\Model\Resource\AbstractResource $resource + * @param \Magento\Framework\Data\Collection\Db $resourceCollection + * @param array $data + */ + public function __construct( + \Magento\Framework\Model\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Framework\App\Config\ScopeConfigInterface $config, + \Magento\Framework\Message\ManagerInterface $messageManager, + \Magento\Framework\Model\Resource\AbstractResource $resource = null, + \Magento\Framework\Data\Collection\Db $resourceCollection = null, + array $data = [] + ) { + $this->messageManager = $messageManager; + parent::__construct($context, $registry, $config, $resource, $resourceCollection, $data); + } + + /** + * Validate ip addresses before save + * + * @return $this + */ + public function beforeSave() + { + $allowedIpsRaw = $this->getValue(); + $noticeMsgArray = []; + $allowedIpsArray = []; + + if (empty($allowedIpsRaw)) { + return parent::beforeSave(); + } + + $dataArray = explode(',', $allowedIpsRaw); + foreach ($dataArray as $data) { + if (filter_var(trim($data), FILTER_VALIDATE_IP)) { + $allowedIpsArray[] = $data; + } else { + $noticeMsgArray[] = $data; + } + } + + $noticeMsg = implode(',', $noticeMsgArray); + if (!empty($noticeMsgArray)) { + $this->messageManager->addNotice( + __( + __('The following invalid values cannot be saved: %values', ['values' => $noticeMsg]) + ) + ); + } + + $this->setValue(implode(',', $allowedIpsArray)); + return parent::beforeSave(); + } +} diff --git a/app/code/Magento/Developer/Test/Unit/Model/Config/Backend/AllowedIpsTest.php b/app/code/Magento/Developer/Test/Unit/Model/Config/Backend/AllowedIpsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bd6b0714c0cb469b4d81c7a4df3350ffda43f44f --- /dev/null +++ b/app/code/Magento/Developer/Test/Unit/Model/Config/Backend/AllowedIpsTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Developer\Test\Unit\Model\Config\Backend; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +/** + * Class AllowedIpsTest + */ +class AllowedIpsTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Developer\Model\Config\Backend\AllowedIps + */ + protected $model; + + protected function setUp() + { + $contextMock = $this->getMockBuilder('\Magento\Framework\Model\Context') + ->disableOriginalConstructor() + ->getMock(); + $eventMangerMock = $this->getMockBuilder('\Magento\Framework\Event\ManagerInterface') + ->disableOriginalConstructor() + ->getMock(); + $contextMock->expects($this->any()) + ->method('getEventDispatcher') + ->willReturn($eventMangerMock); + + $objectManagerHelper = new ObjectManagerHelper($this); + + $this->model = $objectManagerHelper->getObject( + 'Magento\Developer\Model\Config\Backend\AllowedIps', + [ + 'context' => $contextMock, + ] + ); + } + + /** + * @param string $value + * @param string $expected + * @dataProvider beforeSaveDataProvider + * @return void + */ + public function testBeforeSave($value, $expected) + { + $this->assertNull($this->model->getValue()); + $this->model->setValue($value); + $this->model->beforeSave(); + $this->assertEquals($expected, trim($this->model->getValue())); + } + + /** + * @return array + */ + public function beforeSaveDataProvider() + { + return [ + [ '', '' ], + [ ', 10.64.206.85, 10. 64.85.206 ', '10.64.206.85' ], + [ '10.64.206.85, 10.64.1a.x, ,,', '10.64.206.85' ], + [ ' ,, 10.64.206.85, 10.49.206.85 , ', '10.64.206.85, 10.49.206.85' ], + [ '2001:db8:0:1234:0:567:8:1, ', '2001:db8:0:1234:0:567:8:1' ], /* valid IPV6 address */ + [ '2001:0cb8:25a3:04c1:1324:8a2b:0471:8221', '2001:0cb8:25a3:04c1:1324:8a2b:0471:8221'], + [ '255.255.255.255', '255.255.255.255'], /* valid private ip */ + [ '127.0.0.1, ::1', '127.0.0.1, ::1'], /* valid reserved ip */ + ['*[789bo88n=], 12.34.56.78,[,q 049cq9840@@', '12.34.56.78'] + ]; + } +} diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json index 4481cd9cef6b380a943b5c9090bbded76cf2a2c4..14647e03ea93f709df3f667cd6efd707e5815067 100644 --- a/app/code/Magento/Developer/composer.json +++ b/app/code/Magento/Developer/composer.json @@ -3,12 +3,12 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Developer/etc/adminhtml/system.xml b/app/code/Magento/Developer/etc/adminhtml/system.xml index 25de378ba8882c53c205fc19a967002a71c113f7..f858f6b51bc275787d5b476b42a1a3f62277ec11 100644 --- a/app/code/Magento/Developer/etc/adminhtml/system.xml +++ b/app/code/Magento/Developer/etc/adminhtml/system.xml @@ -15,6 +15,14 @@ <source_model>Magento\Developer\Model\Config\Source\WorkflowType</source_model> </field> </group> + <group id="restrict" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> + <label>Developer Client Restrictions</label> + <field id="allow_ips" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> + <label>Allowed IPs (comma separated)</label> + <comment>Leave empty for access from any location.</comment> + <backend_model>Magento\Developer\Model\Config\Backend\AllowedIps</backend_model> + </field> + </group> </section> </system> </config> diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json index 0b55a5e7fb7583d45e8f575500caeec4108fbf84..f8b23f85eb976a51e0e648a96ab6765cbba5576d 100644 --- a/app/code/Magento/Dhl/composer.json +++ b/app/code/Magento/Dhl/composer.json @@ -3,22 +3,22 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json index 9fe7db235aa15e9e2fc07d008c844581b73ece0b..8daa181fa0d1d5dcdd2d79c25d90835abf171213 100644 --- a/app/code/Magento/Directory/composer.json +++ b/app/code/Magento/Directory/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json index e1c4c4f63618d9fc705d4722a1ee9cda57b5f62a..c619d5650a2b8222d8f09df6f67404634ec47d5c 100644 --- a/app/code/Magento/Downloadable/composer.json +++ b/app/code/Magento/Downloadable/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-wishlist": "0.74.0-beta2", - "magento/module-gift-message": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-msrp": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-wishlist": "0.74.0-beta3", + "magento/module-gift-message": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-msrp": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json index 837f27f1db1cd0fec7b61a883878092b47ff7ae7..586b44dee399017fe3d53db1b240e1c5e3b4817e 100644 --- a/app/code/Magento/Eav/composer.json +++ b/app/code/Magento/Eav/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json index 1ea2d97faf7463293d39d9e65617cfa53ae03886..0958f72411bb1281b5befcad93fb8fe106bae16d 100644 --- a/app/code/Magento/Email/composer.json +++ b/app/code/Magento/Email/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-variable": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-variable": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json index 090e04498b0459ffd3621b67917a16f83004e0e6..6e5bca67572715ac7b0d07fae1a49a525f723aca 100644 --- a/app/code/Magento/Fedex/composer.json +++ b/app/code/Magento/Fedex/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json index 32828754a4c6050ddcb32c41fa72777194e61729..d094a022bdc90d2673193a4f1df14a1e57730262 100644 --- a/app/code/Magento/GiftMessage/composer.json +++ b/app/code/Magento/GiftMessage/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-multishipping": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-multishipping": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json index 5910e7b7bd1c3e6ecf4ede31914c3b0742d2c8b8..20cc0cca177bd3e3a16470c0bc9eab7d428b2047 100644 --- a/app/code/Magento/GoogleAdwords/composer.json +++ b/app/code/Magento/GoogleAdwords/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json index 3df1f85b5e00267b40039d4eea1a7420f8b1c032..7f4b624cc674b86d13a65f5ec7e3b6b760daa484 100644 --- a/app/code/Magento/GoogleAnalytics/composer.json +++ b/app/code/Magento/GoogleAnalytics/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-cookie": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-cookie": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json index 7d9229a0ae1edfb7bb880df7b31bd5e20e13563f..bfd899db5dcfd14f958cf2759683fca8a5f4a27d 100644 --- a/app/code/Magento/GoogleOptimizer/composer.json +++ b/app/code/Magento/GoogleOptimizer/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-google-analytics": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-google-analytics": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleShopping/composer.json b/app/code/Magento/GoogleShopping/composer.json index d1c57e9befe38f5d1d813b751043ebedd83cd8cf..876ba64beaafac2f93140a2b1a27c18d5ef04785 100644 --- a/app/code/Magento/GoogleShopping/composer.json +++ b/app/code/Magento/GoogleShopping/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json index 5a287d286f7f3ba465d0ff7b3192be469a41e2af..ba9c385a52d2fce0c284cf2fb03f350b5f8eb584 100644 --- a/app/code/Magento/GroupedImportExport/composer.json +++ b/app/code/Magento/GroupedImportExport/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-import-export": "0.74.0-beta2", - "magento/module-catalog-import-export": "0.74.0-beta2", - "magento/module-grouped-product": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-import-export": "0.74.0-beta3", + "magento/module-catalog-import-export": "0.74.0-beta3", + "magento/module-grouped-product": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json index 7d0848de8487442f4374094c8f1166dfafcaee0b..69ad6a56e9af77f4871748f386b5e4ff8f2cf27d 100644 --- a/app/code/Magento/GroupedProduct/composer.json +++ b/app/code/Magento/GroupedProduct/composer.json @@ -3,22 +3,22 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/module-msrp": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/module-msrp": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index 0babfceb059a23506fb519fbc4fe9d095221eb44..f217da9e091e7a2729de22998b5f4e39ebf8df6e 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-indexer": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-indexer": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "ext-ctype": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json index 29b3528dad550e62e60d931a2166f146d100f54f..ef774c33b78430ba2b679d9be84534c41bc18b62 100644 --- a/app/code/Magento/Indexer/composer.json +++ b/app/code/Magento/Indexer/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta2", - "magento/module-page-cache": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-backend": "0.74.0-beta3", + "magento/module-page-cache": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json index 70db5bfe2d95a86570d9ab2039d1c91229373435..e908c19f24c72259799e750135f8a29bed147a6f 100644 --- a/app/code/Magento/Integration/composer.json +++ b/app/code/Magento/Integration/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-user": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-authorization": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-user": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-authorization": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json index d0f240acf188433f974962216238443f4075689c..8d82203c6c0981ba9c6eecc830d029a964bd0614 100644 --- a/app/code/Magento/LayeredNavigation/composer.json +++ b/app/code/Magento/LayeredNavigation/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Log/composer.json b/app/code/Magento/Log/composer.json index 55ef40e0c62e08b89a1ab092e266a95993e212bb..8d6db5267a365509aeb686071d3bd7392a6050f2 100644 --- a/app/code/Magento/Log/composer.json +++ b/app/code/Magento/Log/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json index bddfdffd918bdb3462c7f604fa558076879079d2..43f1465db885dcb59df237672ed89c20396eaf7f 100644 --- a/app/code/Magento/MediaStorage/composer.json +++ b/app/code/Magento/MediaStorage/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json index 27b2fad7748b152f986ffee32f54ff46472aecbf..d6644e15d3d28e02dcc7b9d73ed41f329a98ae45 100644 --- a/app/code/Magento/Msrp/composer.json +++ b/app/code/Magento/Msrp/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-bundle": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-downloadable": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-grouped-product": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-bundle": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-downloadable": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-grouped-product": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json index 437f0d8c722e7021258e8e6e0b92a60266836cdc..3c747079bda9ae83c31afff571e1301244d9e512 100644 --- a/app/code/Magento/Multishipping/composer.json +++ b/app/code/Magento/Multishipping/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-payment": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-payment": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json index 460524e9b3689cdb22c9d4215a5d2826b13de4e2..74e9a4d2d47a02f78007096533d06d9140e68383 100644 --- a/app/code/Magento/Newsletter/composer.json +++ b/app/code/Magento/Newsletter/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-email": "0.74.0-beta2", - "magento/module-cron": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-require-js": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-email": "0.74.0-beta3", + "magento/module-cron": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-require-js": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json index 11f6f88c5c9a6d2cacb80f4308e13a8fabb4007c..63a017be64551ca9ee3c9c2dac081f2dc38dec30 100644 --- a/app/code/Magento/OfflinePayments/composer.json +++ b/app/code/Magento/OfflinePayments/composer.json @@ -3,12 +3,12 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-payment": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-payment": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json index 53659003e0037b744fb74c281efde0dcb4d3e8da..a658cd0560c16e7a83fe0e3c2a8319d9a7239604 100644 --- a/app/code/Magento/OfflineShipping/composer.json +++ b/app/code/Magento/OfflineShipping/composer.json @@ -3,21 +3,21 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-sales-rule": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-sales-rule": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json index bf42a2eeb57e54ed7caabde4b982abcfbf91fc2b..2c2478d7bf220572f6b42d372c22cd9ea448bc0d 100644 --- a/app/code/Magento/PageCache/composer.json +++ b/app/code/Magento/PageCache/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Payment/Block/Info.php b/app/code/Magento/Payment/Block/Info.php index 55f6be202901650d5f8b3a32c6e3bb05af46d60b..d56f2c61fe3559e242c97aecc6bc23a704fe1dd6 100644 --- a/app/code/Magento/Payment/Block/Info.php +++ b/app/code/Magento/Payment/Block/Info.php @@ -25,13 +25,13 @@ class Info extends \Magento\Framework\View\Element\Template /** * Retrieve info model * - * @return \Magento\Payment\Model\Info + * @return \Magento\Payment\Model\InfoInterface * @throws \Magento\Framework\Exception\LocalizedException */ public function getInfo() { $info = $this->getData('info'); - if (!$info instanceof \Magento\Payment\Model\Info) { + if (!$info instanceof \Magento\Payment\Model\InfoInterface) { throw new \Magento\Framework\Exception\LocalizedException( __('We cannot retrieve the payment info model object.') ); diff --git a/app/code/Magento/Payment/Helper/Data.php b/app/code/Magento/Payment/Helper/Data.php index 0792fa1e73c3792306857135b1be3830ba4e480a..943b44b9e453234939438598a54f3a7095c028ce 100644 --- a/app/code/Magento/Payment/Helper/Data.php +++ b/app/code/Magento/Payment/Helper/Data.php @@ -9,7 +9,7 @@ use Magento\Payment\Model\Method\Substitution; use Magento\Quote\Model\Quote; use Magento\Store\Model\Store; use Magento\Payment\Block\Form; -use Magento\Payment\Model\Info; +use Magento\Payment\Model\InfoInterface; use Magento\Framework\View\Element\Template; use Magento\Framework\View\LayoutInterface; use Magento\Framework\View\LayoutFactory; @@ -182,11 +182,11 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper /** * Retrieve payment information block * - * @param Info $info + * @param InfoInterface $info * @param \Magento\Framework\View\LayoutInterface $layout * @return Template */ - public function getInfoBlock(Info $info, LayoutInterface $layout = null) + public function getInfoBlock(InfoInterface $info, LayoutInterface $layout = null) { $layout = $layout ?: $this->_layout; $blockType = $info->getMethodInstance()->getInfoBlockType(); @@ -198,12 +198,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper /** * Render payment information block * - * @param Info $info + * @param InfoInterface $info * @param int $storeId * @return string * @throws \Exception */ - public function getInfoBlockHtml(Info $info, $storeId) + public function getInfoBlockHtml(InfoInterface $info, $storeId) { $this->_appEmulation->startEnvironmentEmulation($storeId); diff --git a/app/code/Magento/Payment/Model/Info.php b/app/code/Magento/Payment/Model/Info.php index 42f76fdb37507adf169c31c48e180303d64b7361..28de02b2dbf7b21ffea4e399750cef3412356711 100644 --- a/app/code/Magento/Payment/Model/Info.php +++ b/app/code/Magento/Payment/Model/Info.php @@ -10,7 +10,7 @@ use Magento\Framework\Model\AbstractExtensibleModel; /** * Payment information model */ -class Info extends AbstractExtensibleModel +class Info extends AbstractExtensibleModel implements InfoInterface { /** * Additional information container diff --git a/app/code/Magento/Payment/Model/InfoInterface.php b/app/code/Magento/Payment/Model/InfoInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..270ee9c16fe89c98208ec2f8ac1cde356adae12b --- /dev/null +++ b/app/code/Magento/Payment/Model/InfoInterface.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Payment\Model; + +/** + * Interface InfoInterface + */ +interface InfoInterface +{ + /** + * Encrypt data + * + * @param string $data + * @return string + */ + public function encrypt($data); + + /** + * Decrypt data + * + * @param string $data + * @return string + */ + public function decrypt($data); + + /** + * Set Additional information about payment into Payment model + * + * @param string $key + * @param string|null $value + * @return mixed + */ + public function setAdditionalInformation($key, $value = null); + + /** + * Check whether there is additional information by specified key + * + * @param mixed|null $key + * @return bool + */ + public function hasAdditionalInformation($key = null); + + /** + * Unsetter for entire additional_information value or one of its element by key + * + * @param string|null $key + * @return $this + */ + public function unsAdditionalInformation($key = null); + + /** + * Getter for entire additional_information value or one of its element by key + * + * @param string|null $key + * @return mixed + */ + public function getAdditionalInformation($key = null); + + /** + * Retrieve payment method model object + * + * @return \Magento\Payment\Model\MethodInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function getMethodInstance(); +} diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php index 926017b8bcce80f53a492ad3cb6849d4cbc2d2eb..74e26082b6c0b7525c47b07c57f5c6cf08bc263d 100644 --- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php +++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php @@ -382,12 +382,12 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl /** * Fetch transaction info * - * @param \Magento\Payment\Model\Info $payment + * @param \Magento\Payment\Model\InfoInterface $payment * @param string $transactionId * @return array * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function fetchTransactionInfo(\Magento\Payment\Model\Info $payment, $transactionId) + public function fetchTransactionInfo(\Magento\Payment\Model\InfoInterface $payment, $transactionId) { return []; } @@ -497,7 +497,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl public function getInfoInstance() { $instance = $this->getData('info_instance'); - if (!$instance instanceof \Magento\Payment\Model\Info) { + if (!$instance instanceof \Magento\Payment\Model\InfoInterface) { throw new \Magento\Framework\Exception\LocalizedException(__('We cannot retrieve the payment information object instance.')); } return $instance; @@ -673,11 +673,11 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl /** * Whether this method can accept or deny payment * - * @param \Magento\Payment\Model\Info $payment + * @param \Magento\Payment\Model\InfoInterface $payment * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function canReviewPayment(\Magento\Payment\Model\Info $payment) + public function canReviewPayment(\Magento\Payment\Model\InfoInterface $payment) { return $this->_canReviewPayment; } @@ -685,11 +685,11 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl /** * Attempt to accept a payment that us under review * - * @param \Magento\Payment\Model\Info $payment + * @param \Magento\Payment\Model\InfoInterface $payment * @return false * @throws \Magento\Framework\Exception\LocalizedException */ - public function acceptPayment(\Magento\Payment\Model\Info $payment) + public function acceptPayment(\Magento\Payment\Model\InfoInterface $payment) { if (!$this->canReviewPayment($payment)) { throw new \Magento\Framework\Exception\LocalizedException(__('The payment review action is unavailable.')); @@ -700,11 +700,11 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl /** * Attempt to deny a payment that us under review * - * @param \Magento\Payment\Model\Info $payment + * @param \Magento\Payment\Model\InfoInterface $payment * @return false * @throws \Magento\Framework\Exception\LocalizedException */ - public function denyPayment(\Magento\Payment\Model\Info $payment) + public function denyPayment(\Magento\Payment\Model\InfoInterface $payment) { if (!$this->canReviewPayment($payment)) { throw new \Magento\Framework\Exception\LocalizedException(__('The payment review action is unavailable.')); diff --git a/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php b/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php index 72deb26aefc070d473031645749bf9e49249fb77..0f0ff5b84c207b16cc30a0c81059877bc1e0fef2 100644 --- a/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php +++ b/app/code/Magento/Payment/Test/Unit/Block/Info/CcTest.php @@ -135,11 +135,11 @@ class CcTest extends \PHPUnit_Framework_TestCase $paymentInfo ->expects($this->any()) ->method('getCcExpMonth') - ->will($this->returnValue($ccExpMonth)); + ->willReturn($ccExpMonth); $paymentInfo ->expects($this->any()) ->method('getCcExpYear') - ->will($this->returnValue($ccExpYear)); + ->willReturn($ccExpYear); $this->model->setData('info', $paymentInfo); $this->localeDate diff --git a/app/code/Magento/Payment/Test/Unit/Model/InfoTest.php b/app/code/Magento/Payment/Test/Unit/Model/InfoTest.php index 59e4cd7d0b91bc7cff458c2ec7afe57205bef730..ae82d7436da935940a66d6abb8134fa3a61a42ac 100644 --- a/app/code/Magento/Payment/Test/Unit/Model/InfoTest.php +++ b/app/code/Magento/Payment/Test/Unit/Model/InfoTest.php @@ -11,7 +11,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHe class InfoTest extends \PHPUnit_Framework_TestCase { - /** @var \Magento\Payment\Model\Info */ + /** @var \Magento\Payment\Model\InfoInterface */ protected $info; /** @var ObjectManagerHelper */ diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json index e01a5f8c9d78683adacbc9ed92cec5d014258aea..3af9de981fff0d3d0d6073693958f37561435dc4 100644 --- a/app/code/Magento/Payment/composer.json +++ b/app/code/Magento/Payment/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-centinel": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-centinel": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json index 9c8da77db34ae907db6b54c55a6854a0639f87c0..b21dded808b80a107abc15457fd4f9bf495e5ca9 100644 --- a/app/code/Magento/Persistent/composer.json +++ b/app/code/Magento/Persistent/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-cron": "0.74.0-beta2", - "magento/module-page-cache": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-cron": "0.74.0-beta3", + "magento/module-page-cache": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json index 26d2e7aec1ff07e2db2d5a71c5a1b72472c9eec0..a5cf3ae86f7f402c90d43a66cc38b4ac287356eb 100644 --- a/app/code/Magento/ProductAlert/composer.json +++ b/app/code/Magento/ProductAlert/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json index ae730104a913cb91e40c2fe35a4b6f0267d33c96..a3ee5112407d202b6551795a0edfbefbf9cc8943 100644 --- a/app/code/Magento/Quote/composer.json +++ b/app/code/Magento/Quote/composer.json @@ -3,23 +3,23 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-catalog-rule": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-authorization": "0.74.0-beta2", - "magento/module-payment": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-catalog-rule": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-authorization": "0.74.0-beta3", + "magento/module-payment": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Reports/Model/Resource/Order/Collection.php b/app/code/Magento/Reports/Model/Resource/Order/Collection.php index 68558080b6670588778570df2e4506f4a246536d..0dd3a60c837619d225492619fa4a7b7b02b14394 100644 --- a/app/code/Magento/Reports/Model/Resource/Order/Collection.php +++ b/app/code/Magento/Reports/Model/Resource/Order/Collection.php @@ -64,13 +64,14 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot * @param \Magento\Framework\DB\Helper $coreResourceHelper * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Sales\Model\Order\Config $orderConfig * @param \Magento\Sales\Model\Resource\Report\OrderFactory $reportOrderFactory - * @param mixed $connection + * @param null $connection * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource * * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -80,6 +81,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, \Magento\Framework\DB\Helper $coreResourceHelper, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Store\Model\StoreManagerInterface $storeManager, @@ -94,6 +96,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection $logger, $fetchStrategy, $eventManager, + $entitySnapshot, $coreResourceHelper, $connection, $resource diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json index 3723ef185420c053d25c340c108fe4be6f96a52f..8da7350e088f7940fcf4998578b61e0a88543706 100644 --- a/app/code/Magento/Reports/composer.json +++ b/app/code/Magento/Reports/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-log": "0.74.0-beta2", - "magento/module-wishlist": "0.74.0-beta2", - "magento/module-review": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-downloadable": "0.74.0-beta2", - "magento/module-sales-rule": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-log": "0.74.0-beta3", + "magento/module-wishlist": "0.74.0-beta3", + "magento/module-review": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-downloadable": "0.74.0-beta3", + "magento/module-sales-rule": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json index ea1e62c2a69b85d7204632e26c74ff33b8b6734e..df6e01d1a57fc808567a83e81c0190c02d08ebb0 100644 --- a/app/code/Magento/RequireJs/composer.json +++ b/app/code/Magento/RequireJs/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json index b8ed58f3b392fc59bea283d23fdf2b890862ef96..19bfff0e4a79ddce6d01f6ad9dfba77015c02015 100644 --- a/app/code/Magento/Review/composer.json +++ b/app/code/Magento/Review/composer.json @@ -3,22 +3,22 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-newsletter": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-ui": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-newsletter": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-ui": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta2" + "magento/module-cookie": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json index 8ffd701cc3c4258b28e307ddeab9d71c3575e5c7..dbeb5f9d7461a7d4ff1e2e5ddfa0f7135158a93f 100644 --- a/app/code/Magento/Rss/composer.json +++ b/app/code/Magento/Rss/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json index a6519c1785c7d7a6cf0337f11c27611e6dd88dea..637f0ff5d774a562a63b7b39f1affec38ae24e77 100644 --- a/app/code/Magento/Rule/composer.json +++ b/app/code/Magento/Rule/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php index c319a376a1bb36434a953c5ce7bcc221acf79852..b83a8eb2ef0b9b3427f0ec74b868f3d34c7f23aa 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php @@ -137,7 +137,11 @@ class View extends \Magento\Backend\Block\Widget\Form\Container return __( 'Credit Memo #%1 | %3 | %2 (%4)', $this->getCreditmemo()->getIncrementId(), - $this->formatDate($this->getCreditmemo()->getCreatedAtDate(), \IntlDateFormatter::MEDIUM, true), + $this->formatDate( + $this->_localeDate->date(new \DateTime($this->getCreditmemo()->getCreatedAt())), + \IntlDateFormatter::MEDIUM, + true + ), $this->getCreditmemo()->getStateName(), $emailSent ); diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php index de3a079d0894f9233392a3d1a6a652372aec7313..eb1570d96db2dd355d0c29e3f930a659754ae494 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php @@ -198,7 +198,11 @@ class View extends \Magento\Backend\Block\Widget\Form\Container $this->getInvoice()->getIncrementId(), $this->getInvoice()->getStateName(), $emailSent, - $this->formatDate($this->getInvoice()->getCreatedAtDate(), \IntlDateFormatter::MEDIUM, true) + $this->formatDate( + $this->_localeDate->date(new \DateTime($this->getInvoice()->getCreatedAt())), + \IntlDateFormatter::MEDIUM, + true + ) ); } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View.php index ffa72f42735bf81a8f1f96d6db68e0c9e58d96d3..be2568dd8698ac7c5fc77015baf009d593a8b432 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/View.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View.php @@ -9,6 +9,7 @@ namespace Magento\Sales\Block\Adminhtml\Order; /** * Adminhtml sales order view + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class View extends \Magento\Backend\Block\Widget\Form\Container { @@ -287,7 +288,11 @@ class View extends \Magento\Backend\Block\Widget\Form\Container 'Order # %1 %2 | %3', $this->getOrder()->getRealOrderId(), $_extOrderId, - $this->formatDate($this->getOrder()->getCreatedAtDate(), \IntlDateFormatter::MEDIUM, true) + $this->formatDate( + $this->_localeDate->date(new \DateTime($this->getOrder()->getCreatedAt())), + \IntlDateFormatter::MEDIUM, + true + ) ); } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Info.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Info.php index f3eb2484bcb0ce2de9e5194cc72ed39252111f28..6d72ad2950fba9c97e9d3bce51b499143e53221b 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Info.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Info.php @@ -7,10 +7,12 @@ namespace Magento\Sales\Block\Adminhtml\Order\View; use Magento\Eav\Model\AttributeDataFactory; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Sales\Model\Order\Address; /** * Order history block * Class Info + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Info extends \Magento\Sales\Block\Adminhtml\Order\AbstractOrder { @@ -35,6 +37,11 @@ class Info extends \Magento\Sales\Block\Adminhtml\Order\AbstractOrder */ protected $_metadataElementFactory; + /** + * @var Address\Renderer + */ + protected $addressRenderer; + /** * Constructor * @@ -44,6 +51,7 @@ class Info extends \Magento\Sales\Block\Adminhtml\Order\AbstractOrder * @param \Magento\Customer\Api\GroupRepositoryInterface $groupRepository * @param \Magento\Customer\Api\CustomerMetadataInterface $metadata * @param \Magento\Customer\Model\Metadata\ElementFactory $elementFactory + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer * @param array $data */ public function __construct( @@ -53,11 +61,13 @@ class Info extends \Magento\Sales\Block\Adminhtml\Order\AbstractOrder \Magento\Customer\Api\GroupRepositoryInterface $groupRepository, \Magento\Customer\Api\CustomerMetadataInterface $metadata, \Magento\Customer\Model\Metadata\ElementFactory $elementFactory, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, array $data = [] ) { $this->groupRepository = $groupRepository; $this->metadata = $metadata; $this->_metadataElementFactory = $elementFactory; + $this->addressRenderer = $addressRenderer; parent::__construct($context, $registry, $adminHelper, $data); } @@ -244,4 +254,38 @@ class Info extends \Magento\Sales\Block\Adminhtml\Order\AbstractOrder { return $this->_storeManager->isSingleStoreMode(); } + + /** + * Get object created at date affected with object store timezone + * + * @param mixed $store + * @param string $createdAt + * @return \DateTime + */ + public function getCreatedAtStoreDate($store, $createdAt) + { + return $this->_localeDate->scopeDate($store, $createdAt, true); + } + + /** + * Get object created at date + * + * @param string $createdAt + * @return \DateTime + */ + public function getOrderAdminDate($createdAt) + { + return $this->_localeDate->date(new \DateTime($createdAt)); + } + + /** + * Returns string with formatted address + * + * @param Address $address + * @return null|string + */ + public function getFormattedAddress(Address $address) + { + return $this->addressRenderer->format($address, 'html'); + } } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php index 7e1f2548c0bf45fa36436c9825dabde5466cc32c..04a27b73b15d0b94e0264d735e9569d94ce80eb3 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php @@ -68,7 +68,7 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen $history[] = $this->_prepareHistoryItem( $orderComment->getStatusLabel(), $orderComment->getIsCustomerNotified(), - $orderComment->getCreatedAtDate(), + $this->getOrderAdminDate($orderComment->getCreatedAt()), $orderComment->getComment() ); } @@ -77,14 +77,14 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen $history[] = $this->_prepareHistoryItem( __('Credit memo #%1 created', $_memo->getIncrementId()), $_memo->getEmailSent(), - $_memo->getCreatedAtDate() + $this->getOrderAdminDate($_memo->getCreatedAt()) ); foreach ($_memo->getCommentsCollection() as $_comment) { $history[] = $this->_prepareHistoryItem( __('Credit memo #%1 comment added', $_memo->getIncrementId()), $_comment->getIsCustomerNotified(), - $_comment->getCreatedAtDate(), + $this->getOrderAdminDate($_comment->getCreatedAt()), $_comment->getComment() ); } @@ -94,14 +94,14 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen $history[] = $this->_prepareHistoryItem( __('Shipment #%1 created', $_shipment->getIncrementId()), $_shipment->getEmailSent(), - $_shipment->getCreatedAtDate() + $this->getOrderAdminDate($_shipment->getCreatedAt()) ); foreach ($_shipment->getCommentsCollection() as $_comment) { $history[] = $this->_prepareHistoryItem( __('Shipment #%1 comment added', $_shipment->getIncrementId()), $_comment->getIsCustomerNotified(), - $_comment->getCreatedAtDate(), + $this->getOrderAdminDate($_comment->getCreatedAt()), $_comment->getComment() ); } @@ -111,14 +111,14 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen $history[] = $this->_prepareHistoryItem( __('Invoice #%1 created', $_invoice->getIncrementId()), $_invoice->getEmailSent(), - $_invoice->getCreatedAtDate() + $this->getOrderAdminDate($_invoice->getCreatedAt()) ); foreach ($_invoice->getCommentsCollection() as $_comment) { $history[] = $this->_prepareHistoryItem( __('Invoice #%1 comment added', $_invoice->getIncrementId()), $_comment->getIsCustomerNotified(), - $_comment->getCreatedAtDate(), + $this->getOrderAdminDate($_comment->getCreatedAt()), $_comment->getComment() ); } @@ -128,7 +128,7 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen $history[] = $this->_prepareHistoryItem( __('Tracking number %1 for %2 assigned', $_track->getNumber(), $_track->getTitle()), false, - $_track->getCreatedAtDate() + $this->getOrderAdminDate($_track->getCreatedAt()) ); } @@ -302,4 +302,15 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen } return $createdAtA->getTimestamp() < $createdAtB->getTimestamp() ? -1 : 1; } + + /** + * Get order admin date + * + * @param int $createdAt + * @return \DateTime + */ + public function getOrderAdminDate($createdAt) + { + return $this->_localeDate->date(new \DateTime($createdAt)); + } } diff --git a/app/code/Magento/Sales/Block/Order/Info.php b/app/code/Magento/Sales/Block/Order/Info.php index eee77fc9b3e588a9846e2a2b1c4ed3f55948d8d8..c0cc355c7844ab0985db090385e117988eb58b2e 100644 --- a/app/code/Magento/Sales/Block/Order/Info.php +++ b/app/code/Magento/Sales/Block/Order/Info.php @@ -5,6 +5,12 @@ */ namespace Magento\Sales\Block\Order; +use Magento\Sales\Model\Order\Address; +use Magento\Framework\View\Element\Template\Context as TemplateContext; +use Magento\Framework\Registry; +use Magento\Payment\Helper\Data as PaymentHelper; +use Magento\Sales\Model\Order\Address\Renderer as AddressRenderer; + /** * Invoice view comments form * @@ -22,27 +28,35 @@ class Info extends \Magento\Framework\View\Element\Template * * @var \Magento\Framework\Registry */ - protected $_coreRegistry = null; + protected $coreRegistry = null; /** * @var \Magento\Payment\Helper\Data */ - protected $_paymentHelper; + protected $paymentHelper; /** - * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Magento\Framework\Registry $registry - * @param \Magento\Payment\Helper\Data $paymentHelper + * @var AddressRenderer + */ + protected $addressRenderer; + + /** + * @param TemplateContext $context + * @param Registry $registry + * @param PaymentHelper $paymentHelper + * @param AddressRenderer $addressRenderer * @param array $data */ public function __construct( - \Magento\Framework\View\Element\Template\Context $context, - \Magento\Framework\Registry $registry, - \Magento\Payment\Helper\Data $paymentHelper, + TemplateContext $context, + Registry $registry, + PaymentHelper $paymentHelper, + AddressRenderer $addressRenderer, array $data = [] ) { - $this->_paymentHelper = $paymentHelper; - $this->_coreRegistry = $registry; + $this->addressRenderer = $addressRenderer; + $this->paymentHelper = $paymentHelper; + $this->coreRegistry = $registry; parent::__construct($context, $data); } @@ -52,7 +66,7 @@ class Info extends \Magento\Framework\View\Element\Template protected function _prepareLayout() { $this->pageConfig->getTitle()->set(__('Order # %1', $this->getOrder()->getRealOrderId())); - $infoBlock = $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment(), $this->getLayout()); + $infoBlock = $this->paymentHelper->getInfoBlock($this->getOrder()->getPayment(), $this->getLayout()); $this->setChild('payment_info', $infoBlock); } @@ -71,6 +85,17 @@ class Info extends \Magento\Framework\View\Element\Template */ public function getOrder() { - return $this->_coreRegistry->registry('current_order'); + return $this->coreRegistry->registry('current_order'); + } + + /** + * Returns string with formatted address + * + * @param Address $address + * @return null|string + */ + public function getFormattedAddress(Address $address) + { + return $this->addressRenderer->format($address, 'html'); } } diff --git a/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php b/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php index 4928f622b5c50a62068f117df3b5e13b1a884440..9f52754ca6a92892506848f409c72fe2899b9b79 100644 --- a/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php +++ b/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php @@ -24,18 +24,26 @@ class Creditmemo extends \Magento\Sales\Block\Items\AbstractItems */ protected $_paymentHelper; + /** + * @var \Magento\Sales\Model\Order\Address\Renderer + */ + protected $addressRenderer; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Payment\Helper\Data $paymentHelper + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Registry $registry, \Magento\Payment\Helper\Data $paymentHelper, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, array $data = [] ) { + $this->addressRenderer = $addressRenderer; $this->_paymentHelper = $paymentHelper; $this->_coreRegistry = $registry; parent::__construct($context, $data); @@ -117,4 +125,16 @@ class Creditmemo extends \Magento\Sales\Block\Items\AbstractItems } return $html; } + + /** + * Formats order address to html, pdf and etc. formats + * + * @param \Magento\Sales\Model\Order\Address $address + * @param string $format + * @return null|string + */ + public function formatAddress(\Magento\Sales\Model\Order\Address $address, $format) + { + return $this->addressRenderer->format($address, $format); + } } diff --git a/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php b/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php index 6d1f74c86cf159a7cf42454d21358302adc06b91..a104edfd514d67f83ffc4526acb9c6e637b6c1fb 100644 --- a/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php +++ b/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php @@ -24,18 +24,26 @@ class Invoice extends \Magento\Sales\Block\Items\AbstractItems */ protected $_paymentHelper; + /** + * @var \Magento\Sales\Model\Order\Address\Renderer + */ + protected $addressRenderer; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Payment\Helper\Data $paymentHelper + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Registry $registry, \Magento\Payment\Helper\Data $paymentHelper, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, array $data = [] ) { + $this->addressRenderer = $addressRenderer; $this->_paymentHelper = $paymentHelper; $this->_coreRegistry = $registry; parent::__construct($context, $data); @@ -117,4 +125,16 @@ class Invoice extends \Magento\Sales\Block\Items\AbstractItems } return $html; } + + /** + * Formats order address to html, pdf and etc. formats + * + * @param \Magento\Sales\Model\Order\Address $address + * @param string $format + * @return null|string + */ + public function formatAddress(\Magento\Sales\Model\Order\Address $address, $format) + { + return $this->addressRenderer->format($address, $format); + } } diff --git a/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php b/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php index e2befcb4362994f0ac881c6e4aa8522e14092e6c..e7110a289774b2b77574434009dd6b48a3f09740 100644 --- a/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php +++ b/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php @@ -17,41 +17,49 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems * * @var array */ - protected $_tracks = []; + protected $tracks = []; /** * Order shipments collection * * @var array|\Magento\Sales\Model\Resource\Order\Shipment\Collection */ - protected $_shipmentsCollection; + protected $shipmentsCollection; /** * Core registry * * @var \Magento\Framework\Registry */ - protected $_coreRegistry = null; + protected $coreRegistry = null; /** * @var \Magento\Payment\Helper\Data */ - protected $_paymentHelper; + protected $paymentHelper; + + /** + * @var \Magento\Sales\Model\Order\Address\Renderer + */ + protected $addressRenderer; /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Payment\Helper\Data $paymentHelper + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Registry $registry, \Magento\Payment\Helper\Data $paymentHelper, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, array $data = [] ) { - $this->_paymentHelper = $paymentHelper; - $this->_coreRegistry = $registry; + $this->paymentHelper = $paymentHelper; + $this->coreRegistry = $registry; + $this->addressRenderer = $addressRenderer; parent::__construct($context, $data); } @@ -66,14 +74,14 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems foreach ($tracksCollection->getItems() as $track) { $shipmentId = $track->getParentId(); - $this->_tracks[$shipmentId][] = $track; + $this->tracks[$shipmentId][] = $track; } - $shipment = $this->_coreRegistry->registry('current_shipment'); + $shipment = $this->coreRegistry->registry('current_shipment'); if ($shipment) { - $this->_shipmentsCollection = [$shipment]; + $this->shipmentsCollection = [$shipment]; } else { - $this->_shipmentsCollection = $this->getOrder()->getShipmentsCollection(); + $this->shipmentsCollection = $this->getOrder()->getShipmentsCollection(); } return parent::_beforeToHtml(); @@ -85,7 +93,7 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems protected function _prepareLayout() { $this->pageConfig->getTitle()->set(__('Order # %1', $this->getOrder()->getRealOrderId())); - $infoBlock = $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment(), $this->getLayout()); + $infoBlock = $this->paymentHelper->getInfoBlock($this->getOrder()->getPayment(), $this->getLayout()); $this->setChild('payment_info', $infoBlock); } @@ -118,7 +126,7 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems */ public function getOrder() { - return $this->_coreRegistry->registry('current_order'); + return $this->coreRegistry->registry('current_order'); } /** @@ -126,7 +134,7 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems */ public function getShipment() { - return $this->_coreRegistry->registry('current_shipment'); + return $this->coreRegistry->registry('current_shipment'); } /** @@ -147,7 +155,7 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems */ public function getShipmentsCollection() { - return $this->_shipmentsCollection; + return $this->shipmentsCollection; } /** @@ -159,8 +167,8 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems public function getShipmentTracks($shipment) { $tracks = []; - if (!empty($this->_tracks[$shipment->getId()])) { - $tracks = $this->_tracks[$shipment->getId()]; + if (!empty($this->tracks[$shipment->getId()])) { + $tracks = $this->tracks[$shipment->getId()]; } return $tracks; } @@ -177,7 +185,7 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems if (!$shippingAddress instanceof \Magento\Sales\Model\Order\Address) { return ''; } - return $shippingAddress->format('html'); + return $this->addressRenderer->format($shippingAddress, 'html'); } /** @@ -192,7 +200,7 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems if (!$billingAddress instanceof \Magento\Sales\Model\Order\Address) { return ''; } - return $billingAddress->format('html'); + return $this->addressRenderer->format($billingAddress, 'html'); } /** diff --git a/app/code/Magento/Sales/Block/Order/Recent.php b/app/code/Magento/Sales/Block/Order/Recent.php index 51771b944b59186d899f5e1a17ca873ff40472f7..570a72fd3a25222054dfd038028578b6fcdc7915 100644 --- a/app/code/Magento/Sales/Block/Order/Recent.php +++ b/app/code/Magento/Sales/Block/Order/Recent.php @@ -52,22 +52,8 @@ class Recent extends \Magento\Framework\View\Element\Template protected function _construct() { parent::_construct(); - - //TODO: add full name logic $orders = $this->_orderCollectionFactory->create()->addAttributeToSelect( '*' - )->joinAttribute( - 'shipping_firstname', - 'order_address/firstname', - 'shipping_address_id', - null, - 'left' - )->joinAttribute( - 'shipping_lastname', - 'order_address/lastname', - 'shipping_address_id', - null, - 'left' )->addAttributeToFilter( 'customer_id', $this->_customerSession->getCustomerId() @@ -80,7 +66,6 @@ class Recent extends \Magento\Framework\View\Element\Template )->setPageSize( '5' )->load(); - $this->setOrders($orders); } diff --git a/app/code/Magento/Sales/Model/AbstractModel.php b/app/code/Magento/Sales/Model/AbstractModel.php index a506b7efd3b3b02c5683a5ea2bc87611422c7de0..fb0388bc92a200b0be128ba4ff16c97fce647d33 100644 --- a/app/code/Magento/Sales/Model/AbstractModel.php +++ b/app/code/Magento/Sales/Model/AbstractModel.php @@ -11,26 +11,16 @@ use Magento\Framework\Model\AbstractExtensibleModel; /** * Sales abstract model * Provide date processing functionality + * + * @SuppressWarnings(PHPMD.NumberOfChildren) */ abstract class AbstractModel extends AbstractExtensibleModel { - /** - * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface - */ - protected $_localeDate; - - /** - * @var \Magento\Framework\Stdlib\DateTime - */ - protected $dateTime; - /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data @@ -40,8 +30,6 @@ abstract class AbstractModel extends AbstractExtensibleModel \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = [] @@ -55,39 +43,6 @@ abstract class AbstractModel extends AbstractExtensibleModel $resourceCollection, $data ); - $this->_localeDate = $localeDate; - $this->dateTime = $dateTime; - } - - /** - * Get object store identifier - * - * @return int | string | \Magento\Store\Model\Store - */ - abstract public function getStore(); - - /** - * Get object created at date affected current active store timezone - * - * @return \DateTime - */ - public function getCreatedAtDate() - { - return $this->_localeDate->date(new \DateTime($this->getCreatedAt())); - } - - /** - * Get object created at date affected with object store timezone - * - * @return \DateTime - */ - public function getCreatedAtStoreDate() - { - return $this->_localeDate->scopeDate( - $this->getStore(), - $this->getCreatedAt(), - true - ); } /** diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index f9cca67e4f7634d3331820e18853aa3e66cb0494..667678cc71d24a24127cd0abb7ace46d519d8ba2 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -257,13 +257,17 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface */ protected $priceCurrency; + /** + * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface + */ + protected $timezone; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime + * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param Order\Config $orderConfig * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository @@ -292,8 +296,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, + \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Sales\Model\Order\Config $orderConfig, \Magento\Catalog\Api\ProductRepositoryInterface $productRepository, @@ -320,7 +323,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface $this->_orderConfig = $orderConfig; $this->productRepository = $productRepository; $this->productListFactory = $productListFactory; - + $this->timezone = $timezone; $this->_orderItemCollectionFactory = $orderItemCollectionFactory; $this->_productVisibility = $productVisibility; $this->_serviceOrderFactory = $serviceOrderFactory; @@ -340,8 +343,6 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data @@ -1835,7 +1836,15 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface */ public function getCreatedAtFormated($format) { - return $this->_localeDate->formatDate($this->getCreatedAtStoreDate(), $format, true); + return $this->timezone->formatDate( + $this->timezone->scopeDate( + $this->getStore(), + $this->getCreatedAt(), + true + ), + $format, + true + ); } /** diff --git a/app/code/Magento/Sales/Model/Order/Address.php b/app/code/Magento/Sales/Model/Order/Address.php index e0bc6ef9445d7e9cf32fd01860013a3b49fc1d90..4d5d86cc06960ca8169b7e080390b6f312737412 100644 --- a/app/code/Magento/Sales/Model/Order/Address.php +++ b/app/code/Magento/Sales/Model/Order/Address.php @@ -5,11 +5,10 @@ */ namespace Magento\Sales\Model\Order; -use Magento\Customer\Api\AddressMetadataInterface; -use Magento\Customer\Api\Data\AddressInterfaceFactory; use Magento\Customer\Api\Data\RegionInterfaceFactory; -use Magento\Customer\Model\Address\AbstractAddress; use Magento\Sales\Api\Data\OrderAddressInterface; +use Magento\Sales\Model\AbstractModel; +use Magento\Customer\Model\Address\AddressModelInterface; /** * Sales order address model @@ -21,12 +20,19 @@ use Magento\Sales\Api\Data\OrderAddressInterface; * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessivePublicCount) */ -class Address extends AbstractAddress implements OrderAddressInterface +class Address extends AbstractModel implements OrderAddressInterface, AddressModelInterface { + /** + * Possible customer address types + */ + const TYPE_BILLING = 'billing'; + + const TYPE_SHIPPING = 'shipping'; + /** * @var \Magento\Sales\Model\Order */ - protected $_order; + protected $order; /** * @var string @@ -41,66 +47,48 @@ class Address extends AbstractAddress implements OrderAddressInterface /** * @var \Magento\Sales\Model\OrderFactory */ - protected $_orderFactory; + protected $orderFactory; + + /** + * @var \Magento\Directory\Model\RegionFactory + */ + protected $regionFactory; /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory - * @param \Magento\Directory\Helper\Data $directoryData - * @param \Magento\Eav\Model\Config $eavConfig - * @param \Magento\Customer\Model\Address\Config $addressConfig - * @param \Magento\Directory\Model\RegionFactory $regionFactory - * @param \Magento\Directory\Model\CountryFactory $countryFactory - * @param AddressMetadataInterface $metadataService - * @param AddressInterfaceFactory $addressDataFactory - * @param RegionInterfaceFactory $regionDataFactory - * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * @param \Magento\Sales\Model\OrderFactory $orderFactory + * @param \Magento\Directory\Model\RegionFactory $regionFactory * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data - * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory, - \Magento\Directory\Helper\Data $directoryData, - \Magento\Eav\Model\Config $eavConfig, - \Magento\Customer\Model\Address\Config $addressConfig, - \Magento\Directory\Model\RegionFactory $regionFactory, - \Magento\Directory\Model\CountryFactory $countryFactory, - AddressMetadataInterface $metadataService, - AddressInterfaceFactory $addressDataFactory, - RegionInterfaceFactory $regionDataFactory, - \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, \Magento\Sales\Model\OrderFactory $orderFactory, + \Magento\Directory\Model\RegionFactory $regionFactory, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = [] ) { + $data = $this->implodeStreetField($data); + $this->regionFactory = $regionFactory; + $this->orderFactory = $orderFactory; parent::__construct( $context, $registry, $extensionFactory, $customAttributeFactory, - $directoryData, - $eavConfig, - $addressConfig, - $regionFactory, - $countryFactory, - $metadataService, - $addressDataFactory, - $regionDataFactory, - $dataObjectHelper, $resource, $resourceCollection, $data ); - $this->_orderFactory = $orderFactory; + } /** @@ -121,7 +109,110 @@ class Address extends AbstractAddress implements OrderAddressInterface */ public function setOrder(\Magento\Sales\Model\Order $order) { - $this->_order = $order; + $this->order = $order; + return $this; + } + + /** + * Return 2 letter state code if available, otherwise full region name + * + * @return null|string + */ + public function getRegionCode() + { + if (is_string($this->getRegion())) { + return $this->getRegion(); + } + $model = $this->regionFactory->create()->load( + ((!$this->getRegionId() && is_numeric($this->getRegion())) ? $this->getRegion() : $this->getRegionId()) + ); + if ($model->getCountryId() == $this->getCountryId()) { + return $model->getCode(); + } else { + return null; + } + } + + /** + * Get full customer name + * + * @return string + */ + public function getName() + { + $name = ''; + if ($this->getPrefix()) { + $name .= $this->getPrefix() . ' '; + } + $name .= $this->getFirstname(); + if ($this->getMiddlename()) { + $name .= ' ' . $this->getMiddlename(); + } + $name .= ' ' . $this->getLastname(); + if ($this->getSuffix()) { + $name .= ' ' . $this->getSuffix(); + } + return $name; + } + + /** + * Combine values of street lines into a single string + * + * @param string[]|string $value + * @return string + */ + protected function implodeStreetValue($value) + { + if (is_array($value)) { + $value = trim(implode(PHP_EOL, $value)); + } + return $value; + } + + /** + * Enforce format of the street field + * + * @param array|string $key + * @param null $value + * @return \Magento\Framework\Object + */ + public function setData($key, $value = null) + { + if (is_array($key)) { + $key = $this->implodeStreetField($key); + } elseif ($key == OrderAddressInterface::STREET) { + $value = $this->implodeStreetValue($value); + } + return parent::setData($key, $value); + } + + /** + * Implode value of the street field, if it is present among other fields + * + * @param array $data + * @return array + */ + protected function implodeStreetField(array $data) + { + if (array_key_exists(OrderAddressInterface::STREET, $data)) { + $data[OrderAddressInterface::STREET] = $this->implodeStreetValue($data[OrderAddressInterface::STREET]); + } + return $data; + } + + /** + * Create fields street1, street2, etc. + * + * To be used in controllers for views data + * + * @return $this + */ + public function explodeStreetAddress() + { + $streetLines = $this->getStreet(); + foreach ($streetLines as $lineNumber => $lineValue) { + $this->setData(OrderAddressInterface::STREET . ($lineNumber + 1), $lineValue); + } return $this; } @@ -132,10 +223,10 @@ class Address extends AbstractAddress implements OrderAddressInterface */ public function getOrder() { - if (!$this->_order) { - $this->_order = $this->_orderFactory->create()->load($this->getParentId()); + if (!$this->order) { + $this->order = $this->orderFactory->create()->load($this->getParentId()); } - return $this->_order; + return $this->order; } /** @@ -330,13 +421,28 @@ class Address extends AbstractAddress implements OrderAddressInterface } /** - * Returns street + * Retrieve street field of an address * * @return string[] */ public function getStreet() { - return parent::getStreet(); + if (is_array($this->getData(OrderAddressInterface::STREET))) { + return $this->getData(OrderAddressInterface::STREET); + } + return explode(PHP_EOL, $this->getData(OrderAddressInterface::STREET)); + } + + /** + * Get street line by number + * + * @param int $number + * @return string + */ + public function getStreetLine($number) + { + $lines = $this->getStreet(); + return isset($lines[$number - 1]) ? $lines[$number - 1] : ''; } /** @@ -442,6 +548,14 @@ class Address extends AbstractAddress implements OrderAddressInterface return $this->setData(OrderAddressInterface::REGION_ID, $id); } + /** + * {@inheritdoc} + */ + public function setStreet($street) + { + return $this->setData(OrderAddressInterface::STREET, $street); + } + /** * {@inheritdoc} */ diff --git a/app/code/Magento/Sales/Model/Order/Address/Renderer.php b/app/code/Magento/Sales/Model/Order/Address/Renderer.php new file mode 100644 index 0000000000000000000000000000000000000000..20b78ce722806a2efedf21c2cf0279808d036209 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Address/Renderer.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Model\Order\Address; + +use Magento\Customer\Model\Address\Config as AddressConfig; +use Magento\Framework\Event\ManagerInterface as EventManager; +use Magento\Sales\Model\Order\Address; + +/** + * Class Renderer using for formatting of order address + */ +class Renderer +{ + /** + * @var AddressConfig + */ + protected $addressConfig; + + /** + * @var EventManager + */ + protected $eventManager; + + /** + * Constructor + * + * @param AddressConfig $addressConfig + * @param EventManager $eventManager + */ + public function __construct( + AddressConfig $addressConfig, + EventManager $eventManager + ) { + $this->addressConfig = $addressConfig; + $this->eventManager = $eventManager; + } + + /** + * Format address in a specific way + * + * @param Address $address + * @param string $type + * @return string|null + */ + public function format(Address $address, $type) + { + $formatType = $this->addressConfig->getFormatByCode($type); + if (!$formatType || !$formatType->getRenderer()) { + return null; + } + $this->eventManager->dispatch('customer_address_format', ['type' => $formatType, 'address' => $address]); + return $formatType->getRenderer()->renderArray($address->getData()); + } +} diff --git a/app/code/Magento/Sales/Model/Order/Address/Validator.php b/app/code/Magento/Sales/Model/Order/Address/Validator.php index 8ab59ffeb7f1542fb7b21a64ee7b8ade492face8..4317f60f290b8f369aa763d9aff9370831448e01 100644 --- a/app/code/Magento/Sales/Model/Order/Address/Validator.php +++ b/app/code/Magento/Sales/Model/Order/Address/Validator.php @@ -6,6 +6,8 @@ namespace Magento\Sales\Model\Order\Address; use Magento\Sales\Model\Order\Address; +use Magento\Directory\Helper\Data as DirectoryHelper; +use Magento\Directory\Model\CountryFactory; /** * Class Validator @@ -28,6 +30,28 @@ class Validator 'address_type' => 'Address Type', ]; + /** + * @var DirectoryHelper + */ + protected $directoryHelper; + + /** + * @var CountryFactory + */ + protected $countryFactory; + + /** + * @param DirectoryHelper $directoryHelper + * @param CountryFactory $countryFactory + */ + public function __construct( + DirectoryHelper $directoryHelper, + CountryFactory $countryFactory + ) { + $this->directoryHelper = $directoryHelper; + $this->countryFactory = $countryFactory; + } + /** * * @param \Magento\Sales\Model\Order\Address $address @@ -49,4 +73,86 @@ class Validator } return $warnings; } + + /** + * Validate address attribute for payment operations + * + * @return bool|array + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + * + * @param Address $address + */ + public function validateForPayment(Address $address) + { + if ($address->getShouldIgnoreValidation()) { + return true; + } + + $errors = []; + + if ($this->isEmpty($address->getFirstname())) { + $errors[] = __('Please enter the first name.'); + } + if ($this->isEmpty($address->getLastname())) { + $errors[] = __('Please enter the last name.'); + } + if ($this->isEmpty($address->getStreetLine(1))) { + $errors[] = __('Please enter the street.'); + } + if ($this->isEmpty($address->getCity())) { + $errors[] = __('Please enter the city.'); + } + if ($this->isEmpty($address->getTelephone())) { + $errors[] = __('Please enter the phone number.'); + } + + $countryId = $address->getCountryId(); + + if ($this->isZipRequired($countryId) && $this->isEmpty($address->getPostcode())) { + $errors[] = __('Please enter the zip/postal code.'); + } + if ($this->isEmpty($countryId)) { + $errors[] = __('Please enter the country.'); + } + if ($this->isStateRequired($countryId) && $this->isEmpty($address->getRegionId())) { + $errors[] = __('Please enter the state/province.'); + } + + return empty($errors) ? true : $errors; + } + + /** + * Check if value is empty + * + * @param mixed $value + * @return bool + */ + protected function isEmpty($value) + { + return empty($value); + } + + /** + * Checks if zip for current country id is required + * + * @param string $countryId + * @return bool + */ + protected function isZipRequired($countryId) + { + return !in_array($countryId, $this->directoryHelper->getCountriesWithOptionalZip()); + } + + /** + * Checks if state for current country id is required + * + * @param string $countryId + * @return bool + */ + protected function isStateRequired($countryId) + { + $country = $this->countryFactory->create()->load($countryId); + return $this->directoryHelper->isRegionRequired($countryId) && $country->getRegionCollection()->getSize(); + } } diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php index 852d09607d019b58e30e627ca8e497e4c7390cd0..ec5829dc30e18066c186db6fead57c9a48f4279c 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php @@ -116,8 +116,6 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param Creditmemo\Config $creditmemoConfig * @param \Magento\Sales\Model\OrderFactory $orderFactory * @param \Magento\Sales\Model\Resource\Order\Creditmemo\Item\CollectionFactory $cmItemCollectionFactory @@ -136,8 +134,6 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Sales\Model\Order\Creditmemo\Config $creditmemoConfig, \Magento\Sales\Model\OrderFactory $orderFactory, \Magento\Sales\Model\Resource\Order\Creditmemo\Item\CollectionFactory $cmItemCollectionFactory, @@ -163,8 +159,6 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php index 02317f4af9c974829dc5b97f77630ad19bb62322..a488162c322611e892d33bc90cd60be5dac7cc6f 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php @@ -33,8 +33,6 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection @@ -46,8 +44,6 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, @@ -58,8 +54,6 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php index e7933bfb00dd9d584900d2fcd4067e52eea0a021..163a03903f878e254e5817243cff2ac0bd1288b0 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php @@ -6,8 +6,8 @@ namespace Magento\Sales\Model\Order\Creditmemo; use Magento\Framework\Api\AttributeValueFactory; -use Magento\Framework\Model\AbstractExtensibleModel; use Magento\Sales\Api\Data\CreditmemoItemInterface; +use Magento\Sales\Model\AbstractModel; /** * @method \Magento\Sales\Model\Resource\Order\Creditmemo\Item _getResource() @@ -15,7 +15,7 @@ use Magento\Sales\Api\Data\CreditmemoItemInterface; * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessivePublicCount) */ -class Item extends AbstractExtensibleModel implements CreditmemoItemInterface +class Item extends AbstractModel implements CreditmemoItemInterface { /** * @var string diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php index 71bdaf7b7619327f41f9dbf634783b6321562b1c..cade13b01d08aaa1f335af5f7ce35547ea8e1ef0 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php @@ -10,20 +10,32 @@ use Magento\Sales\Model\Order\Creditmemo; use Magento\Sales\Model\Order\Email\Container\CreditmemoCommentIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class CreditmemoCommentSender + */ class CreditmemoCommentSender extends NotifySender { + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param CreditmemoCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, CreditmemoCommentIdentity $identityContainer, - \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory + \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); + $this->addressRenderer = $addressRenderer; } /** @@ -37,6 +49,12 @@ class CreditmemoCommentSender extends NotifySender public function send(Creditmemo $creditmemo, $notify = true, $comment = '') { $order = $creditmemo->getOrder(); + if ($order->getShippingAddress()) { + $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html'); + } else { + $formattedShippingAddress = ''; + } + $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); $this->templateContainer->setTemplateVars( [ 'order' => $order, @@ -44,6 +62,8 @@ class CreditmemoCommentSender extends NotifySender 'comment' => $comment, 'billing' => $order->getBillingAddress(), 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, ] ); diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php index 941e880d1d73fcd104cf6a2606b161b1ac9cdbc3..71b12c860c301df2a011a4493da652989a51364a 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php @@ -12,7 +12,11 @@ use Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Resource\Order\Creditmemo as CreditmemoResource; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class CreditmemoSender + */ class CreditmemoSender extends NotifySender { /** @@ -25,23 +29,31 @@ class CreditmemoSender extends NotifySender */ protected $creditmemoResource; + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param CreditmemoIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param PaymentHelper $paymentHelper * @param CreditmemoResource $creditmemoResource + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, CreditmemoIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, PaymentHelper $paymentHelper, - CreditmemoResource $creditmemoResource + CreditmemoResource $creditmemoResource, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); $this->paymentHelper = $paymentHelper; $this->creditmemoResource = $creditmemoResource; + $this->addressRenderer = $addressRenderer; } /** @@ -55,14 +67,22 @@ class CreditmemoSender extends NotifySender public function send(Creditmemo $creditmemo, $notify = true, $comment = '') { $order = $creditmemo->getOrder(); + if ($order->getShippingAddress()) { + $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html'); + } else { + $formattedShippingAddress = ''; + } + $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); $this->templateContainer->setTemplateVars( [ 'order' => $creditmemo->getOrder(), - 'invoice' => $creditmemo, + 'creditmemo' => $creditmemo, 'comment' => $comment, 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, ] ); diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php index ae4d3340f2407b12f16f54a4ba0dd708d54a2d2d..3fe28ebf527b034d55bc84afb5d6a7c793b73e6a 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php @@ -10,20 +10,32 @@ use Magento\Sales\Model\Order\Email\Container\InvoiceCommentIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Invoice; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class InvoiceCommentSender + */ class InvoiceCommentSender extends NotifySender { + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param InvoiceCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, InvoiceCommentIdentity $identityContainer, - \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory + \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); + $this->addressRenderer = $addressRenderer; } /** @@ -37,6 +49,12 @@ class InvoiceCommentSender extends NotifySender public function send(Invoice $invoice, $notify = true, $comment = '') { $order = $invoice->getOrder(); + if ($order->getShippingAddress()) { + $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html'); + } else { + $formattedShippingAddress = ''; + } + $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); $this->templateContainer->setTemplateVars( [ 'order' => $order, @@ -44,6 +62,8 @@ class InvoiceCommentSender extends NotifySender 'comment' => $comment, 'billing' => $order->getBillingAddress(), 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, ] ); return $this->checkAndSend($order, $notify); diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php index 44444d27bafd620621bc63e176c345f2b639821e..b498dd1930983b73d6322fe6e37fbd1f933dc41f 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php @@ -12,7 +12,11 @@ use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Invoice; use Magento\Sales\Model\Resource\Order\Invoice as InvoiceResource; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class InvoiceSender + */ class InvoiceSender extends NotifySender { /** @@ -25,23 +29,31 @@ class InvoiceSender extends NotifySender */ protected $invoiceResource; + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param InvoiceIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param PaymentHelper $paymentHelper * @param InvoiceResource $invoiceResource + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, InvoiceIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, PaymentHelper $paymentHelper, - InvoiceResource $invoiceResource + InvoiceResource $invoiceResource, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); $this->paymentHelper = $paymentHelper; $this->invoiceResource = $invoiceResource; + $this->addressRenderer = $addressRenderer; } /** @@ -55,6 +67,12 @@ class InvoiceSender extends NotifySender public function send(Invoice $invoice, $notify = true, $comment = '') { $order = $invoice->getOrder(); + if ($order->getShippingAddress()) { + $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html'); + } else { + $formattedShippingAddress = ''; + } + $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); $this->templateContainer->setTemplateVars( [ 'order' => $order, @@ -63,6 +81,8 @@ class InvoiceSender extends NotifySender 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, ] ); $result = $this->checkAndSend($order, $notify); diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php index c72ded66c542f97d5452eb80b284dc9404cd719f..02e77761e3ec45b0fc7763f75e30143ff9810d92 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php @@ -9,20 +9,32 @@ use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class OrderCommentSender + */ class OrderCommentSender extends NotifySender { + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param OrderCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, OrderCommentIdentity $identityContainer, - \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory + \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); + $this->addressRenderer = $addressRenderer; } /** @@ -35,12 +47,20 @@ class OrderCommentSender extends NotifySender */ public function send(Order $order, $notify = true, $comment = '') { + if ($order->getShippingAddress()) { + $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html'); + } else { + $formattedShippingAddress = ''; + } + $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); $this->templateContainer->setTemplateVars( [ 'order' => $order, 'comment' => $comment, 'billing' => $order->getBillingAddress(), 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, ] ); return $this->checkAndSend($order, $notify); diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php index 493ac166c3d553be5200ce10b70178e325bee919..ce11ff7ad4e167f865bf9454d4da5af78d751a85 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php @@ -11,7 +11,11 @@ use Magento\Sales\Model\Order\Email\Container\OrderIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\Sender; use Magento\Sales\Model\Resource\Order as OrderResource; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class OrderSender + */ class OrderSender extends Sender { /** @@ -24,23 +28,31 @@ class OrderSender extends Sender */ protected $orderResource; + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param OrderIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param PaymentHelper $paymentHelper * @param OrderResource $orderResource + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, OrderIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, PaymentHelper $paymentHelper, - OrderResource $orderResource + OrderResource $orderResource, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); $this->paymentHelper = $paymentHelper; $this->orderResource = $orderResource; + $this->addressRenderer = $addressRenderer; } /** @@ -73,6 +85,8 @@ class OrderSender extends Sender 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), 'store' => $order->getStore(), + 'formattedShippingAddress' => $this->addressRenderer->format($order->getShippingAddress(), 'html'), + 'formattedBillingAddress' => $this->addressRenderer->format($order->getBillingAddress(), 'html'), ] ); parent::prepareTemplate($order); diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php index bb39c9b529f0cf4f62ac4cb6566eced615a3aae2..9c60fff9f4ee158b0b9b7bc22838d5d795dc4dd7 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php @@ -10,20 +10,32 @@ use Magento\Sales\Model\Order\Email\Container\ShipmentCommentIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Shipment; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class ShipmentCommentSender + */ class ShipmentCommentSender extends NotifySender { + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param ShipmentCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, ShipmentCommentIdentity $identityContainer, - \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory + \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); + $this->addressRenderer = $addressRenderer; } /** @@ -37,6 +49,12 @@ class ShipmentCommentSender extends NotifySender public function send(Shipment $shipment, $notify = true, $comment = '') { $order = $shipment->getOrder(); + if ($order->getShippingAddress()) { + $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html'); + } else { + $formattedShippingAddress = ''; + } + $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); $this->templateContainer->setTemplateVars( [ 'order' => $order, @@ -44,6 +62,8 @@ class ShipmentCommentSender extends NotifySender 'comment' => $comment, 'billing' => $order->getBillingAddress(), 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, ] ); return $this->checkAndSend($order, $notify); diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php index ed239ed354c8bee6b02367ad90ccb9c877f65519..b44bd2c862d4c152ad98fb6a1a2addca81803be4 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php @@ -12,7 +12,11 @@ use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Shipment; use Magento\Sales\Model\Resource\Order\Shipment as ShipmentResource; +use Magento\Sales\Model\Order\Address\Renderer; +/** + * Class ShipmentSender + */ class ShipmentSender extends NotifySender { /** @@ -25,23 +29,31 @@ class ShipmentSender extends NotifySender */ protected $shipmentResource; + /** + * @var Renderer + */ + protected $addressRenderer; + /** * @param Template $templateContainer * @param ShipmentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param PaymentHelper $paymentHelper * @param ShipmentResource $shipmentResource + * @param Renderer $addressRenderer */ public function __construct( Template $templateContainer, ShipmentIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, PaymentHelper $paymentHelper, - ShipmentResource $shipmentResource + ShipmentResource $shipmentResource, + Renderer $addressRenderer ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory); $this->paymentHelper = $paymentHelper; $this->shipmentResource = $shipmentResource; + $this->addressRenderer = $addressRenderer; } /** @@ -55,6 +67,12 @@ class ShipmentSender extends NotifySender public function send(Shipment $shipment, $notify = true, $comment = '') { $order = $shipment->getOrder(); + if ($order->getShippingAddress()) { + $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html'); + } else { + $formattedShippingAddress = ''; + } + $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); $this->templateContainer->setTemplateVars( [ 'order' => $order, @@ -63,6 +81,8 @@ class ShipmentSender extends NotifySender 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, ] ); $result = $this->checkAndSend($order, $notify); diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php index b77691482983631e6c0cbffe10e980a319fa80e4..d88dfa1d8850a2fd04018895cb9c4417ed041c41 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice.php +++ b/app/code/Magento/Sales/Model/Order/Invoice.php @@ -118,8 +118,6 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param Invoice\Config $invoiceConfig * @param \Magento\Sales\Model\OrderFactory $orderFactory * @param \Magento\Framework\Math\CalculatorFactory $calculatorFactory @@ -136,8 +134,6 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Sales\Model\Order\Invoice\Config $invoiceConfig, \Magento\Sales\Model\OrderFactory $orderFactory, \Magento\Framework\Math\CalculatorFactory $calculatorFactory, @@ -159,8 +155,6 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Comment.php b/app/code/Magento/Sales/Model/Order/Invoice/Comment.php index e1f31fa4c025719b4a95caac311b1f42fedfbe1b..074e77b3638e656906f3da22e3727cea61423e98 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/Comment.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/Comment.php @@ -33,8 +33,6 @@ class Comment extends AbstractModel implements InvoiceCommentInterface * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection @@ -46,8 +44,6 @@ class Comment extends AbstractModel implements InvoiceCommentInterface \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, @@ -58,8 +54,6 @@ class Comment extends AbstractModel implements InvoiceCommentInterface $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Item.php b/app/code/Magento/Sales/Model/Order/Invoice/Item.php index e6bee5dc842902177f6f7d4650152c9b1c84b692..403e14bfa9ec63312bcf734dd472fdc6e794a5ee 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/Item.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/Item.php @@ -6,8 +6,8 @@ namespace Magento\Sales\Model\Order\Invoice; use Magento\Framework\Api\AttributeValueFactory; -use Magento\Framework\Model\AbstractExtensibleModel; use Magento\Sales\Api\Data\InvoiceItemInterface; +use Magento\Sales\Model\AbstractModel; /** * @method \Magento\Sales\Model\Resource\Order\Invoice\Item _getResource() @@ -32,7 +32,7 @@ use Magento\Sales\Api\Data\InvoiceItemInterface; * @method \Magento\Sales\Model\Order\Invoice\Item setWeeeTaxApplied(string $value) * @SuppressWarnings(PHPMD.ExcessivePublicCount) */ -class Item extends AbstractExtensibleModel implements InvoiceItemInterface +class Item extends AbstractModel implements InvoiceItemInterface { /** * @var string diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index bd7b1267831961e6a67599801b4bb628fba26375..b23a34296c690d5584dc2a6e314401669981bd3a 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -6,7 +6,7 @@ namespace Magento\Sales\Model\Order; use Magento\Framework\Api\AttributeValueFactory; -use Magento\Framework\Model\AbstractExtensibleModel; +use Magento\Sales\Model\AbstractModel; use Magento\Sales\Api\Data\OrderItemInterface; /** @@ -23,7 +23,7 @@ use Magento\Sales\Api\Data\OrderItemInterface; * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Item extends AbstractExtensibleModel implements OrderItemInterface +class Item extends AbstractModel implements OrderItemInterface { const STATUS_PENDING = 1; diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php index f308b43487ffc6e238e31f87b45185d123431bf4..ce5d9a79c6a57ee38ec8c38f1bb5878ba86ae767 100644 --- a/app/code/Magento/Sales/Model/Order/Payment.php +++ b/app/code/Magento/Sales/Model/Order/Payment.php @@ -9,7 +9,7 @@ namespace Magento\Sales\Model\Order; use Magento\Framework\Pricing\PriceCurrencyInterface; -use Magento\Payment\Model\Info; +use Magento\Sales\Model\Order\Payment\Info; use Magento\Sales\Api\Data\OrderPaymentInterface; /** diff --git a/app/code/Magento/Sales/Model/Order/Payment/Info.php b/app/code/Magento/Sales/Model/Order/Payment/Info.php new file mode 100644 index 0000000000000000000000000000000000000000..aa7339078b6923bb6b32f58a878bf991f9b04928 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Payment/Info.php @@ -0,0 +1,232 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Model\Order\Payment; + +use Magento\Sales\Model\AbstractModel; +use Magento\Payment\Model\Method\Substitution; +use Magento\Payment\Model\InfoInterface; + +/** + * + * Payment information model + */ +class Info extends AbstractModel implements InfoInterface +{ + /** + * Additional information container + * + * @var array + */ + protected $additionalInformation = []; + + /** + * Payment data + * + * @var \Magento\Payment\Helper\Data + */ + protected $paymentData; + + /** + * @var \Magento\Framework\Encryption\EncryptorInterface + */ + protected $encryptor; + + /** + * @param \Magento\Framework\Model\Context $context + * @param \Magento\Framework\Registry $registry + * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory + * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory, + * @param \Magento\Payment\Helper\Data $paymentData + * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor + * @param \Magento\Framework\Model\Resource\AbstractResource $resource + * @param \Magento\Framework\Data\Collection\Db $resourceCollection + * @param array $data + */ + public function __construct( + \Magento\Framework\Model\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, + \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory, + \Magento\Payment\Helper\Data $paymentData, + \Magento\Framework\Encryption\EncryptorInterface $encryptor, + \Magento\Framework\Model\Resource\AbstractResource $resource = null, + \Magento\Framework\Data\Collection\Db $resourceCollection = null, + array $data = [] + ) { + $this->paymentData = $paymentData; + $this->encryptor = $encryptor; + parent::__construct( + $context, + $registry, + $extensionFactory, + $customAttributeFactory, + $resource, + $resourceCollection, + $data + ); + } + + /** + * Retrieve data + * + * @param string $key + * @param mixed $index + * @return mixed + */ + public function getData($key = '', $index = null) + { + if ('cc_number' === $key) { + $ccNumber = parent::getData('cc_number'); + $ccNumberEnc = parent::getData('cc_number_enc'); + if (empty($ccNumber) && !empty($ccNumberEnc)) { + $this->setData('cc_number', $this->decrypt($ccNumberEnc)); + } + } + if ('cc_cid' === $key) { + $ccCid = parent::getData('cc_cid'); + $ccCidEnc = parent::getData('cc_cid_enc'); + if (empty($ccCid) && !empty($ccCidEnc)) { + $this->setData('cc_cid', $this->decrypt($ccCidEnc)); + } + } + return parent::getData($key, $index); + } + + /** + * Retrieve payment method model object + * + * @return \Magento\Payment\Model\MethodInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function getMethodInstance() + { + if (!$this->hasMethodInstance()) { + if (!$this->getMethod()) { + throw new \Magento\Framework\Exception\LocalizedException( + __('The payment method you requested is not available.') + ); + } + try { + $instance = $this->paymentData->getMethodInstance($this->getMethod()); + } catch (\UnexpectedValueException $e) { + $instance = $this->paymentData->getMethodInstance(Substitution::CODE); + } + $instance->setInfoInstance($this); + $this->setMethodInstance($instance); + } + return $this->getData('method_instance'); + } + + /** + * Encrypt data + * + * @param string $data + * @return string + */ + public function encrypt($data) + { + return $this->encryptor->encrypt($data); + } + + /** + * Decrypt data + * + * @param string $data + * @return string + */ + public function decrypt($data) + { + return $this->encryptor->decrypt($data); + } + + /** + * Additional information setter + * Updates data inside the 'additional_information' array + * or all 'additional_information' if key is data array + * + * @param string|array $key + * @param mixed $value + * @return $this + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function setAdditionalInformation($key, $value = null) + { + if (is_object($value)) { + throw new \Magento\Framework\Exception\LocalizedException(__('The payment disallows storing objects.')); + } + $this->initAdditionalInformation(); + if (is_array($key) && $value === null) { + $this->additionalInformation = $key; + } else { + $this->additionalInformation[$key] = $value; + } + return $this->setData('additional_information', $this->additionalInformation); + } + + /** + * Getter for entire additional_information value or one of its element by key + * + * @param string $key + * @return array|null|mixed + */ + public function getAdditionalInformation($key = null) + { + $this->initAdditionalInformation(); + if (null === $key) { + return $this->additionalInformation; + } + return isset($this->additionalInformation[$key]) ? $this->additionalInformation[$key] : null; + } + + /** + * Unsetter for entire additional_information value or one of its element by key + * + * @param string $key + * @return $this + */ + public function unsAdditionalInformation($key = null) + { + if ($key && isset($this->additionalInformation[$key])) { + unset($this->additionalInformation[$key]); + return $this->setData('additional_information', $this->additionalInformation); + } + $this->additionalInformation = []; + return $this->unsetData('additional_information'); + } + + /** + * Check whether there is additional information by specified key + * + * @param mixed|null $key + * @return bool + */ + public function hasAdditionalInformation($key = null) + { + $this->initAdditionalInformation(); + return null === $key ? !empty($this->additionalInformation) : array_key_exists( + $key, + $this->additionalInformation + ); + } + + /** + * Initialize additional information container with data from model + * if property empty + * + * @return void + */ + protected function initAdditionalInformation() + { + $additionalInfo = $this->getData('additional_information'); + if (empty($this->additionalInformation) && $additionalInfo) { + if (!is_array($additionalInfo)) { + $additionalInfo = unserialize($additionalInfo); + } + $this->additionalInformation = $additionalInfo; + } + } +} diff --git a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php index 942cf9475983eb24457bfd676c6cf216dc8f2294..3c0d281f3e27cd8630d0471e6e8f505c29f6b10c 100644 --- a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php +++ b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php @@ -9,8 +9,8 @@ namespace Magento\Sales\Model\Order\Payment; use Magento\Framework\Api\AttributeValueFactory; -use Magento\Framework\Model\AbstractExtensibleModel; use Magento\Sales\Api\Data\TransactionInterface; +use Magento\Sales\Model\AbstractModel; /** * Payment transaction model @@ -25,7 +25,7 @@ use Magento\Sales\Api\Data\TransactionInterface; * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Transaction extends AbstractExtensibleModel implements TransactionInterface +class Transaction extends AbstractModel implements TransactionInterface { /**#@+ * Supported transaction types diff --git a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php index 87bac857aa6a9a0d82fef129c00f159491d0dcd0..f324da6d3b7196310388dbcb3ce2eb98a655b8e4 100644 --- a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php +++ b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php @@ -110,18 +110,23 @@ abstract class AbstractPdf extends \Magento\Framework\Object */ protected $inlineTranslation; + /** + * @var \Magento\Sales\Model\Order\Address\Renderer + */ + protected $addressRenderer; + /** * @param \Magento\Payment\Helper\Data $paymentData * @param \Magento\Framework\Stdlib\String $string * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Filesystem $filesystem * @param Config $pdfConfig - * @param \Magento\Sales\Model\Order\Pdf\Total\Factory $pdfTotalFactory - * @param \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory + * @param Total\Factory $pdfTotalFactory + * @param ItemsFactory $pdfItemsFactory * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer * @param array $data - * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -134,8 +139,10 @@ abstract class AbstractPdf extends \Magento\Framework\Object \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, array $data = [] ) { + $this->addressRenderer = $addressRenderer; $this->_paymentData = $paymentData; $this->_localeDate = $localeDate; $this->string = $string; @@ -288,13 +295,13 @@ abstract class AbstractPdf extends \Magento\Framework\Object $this->y = $this->y ? $this->y : 815; $top = 815; foreach (explode( - "\n", - $this->_scopeConfig->getValue( - 'sales/identity/address', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, - $store - ) - ) as $value) { + "\n", + $this->_scopeConfig->getValue( + 'sales/identity/address', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $store + ) + ) as $value) { if ($value !== '') { $value = preg_replace('/<br[^>]*>/i', "\n", $value); foreach ($this->string->split($value, 45, true, true) as $_value) { @@ -390,7 +397,16 @@ abstract class AbstractPdf extends \Magento\Framework\Object $page->drawText(__('Order # ') . $order->getRealOrderId(), 35, $top -= 30, 'UTF-8'); } $page->drawText( - __('Order Date: ') . $this->_localeDate->formatDate($order->getCreatedAtStoreDate(), \IntlDateFormatter::MEDIUM, false), + __('Order Date: ') . + $this->_localeDate->formatDate( + $this->_localeDate->scopeDate( + $order->getStore(), + $order->getCreatedAt(), + true + ), + \IntlDateFormatter::MEDIUM, + false + ), 35, $top -= 15, 'UTF-8' @@ -406,7 +422,7 @@ abstract class AbstractPdf extends \Magento\Framework\Object /* Calculate blocks info */ /* Billing Address */ - $billingAddress = $this->_formatAddress($order->getBillingAddress()->format('pdf')); + $billingAddress = $this->_formatAddress($this->addressRenderer->format($order->getBillingAddress(), 'pdf')); /* Payment */ $paymentInfo = $this->_paymentData->getInfoBlock($order->getPayment())->setIsSecureMode(true)->toPdf(); @@ -422,7 +438,7 @@ abstract class AbstractPdf extends \Magento\Framework\Object /* Shipping Address and Method */ if (!$order->getIsVirtual()) { /* Shipping Address */ - $shippingAddress = $this->_formatAddress($order->getShippingAddress()->format('pdf')); + $shippingAddress = $this->_formatAddress($this->addressRenderer->format($order->getShippingAddress(), 'pdf')); $shippingMethod = $order->getShippingDescription(); } @@ -536,10 +552,10 @@ abstract class AbstractPdf extends \Magento\Framework\Object $yShipments = $this->y; $totalShippingChargesText = "(" . __( - 'Total Shipping Charges' - ) . " " . $order->formatPriceTxt( - $order->getShippingAmount() - ) . ")"; + 'Total Shipping Charges' + ) . " " . $order->formatPriceTxt( + $order->getShippingAmount() + ) . ")"; $page->drawText($totalShippingChargesText, 285, $yShipments - $topMargin, 'UTF-8'); $yShipments -= $topMargin + 10; diff --git a/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php index acd8d3f9b6d78474726192cf53fa521f997b935c..ed58b86ba42f3e7f1ccdd98413fdc5307c1dfcdb 100644 --- a/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php @@ -26,6 +26,7 @@ class Creditmemo extends AbstractPdf * @param \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Locale\ResolverInterface $localeResolver * @param array $data @@ -43,6 +44,7 @@ class Creditmemo extends AbstractPdf \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Locale\ResolverInterface $localeResolver, array $data = [] @@ -59,6 +61,7 @@ class Creditmemo extends AbstractPdf $pdfItemsFactory, $localeDate, $inlineTranslation, + $addressRenderer, $data ); } diff --git a/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php b/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php index 79b3130b684496b306b556ac7a089651960137f5..a69597674acee68bca0f662e37f966a69e0e411a 100644 --- a/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php +++ b/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php @@ -30,8 +30,9 @@ class Invoice extends AbstractPdf * @param \Magento\Sales\Model\Order\Pdf\Total\Factory $pdfTotalFactory * @param \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer + * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Locale\ResolverInterface $localeResolver * @param array $data * @@ -47,6 +48,7 @@ class Invoice extends AbstractPdf \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Locale\ResolverInterface $localeResolver, array $data = [] @@ -63,6 +65,7 @@ class Invoice extends AbstractPdf $pdfItemsFactory, $localeDate, $inlineTranslation, + $addressRenderer, $data ); } diff --git a/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php b/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php index 46594554ba69d203c2f2215dd2cdbac639d0c53b..f630bf25543fe7d9e2e83549d0f9483176c2d9ab 100644 --- a/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php +++ b/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php @@ -31,6 +31,7 @@ class Shipment extends AbstractPdf * @param \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Locale\ResolverInterface $localeResolver * @param array $data @@ -47,6 +48,7 @@ class Shipment extends AbstractPdf \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Locale\ResolverInterface $localeResolver, array $data = [] @@ -63,6 +65,7 @@ class Shipment extends AbstractPdf $pdfItemsFactory, $localeDate, $inlineTranslation, + $addressRenderer, $data ); } diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php index fae8ba458a55c9d9cd523b62c04f691824942d40..ec3a0561cf262bb577f4f3a9e6f381b1ca121566 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Order/Shipment.php @@ -94,8 +94,6 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Sales\Model\OrderFactory $orderFactory * @param \Magento\Sales\Model\Resource\Order\Shipment\Item\CollectionFactory $shipmentItemCollectionFactory * @param \Magento\Sales\Model\Resource\Order\Shipment\Track\CollectionFactory $trackCollectionFactory @@ -111,8 +109,6 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Sales\Model\OrderFactory $orderFactory, \Magento\Sales\Model\Resource\Order\Shipment\Item\CollectionFactory $shipmentItemCollectionFactory, \Magento\Sales\Model\Resource\Order\Shipment\Track\CollectionFactory $trackCollectionFactory, @@ -132,8 +128,6 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Comment.php b/app/code/Magento/Sales/Model/Order/Shipment/Comment.php index 871d04fa49f472f06913b2ceb950557d7912f9db..43361d79d59c4a4b6e403a7b0c7677ba1dbc1784 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Comment.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Comment.php @@ -33,8 +33,6 @@ class Comment extends AbstractModel implements ShipmentCommentInterface * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection @@ -46,8 +44,6 @@ class Comment extends AbstractModel implements ShipmentCommentInterface \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, @@ -58,8 +54,6 @@ class Comment extends AbstractModel implements ShipmentCommentInterface $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php index 415b2bfcb79dfcc4ff72e9ac26fcf075358e0534..8a158869d1cf02c8d93c6224ba5fd229c089bfb1 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php @@ -9,15 +9,15 @@ namespace Magento\Sales\Model\Order\Shipment; use Magento\Framework\Api\AttributeValueFactory; -use Magento\Framework\Model\AbstractExtensibleModel; use Magento\Sales\Api\Data\ShipmentItemInterface; +use Magento\Sales\Model\AbstractModel; /** * @method \Magento\Sales\Model\Resource\Order\Shipment\Item _getResource() * @method \Magento\Sales\Model\Resource\Order\Shipment\Item getResource() * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Item extends AbstractExtensibleModel implements ShipmentItemInterface +class Item extends AbstractModel implements ShipmentItemInterface { /** * @var string diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Track.php b/app/code/Magento/Sales/Model/Order/Shipment/Track.php index 85b0e3419eca06e7e7564a9a9b57d72317fbf37a..325c9837bee51bc906c55afdc3d172c9da8966f3 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Track.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Track.php @@ -54,8 +54,6 @@ class Track extends AbstractModel implements ShipmentTrackInterface * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory * @param \Magento\Framework\Model\Resource\AbstractResource $resource @@ -68,8 +66,6 @@ class Track extends AbstractModel implements ShipmentTrackInterface \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory, \Magento\Framework\Model\Resource\AbstractResource $resource = null, @@ -81,8 +77,6 @@ class Track extends AbstractModel implements ShipmentTrackInterface $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Order/Status/History.php b/app/code/Magento/Sales/Model/Order/Status/History.php index e1610030dc25ff2e2a1779fd4ebb257c7ec4e189..edd828956c8241f11fcc8d929f4618a36d75e858 100644 --- a/app/code/Magento/Sales/Model/Order/Status/History.php +++ b/app/code/Magento/Sales/Model/Order/Status/History.php @@ -48,8 +48,6 @@ class History extends AbstractModel implements OrderStatusHistoryInterface * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection @@ -61,8 +59,6 @@ class History extends AbstractModel implements OrderStatusHistoryInterface \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, @@ -73,8 +69,6 @@ class History extends AbstractModel implements OrderStatusHistoryInterface $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $resource, $resourceCollection, $data diff --git a/app/code/Magento/Sales/Model/Resource/Collection/AbstractCollection.php b/app/code/Magento/Sales/Model/Resource/Collection/AbstractCollection.php index c2419e03710bf69921a5d74d346a1917369ad3c7..b0e4edf8dd32d65c367b71a823f16dca05c47219 100644 --- a/app/code/Magento/Sales/Model/Resource/Collection/AbstractCollection.php +++ b/app/code/Magento/Sales/Model/Resource/Collection/AbstractCollection.php @@ -7,8 +7,7 @@ namespace Magento\Sales\Model\Resource\Collection; /** * Flat sales abstract collection - * - * @author Magento Core Team <core@magentocommerce.com> + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ abstract class AbstractCollection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection { @@ -17,6 +16,34 @@ abstract class AbstractCollection extends \Magento\Framework\Model\Resource\Db\C */ protected $_countSelect; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot + */ + protected $entitySnapshot; + + /** + * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory + * @param \Psr\Log\LoggerInterface $logger + * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy + * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot + * @param string|null $connection + * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource + * @throws \Zend_Exception + */ + public function __construct( + \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory, + \Psr\Log\LoggerInterface $logger, + \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, + \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, + $connection = null, + \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null + ) { + $this->entitySnapshot = $entitySnapshot; + parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + } + /** * Set select count sql * @@ -151,25 +178,6 @@ abstract class AbstractCollection extends \Magento\Framework\Model\Resource\Db\C return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams); } - /** - * Backward compatibility with EAV collection - * - * @param string $alias - * @param string $attribute - * @param string $bind - * @param string $filter - * @param string $joinType - * @param int $storeId - * @return $this - * - * @todo implement join functionality if necessary - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function joinAttribute($alias, $attribute, $bind, $filter = null, $joinType = 'inner', $storeId = null) - { - return $this; - } - /** * Get search criteria. * @@ -225,4 +233,63 @@ abstract class AbstractCollection extends \Magento\Framework\Model\Resource\Db\C { return $this; } + + /** + * Returns a collection item that corresponds to the fetched row + * and moves the internal data pointer ahead + * All returned rows marked as non changed to prevent unnecessary persistence operations + * + * @return \Magento\Framework\Object|bool + */ + public function fetchItem() + { + if (null === $this->_fetchStmt) { + $this->_renderOrders()->_renderLimit(); + + $this->_fetchStmt = $this->getConnection()->query($this->getSelect()); + } + $data = $this->_fetchStmt->fetch(); + if (!empty($data) && is_array($data)) { + /**@var \Magento\Sales\Model\AbstractModel $item */ + $item = $this->getNewEmptyItem(); + if ($this->getIdFieldName()) { + $item->setIdFieldName($this->getIdFieldName()); + } + $item->setData($data); + $this->entitySnapshot->registerSnapshot($item); + return $item; + } + return false; + } + + /** + * Load data with filter in place + * All returned rows marked as non changed to prevent unnecessary persistence operations + * + * @param bool $printQuery + * @param bool $logQuery + * @return $this + */ + public function loadWithFilter($printQuery = false, $logQuery = false) + { + $this->_beforeLoad(); + $this->_renderFilters()->_renderOrders()->_renderLimit(); + $this->printLogQuery($printQuery, $logQuery); + $data = $this->getData(); + $this->resetData(); + if (is_array($data)) { + foreach ($data as $row) { + $item = $this->getNewEmptyItem(); + if ($this->getIdFieldName()) { + $item->setIdFieldName($this->getIdFieldName()); + } + $item->setData($row); + $this->entitySnapshot->registerSnapshot($item); + $this->addItem($item); + } + } + $this->_setIsLoaded(); + $this->_afterLoad(); + return $this; + } } diff --git a/app/code/Magento/Sales/Model/Resource/Entity.php b/app/code/Magento/Sales/Model/Resource/EntityAbstract.php similarity index 50% rename from app/code/Magento/Sales/Model/Resource/Entity.php rename to app/code/Magento/Sales/Model/Resource/EntityAbstract.php index 9c1f3f65522ad540885b495a9f130661d12181ee..7b03391b8fa1346a122ab5d24c0fefb12ddf8451 100644 --- a/app/code/Magento/Sales/Model/Resource/Entity.php +++ b/app/code/Magento/Sales/Model/Resource/EntityAbstract.php @@ -7,12 +7,14 @@ namespace Magento\Sales\Model\Resource; use Magento\Framework\Model\Resource\Db\AbstractDb; use Magento\Sales\Model\EntityInterface; +use Magento\SalesSequence\Model\Manager; /** - * Flat sales resource abstract + * Abstract sales entity provides to its children knowledge about eventPrefix and eventObject + * * @SuppressWarnings(PHPMD.NumberOfChildren) */ -abstract class Entity extends AbstractDb +abstract class EntityAbstract extends AbstractDb { /** * Event prefix @@ -45,25 +47,37 @@ abstract class Entity extends AbstractDb */ protected $attribute; + + /** + * @var Manager + */ + protected $sequenceManager; + /** - * @var \Magento\Sales\Model\Increment + * @var EntitySnapshot */ - protected $salesIncrement; + protected $entitySnapshot; /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute - * @param \Magento\Sales\Model\Increment $salesIncrement + * @param Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param string|null $resourcePrefix + * @param GridInterface|null $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, - \Magento\Sales\Model\Increment $salesIncrement, - $resourcePrefix = null + Manager $sequenceManager, + EntitySnapshot $entitySnapshot, + $resourcePrefix = null, + \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null ) { $this->attribute = $attribute; - $this->salesIncrement = $salesIncrement; + $this->sequenceManager = $sequenceManager; + $this->gridAggregator = $gridAggregator; + $this->entitySnapshot = $entitySnapshot; parent::__construct($context, $resourcePrefix); } @@ -101,34 +115,27 @@ abstract class Entity extends AbstractDb /** * Perform actions before object save + * Perform actions before object save, calculate next sequence value for increment Id * * @param \Magento\Framework\Model\AbstractModel|\Magento\Framework\Object $object * @return $this */ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object) { + + /** @var \Magento\Sales\Model\AbstractModel $object */ if ($object instanceof EntityInterface && $object->getIncrementId() == null) { - $object->setIncrementId($this->salesIncrement->getNextValue($object->getStoreId())); + $object->setIncrementId( + $this->sequenceManager->getSequence( + $object->getEntityType(), + $object->getStore()->getId() + )->getNextValue() + ); } parent::_beforeSave($object); return $this; } - /** - * Save object data - * - * @param \Magento\Framework\Model\AbstractModel $object - * @return $this - */ - public function save(\Magento\Framework\Model\AbstractModel $object) - { - if (!$object->getForceObjectSave()) { - parent::save($object); - } - - return $this; - } - /** * Perform actions after object save * @@ -167,4 +174,87 @@ abstract class Entity extends AbstractDb parent::_afterDelete($object); return $this; } + + /** + * Perform actions after object load, mark loaded data as data without changes + * + * @param \Magento\Framework\Model\AbstractModel|\Magento\Framework\Object $object + * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function _afterLoad(\Magento\Framework\Model\AbstractModel $object) + { + $this->entitySnapshot->registerSnapshot($object); + return $this; + } + + /** + * Process entity relations + * + * @param \Magento\Framework\Model\AbstractModel $object + * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function processRelations(\Magento\Framework\Model\AbstractModel $object) + { + return $this; + } + + /** + * Save entity + * + * @param \Magento\Framework\Model\AbstractModel $object + * @return $this + * @throws \Exception + */ + public function save(\Magento\Framework\Model\AbstractModel $object) + { + if ($object->isDeleted()) { + return $this->delete($object); + } + if (!$this->entitySnapshot->isModified($object)) { + $this->processRelations($object); + return $this; + } + $this->beginTransaction(); + + try { + $object->validateBeforeSave(); + $object->beforeSave(); + if ($object->isSaveAllowed()) { + $this->_serializeFields($object); + $this->_beforeSave($object); + $this->_checkUnique($object); + $this->objectRelationProcessor->validateDataIntegrity($this->getMainTable(), $object->getData()); + if ($object->getId() !== null && (!$this->_useIsObjectNew || !$object->isObjectNew())) { + $condition = $this->_getWriteAdapter()->quoteInto($this->getIdFieldName() . '=?', $object->getId()); + $data = $this->_prepareDataForSave($object); + unset($data[$this->getIdFieldName()]); + $this->_getWriteAdapter()->update($this->getMainTable(), $data, $condition); + } else { + $bind = $this->_prepareDataForSave($object); + unset($bind[$this->getIdFieldName()]); + $this->_getWriteAdapter()->insert($this->getMainTable(), $bind); + + $object->setId($this->_getWriteAdapter()->lastInsertId($this->getMainTable())); + + if ($this->_useIsObjectNew) { + $object->isObjectNew(false); + } + } + $this->unserializeFields($object); + $this->_afterSave($object); + $this->entitySnapshot->registerSnapshot($object); + $object->afterSave(); + $this->processRelations($object); + } + $this->addCommitCallback([$object, 'afterCommitCallback'])->commit(); + $object->setHasDataChanges(false); + } catch (\Exception $e) { + $this->rollBack(); + $object->setHasDataChanges(true); + throw $e; + } + return $this; + } } diff --git a/app/code/Magento/Sales/Model/Resource/EntityMetadata.php b/app/code/Magento/Sales/Model/Resource/EntityMetadata.php new file mode 100644 index 0000000000000000000000000000000000000000..d39a9a63cb5ab9b25dd11321a01a4dbdbb8560ab --- /dev/null +++ b/app/code/Magento/Sales/Model/Resource/EntityMetadata.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Resource; + +use Magento\Sales\Model\AbstractModel; + +/** + * Class EntityMetadata represents a list of entity fields that are applicable for persistence operations + */ +class EntityMetadata +{ + /** + * @var array + */ + protected $metadataInfo = []; + + /** + * Returns list of entity fields that are applicable for persistence operations + * + * @param AbstractModel $entity + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function getFields(AbstractModel $entity) + { + if (!isset($this->metadataInfo[get_class($entity)])) { + $this->metadataInfo[get_class($entity)] = + $entity->getResource()->getReadConnection()->describeTable( + $entity->getResource()->getMainTable() + ); + } + return $this->metadataInfo[get_class($entity)]; + } +} diff --git a/app/code/Magento/Sales/Model/Resource/EntitySnapshot.php b/app/code/Magento/Sales/Model/Resource/EntitySnapshot.php new file mode 100644 index 0000000000000000000000000000000000000000..47a008445ebf5f3807944a1115a39d5d72f86c87 --- /dev/null +++ b/app/code/Magento/Sales/Model/Resource/EntitySnapshot.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Resource; + +use Magento\Framework\Model\AbstractModel; + +/** + * Class EntitySnapshot register snapshot of entity data, for tracking changes + */ +class EntitySnapshot +{ + /** + * Array of snapshots of entities data + * + * @var array + */ + protected $snapshotData = []; + + /** + * @var EntityMetadata + */ + protected $entityMetadata; + + /** + * Initialization + * + * @param EntityMetadata $entityMetadata + */ + public function __construct( + EntityMetadata $entityMetadata + ) { + $this->entityMetadata = $entityMetadata; + } + + /** + * Register snapshot of entity data, for tracking changes + * + * @param AbstractModel $entity + * @return void + */ + public function registerSnapshot(AbstractModel $entity) + { + $data = array_intersect_key($entity->getData(), $this->entityMetadata->getFields($entity)); + $this->snapshotData[get_class($entity)][$entity->getId()] = $data; + } + + /** + * Check is current entity has changes, by comparing current object state with stored snapshot + * + * @param AbstractModel $entity + * @return bool + */ + public function isModified(AbstractModel $entity) + { + if (!$entity->getId()) { + return true; + } + if (!isset($this->snapshotData[get_class($entity)][$entity->getId()])) { + return true; + } + $data = array_intersect_key($entity->getData(), $this->entityMetadata->getFields($entity)); + if ($data !== $this->snapshotData[get_class($entity)][$entity->getId()]) { + return true; + } + return false; + } +} diff --git a/app/code/Magento/Sales/Model/Resource/Order.php b/app/code/Magento/Sales/Model/Resource/Order.php index 5a2cd7fedbdb9ba58feb7a9d830015b8e0182077..67f1fbf14b845619a962888414c88cace3dec3fb 100644 --- a/app/code/Magento/Sales/Model/Resource/Order.php +++ b/app/code/Magento/Sales/Model/Resource/Order.php @@ -7,8 +7,8 @@ namespace Magento\Sales\Model\Resource; use Magento\Framework\App\Resource as AppResource; use Magento\Framework\Math\Random; -use Magento\Sales\Model\Increment as SalesIncrement; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\SalesSequence\Model\Manager; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; use Magento\Sales\Model\Resource\Order\Handler\Address as AddressHandler; use Magento\Sales\Model\Resource\Order\Handler\State as StateHandler; use Magento\Sales\Model\Spi\OrderResourceInterface; @@ -17,6 +17,7 @@ use Magento\Sales\Model\Spi\OrderResourceInterface; * Flat sales order resource * * @author Magento Core Team <core@magentocommerce.com> + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Order extends SalesResource implements OrderResourceInterface { @@ -57,22 +58,24 @@ class Order extends SalesResource implements OrderResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute - * @param SalesIncrement $salesIncrement + * @param Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param AddressHandler $addressHandler * @param StateHandler $stateHandler - * @param string|null $resourcePrefix + * @param null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, Attribute $attribute, - SalesIncrement $salesIncrement, + Manager $sequenceManager, + EntitySnapshot $entitySnapshot, AddressHandler $addressHandler, StateHandler $stateHandler, $resourcePrefix = null ) { $this->stateHandler = $stateHandler; $this->addressHandler = $addressHandler; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** @@ -163,7 +166,7 @@ class Order extends SalesResource implements OrderResourceInterface * @param \Magento\Framework\Model\AbstractModel $object * @return $this */ - protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) + protected function processRelations(\Magento\Framework\Model\AbstractModel $object) { /** @var \Magento\Sales\Model\Order $object */ $this->addressHandler->process($object); @@ -192,11 +195,12 @@ class Order extends SalesResource implements OrderResourceInterface $statusHistory->setOrder($object); } } - foreach ($object->getRelatedObjects() as $relatedObject) { - $relatedObject->save(); - $relatedObject->setOrder($object); + if (null !== $object->getRelatedObjects()) { + foreach ($object->getRelatedObjects() as $relatedObject) { + $relatedObject->save(); + $relatedObject->setOrder($object); + } } - - return parent::_afterSave($object); + return parent::processRelations($object); } } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Address.php b/app/code/Magento/Sales/Model/Resource/Order/Address.php index bacacbbcd01e37894b0cbbe547f002d8db5d4545..b11ffd3c45827ca6b6cc0c8fa37bf5a5cb4caf37 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Address.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Address.php @@ -5,8 +5,9 @@ */ namespace Magento\Sales\Model\Resource\Order; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; use Magento\Sales\Model\Spi\OrderAddressResourceInterface; +use Magento\Sales\Model\Resource\EntitySnapshot; /** * Flat sales order address resource @@ -33,7 +34,8 @@ class Address extends SalesResource implements OrderAddressResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param \Magento\Sales\Model\Resource\Attribute $attribute - * @param \Magento\Sales\Model\Increment $salesIncrement + * @param \Magento\SalesSequence\Model\Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param \Magento\Sales\Model\Order\Address\Validator $validator * @param \Magento\Sales\Model\Resource\GridPool $gridPool * @param string|null $resourcePrefix @@ -41,14 +43,15 @@ class Address extends SalesResource implements OrderAddressResourceInterface public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, - \Magento\Sales\Model\Increment $salesIncrement, + \Magento\SalesSequence\Model\Manager $sequenceManager, + EntitySnapshot $entitySnapshot, \Magento\Sales\Model\Order\Address\Validator $validator, \Magento\Sales\Model\Resource\GridPool $gridPool, $resourcePrefix = null ) { $this->_validator = $validator; $this->gridPool = $gridPool; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** @@ -120,7 +123,7 @@ class Address extends SalesResource implements OrderAddressResourceInterface protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) { $resource = parent::_afterSave($object); - if ($object->hasDataChanges() && $object->getOrderId()) { + if ($object->getOrderId()) { $this->gridPool->refreshByOrderId($object->getOrderId()); } return $resource; diff --git a/app/code/Magento/Sales/Model/Resource/Order/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Collection.php index e3afc7640f99c92feb0bfe62ae9b0cf7ad10c4eb..4254242321fa2c11b6bf60fb819bc2c74a6ce615 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Collection.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Collection.php @@ -39,8 +39,9 @@ class Collection extends AbstractCollection implements OrderSearchResultInterfac * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot * @param \Magento\Framework\DB\Helper $coreResourceHelper - * @param \Zend_Db_Adapter_Abstract $connection + * @param string|null $connection * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource */ public function __construct( @@ -48,11 +49,20 @@ class Collection extends AbstractCollection implements OrderSearchResultInterfac \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, \Magento\Framework\DB\Helper $coreResourceHelper, $connection = null, \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null ) { - parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + parent::__construct( + $entityFactory, + $logger, + $fetchStrategy, + $eventManager, + $entitySnapshot, + $connection, + $resource + ); $this->_coreResourceHelper = $coreResourceHelper; } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php index 5f2797d8efcef0b57860d26d44f81219d405a679..b2dab0f476b8a99da5cc62196419897a73391393 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php @@ -6,9 +6,10 @@ namespace Magento\Sales\Model\Resource\Order; use Magento\Framework\App\Resource as AppResource; -use Magento\Sales\Model\Increment as SalesIncrement; +use Magento\SalesSequence\Model\Manager; use Magento\Sales\Model\Resource\Attribute; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; +use Magento\Sales\Model\Resource\EntitySnapshot; use Magento\Sales\Model\Spi\CreditmemoResourceInterface; /** @@ -36,20 +37,20 @@ class Creditmemo extends SalesResource implements CreditmemoResourceInterface } /** - * Constructor - * * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute - * @param SalesIncrement $salesIncrement + * @param Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, Attribute $attribute, - SalesIncrement $salesIncrement, + Manager $sequenceManager, + EntitySnapshot $entitySnapshot, $resourcePrefix = null ) { - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** @@ -75,7 +76,7 @@ class Creditmemo extends SalesResource implements CreditmemoResourceInterface * @param \Magento\Framework\Model\AbstractModel $object * @return $this */ - protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) + protected function processRelations(\Magento\Framework\Model\AbstractModel $object) { /** @var \Magento\Sales\Model\Order\Creditmemo $object */ if (null !== $object->getItems()) { @@ -90,7 +91,6 @@ class Creditmemo extends SalesResource implements CreditmemoResourceInterface $comment->save(); } } - - return parent::_afterSave($object); + return parent::processRelations($object); } } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php index dce44c4bb8673690183a8013b40a0b19405d1549..aca0ff4e7508ff89996378412d1cc0b154bdc3a3 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php @@ -5,7 +5,8 @@ */ namespace Magento\Sales\Model\Resource\Order\Creditmemo; -use Magento\Sales\Model\Resource\Entity; +use Magento\Sales\Model\Resource\EntityAbstract; +use Magento\Sales\Model\Resource\EntitySnapshot; use Magento\Sales\Model\Spi\CreditmemoCommentResourceInterface; /** @@ -13,7 +14,7 @@ use Magento\Sales\Model\Spi\CreditmemoCommentResourceInterface; * * @author Magento Core Team <core@magentocommerce.com> */ -class Comment extends Entity implements CreditmemoCommentResourceInterface +class Comment extends EntityAbstract implements CreditmemoCommentResourceInterface { /** * Event prefix @@ -32,19 +33,21 @@ class Comment extends Entity implements CreditmemoCommentResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param \Magento\Sales\Model\Resource\Attribute $attribute - * @param \Magento\Sales\Model\Increment $salesIncrement + * @param \Magento\SalesSequence\Model\Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param \Magento\Sales\Model\Order\Creditmemo\Comment\Validator $validator * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, - \Magento\Sales\Model\Increment $salesIncrement, + \Magento\SalesSequence\Model\Manager $sequenceManager, + EntitySnapshot $entitySnapshot, \Magento\Sales\Model\Order\Creditmemo\Comment\Validator $validator, $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Item.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Item.php index 8a1a037b736d6c334643b323a1b5fba17f169978..7a8047fb5a7ea3a32d78f8e21c0efaaf3805179d 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Item.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Item.php @@ -5,7 +5,7 @@ */ namespace Magento\Sales\Model\Resource\Order\Creditmemo; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; use Magento\Sales\Model\Spi\CreditmemoItemResourceInterface; /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php index afa36e2eb0e4d123548c743a1398e2179ed46b2e..85eeb520f00038005fc02d39303e096723775948 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php @@ -23,6 +23,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Creditmemo\Grid\Col * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Framework\Registry $registryManager + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot * @param null $connection * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource */ @@ -31,12 +32,21 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Creditmemo\Grid\Col \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, \Magento\Framework\Registry $registryManager, $connection = null, \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null ) { $this->registryManager = $registryManager; - parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + parent::__construct( + $entityFactory, + $logger, + $fetchStrategy, + $eventManager, + $entitySnapshot, + $connection, + $resource + ); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice.php index 406589dafd152ccf2f0f602f01fe74bf38188955..346d85f342b6c9a710a33e46302febde371bb89a 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Invoice.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice.php @@ -6,9 +6,10 @@ namespace Magento\Sales\Model\Resource\Order; use Magento\Framework\App\Resource; -use Magento\Sales\Model\Increment as SalesIncrement; +use Magento\SalesSequence\Model\Manager; use Magento\Sales\Model\Resource\Attribute; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; +use Magento\Sales\Model\Resource\EntitySnapshot; use Magento\Sales\Model\Spi\InvoiceResourceInterface; /** @@ -36,16 +37,18 @@ class Invoice extends SalesResource implements InvoiceResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute - * @param SalesIncrement $salesIncrement + * @param Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, Attribute $attribute, - SalesIncrement $salesIncrement, + Manager $sequenceManager, + EntitySnapshot $entitySnapshot, $resourcePrefix = null ) { - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** @@ -71,7 +74,7 @@ class Invoice extends SalesResource implements InvoiceResourceInterface * @param \Magento\Framework\Model\AbstractModel|\Magento\Framework\Object $object * @return $this */ - protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) + protected function processRelations(\Magento\Framework\Model\AbstractModel $object) { /** @var \Magento\Sales\Model\Order\Invoice $object */ if (null !== $object->getItems()) { @@ -90,7 +93,6 @@ class Invoice extends SalesResource implements InvoiceResourceInterface $comment->save(); } } - - return parent::_afterSave($object); + return parent::processRelations($object); } } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php index 5d44bd40bd5c0d50c8632f7647c16a089e026a0e..f1ee7de58b2fbcee010811d7249e97c4e295a306 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php @@ -5,7 +5,8 @@ */ namespace Magento\Sales\Model\Resource\Order\Invoice; -use Magento\Sales\Model\Resource\Entity; +use Magento\Sales\Model\Resource\EntityAbstract; +use Magento\Sales\Model\Resource\EntitySnapshot; use Magento\Sales\Model\Spi\InvoiceCommentResourceInterface; /** @@ -13,7 +14,7 @@ use Magento\Sales\Model\Spi\InvoiceCommentResourceInterface; * * @author Magento Core Team <core@magentocommerce.com> */ -class Comment extends Entity implements InvoiceCommentResourceInterface +class Comment extends EntityAbstract implements InvoiceCommentResourceInterface { /** * Event prefix @@ -32,19 +33,23 @@ class Comment extends Entity implements InvoiceCommentResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param \Magento\Sales\Model\Resource\Attribute $attribute - * @param \Magento\Sales\Model\Increment $salesIncrement + * @param \Magento\SalesSequence\Model\Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param \Magento\Sales\Model\Order\Invoice\Comment\Validator $validator * @param string|null $resourcePrefix + * @param \Magento\Sales\Model\Resource\GridInterface $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, - \Magento\Sales\Model\Increment $salesIncrement, + \Magento\SalesSequence\Model\Manager $sequenceManager, + EntitySnapshot $entitySnapshot, \Magento\Sales\Model\Order\Invoice\Comment\Validator $validator, - $resourcePrefix = null + $resourcePrefix = null, + \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix, $gridAggregator); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Item.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Item.php index c3770dac00b712d969d8b5710f9c5d4e9bcfbed5..03c13845e9ba237329ecc0a10e09ec2bc5c4ac67 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Item.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Item.php @@ -10,7 +10,7 @@ namespace Magento\Sales\Model\Resource\Order\Invoice; * * @author Magento Core Team <core@magentocommerce.com> */ -class Item extends \Magento\Sales\Model\Resource\Entity +class Item extends \Magento\Sales\Model\Resource\EntityAbstract { /** * Event prefix diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php index 90ee71e1d18b707a006b5fdbf650174dbcae9fb1..6f6d71c655ebb10c595db011e3f5777c6e1a1754 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php @@ -17,6 +17,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Invoice\Grid\Collec * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot * @param \Magento\Framework\Registry $registryManager * @param null $connection * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource @@ -26,12 +27,21 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Invoice\Grid\Collec \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, \Magento\Framework\Registry $registryManager, $connection = null, \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null ) { $this->registryManager = $registryManager; - parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + parent::__construct( + $entityFactory, + $logger, + $fetchStrategy, + $eventManager, + $entitySnapshot, + $connection, + $resource + ); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Item.php b/app/code/Magento/Sales/Model/Resource/Order/Item.php index 3a8b7282109cb1f9dad4cec3da60dfb517b25e1c..426b9b3e2d5e5f203581ba0a1d7ccaeb813e6c6e 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Item.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Item.php @@ -5,7 +5,7 @@ */ namespace Magento\Sales\Model\Resource\Order; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; /** * Flat sales order item resource diff --git a/app/code/Magento/Sales/Model/Resource/Order/Payment.php b/app/code/Magento/Sales/Model/Resource/Order/Payment.php index 150ce9e8826412860e0cd95a1f478b13751918fb..2d4603ec74021ce02a0e7e52a6da34b08e09083b 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Payment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Payment.php @@ -6,7 +6,7 @@ namespace Magento\Sales\Model\Resource\Order; use Magento\Framework\App\Resource; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; /** * Flat sales order payment resource diff --git a/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php index 4dccf8d02cbf2ed56d49a31d7520e967cab12484..8f73ee346165a646e8e8939bcdae16d6d64256b4 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php @@ -32,7 +32,8 @@ class Collection extends AbstractCollection implements OrderPaymentSearchResultI * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Zend_Db_Adapter_Abstract $connection + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot + * @param null $connection * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource */ public function __construct( @@ -40,10 +41,19 @@ class Collection extends AbstractCollection implements OrderPaymentSearchResultI \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, $connection = null, \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null ) { - parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + parent::__construct( + $entityFactory, + $logger, + $fetchStrategy, + $eventManager, + $entitySnapshot, + $connection, + $resource + ); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Payment/Transaction.php b/app/code/Magento/Sales/Model/Resource/Order/Payment/Transaction.php index 8f5bb11b83415a7e318a2741cfbb2bea6d61d324..0b11338a24376f55f1d8b29a6f2fb3b63d37bf65 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Payment/Transaction.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Payment/Transaction.php @@ -5,7 +5,7 @@ */ namespace Magento\Sales\Model\Resource\Order\Payment; -use Magento\Sales\Model\Resource\Entity; +use Magento\Sales\Model\Resource\EntityAbstract; use Magento\Sales\Model\Spi\TransactionResourceInterface; /** @@ -13,7 +13,7 @@ use Magento\Sales\Model\Spi\TransactionResourceInterface; * * @author Magento Core Team <core@magentocommerce.com> */ -class Transaction extends Entity implements TransactionResourceInterface +class Transaction extends EntityAbstract implements TransactionResourceInterface { /** * Serializeable field: additional_information diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment.php index 1d11adfed6748e73b3d0a02cb6faeedc23beaf47..577876a9e33142156c807b9d9ed4858895d86811 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment.php @@ -6,9 +6,11 @@ namespace Magento\Sales\Model\Resource\Order; use Magento\Framework\App\Resource as AppResource; -use Magento\Sales\Model\Increment as SalesIncrement; +use Magento\SalesSequence\Model\Manager; use Magento\Sales\Model\Resource\Attribute; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; +use Magento\Sales\Model\Resource\EntitySnapshot; +use Magento\Sales\Model\Resource\Order\Shipment\Grid as ShipmentGrid; use Magento\Sales\Model\Spi\ShipmentResourceInterface; /** @@ -45,16 +47,18 @@ class Shipment extends SalesResource implements ShipmentResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute - * @param SalesIncrement $salesIncrement + * @param Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, Attribute $attribute, - SalesIncrement $salesIncrement, + Manager $sequenceManager, + EntitySnapshot $entitySnapshot, $resourcePrefix = null ) { - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** @@ -85,7 +89,7 @@ class Shipment extends SalesResource implements ShipmentResourceInterface * @param \Magento\Framework\Model\AbstractModel $object * @return $this */ - protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) + protected function processRelations(\Magento\Framework\Model\AbstractModel $object) { /** @var \Magento\Sales\Model\Order\Shipment $object */ if (null !== $object->getItems()) { @@ -107,6 +111,6 @@ class Shipment extends SalesResource implements ShipmentResourceInterface } } - return parent::_afterSave($object); + return parent::processRelations($object); } } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php index ab50e07d1afa570c0bada035ae60344a5b9fbbf3..affdf26d6138cf22136b4680666b682482697efb 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php @@ -5,7 +5,8 @@ */ namespace Magento\Sales\Model\Resource\Order\Shipment; -use Magento\Sales\Model\Resource\Entity; +use Magento\Sales\Model\Resource\EntityAbstract; +use Magento\Sales\Model\Resource\EntitySnapshot; use Magento\Sales\Model\Spi\ShipmentCommentResourceInterface; /** @@ -13,7 +14,7 @@ use Magento\Sales\Model\Spi\ShipmentCommentResourceInterface; * * @author Magento Core Team <core@magentocommerce.com> */ -class Comment extends Entity implements ShipmentCommentResourceInterface +class Comment extends EntityAbstract implements ShipmentCommentResourceInterface { /** * Event prefix @@ -32,19 +33,21 @@ class Comment extends Entity implements ShipmentCommentResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param \Magento\Sales\Model\Resource\Attribute $attribute - * @param \Magento\Sales\Model\Increment $salesIncrement + * @param \Magento\SalesSequence\Model\Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param \Magento\Sales\Model\Order\Shipment\Comment\Validator $validator * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, - \Magento\Sales\Model\Increment $salesIncrement, + \Magento\SalesSequence\Model\Manager $sequenceManager, + EntitySnapshot $entitySnapshot, \Magento\Sales\Model\Order\Shipment\Comment\Validator $validator, $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Item.php index 7e653e739c79032eca9dd5d8c7c2ead15d93bb5d..fb13970fe19ffd7bbfb8f802a207035dcdc3029b 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Item.php @@ -5,7 +5,7 @@ */ namespace Magento\Sales\Model\Resource\Order\Shipment; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; use Magento\Sales\Model\Spi\ShipmentItemResourceInterface; /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php index 79c797ce1240938e322ed1f4efcfda1a0b98e2ca..ae31f67f65deb94365871772b991d45ebcebf9f0 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php @@ -22,6 +22,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Shipment\Grid\Colle * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot * @param \Magento\Framework\Registry $registryManager * @param null $connection * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource @@ -31,12 +32,21 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Shipment\Grid\Colle \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, \Magento\Framework\Registry $registryManager, $connection = null, \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null ) { $this->registryManager = $registryManager; - parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + parent::__construct( + $entityFactory, + $logger, + $fetchStrategy, + $eventManager, + $entitySnapshot, + $connection, + $resource + ); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php index 86b27bc301c0e4084b8bcd9f718f4756f2f9b411..cdbdbf78d8986d36f593886eb1cd0144e79670bf 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php @@ -5,7 +5,8 @@ */ namespace Magento\Sales\Model\Resource\Order\Shipment; -use Magento\Sales\Model\Resource\Entity as SalesResource; +use Magento\Sales\Model\Resource\EntityAbstract as SalesResource; +use Magento\Sales\Model\Resource\EntitySnapshot; use Magento\Sales\Model\Spi\ShipmentTrackResourceInterface; /** @@ -32,19 +33,21 @@ class Track extends SalesResource implements ShipmentTrackResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param \Magento\Sales\Model\Resource\Attribute $attribute - * @param \Magento\Sales\Model\Increment $salesIncrement + * @param \Magento\SalesSequence\Model\Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param \Magento\Sales\Model\Order\Shipment\Track\Validator $validator * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, - \Magento\Sales\Model\Increment $salesIncrement, + \Magento\SalesSequence\Model\Manager $sequenceManager, + EntitySnapshot $entitySnapshot, \Magento\Sales\Model\Order\Shipment\Track\Validator $validator, $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Status/History.php b/app/code/Magento/Sales/Model/Resource/Order/Status/History.php index bf50f4b6b004e7f2beb4c2eaeb1838408ea5c343..c7aadebf49e3b9b659528753b0f8edc7766c81d7 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Status/History.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Status/History.php @@ -6,7 +6,8 @@ namespace Magento\Sales\Model\Resource\Order\Status; use Magento\Sales\Model\Order\Status\History\Validator; -use Magento\Sales\Model\Resource\Entity; +use Magento\Sales\Model\Resource\EntityAbstract; +use Magento\Sales\Model\Resource\EntitySnapshot; use Magento\Sales\Model\Spi\OrderStatusHistoryResourceInterface; /** @@ -14,7 +15,7 @@ use Magento\Sales\Model\Spi\OrderStatusHistoryResourceInterface; * * @author Magento Core Team <core@magentocommerce.com> */ -class History extends Entity implements OrderStatusHistoryResourceInterface +class History extends EntityAbstract implements OrderStatusHistoryResourceInterface { /** * @var Validator @@ -24,19 +25,21 @@ class History extends Entity implements OrderStatusHistoryResourceInterface /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param \Magento\Sales\Model\Resource\Attribute $attribute - * @param \Magento\Sales\Model\Increment $salesIncrement + * @param \Magento\SalesSequence\Model\Manager $sequenceManager + * @param EntitySnapshot $entitySnapshot * @param Validator $validator * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, - \Magento\Sales\Model\Increment $salesIncrement, + \Magento\SalesSequence\Model\Manager $sequenceManager, + EntitySnapshot $entitySnapshot, Validator $validator, $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); + parent::__construct($context, $attribute, $sequenceManager, $entitySnapshot, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php index e6e5ac0812861a40f4da10a9b1f01d314473ac61..9bd3c5d4aac539ad12d462d2d4c3100be3328703 100644 --- a/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php +++ b/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php @@ -20,6 +20,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Payment\Transaction * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot * @param \Magento\Framework\Registry $registryManager * @param null $connection * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource @@ -29,12 +30,21 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Payment\Transaction \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Sales\Model\Resource\EntitySnapshot $entitySnapshot, \Magento\Framework\Registry $registryManager, $connection = null, \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null ) { $this->registryManager = $registryManager; - parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + parent::__construct( + $entityFactory, + $logger, + $fetchStrategy, + $eventManager, + $entitySnapshot, + $connection, + $resource + ); } /** diff --git a/app/code/Magento/Sales/Setup/InstallData.php b/app/code/Magento/Sales/Setup/InstallData.php index 9dc4b6c7a2d6caa160da1222606d26d1b61fad2e..0c19a25a166708cb5576ca45e9ae8e79961f0ab6 100644 --- a/app/code/Magento/Sales/Setup/InstallData.php +++ b/app/code/Magento/Sales/Setup/InstallData.php @@ -9,6 +9,8 @@ namespace Magento\Sales\Setup; use Magento\Framework\Setup\InstallDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\SalesSequence\Model\Builder; +use Magento\SalesSequence\Model\Config as SequenceConfig; /** * Class InstallData @@ -25,13 +27,28 @@ class InstallData implements InstallDataInterface private $salesSetupFactory; /** - * Init - * + * @var Builder + */ + private $sequenceBuilder; + + /** + * @var SequenceConfig + */ + private $sequenceConfig; + + /** * @param SalesSetupFactory $salesSetupFactory + * @param Builder $sequenceBuilder + * @param SequenceConfig $sequenceConfig */ - public function __construct(SalesSetupFactory $salesSetupFactory) - { + public function __construct( + SalesSetupFactory $salesSetupFactory, + Builder $sequenceBuilder, + SequenceConfig $sequenceConfig + ) { $this->salesSetupFactory = $salesSetupFactory; + $this->sequenceBuilder = $sequenceBuilder; + $this->sequenceConfig = $sequenceConfig; } /** diff --git a/app/code/Magento/Sales/Setup/UpgradeSchema.php b/app/code/Magento/Sales/Setup/UpgradeSchema.php index 6f3f45fa05e18b0595892a8f0c9201a711388652..b1178f1268f0dc446d252882798158ce8920ad11 100644 --- a/app/code/Magento/Sales/Setup/UpgradeSchema.php +++ b/app/code/Magento/Sales/Setup/UpgradeSchema.php @@ -18,9 +18,13 @@ class UpgradeSchema implements UpgradeSchemaInterface { /** * {@inheritdoc} + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context) { + $installer = $setup; + $connection = $installer->getConnection(); if (version_compare($context->getVersion(), '2.0.1') < 0) { $installer = $setup; @@ -107,5 +111,49 @@ class UpgradeSchema implements UpgradeSchemaInterface ); } } + if (version_compare($context->getVersion(), '2.0.3') < 0) { + $dropIncrementIndexTables = [ + 'sales_creditmemo', + 'sales_invoice', + 'sales_order', + 'sales_shipment', + 'sales_creditmemo_grid', + 'sales_invoice_grid', + 'sales_order_grid', + 'sales_shipment_grid', + ]; + foreach ($dropIncrementIndexTables as $table) { + $connection->dropIndex( + $installer->getTable($table), + $installer->getIdxName( + $installer->getTable($table), + ['increment_id'], + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ) + ); + } + $createIncrementIndexTables = [ + 'sales_creditmemo', + 'sales_invoice', + 'sales_order', + 'sales_shipment', + 'sales_creditmemo_grid', + 'sales_invoice_grid', + 'sales_order_grid', + 'sales_shipment_grid', + ]; + foreach ($createIncrementIndexTables as $table) { + $connection->addIndex( + $installer->getTable($table), + $installer->getIdxName( + $installer->getTable($table), + ['increment_id', 'store_id'], + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ), + ['increment_id', 'store_id'], + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ); + } + } } } diff --git a/app/code/Magento/Sales/Test/Unit/Block/Order/RecentTest.php b/app/code/Magento/Sales/Test/Unit/Block/Order/RecentTest.php index 85213a415a84f2aacf448f170130e08a2c681bb6..a0b88ac060af55a682a1df24d8883461299c777f 100644 --- a/app/code/Magento/Sales/Test/Unit/Block/Order/RecentTest.php +++ b/app/code/Magento/Sales/Test/Unit/Block/Order/RecentTest.php @@ -10,7 +10,7 @@ class RecentTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Sales\Block\Order\Recent */ - protected $model; + protected $block; /** * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject @@ -84,7 +84,6 @@ class RecentTest extends \PHPUnit_Framework_TestCase [ 'addAttributeToSelect', 'addFieldToFilter', - 'joinAttribute', 'addAttributeToFilter', 'addAttributeToSort', 'setPageSize', @@ -95,65 +94,39 @@ class RecentTest extends \PHPUnit_Framework_TestCase false, false ); + $this->orderCollectionFactory->expects($this->once()) + ->method('create') + ->will($this->returnValue($orderCollection)); $orderCollection->expects($this->at(0)) ->method('addAttributeToSelect') ->with($this->equalTo('*')) ->will($this->returnSelf()); $orderCollection->expects($this->at(1)) - ->method('joinAttribute') - ->with( - 'shipping_firstname', - 'order_address/firstname', - 'shipping_address_id', - $this->equalTo(null), - 'left' - ) - ->will($this->returnSelf()); - $orderCollection->expects($this->at(2)) - ->method('joinAttribute') - ->with( - 'shipping_lastname', - 'order_address/lastname', - 'shipping_address_id', - $this->equalTo(null), - 'left' - ) - ->will($this->returnSelf()); - - $orderCollection->expects($this->at(3)) ->method('addAttributeToFilter') - ->with( - $attribute[0], - $this->equalTo($customerId) - ) - ->will($this->returnSelf()); - $orderCollection->expects($this->at(4)) + ->with($attribute[0], $this->equalTo($customerId)) + ->willReturnSelf(); + $orderCollection->expects($this->at(2)) ->method('addAttributeToFilter') ->with($attribute[1], $this->equalTo(['in' => $statuses])) ->will($this->returnSelf()); - $orderCollection->expects($this->at(5)) + $orderCollection->expects($this->at(3)) ->method('addAttributeToSort') ->with('created_at', 'desc') ->will($this->returnSelf()); - $orderCollection->expects($this->at(6)) + $orderCollection->expects($this->at(4)) ->method('setPageSize') ->with('5') ->will($this->returnSelf()); - $orderCollection->expects($this->at(7)) + $orderCollection->expects($this->at(5)) ->method('load') ->will($this->returnSelf()); - - $this->orderCollectionFactory->expects($this->atLeastOnce()) - ->method('create') - ->will($this->returnValue($orderCollection)); - - $this->model = new \Magento\Sales\Block\Order\Recent( + $this->block = new \Magento\Sales\Block\Order\Recent( $this->context, $this->orderCollectionFactory, $this->customerSession, $this->orderConfig, $data ); - $this->assertEquals($orderCollection, $this->model->getOrders()); + $this->assertEquals($orderCollection, $this->block->getOrders()); } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Address/ValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Address/ValidatorTest.php index 1b54c7c90a20fa499ba78ba47dad6ca5692354a8..8c19adcecfdeb597e8232266925d4f73cabc2e81 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Address/ValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Address/ValidatorTest.php @@ -20,6 +20,16 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase */ protected $addressMock; + /** + * @var \Magento\Directory\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + */ + protected $directoryHelperMock; + + /** + * @var \Magento\Directory\Model\CountryFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $countryFactoryMock; + /** * Mock order address model */ @@ -32,7 +42,24 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase '', false ); - $this->validator = new \Magento\Sales\Model\Order\Address\Validator(); + $this->directoryHelperMock = $this->getMock( + 'Magento\Directory\Helper\Data', + [], + [], + '', + false + ); + $this->countryFactoryMock = $this->getMock( + 'Magento\Directory\Model\CountryFactory', + [], + [], + '', + false + ); + $this->validator = new \Magento\Sales\Model\Order\Address\Validator( + $this->directoryHelperMock, + $this->countryFactoryMock + ); } /** diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/AddressTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/AddressTest.php new file mode 100644 index 0000000000000000000000000000000000000000..985723b3f8523b125e92ad77a98b2fa9aff694b8 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/AddressTest.php @@ -0,0 +1,157 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Test\Unit\Model\Order; + +use \Magento\Sales\Model\Order\Payment; + +/** + * Class PaymentTest + * + * @package Magento\Sales\Model\Order + */ +class AddressTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Model\Order\Address + */ + protected $address; + /** + * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject + */ + protected $orderMock; + /** + * @var \Magento\Directory\Model\RegionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $regionFactoryMock; + /** + * @var \Magento\Directory\Model\Region|\PHPUnit_Framework_MockObject_MockObject + */ + protected $regionMock; + + protected function setUp() + { + $this->orderMock = $this->getMock( + 'Magento\Sales\Model\Order', + [], + [], + '', + false + ); + $this->orderMock = $this->getMock( + 'Magento\Sales\Model\Order', + [], + [], + '', + false + ); + $this->regionFactoryMock = $this->getMock( + 'Magento\Directory\Model\RegionFactory', + [], + [], + '', + false + ); + $this->regionMock = $this->getMock( + 'Magento\Directory\Model\Region', + ['load', 'getCountryId', 'getCode'], + [], + '', + false + ); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->address = $objectManager->getObject( + 'Magento\Sales\Model\Order\Address', + [ + 'regionFactory' => $this->regionFactoryMock + ] + ); + } + + public function testSetOrder() + { + $this->assertEquals($this->address, $this->address->setOrder($this->orderMock)); + } + + public function testGetRegionCodeRegionIsSet() + { + $this->address->setData('region', 'region'); + $this->regionFactoryMock->expects($this->never()) + ->method('create'); + $this->assertEquals('region', $this->address->getRegionCode()); + } + + public function regionProvider() + { + return [ [1, null], [null, 1]]; + } + + /** + * @dataProvider regionProvider + */ + public function testGetRegionCodeRegion($region, $regionId) + { + $this->address->setData( + [ + 'region' => $region, + 'region_id' => $regionId, + 'country_id' => 1 + ] + ); + $this->regionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->regionMock); + $this->regionMock->expects($this->once()) + ->method('load') + ->with(1) + ->willReturn($this->regionMock); + $this->regionMock->expects($this->once()) + ->method('getCountryId') + ->willReturn(1); + $this->regionMock->expects($this->once()) + ->method('getCode') + ->willReturn('region'); + $this->assertEquals('region', $this->address->getRegionCode()); + } + + public function testGetRegionCodeRegionFailure() + { + $this->address->setData( + [ + 'region' => 1, + 'region_id' => 1, + 'country_id' => 1 + ] + ); + $this->regionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->regionMock); + $this->regionMock->expects($this->once()) + ->method('load') + ->with(1) + ->willReturn($this->regionMock); + $this->regionMock->expects($this->once()) + ->method('getCountryId') + ->willReturn(2); + $this->regionMock->expects($this->never()) + ->method('getCode'); + $this->assertEquals(null, $this->address->getRegionCode()); + } + + public function testGetName() + { + $this->address->setData( + [ + 'suffix' => 'suffix', + 'prefix' => 'prefix', + 'firstname' => 'firstname', + 'middlename' => 'middlename', + 'lastname' => 'lastname' + ] + ); + $this->assertEquals('prefix firstname middlename lastname suffix', $this->address->getName()); + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..54c00939476681f67f515108ab618919fd5b6e20 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php @@ -0,0 +1,145 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; + +/** + * Class AbstractSenderTest + */ +abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $senderBuilderFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $templateContainerMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $identityContainerMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $storeMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $orderMock; + + /** + * @var \Magento\Sales\Model\Order\Address\Renderer | \PHPUnit_Framework_MockObject_MockObject + */ + protected $addressRendererMock; + + /** + * @var \Magento\Sales\Model\Order\Address | \PHPUnit_Framework_MockObject_MockObject + */ + protected $addressMock; + + public function stepMockSetup() + { + $this->senderBuilderFactoryMock = $this->getMock( + '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', + ['create'], + [], + '', + false + ); + $this->templateContainerMock = $this->getMock( + '\Magento\Sales\Model\Order\Email\Container\Template', + ['setTemplateVars'], + [], + '', + false + ); + + $this->storeMock = $this->getMock( + '\Magento\Store\Model\Store', + ['getStoreId', '__wakeup'], + [], + '', + false + ); + + $this->orderMock = $this->getMock( + '\Magento\Sales\Model\Order', + [], + [], + '', + false + ); + + $this->orderMock->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($this->storeMock)); + + + $this->addressRendererMock = $this->getMock('Magento\Sales\Model\Order\Address\Renderer', [], [], '', false); + $this->addressMock = $this->getMock('Magento\Sales\Model\Order\Address', [], [], '', false); + $this->addressRendererMock->expects($this->any())->method('format')->willReturn(1); + } + + public function stepAddressFormat($billingAddress) + { + $this->orderMock->expects($this->any()) + ->method('getBillingAddress') + ->will($this->returnValue($billingAddress)); + $this->orderMock->expects($this->any()) + ->method('getShippingAddress') + ->will($this->returnValue($billingAddress)); + } + + public function stepSendWithoutSendCopy() + { + $this->stepSend($this->once(), $this->never()); + } + + public function stepSendWithCallSendCopyTo() + { + $this->stepSend($this->never(), $this->once()); + } + + public function stepIdentityContainerInit($identityMockClassName) + { + $this->identityContainerMock = $this->getMock( + $identityMockClassName, + ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], + [], + '', + false + ); + $this->identityContainerMock->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($this->storeMock)); + } + + protected function stepSend( + \PHPUnit_Framework_MockObject_Matcher_InvokedCount $sendExpects, + \PHPUnit_Framework_MockObject_Matcher_InvokedCount $sendCopyToExpects + ) { + $senderMock = $this->getMock( + 'Magento\Sales\Model\Order\Email\Sender', + ['send', 'sendCopyTo'], + [], + '', + false + ); + $senderMock->expects($sendExpects) + ->method('send'); + $senderMock->expects($sendCopyToExpects) + ->method('sendCopyTo'); + + $this->senderBuilderFactoryMock->expects($this->once()) + ->method('create') + ->will($this->returnValue($senderMock)); + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php index 081790c14de2d6bd507fefff8a2421a903287abd..33b46511c8478d0345b8ea0d1aca0fcb5464766f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php @@ -7,38 +7,13 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\CreditmemoCommentSender; -class CreditmemoCommentSenderTest extends \PHPUnit_Framework_TestCase +class CreditmemoCommentSenderTest extends AbstractSenderTest { /** - * @var \Magento\Sales\Model\Order\Email\Sender\InvoiceCommentSender + * @var \Magento\Sales\Model\Order\Email\Sender\CreditmemoCommentSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -46,56 +21,8 @@ class CreditmemoCommentSenderTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); - - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); - - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\CreditmemoCommentIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - + $this->stepMockSetup(); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\CreditmemoCommentIdentity'); $this->creditmemoMock = $this->getMock( '\Magento\Sales\Model\Order\Creditmemo', ['getStore', '__wakeup', 'getOrder'], @@ -109,32 +36,31 @@ class CreditmemoCommentSenderTest extends \PHPUnit_Framework_TestCase $this->creditmemoMock->expects($this->any()) ->method('getOrder') ->will($this->returnValue($this->orderMock)); - $this->sender = new CreditmemoCommentSender( $this->templateContainerMock, $this->identityContainerMock, - $this->senderBuilderFactoryMock + $this->senderBuilderFactoryMock, + $this->addressRendererMock ); } public function testSendFalse() { + $billingAddress = $this->addressMock; + $this->stepAddressFormat($billingAddress); $result = $this->sender->send($this->creditmemoMock); $this->assertFalse($result); } public function testSendTrueWithCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); - + $this->stepAddressFormat($billingAddress); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') ->will($this->returnValue(true)); @@ -148,42 +74,25 @@ class CreditmemoCommentSenderTest extends \PHPUnit_Framework_TestCase 'comment' => $comment, 'billing' => $billingAddress, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->never()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithoutSendCopy(); $result = $this->sender->send($this->creditmemoMock, true, $comment); $this->assertTrue($result); } public function testSendTrueWithoutCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); - + $this->stepAddressFormat($billingAddress); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') ->will($this->returnValue(true)); @@ -197,25 +106,12 @@ class CreditmemoCommentSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->never()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithCallSendCopyTo(); $result = $this->sender->send($this->creditmemoMock, false, $comment); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php index 6451e4efde8c2f4fad8bef42d10f5c9e9c70a671..154de077e24978d47c1e6b58439e39f9f56d3734 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php @@ -7,38 +7,13 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\CreditmemoSender; -class CreditmemoSenderTest extends \PHPUnit_Framework_TestCase +class CreditmemoSenderTest extends AbstractSenderTest { /** * @var \Magento\Sales\Model\Order\Email\Sender\CreditmemoSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -55,20 +30,7 @@ class CreditmemoSenderTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); + $this->stepMockSetup(); $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false); $this->paymentHelper->expects($this->any()) ->method('getInfoBlockHtml') @@ -81,41 +43,7 @@ class CreditmemoSenderTest extends \PHPUnit_Framework_TestCase '', false ); - - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); - - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity'); $paymentInfoMock = $this->getMock( '\Magento\Payment\Model\Info', [], @@ -140,34 +68,31 @@ class CreditmemoSenderTest extends \PHPUnit_Framework_TestCase $this->creditmemoMock->expects($this->any()) ->method('getOrder') ->will($this->returnValue($this->orderMock)); - $this->sender = new CreditmemoSender( $this->templateContainerMock, $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->paymentHelper, - $this->creditmemoResource + $this->creditmemoResource, + $this->addressRendererMock ); } public function testSendFalse() { + $this->stepAddressFormat($this->addressMock); $result = $this->sender->send($this->creditmemoMock); $this->assertFalse($result); } public function testSendTrueWithCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; + $this->stepAddressFormat($this->addressMock); $comment = 'comment_test'; - $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); - $this->identityContainerMock->expects($this->once()) ->method('isEnabled') ->will($this->returnValue(true)); @@ -177,11 +102,13 @@ class CreditmemoSenderTest extends \PHPUnit_Framework_TestCase $this->equalTo( [ 'order' => $this->orderMock, - 'invoice' => $this->creditmemoMock, + 'creditmemo' => $this->creditmemoMock, 'comment' => $comment, 'billing' => $billingAddress, 'payment_html' => 'payment', 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); @@ -195,39 +122,19 @@ class CreditmemoSenderTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getPayment') ->will($this->returnValue($paymentInfoMock)); - - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->never()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithoutSendCopy(); $result = $this->sender->send($this->creditmemoMock, true, $comment); $this->assertTrue($result); } public function testSendTrueWithoutCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; + $this->stepAddressFormat($billingAddress); $comment = 'comment_test'; - $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); - $this->identityContainerMock->expects($this->once()) ->method('isEnabled') ->will($this->returnValue(true)); @@ -237,30 +144,17 @@ class CreditmemoSenderTest extends \PHPUnit_Framework_TestCase $this->equalTo( [ 'order' => $this->orderMock, - 'invoice' => $this->creditmemoMock, + 'creditmemo' => $this->creditmemoMock, 'billing' => $billingAddress, 'payment_html' => 'payment', 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->never()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithCallSendCopyTo(); $result = $this->sender->send($this->creditmemoMock, false, $comment); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php index ba4ebf7c7ec58e6bfd60ec90765be3a01e8d6fbe..aefd016bcaac36806be7ffe2a54bd4267b0c5330 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php @@ -7,38 +7,13 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\InvoiceCommentSender; -class InvoiceCommentSenderTest extends \PHPUnit_Framework_TestCase +class InvoiceCommentSenderTest extends AbstractSenderTest { /** * @var \Magento\Sales\Model\Order\Email\Sender\InvoiceCommentSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -46,20 +21,7 @@ class InvoiceCommentSenderTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); + $this->stepMockSetup(); $this->paymentHelper = $this->getMock( '\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], @@ -76,40 +38,7 @@ class InvoiceCommentSenderTest extends \PHPUnit_Framework_TestCase false ); - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); - - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\InvoiceCommentIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\InvoiceCommentIdentity'); $this->invoiceMock = $this->getMock( '\Magento\Sales\Model\Order\Invoice', @@ -128,28 +57,26 @@ class InvoiceCommentSenderTest extends \PHPUnit_Framework_TestCase $this->sender = new InvoiceCommentSender( $this->templateContainerMock, $this->identityContainerMock, - $this->senderBuilderFactoryMock + $this->senderBuilderFactoryMock, + $this->addressRendererMock ); } public function testSendFalse() { + $this->stepAddressFormat($this->addressMock); $result = $this->sender->send($this->invoiceMock); $this->assertFalse($result); } public function testSendTrueWithCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; + $this->stepAddressFormat($billingAddress); $comment = 'comment_test'; - $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); - $this->identityContainerMock->expects($this->once()) ->method('isEnabled') ->will($this->returnValue(true)); @@ -163,41 +90,25 @@ class InvoiceCommentSenderTest extends \PHPUnit_Framework_TestCase 'comment' => $comment, 'billing' => $billingAddress, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->never()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithoutSendCopy(); $result = $this->sender->send($this->invoiceMock, true, $comment); $this->assertTrue($result); } public function testSendTrueWithoutCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; + $this->stepAddressFormat($billingAddress); $comment = 'comment_test'; - $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -212,25 +123,12 @@ class InvoiceCommentSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->never()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithCallSendCopyTo(); $result = $this->sender->send($this->invoiceMock, false, $comment); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php index 1fc111e5d4a92dcdc66c67bace5a92d32fb7d4fc..9737d7271637a34df4452b8147196fb55b75c50f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php @@ -7,38 +7,13 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\InvoiceSender; -class InvoiceSenderTest extends \PHPUnit_Framework_TestCase +class InvoiceSenderTest extends AbstractSenderTest { /** * @var \Magento\Sales\Model\Order\Email\Sender\InvoiceSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -55,20 +30,7 @@ class InvoiceSenderTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); + $this->stepMockSetup(); $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false); $this->paymentHelper->expects($this->any()) ->method('getInfoBlockHtml') @@ -82,40 +44,8 @@ class InvoiceSenderTest extends \PHPUnit_Framework_TestCase false ); - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\InvoiceIdentity'); - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\InvoiceIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); $paymentInfoMock = $this->getMock( '\Magento\Payment\Model\Info', [], @@ -146,27 +76,28 @@ class InvoiceSenderTest extends \PHPUnit_Framework_TestCase $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->paymentHelper, - $this->invoiceResource + $this->invoiceResource, + $this->addressRendererMock ); } public function testSendFalse() { + $billingAddress = $this->addressMock; + $this->stepAddressFormat($billingAddress); $result = $this->sender->send($this->invoiceMock); $this->assertFalse($result); } public function testSendTrueWithCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; + $this->stepAddressFormat($billingAddress); $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -182,6 +113,8 @@ class InvoiceSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'payment_html' => 'payment', 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); @@ -195,38 +128,20 @@ class InvoiceSenderTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getPayment') ->will($this->returnValue($paymentInfoMock)); - - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->never()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithoutSendCopy(); $result = $this->sender->send($this->invoiceMock, true, $comment); $this->assertTrue($result); } public function testSendTrueWithoutCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; + $this->stepAddressFormat($billingAddress); $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -242,25 +157,12 @@ class InvoiceSenderTest extends \PHPUnit_Framework_TestCase 'payment_html' => 'payment', 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->never()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithCallSendCopyTo(); $result = $this->sender->send($this->invoiceMock, false, $comment); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php index 5cebccdd9245193283929a2144639b2c0f40648b..cded51e45c435dfc6a168b5820a4c4e8f7e84886 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php @@ -7,114 +7,41 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\OrderCommentSender; -class OrderCommentSenderTest extends \PHPUnit_Framework_TestCase +class OrderCommentSenderTest extends AbstractSenderTest { /** * @var \Magento\Sales\Model\Order\Email\Sender\OrderCommentSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); - - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); - - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - + $this->stepMockSetup(); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity'); $this->sender = new OrderCommentSender( $this->templateContainerMock, $this->identityContainerMock, - $this->senderBuilderFactoryMock + $this->senderBuilderFactoryMock, + $this->addressRendererMock ); } public function testSendFalse() { + $this->stepAddressFormat($this->addressMock); $result = $this->sender->send($this->orderMock); $this->assertFalse($result); } public function testSendTrue() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $comment = 'comment_test'; - + $this->stepAddressFormat($billingAddress); $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); + $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -128,25 +55,12 @@ class OrderCommentSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->never()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithoutSendCopy(); $result = $this->sender->send($this->orderMock, true, $comment); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php index 91f080cf051c5e04845a26b4f997d9c8393d4ffc..0de55aa2f4ecdf1759afc35b29dd47c50f0b7318 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php @@ -7,28 +7,13 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\OrderSender; -class OrderSenderTest extends \PHPUnit_Framework_TestCase +class OrderSenderTest extends AbstractSenderTest { /** * @var \Magento\Sales\Model\Order\Email\Sender\OrderSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -39,32 +24,9 @@ class OrderSenderTest extends \PHPUnit_Framework_TestCase */ protected $orderResource; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); + $this->stepMockSetup(); $this->paymentHelper = $this->getMock( '\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], @@ -83,67 +45,33 @@ class OrderSenderTest extends \PHPUnit_Framework_TestCase '', false ); - - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); - - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\OrderIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\OrderIdentity'); $this->sender = new OrderSender( $this->templateContainerMock, $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->paymentHelper, - $this->orderResource + $this->orderResource, + $this->addressRendererMock ); } public function testSendFalse() { + $this->stepAddressFormat($this->addressMock); $result = $this->sender->send($this->orderMock); $this->assertFalse($result); } public function testSendTrueForCustomer() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); + $this->stepAddressFormat($billingAddress); $paymentInfoMock = $this->getMock( '\Magento\Payment\Model\Info', @@ -168,25 +96,12 @@ class OrderSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'payment_html' => 'payment', 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSend($this->once(), $this->once()); $result = $this->sender->send($this->orderMock); $this->assertTrue($result); } @@ -200,7 +115,7 @@ class OrderSenderTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->stepAddressFormat($billingAddress); $billingAddress->expects($this->any()) ->method('getName') ->will($this->returnValue('name')); @@ -234,25 +149,12 @@ class OrderSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'payment_html' => 'payment', 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSend($this->once(), $this->once()); $result = $this->sender->send($this->orderMock); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php index 46c6e7812add026cc51a921703182c69ed5161bd..86bd927b7d6ba1b62d09cbbdfdc5b38e59d4b26d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php @@ -7,38 +7,13 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\ShipmentCommentSender; -class ShipmentCommentSenderTest extends \PHPUnit_Framework_TestCase +class ShipmentCommentSenderTest extends AbstractSenderTest { /** * @var \Magento\Sales\Model\Order\Email\Sender\ShipmentCommentSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -46,56 +21,8 @@ class ShipmentCommentSenderTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); - - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); - - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\ShipmentCommentIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - + $this->stepMockSetup(); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\ShipmentCommentIdentity'); $this->shipmentMock = $this->getMock( '\Magento\Sales\Model\Order\Shipment', ['getStore', '__wakeup', 'getOrder'], @@ -113,27 +40,27 @@ class ShipmentCommentSenderTest extends \PHPUnit_Framework_TestCase $this->sender = new ShipmentCommentSender( $this->templateContainerMock, $this->identityContainerMock, - $this->senderBuilderFactoryMock + $this->senderBuilderFactoryMock, + $this->addressRendererMock ); } public function testSendFalse() { + $this->stepAddressFormat($this->addressMock); $result = $this->sender->send($this->shipmentMock); $this->assertFalse($result); } public function testSendTrueWithCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); + $this->stepAddressFormat($billingAddress); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -148,40 +75,25 @@ class ShipmentCommentSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->never()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithoutSendCopy(); $result = $this->sender->send($this->shipmentMock, true, $comment); $this->assertTrue($result); } public function testSendTrueWithoutCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); + $this->stepAddressFormat($billingAddress); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -196,25 +108,12 @@ class ShipmentCommentSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->never()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithCallSendCopyTo(); $result = $this->sender->send($this->shipmentMock, false, $comment); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php index 24016ede78a4b786ff4b1025f42f7906eb37bfec..c9ca8b266166fcc731241f83d0780a1cbff38837 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php @@ -7,38 +7,13 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; use \Magento\Sales\Model\Order\Email\Sender\ShipmentSender; -class ShipmentSenderTest extends \PHPUnit_Framework_TestCase +class ShipmentSenderTest extends AbstractSenderTest { /** * @var \Magento\Sales\Model\Order\Email\Sender\ShipmentSender */ protected $sender; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $senderBuilderFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $templateContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $identityContainerMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -55,20 +30,7 @@ class ShipmentSenderTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->senderBuilderFactoryMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\SenderBuilderFactory', - ['create'], - [], - '', - false - ); - $this->templateContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\Template', - ['setTemplateVars'], - [], - '', - false - ); + $this->stepMockSetup(); $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false); $this->paymentHelper->expects($this->any()) ->method('getInfoBlockHtml') @@ -82,40 +44,8 @@ class ShipmentSenderTest extends \PHPUnit_Framework_TestCase false ); - $this->storeMock = $this->getMock( - '\Magento\Store\Model\Store', - ['getStoreId', '__wakeup'], - [], - '', - false - ); + $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\ShipmentIdentity'); - $this->identityContainerMock = $this->getMock( - '\Magento\Sales\Model\Order\Email\Container\ShipmentIdentity', - ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'], - [], - '', - false - ); - $this->identityContainerMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); - - $this->orderMock = $this->getMock( - '\Magento\Sales\Model\Order', - [ - 'getStore', 'getBillingAddress', 'getPayment', - '__wakeup', 'getCustomerIsGuest', 'getCustomerName', - 'getCustomerEmail' - ], - [], - '', - false - ); - - $this->orderMock->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->storeMock)); $paymentInfoMock = $this->getMock( '\Magento\Payment\Model\Info', [], @@ -146,27 +76,27 @@ class ShipmentSenderTest extends \PHPUnit_Framework_TestCase $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->paymentHelper, - $this->shipmentResource + $this->shipmentResource, + $this->addressRendererMock ); } public function testSendFalse() { + $this->stepAddressFormat($this->addressMock); $result = $this->sender->send($this->shipmentMock); $this->assertFalse($result); } public function testSendTrueWithCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); + $this->stepAddressFormat($billingAddress); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -182,6 +112,8 @@ class ShipmentSenderTest extends \PHPUnit_Framework_TestCase 'billing' => $billingAddress, 'payment_html' => 'payment', 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); @@ -195,38 +127,20 @@ class ShipmentSenderTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getPayment') ->will($this->returnValue($paymentInfoMock)); - - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->once()) - ->method('send'); - $senderMock->expects($this->never()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithoutSendCopy(); $result = $this->sender->send($this->shipmentMock, true, $comment); $this->assertTrue($result); } public function testSendTrueWithoutCustomerCopy() { - $billingAddress = 'billing_address'; + $billingAddress = $this->addressMock; $comment = 'comment_test'; $this->orderMock->expects($this->once()) ->method('getCustomerIsGuest') ->will($this->returnValue(false)); - $this->orderMock->expects($this->any()) - ->method('getBillingAddress') - ->will($this->returnValue($billingAddress)); + $this->stepAddressFormat($billingAddress); $this->identityContainerMock->expects($this->once()) ->method('isEnabled') @@ -242,25 +156,12 @@ class ShipmentSenderTest extends \PHPUnit_Framework_TestCase 'payment_html' => 'payment', 'comment' => $comment, 'store' => $this->storeMock, + 'formattedShippingAddress' => 1, + 'formattedBillingAddress' => 1 ] ) ); - $senderMock = $this->getMock( - 'Magento\Sales\Model\Order\Email\Sender', - ['send', 'sendCopyTo'], - [], - '', - false - ); - $senderMock->expects($this->never()) - ->method('send'); - $senderMock->expects($this->once()) - ->method('sendCopyTo'); - - $this->senderBuilderFactoryMock->expects($this->once()) - ->method('create') - ->will($this->returnValue($senderMock)); - + $this->stepSendWithCallSendCopyTo(); $result = $this->sender->send($this->shipmentMock, false, $comment); $this->assertTrue($result); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/InfoTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/InfoTest.php new file mode 100644 index 0000000000000000000000000000000000000000..572ea62f5df8232a9ef5c1b895e049ed88ec60be --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/InfoTest.php @@ -0,0 +1,263 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Test\Unit\Model\Order\Payment; + +use Magento\Payment\Model\Method; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class InfoTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Sales\Model\Order\Payment\Info */ + protected $info; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject */ + protected $contextMock; + + /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */ + protected $registryMock; + + /** @var \Magento\Payment\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ + protected $paymentHelperMock; + + /** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $encryptorInterfaceMock; + + /** @var \Magento\Payment\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ + protected $methodInstanceMock; + + protected function setUp() + { + $this->contextMock = $this->getMock('Magento\Framework\Model\Context', [], [], '', false); + $this->registryMock = $this->getMock('Magento\Framework\Registry'); + $this->paymentHelperMock = $this->getMock('Magento\Payment\Helper\Data', ['getMethodInstance'], [], '', false); + $this->encryptorInterfaceMock = $this->getMock( + 'Magento\Framework\Encryption\EncryptorInterface', + [], + [], + '', + false + ); + $this->methodInstanceMock = $this->getMockBuilder('Magento\Payment\Model\MethodInterface') + ->disableOriginalConstructor() + ->setMethods(['setInfoInstance', 'getCode', 'getFormBlockType', 'getTitle']) + ->getMock(); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->info = $this->objectManagerHelper->getObject( + 'Magento\Sales\Model\Order\Payment\Info', + [ + 'context' => $this->contextMock, + 'registry' => $this->registryMock, + 'paymentData' => $this->paymentHelperMock, + 'encryptor' => $this->encryptorInterfaceMock + ] + ); + } + + /** + * @dataProvider ccKeysDataProvider + * @param string $keyCc + * @param string $keyCcEnc + */ + public function testGetDataCcNumber($keyCc, $keyCcEnc) + { + // no data was set + $this->assertNull($this->info->getData($keyCc)); + + // we set encrypted data + $this->info->setData($keyCcEnc, $keyCcEnc); + $this->encryptorInterfaceMock->expects($this->once())->method('decrypt')->with($keyCcEnc)->will( + $this->returnValue($keyCc) + ); + $this->assertEquals($keyCc, $this->info->getData($keyCc)); + } + + /** + * Returns array of Cc keys which needs prepare logic + * + * @return array + */ + public function ccKeysDataProvider() + { + return [ + ['cc_number', 'cc_number_enc'], + ['cc_cid', 'cc_cid_enc'] + ]; + } + + + public function testGetMethodInstanceWithRealMethod() + { + $method = 'real_method'; + $this->info->setData('method', $method); + + $this->methodInstanceMock->expects($this->once()) + ->method('setInfoInstance') + ->with($this->info); + + $this->paymentHelperMock->expects($this->once()) + ->method('getMethodInstance') + ->with($method) + ->willReturn($this->methodInstanceMock); + + $this->info->getMethodInstance(); + } + + + public function testGetMethodInstanceWithUnrealMethod() + { + $method = 'unreal_method'; + $this->info->setData('method', $method); + + $this->paymentHelperMock->expects($this->at(0)) + ->method('getMethodInstance') + ->with($method) + ->willThrowException(new \UnexpectedValueException()); + + $this->methodInstanceMock->expects($this->once()) + ->method('setInfoInstance') + ->with($this->info); + + $this->paymentHelperMock->expects($this->at(1)) + ->method('getMethodInstance') + ->with(Method\Substitution::CODE) + ->willReturn($this->methodInstanceMock); + + $this->info->getMethodInstance(); + } + + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage The payment method you requested is not available. + */ + public function testGetMethodInstanceWithNoMethod() + { + $this->info->setData('method', false); + $this->info->getMethodInstance(); + } + + public function testGetMethodInstanceRequestedMethod() + { + $code = 'real_method'; + $this->info->setData('method', $code); + + $this->paymentHelperMock->expects($this->once()) + ->method('getMethodInstance')->with($code) + ->willReturn($this->methodInstanceMock); + + $this->methodInstanceMock->expects($this->once()) + ->method('setInfoInstance') + ->with($this->info); + + $this->assertSame($this->methodInstanceMock, $this->info->getMethodInstance()); + + // as the method is already stored at Info, check that it's not initialized again + $this->assertSame($this->methodInstanceMock, $this->info->getMethodInstance()); + } + + public function testEncrypt() + { + $data = 'data'; + $encryptedData = 'd1a2t3a4'; + + $this->encryptorInterfaceMock->expects($this->once())->method('encrypt')->with($data)->will( + $this->returnValue($encryptedData) + ); + $this->assertEquals($encryptedData, $this->info->encrypt($data)); + } + + public function testDecrypt() + { + $data = 'data'; + $encryptedData = 'd1a2t3a4'; + + $this->encryptorInterfaceMock->expects($this->once())->method('decrypt')->with($encryptedData)->will( + $this->returnValue($data) + ); + $this->assertEquals($data, $this->info->decrypt($encryptedData)); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testSetAdditionalInformationException() + { + $this->info->setAdditionalInformation('object', new \StdClass()); + } + + /** + * @dataProvider additionalInformationDataProvider + * @param mixed $key + * @param mixed $value + */ + public function testSetAdditionalInformationMultipleTypes($key, $value = null) + { + $this->info->setAdditionalInformation($key, $value); + $this->assertEquals($value ? [$key => $value] : $key, $this->info->getAdditionalInformation()); + } + + /** + * Prepared data for testSetAdditionalInformationMultipleTypes + * + * @return array + */ + public function additionalInformationDataProvider() + { + return [ + [['key1' => 'data1', 'key2' => 'data2'], null], + ['key', 'data'] + ]; + } + + public function testGetAdditionalInformationByKey() + { + $key = 'key'; + $value = 'value'; + $this->info->setAdditionalInformation($key, $value); + $this->assertEquals($value, $this->info->getAdditionalInformation($key)); + } + + public function testUnsAdditionalInformation() + { + // set array to additional + $data = ['key1' => 'data1', 'key2' => 'data2']; + $this->info->setAdditionalInformation($data); + + // unset by key + $this->assertEquals( + ['key2' => 'data2'], + $this->info->unsAdditionalInformation('key1')->getAdditionalInformation() + ); + + // unset all + $this->assertEmpty($this->info->unsAdditionalInformation()->getAdditionalInformation()); + } + + public function testHasAdditionalInformation() + { + $this->assertFalse($this->info->hasAdditionalInformation()); + + $data = ['key1' => 'data1', 'key2' => 'data2']; + $this->info->setAdditionalInformation($data); + $this->assertFalse($this->info->hasAdditionalInformation('key3')); + + $this->assertTrue($this->info->hasAdditionalInformation('key2')); + $this->assertTrue($this->info->hasAdditionalInformation()); + } + + public function testInitAdditionalInformationWithUnserialize() + { + $data = serialize(['key1' => 'data1', 'key2' => 'data2']); + $this->info->setData('additional_information', $data); + + $this->assertEquals(unserialize($data), $this->info->getAdditionalInformation()); + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Pdf/AbstractTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Pdf/AbstractTest.php index 4781b02702a6566913f8535e413f892532ca26ec..abdd2d101a852c7b2d64c6cdf1131a56f400b370 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Pdf/AbstractTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Pdf/AbstractTest.php @@ -22,6 +22,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase // Setup most constructor dependencies $paymentData = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false); + $addressRenderer = $this->getMock('Magento\Sales\Model\Order\Address\Renderer', [], [], '', false); $string = $this->getMock('Magento\Framework\Stdlib\String', [], [], '', false); $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); $translate = $this->getMock('Magento\Framework\Translate\Inline\StateInterface', [], [], '', false); @@ -87,7 +88,8 @@ class AbstractTest extends \PHPUnit_Framework_TestCase $pdfTotalFactory, $pdfItemsFactory, $localeMock, - $translate + $translate, + $addressRenderer ], '', true, diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/AddressTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/AddressTest.php index 6dee39fe4ccb08fcef1111f38a37f35afec074f1..92b3222098a503419e18d1978c44f998fb18c0e7 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/AddressTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/AddressTest.php @@ -45,6 +45,11 @@ class AddressTest extends \PHPUnit_Framework_TestCase */ protected $gridPoolMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; + public function setUp() { $this->addressMock = $this->getMock( @@ -89,6 +94,13 @@ class AddressTest extends \PHPUnit_Framework_TestCase '', false ); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); $this->appResourceMock->expects($this->any()) ->method('getConnection') ->will($this->returnValue($this->adapterMock)); @@ -105,7 +117,8 @@ class AddressTest extends \PHPUnit_Framework_TestCase [ 'resource' => $this->appResourceMock, 'validator' => $this->validatorMock, - 'gridPool' => $this->gridPoolMock + 'gridPool' => $this->gridPoolMock, + 'entitySnapshot' => $this->entitySnapshotMock ] ); } @@ -119,9 +132,10 @@ class AddressTest extends \PHPUnit_Framework_TestCase ->method('validate') ->with($this->equalTo($this->addressMock)) ->will($this->returnValue([])); - $this->addressMock->expects($this->any()) - ->method('hasDataChanges') - ->will($this->returnValue(true)); + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->addressMock) + ->willReturn(true); $this->addressMock->expects($this->exactly(2)) ->method('getOrder') ->will($this->returnValue($this->orderMock)); @@ -147,6 +161,10 @@ class AddressTest extends \PHPUnit_Framework_TestCase */ public function testSaveValidationFailed() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->addressMock) + ->willReturn(true); $this->addressMock->expects($this->any()) ->method('hasDataChanges') ->will($this->returnValue(true)); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Creditmemo/CommentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Creditmemo/CommentTest.php index 9044816b53549032f2220ddf349da33b82ef11ba..cb90e1429574daec837ab14470e58f5685eb192f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Creditmemo/CommentTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Creditmemo/CommentTest.php @@ -34,6 +34,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase * @var \Magento\Sales\Model\Order\Creditmemo\Comment\Validator|\PHPUnit_Framework_MockObject_MockObject */ protected $validatorMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; /** * Set up @@ -68,6 +72,14 @@ class CommentTest extends \PHPUnit_Framework_TestCase '', false ); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); + $this->appResourceMock->expects($this->any()) ->method('getConnection') ->will($this->returnValue($this->adapterMock)); @@ -98,7 +110,8 @@ class CommentTest extends \PHPUnit_Framework_TestCase 'Magento\Sales\Model\Resource\Order\Creditmemo\Comment', [ 'context' => $contextMock, - 'validator' => $this->validatorMock + 'validator' => $this->validatorMock, + 'entitySnapshot' => $this->entitySnapshotMock ] ); } @@ -112,7 +125,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase ->method('validate') ->with($this->equalTo($this->commentModelMock)) ->will($this->returnValue([])); - + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->commentModelMock) + ->willReturn(true); $this->commentModelMock->expects($this->any())->method('getData')->willReturn([]); $this->commentResource->save($this->commentModelMock); $this->assertTrue(true); @@ -126,6 +142,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase */ public function testSaveValidationFailed() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->commentModelMock) + ->willReturn(true); $this->validatorMock->expects($this->once()) ->method('validate') ->with($this->equalTo($this->commentModelMock)) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Invoice/CommentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Invoice/CommentTest.php index 64fd731a9a21c02c4feb22e1d9ac526ac35a9105..307b36d867efaf5e2d92b2b1c2bd54fb00147493 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Invoice/CommentTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Invoice/CommentTest.php @@ -34,6 +34,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase * @var \Magento\Sales\Model\Order\Invoice\Comment\Validator|\PHPUnit_Framework_MockObject_MockObject */ protected $validatorMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; /** * Set up @@ -68,6 +72,13 @@ class CommentTest extends \PHPUnit_Framework_TestCase '', false ); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); $this->appResourceMock->expects($this->any()) ->method('getConnection') ->will($this->returnValue($this->adapterMock)); @@ -98,7 +109,8 @@ class CommentTest extends \PHPUnit_Framework_TestCase 'Magento\Sales\Model\Resource\Order\Invoice\Comment', [ 'context' => $contextMock, - 'validator' => $this->validatorMock + 'validator' => $this->validatorMock, + 'entitySnapshot' => $this->entitySnapshotMock ] ); } @@ -108,6 +120,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase */ public function testSave() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->commentModelMock) + ->willReturn(true); $this->validatorMock->expects($this->once()) ->method('validate') ->with($this->equalTo($this->commentModelMock)) @@ -125,6 +141,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase */ public function testSaveValidationFailed() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->commentModelMock) + ->willReturn(true); $this->validatorMock->expects($this->once()) ->method('validate') ->with($this->equalTo($this->commentModelMock)) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/CommentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/CommentTest.php index 3a13ca729f6c53154651e11e9979ca290240e2d7..bc6d3793a0621a69cc068d564fb0c267c1bdee8c 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/CommentTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/CommentTest.php @@ -34,6 +34,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase * @var \Magento\Sales\Model\Order\Shipment\Comment\Validator|\PHPUnit_Framework_MockObject_MockObject */ protected $validatorMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; /** * Set up @@ -68,6 +72,13 @@ class CommentTest extends \PHPUnit_Framework_TestCase '', false ); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); $this->appResourceMock->expects($this->any()) ->method('getConnection') ->will($this->returnValue($this->adapterMock)); @@ -98,7 +109,8 @@ class CommentTest extends \PHPUnit_Framework_TestCase 'Magento\Sales\Model\Resource\Order\Shipment\Comment', [ 'context' => $contextMock, - 'validator' => $this->validatorMock + 'validator' => $this->validatorMock, + 'entitySnapshot' => $this->entitySnapshotMock ] ); } @@ -108,6 +120,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase */ public function testSave() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->commentModelMock) + ->willReturn(true); $this->validatorMock->expects($this->once()) ->method('validate') ->with($this->equalTo($this->commentModelMock)) @@ -125,6 +141,10 @@ class CommentTest extends \PHPUnit_Framework_TestCase */ public function testSaveValidationFailed() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->commentModelMock) + ->willReturn(true); $this->validatorMock->expects($this->once()) ->method('validate') ->with($this->equalTo($this->commentModelMock)) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/TrackTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/TrackTest.php index f4a4c554c5e2ff0568e9dae503ad453c4158c09d..d9c4b184b6c3812fa386c4489fc7e13f4504f55d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/TrackTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Shipment/TrackTest.php @@ -34,6 +34,10 @@ class TrackTest extends \PHPUnit_Framework_TestCase * @var \Magento\Sales\Model\Order\Shipment\Track\Validator|\PHPUnit_Framework_MockObject_MockObject */ protected $validatorMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; /** * Set up @@ -68,6 +72,13 @@ class TrackTest extends \PHPUnit_Framework_TestCase '', false ); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); $this->appResourceMock->expects($this->any()) ->method('getConnection') ->will($this->returnValue($this->adapterMock)); @@ -98,7 +109,8 @@ class TrackTest extends \PHPUnit_Framework_TestCase 'Magento\Sales\Model\Resource\Order\Shipment\Track', [ 'context' => $contextMock, - 'validator' => $this->validatorMock + 'validator' => $this->validatorMock, + 'entitySnapshot' => $this->entitySnapshotMock ] ); } @@ -108,6 +120,10 @@ class TrackTest extends \PHPUnit_Framework_TestCase */ public function testSave() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->trackModelMock) + ->willReturn(true); $this->validatorMock->expects($this->once()) ->method('validate') ->with($this->equalTo($this->trackModelMock)) @@ -125,6 +141,10 @@ class TrackTest extends \PHPUnit_Framework_TestCase */ public function testSaveValidationFailed() { + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->trackModelMock) + ->willReturn(true); $this->validatorMock->expects($this->once()) ->method('validate') ->with($this->equalTo($this->trackModelMock)) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/History/CollectionTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/History/CollectionTest.php index e08aac0fcea7079e7b0eeca8da3ac08ae6cc430b..f2390ca68cd4b6a1843f8172ee231a95f3aa8fb1 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/History/CollectionTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/History/CollectionTest.php @@ -47,6 +47,10 @@ class CollectionTest extends \PHPUnit_Framework_TestCase * @var \Magento\Framework\Data\Collection\EntityFactory|\PHPUnit_Framework_MockObject_MockObject */ protected $entityFactoryMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; public function setUp() { @@ -55,7 +59,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $this->selectMock = $this->getMock('Zend_Db_Select', [], [], '', false); $this->historyItemMock = $this->getMock( 'Magento\Sales\Model\Order\Status\History', - ['__wakeup', 'addData'], + ['__wakeup', 'setData'], [], '', false @@ -69,6 +73,13 @@ class CollectionTest extends \PHPUnit_Framework_TestCase true, ['getReadConnection', 'getMainTable', 'getTable', '__wakeup'] ); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); $this->fetchStrategyMock = $this->getMockForAbstractClass( 'Magento\Framework\Data\Collection\Db\FetchStrategyInterface' ); @@ -86,7 +97,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $data = [['data']]; $this->historyItemMock->expects($this->once()) - ->method('addData') + ->method('setData') ->with($this->equalTo($data[0])) ->will($this->returnValue($this->historyItemMock)); @@ -104,6 +115,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $logger, $this->fetchStrategyMock, $this->eventManagerMock, + $this->entitySnapshotMock, $this->connectionMock, $this->resourceMock ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/HistoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/HistoryTest.php index c97592239333231d7f6333e1facab999fbc84df1..eced486c174c08fccd775c5540d6f16a6b34c624 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/HistoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/Order/Status/HistoryTest.php @@ -36,6 +36,11 @@ class HistoryTest extends \PHPUnit_Framework_TestCase */ protected $validatorMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; + public function setUp() { $this->appResourceMock = $this->getMock( @@ -59,6 +64,13 @@ class HistoryTest extends \PHPUnit_Framework_TestCase '', false ); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); $this->appResourceMock->expects($this->any()) ->method('getConnection') ->will($this->returnValue($this->adapterMock)); @@ -87,7 +99,8 @@ class HistoryTest extends \PHPUnit_Framework_TestCase 'Magento\Sales\Model\Resource\Order\Status\History', [ 'context' => $contextMock, - 'validator' => $this->validatorMock + 'validator' => $this->validatorMock, + 'entitySnapshot' => $this->entitySnapshotMock ] ); } @@ -104,7 +117,7 @@ class HistoryTest extends \PHPUnit_Framework_TestCase '', false ); - $historyMock->expects($this->any())->method('hasDataChanges')->will($this->returnValue(true)); + $this->entitySnapshotMock->expects($this->once())->method('isModified')->with($historyMock)->willReturn(true); $historyMock->expects($this->any())->method('isSaveAllowed')->will($this->returnValue(true)); $this->validatorMock->expects($this->once()) ->method('validate') @@ -128,7 +141,7 @@ class HistoryTest extends \PHPUnit_Framework_TestCase '', false ); - $historyMock->expects($this->any())->method('hasDataChanges')->will($this->returnValue(true)); + $this->entitySnapshotMock->expects($this->once())->method('isModified')->with($historyMock)->willReturn(true); $historyMock->expects($this->any())->method('isSaveAllowed')->will($this->returnValue(true)); $this->validatorMock->expects($this->once()) ->method('validate') diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php index 6819c63725246e283b3ed876a3695d00384e45d2..efeb4c7fd5abd00c11b94d99f8a2f31996c43125 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php @@ -36,9 +36,17 @@ class OrderTest extends \PHPUnit_Framework_TestCase */ protected $stateHandlerMock; /** - * @var \Magento\Sales\Model\Increment|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\SalesSequence\Model\Manager|\PHPUnit_Framework_MockObject_MockObject */ - protected $salesIncrementMock; + protected $salesSequenceManagerMock; + /** + * @var \Magento\SalesSequence\Model\Sequence|\PHPUnit_Framework_MockObject_MockObject + */ + protected $salesSequenceMock; + /** + * @var \Magento\Sales\Model\Resource\Order\Grid|\PHPUnit_Framework_MockObject_MockObject + */ + protected $gridAggregatorMock; /** * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject */ @@ -75,6 +83,10 @@ class OrderTest extends \PHPUnit_Framework_TestCase * @var \Magento\Framework\DB\Adapter\Pdo\Mysql|\PHPUnit_Framework_MockObject_MockObject */ protected $adapterMock; + /** + * @var \Magento\Sales\Model\Resource\EntitySnapshot|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entitySnapshotMock; /** * Mock class dependencies @@ -92,6 +104,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase ); $this->stateHandlerMock = $this->getMock('Magento\Sales\Model\Resource\Order\Handler\State', [], [], '', false); $this->salesIncrementMock = $this->getMock('Magento\Sales\Model\Increment', [], [], '', false); + $this->gridAggregatorMock = $this->getMock('Magento\Sales\Model\Resource\Order\Grid', [], [], '', false); $this->orderMock = $this->getMock( 'Magento\Sales\Model\Order', [], @@ -140,14 +153,29 @@ class OrderTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->salesSequenceManagerMock = $this->getMock( + 'Magento\SalesSequence\Model\Manager', + [], + [], + '', + false + ); + $this->salesSequenceMock = $this->getMock('Magento\SalesSequence\Sequence', [], [], '', false); + $this->entitySnapshotMock = $this->getMock( + 'Magento\Sales\Model\Resource\EntitySnapshot', + [], + [], + '', + false + ); $contextMock = $this->getMock('\Magento\Framework\Model\Resource\Db\Context', [], [], '', false); $contextMock->expects($this->once())->method('getResources')->willReturn($this->resourceMock); $this->resource = new Order( $contextMock, $this->attributeMock, - $this->salesIncrementMock, + $this->salesSequenceManagerMock, + $this->entitySnapshotMock, $this->addressHandlerMock, $this->stateHandlerMock ); @@ -170,7 +198,10 @@ class OrderTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->any()) ->method('getId') ->will($this->returnValue(1)); - $this->orderMock->expects($this->once())->method('hasDataChanges')->will($this->returnValue(true)); + $this->entitySnapshotMock->expects($this->once()) + ->method('isModified') + ->with($this->orderMock) + ->will($this->returnValue(true)); $this->resource->save($this->orderMock); } } diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json index 31b8dbf81c00ce7e59155bcdfb5e8a1bf8edef0e..47bb69b77715bc4807544e926ddbc3babe534bfd 100644 --- a/app/code/Magento/Sales/composer.json +++ b/app/code/Magento/Sales/composer.json @@ -3,34 +3,35 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-authorization": "0.74.0-beta2", - "magento/module-payment": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-sales-rule": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-gift-message": "0.74.0-beta2", - "magento/module-reports": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-wishlist": "0.74.0-beta2", - "magento/module-email": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-ui": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-authorization": "0.74.0-beta3", + "magento/module-payment": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-sales-rule": "0.74.0-beta3", + "magento/module-sales-sequence": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-gift-message": "0.74.0-beta3", + "magento/module-reports": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-wishlist": "0.74.0-beta3", + "magento/module-email": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-ui": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index b30edfeb3afc1280ce7cc77f844c982b51110c10..ba45f06f9d73eed3c92d5d35faaaf5210363d158 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -157,4 +157,14 @@ <argument name="entityGrid" xsi:type="object">Magento\Sales\Model\Resource\Order\Creditmemo\Grid</argument> </arguments> </virtualType> + <type name="Magento\SalesSequence\Model\EntityPool"> + <arguments> + <argument name="entities" xsi:type="array"> + <item name="order" xsi:type="string">order</item> + <item name="invoice" xsi:type="string">invoice</item> + <item name="creditmemo" xsi:type="string">creditmemo</item> + <item name="shipment" xsi:type="string">shipment</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Sales/etc/events.xml b/app/code/Magento/Sales/etc/events.xml index 7829d98ef926c6c14de526616d7ca5213d61827a..1260e97f8d9d48c95b7e9e77102267339abefcc6 100644 --- a/app/code/Magento/Sales/etc/events.xml +++ b/app/code/Magento/Sales/etc/events.xml @@ -39,4 +39,7 @@ <observer name="sales_grid_order_shipment_async_insert" instance="Magento\Sales\Model\Observer\Order\Shipment\IndexGrid" method="asyncInsert" /> <observer name="sales_grid_order_creditmemo_async_insert" instance="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" method="asyncInsert" /> </event> + <event name="store_add"> + <observer name="magento_sequence" instance="Magento\SalesSequence\Model\Observer" method="execute" /> + </event> </config> diff --git a/app/code/Magento/Sales/etc/module.xml b/app/code/Magento/Sales/etc/module.xml index 90aa0777f18f1719f61c05970857a20669d7163b..eb894f667baef8cdb7b1214aec572f7660e00f50 100644 --- a/app/code/Magento/Sales/etc/module.xml +++ b/app/code/Magento/Sales/etc/module.xml @@ -6,12 +6,13 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> - <module name="Magento_Sales" setup_version="2.0.2"> + <module name="Magento_Sales" setup_version="2.0.3"> <sequence> <module name="Magento_Rule"/> <module name="Magento_Catalog"/> <module name="Magento_Customer"/> <module name="Magento_Payment"/> + <module name="Magento_SalesSequence"/> </sequence> </module> </config> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml index fbcdaf14723840f56efa7b8ea620fd93f629d4f1..1ab29b8edab244721e0ea0359093ca425a3fc779 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml @@ -10,8 +10,16 @@ <?php /** @var $block \Magento\Sales\Block\Adminhtml\Order\View\Info */ ?> <?php $_order = $block->getOrder() ?> <?php -$orderAdminDate = $block->formatDate($_order->getCreatedAtDate(), \IntlDateFormatter::MEDIUM, true); -$orderStoreDate = $block->formatDate($_order->getCreatedAtStoreDate(), \IntlDateFormatter::MEDIUM, true); +$orderAdminDate = $block->formatDate( + $block->getOrderAdminDate($_order->getCreatedAt()), + \IntlDateFormatter::MEDIUM, + true +); +$orderStoreDate = $block->formatDate( + $block->getCreatedAtStoreDate($_order->getStore(), $_order->getCreatedAt()), + \IntlDateFormatter::MEDIUM, + true +); ?> <?php /* the opening and closing divs of these two clearfixes are in app\code\core\Mage\Adminhtml\view\adminhtml\sales\order\invoice\create\form.phtml */?> @@ -43,7 +51,13 @@ $orderStoreDate = $block->formatDate($_order->getCreatedAtStoreDate(), \IntlDate </tr> <?php if ($orderAdminDate != $orderStoreDate):?> <tr> - <th><?php echo __('Order Date (%1)', $_order->getCreatedAtStoreDate()->getTimezone()->getName()) ?></th> + <th><?php echo __( + 'Order Date (%1)', + $block->getCreatedAtStoreDate( + $_order->getStore(), + $_order->getCreatedAt() + )->getTimezone()->getName() + ) ?></th> <td><?php echo $orderStoreDate ?></td> </tr> <?php endif;?> @@ -144,7 +158,7 @@ $orderStoreDate = $block->formatDate($_order->getCreatedAtStoreDate(), \IntlDate <div class="actions"><?php echo $block->getAddressEditLink($_order->getBillingAddress()); ?></div> <span class="title"><?php echo __('Billing Address') ?></span> </div> - <address><?php echo $_order->getBillingAddress()->format('html') ?></address> + <address><?php echo $block->getFormattedAddress($_order->getBillingAddress()); ?></address> </div> </div> @@ -156,7 +170,7 @@ $orderStoreDate = $block->formatDate($_order->getCreatedAtStoreDate(), \IntlDate <div class="actions"><?php echo $block->getAddressEditLink($_order->getShippingAddress()); ?></div> <span class="title"><?php echo __('Shipping Address') ?></span> </div> - <address><?php echo $_order->getShippingAddress()->format('html') ?></address> + <address><?php echo $block->getFormattedAddress($_order->getShippingAddress()); ?></address> </div> </div> </div> diff --git a/app/code/Magento/Sales/view/email/creditmemo_new.html b/app/code/Magento/Sales/view/email/creditmemo_new.html index 9fd0a0770fbdeb3766d397e1a2cfed1268ffd4dc..c37e42e9c96f5c8f9f84106c7fb53d77ac466ff9 100644 --- a/app/code/Magento/Sales/view/email/creditmemo_new.html +++ b/app/code/Magento/Sales/view/email/creditmemo_new.html @@ -14,9 +14,9 @@ "store url=\"customer/account/\"":"Customer Account Url", "var creditmemo.increment_id":"Credit Memo Id", "var order.increment_id":"Order Id", -"var order.billing_address.format('html')":"Billing Address", -"payment_html":"Payment Details", -"var order.shipping_address.format('html')":"Shipping Address", +"var formattedBillingAddress":"Billing Address", +"var payment_html":"Payment Details", +"var formattedShippingAddress":"Shipping Address", "var order.shipping_description":"Shipping Description", "layout handle=\"sales_email_order_creditmemo_items\" creditmemo=$creditmemo order=$order":"Credit Memo Items Grid", "var comment":"Credit Memo Comment"} @@ -64,7 +64,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.billing_address.format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -86,7 +86,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.shipping_address.format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/email/creditmemo_new_guest.html b/app/code/Magento/Sales/view/email/creditmemo_new_guest.html index ffccaebc7c765f96eda2dddb3df32f24b93b5d38..2d91c7aa04834b2b349f88b2bf9bf818dc4878db 100644 --- a/app/code/Magento/Sales/view/email/creditmemo_new_guest.html +++ b/app/code/Magento/Sales/view/email/creditmemo_new_guest.html @@ -13,9 +13,9 @@ "var store.getFrontendName()":"Store Name", "var creditmemo.increment_id":"Credit Memo Id", "var order.increment_id":"Order Id", -"var order.billing_address.format('html')":"Billing Address", +"var formattedBillingAddress":"Billing Address", "var payment_html":"Payment Details", -"var order.shipping_address.format('html')":"Shipping Address", +"var formattedShippingAddress":"Shipping Address", "var order.shipping_description":"Shipping Description", "layout handle=\"sales_email_order_creditmemo_items\" creditmemo=$creditmemo order=$order":"Credit Memo Items Grid", "var comment":"Credit Memo Comment"} @@ -62,7 +62,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.billing_address.format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -84,7 +84,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.shipping_address.format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/email/invoice_new.html b/app/code/Magento/Sales/view/email/invoice_new.html index 12ae780cc0682a618cf54e8a3774d3b1ca61e5c0..b9b8d8bfb2a7e36aa31b71a7410c20d897af14cf 100644 --- a/app/code/Magento/Sales/view/email/invoice_new.html +++ b/app/code/Magento/Sales/view/email/invoice_new.html @@ -14,9 +14,9 @@ "store url=\"customer/account/\"":"Customer Account Url", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.billing_address.format('html')":"Billing Address", +"var formattedBillingAddress":"Billing Address", "var payment_html":"Payment Details", -"var order.shipping_address.format('html')":"Shipping Address", +"var formattedShippingAddress":"Shipping Address", "var order.shipping_description":"Shipping Description", "layout area=\"frontend\" handle=\"sales_email_order_invoice_items\" invoice=$invoice order=$order":"Invoice Items Grid", "var comment":"Invoice Comment"} @@ -64,7 +64,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.billing_address.format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -86,7 +86,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.shipping_address.format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/email/invoice_new_guest.html b/app/code/Magento/Sales/view/email/invoice_new_guest.html index 634193321aa00f815660f5f142c20b09706c1725..99511adf65684a47c2156e54a812770fb7eaa0a1 100644 --- a/app/code/Magento/Sales/view/email/invoice_new_guest.html +++ b/app/code/Magento/Sales/view/email/invoice_new_guest.html @@ -13,9 +13,9 @@ "var store.getFrontendName()":"Store Name", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.billing_address.format('html')":"Billing Address", +"var formattedBillingAddress":"Billing Address", "var payment_html":"Payment Details", -"var order.shipping_address.format('html')":"Shipping Address", +"var formattedShippingAddress":"Shipping Address", "var order.shipping_description":"Shipping Description", "layout handle=\"sales_email_order_invoice_items\" invoice=$invoice order=$order":"Invoice Items Grid", "var comment":"Invoice Comment"} @@ -62,7 +62,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.billing_address.format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -84,7 +84,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.shipping_address.format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/email/order_new.html b/app/code/Magento/Sales/view/email/order_new.html index 0063a9e6b6130d7da0283b378463feb0fec1f075..74948c978587e8a9d5bb2acd80004ee8e0cafaee 100644 --- a/app/code/Magento/Sales/view/email/order_new.html +++ b/app/code/Magento/Sales/view/email/order_new.html @@ -14,9 +14,9 @@ "store url=\"customer/account/\"":"Customer Account Url", "var order.increment_id":"Order Id", "var order.getCreatedAtFormated(1)":"Order Created At (datetime)", -"var order.getBillingAddress().format('html')":"Billing Address", +"var formattedBillingAddress":"Billing Address", "var payment_html":"Payment Details", -"var order.getShippingAddress().format('html')":"Shipping Address", +"var formattedShippingAddress":"Shipping Address", "var order.getShippingDescription()":"Shipping Description", "layout handle=\"sales_email_order_items\" order=$order":"Order Items Grid", "var order.getEmailCustomerNote()":"Email Order Note"} @@ -66,7 +66,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.getBillingAddress().format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -88,7 +88,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.getShippingAddress().format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/email/order_new_guest.html b/app/code/Magento/Sales/view/email/order_new_guest.html index 202714ed9b56b496a24d432f14c76ee22abe2af2..ae97a164c268e1235e69f02b65f7d49fc10210fb 100644 --- a/app/code/Magento/Sales/view/email/order_new_guest.html +++ b/app/code/Magento/Sales/view/email/order_new_guest.html @@ -13,9 +13,9 @@ "var store.getFrontendName()":"Store Name", "var order.increment_id":"Order Id", "var order.getCreatedAtFormated(1)":"Order Created At (datetime)", -"var order.getBillingAddress().format('html')":"Billing Address", +"var formattedBillingAddress":"Billing Address", "var payment_html":"Payment Details", -"var order.getShippingAddress().format('html')":"Shipping Address", +"var formattedShippingAddress":"Shipping Address", "var order.getShippingDescription()":"Shipping Description", "layout handle=\"sales_email_order_items\" order=$order":"Order Items Grid", "var order.getEmailCustomerNote()":"Email Order Note"} @@ -64,7 +64,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.getBillingAddress().format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -86,7 +86,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.getShippingAddress().format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/email/shipment_new.html b/app/code/Magento/Sales/view/email/shipment_new.html index a4f948c887a47a03bba1d29345fbe10c4a92a3e7..99537c6ebb4bd1a53cc46d5fb221106094db632c 100644 --- a/app/code/Magento/Sales/view/email/shipment_new.html +++ b/app/code/Magento/Sales/view/email/shipment_new.html @@ -14,9 +14,9 @@ "store url=\"customer/account/\"":"Customer Account Url", "var shipment.increment_id":"Shipment Id", "var order.increment_id":"Order Id", -"var order.billing_address.format('html')":"Billing Address", +"var formattedBillingAddress":"Billing Address", "var payment_html":"Payment Details", -"var order.shipping_address.format('html')":"Shipping Address", +"var formattedShippingAddress":"Shipping Address", "var order.shipping_description":"Shipping Description", "layout handle=\"sales_email_order_shipment_items\" shipment=$shipment order=$order":"Shipment Items Grid", "block type='Magento\\Framework\\View\\Element\\Template' area='frontend' template='email/shipment/track.phtml' shipment=$shipment order=$order":"Shipment Track Details", @@ -68,7 +68,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.billing_address.format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -89,7 +89,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.shipping_address.format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/email/shipment_new_guest.html b/app/code/Magento/Sales/view/email/shipment_new_guest.html index 0a94cfdb194a70cb304381ee8ca99ae43b78212e..bdd9a0cb88d5850ac266c8fe950fea28cc07c6b9 100644 --- a/app/code/Magento/Sales/view/email/shipment_new_guest.html +++ b/app/code/Magento/Sales/view/email/shipment_new_guest.html @@ -13,9 +13,9 @@ "var store.getFrontendName()":"Store Name", "var shipment.increment_id":"Shipment Id", "var order.increment_id":"Order Id", -"var order.billing_address.format('html')":"Billing Address", +"var formattedBillingAddress":"Billing Address", "var payment_html":"Payment Details", -"var order.shipping_address.format('html')":"Shipping Address", +"var formattedShippingAddress":"Shipping Address", "var order.shipping_description":"Shipping Description", "layout handle=\"sales_email_order_shipment_items\" shipment=$shipment order=$order":"Shipment Items Grid", "block type='Magento\\Framework\\View\\Element\\Template' area='frontend' template='email/shipment/track.phtml' shipment=$shipment order=$order":"Shipment Track Details", @@ -66,7 +66,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.billing_address.format('html')}} + {{var formattedBillingAddress }} </td> <td> </td> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> @@ -87,7 +87,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; <tbody> <tr> <td valign="top" style="font-size:12px; padding:7px 9px 9px 9px; border-left:1px solid #EAEAEA; border-bottom:1px solid #EAEAEA; border-right:1px solid #EAEAEA;"> - {{var order.shipping_address.format('html')}} + {{var formattedShippingAddress }} </td> <td> </td> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/info.phtml b/app/code/Magento/Sales/view/frontend/templates/order/info.phtml index f7c8fe0c86f44d1e9a639263cb8cf9440c950feb..8ce77fbece84951fe27eccaaf11a000396919f59 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/info.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/info.phtml @@ -18,7 +18,7 @@ <div class="box box-order-shipping-address"> <strong class="box-title"><span><?php echo __('Shipping Address') ?></span></strong> <div class="box-content"> - <address><?php echo $_order->getShippingAddress()->format('html') ?></address> + <address><?php echo $block->getFormattedAddress($_order->getShippingAddress()); ?></address> </div> </div> @@ -41,7 +41,7 @@ <span><?php echo __('Billing Address') ?></span> </strong> <div class="box-content"> - <address><?php echo $_order->getBillingAddress()->format('html') ?></address> + <address><?php echo $block->getFormattedAddress($_order->getBillingAddress()); ?></address> </div> </div> <div class="box box-order-billing-method"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml b/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml index a4cc429892a3e1b5c045bd853c216e8e26d498d1..dddc81402d8fa283149a923bcd168d62bebc50eb 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml @@ -60,7 +60,7 @@ </div> <div class="box-content"> <?php $_shipping = $_creditmemo->getShippingAddress() ?> - <address><?php echo $_shipping->format('html') ?></address> + <address><?php echo $block->formatAddress($_shipping, 'html') ?></address> </div> </div> <div class="box box-order-shipping-method"> @@ -78,7 +78,7 @@ </div> <div class="box-content"> <?php $_billing = $_creditmemo->getbillingAddress() ?> - <address><?php echo $_order->getBillingAddress()->format('html') ?></address> + <address><?php echo $block->formatAddress($_order->getBillingAddress(), 'html') ?></address> </div> </div> <div class="box box-order-billing-method"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml b/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml index dcf73da37081fd209aa6221bdba273015c0ce8a8..191dbdb8bdeba59fecc485347693d3243579c0ea 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml @@ -58,7 +58,7 @@ </div> <div class="box-content"> <?php $_shipping = $_invoice->getShippingAddress() ?> - <address><?php echo $_shipping->format('html') ?></address> + <address><?php echo $block->formatAddress($_shipping, 'html') ?></address> </div> </div> @@ -81,7 +81,7 @@ </div> <div class="box-content"> <?php $_billing = $_invoice->getbillingAddress() ?> - <address><?php echo $_order->getBillingAddress()->format('html') ?></address> + <address><?php echo $block->formatAddress($_order->getBillingAddress(), 'html') ?></address> </div> </div> diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json index e51f138d4a36c70bcfdda1c4bc5f7575a53c9bfb..880e3c7ee570e7be32266054846b00fb02914a07 100644 --- a/app/code/Magento/SalesRule/composer.json +++ b/app/code/Magento/SalesRule/composer.json @@ -3,26 +3,26 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-rule": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-payment": "0.74.0-beta2", - "magento/module-reports": "0.74.0-beta2", - "magento/module-catalog-rule": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-rule": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-payment": "0.74.0-beta3", + "magento/module-reports": "0.74.0-beta3", + "magento/module-catalog-rule": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/SalesSequence/LICENSE.txt b/app/code/Magento/SalesSequence/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..49525fd99da9c51e6d85420266d41cb3d6b7a648 --- /dev/null +++ b/app/code/Magento/SalesSequence/LICENSE.txt @@ -0,0 +1,48 @@ + +Open Software License ("OSL") v. 3.0 + +This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Open Software License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/app/code/Magento/SalesSequence/LICENSE_AFL.txt b/app/code/Magento/SalesSequence/LICENSE_AFL.txt new file mode 100644 index 0000000000000000000000000000000000000000..87943b95d43a5bb8736093275afe3cb8e1d93d26 --- /dev/null +++ b/app/code/Magento/SalesSequence/LICENSE_AFL.txt @@ -0,0 +1,48 @@ + +Academic Free License ("AFL") v. 3.0 + +This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Academic Free License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/app/code/Magento/SalesSequence/Model/Builder.php b/app/code/Magento/SalesSequence/Model/Builder.php new file mode 100644 index 0000000000000000000000000000000000000000..2e7a1cda6798f150f7e5288cfebbcc291ba653f6 --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Builder.php @@ -0,0 +1,265 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +use Magento\Framework\Webapi\Exception; +use Magento\SalesSequence\Model\Resource\Meta as ResourceMetadata; +use Magento\Framework\App\Resource as AppResource; +use Magento\Framework\DB\Ddl\Sequence as DdlSequence; +use Psr\Log\LoggerInterface as Logger; + +/** + * Class Builder + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Builder +{ + /** + * @var resourceMetadata + */ + protected $resourceMetadata; + + /** + * @var ProfileFactory + */ + protected $profileFactory; + + /** + * @var MetaFactory + */ + protected $metaFactory; + + /** + * @var AppResource + */ + protected $appResource; + + /** + * @var DdlSequence + */ + protected $ddlSequence; + + /** + * List of required sequence attribute + * + * @var array + */ + protected $required = [ + 'entityType', + 'storeId' + ]; + + /** + * Default pattern for sequence creation, full list of attributes that can be defined by customer + * + * @var array + */ + protected $pattern = [ + 'entity_type', + 'store_id', + 'prefix', + 'suffix', + 'start_value', + 'step', + 'max_value', + 'warning_value', + ]; + + /** + * Concrete data of sequence + * + * @var array + */ + protected $data = []; + + /** + * @var Logger + */ + protected $logger; + + /** + * @param ResourceMetadata $resourceMetadata + * @param MetaFactory $metaFactory + * @param ProfileFactory $profileFactory + * @param AppResource $appResource + * @param DdlSequence $ddlSequence + * @param Logger $logger + */ + public function __construct( + ResourceMetadata $resourceMetadata, + MetaFactory $metaFactory, + ProfileFactory $profileFactory, + AppResource $appResource, + DdlSequence $ddlSequence, + Logger $logger + ) { + $this->resourceMetadata = $resourceMetadata; + $this->metaFactory = $metaFactory; + $this->profileFactory = $profileFactory; + $this->appResource = $appResource; + $this->ddlSequence = $ddlSequence; + $this->logger = $logger; + $this->data = array_flip($this->pattern); + } + + + /** + * @param string $entityType + * @return $this + */ + public function setEntityType($entityType) + { + $this->data['entity_type'] = $entityType; + return $this; + } + + /** + * @param int $storeId + * @return $this + */ + public function setStoreId($storeId) + { + $this->data['store_id'] = $storeId; + return $this; + } + + /** + * @param string $prefix + * @return $this + */ + public function setPrefix($prefix) + { + $this->data['prefix'] = $prefix; + return $this; + } + + /** + * @param string $suffix + * @return $this + */ + public function setSuffix($suffix) + { + $this->data['suffix'] = $suffix; + return $this; + } + + /** + * @param int $startValue + * @return $this + */ + public function setStartValue($startValue) + { + $this->data['start_value'] = $startValue; + return $this; + } + + /** + * @param int $step + * @return $this + */ + public function setStep($step) + { + $this->data['step'] = $step; + return $this; + } + + /** + * @param int $maxValue + * @return $this + */ + public function setMaxValue($maxValue) + { + $this->data['max_value'] = $maxValue; + return $this; + } + + /** + * @param int $warningValue + * @return $this + */ + public function setWarningValue($warningValue) + { + $this->data['warning_value'] = $warningValue; + return $this; + } + + /** + * Returns sequence table name + * + * @return string + */ + protected function getSequenceName() + { + return $this->appResource->getTableName( + sprintf( + 'sequence_%s_%s', + $this->data['entity_type'], + $this->data['store_id'] + ) + ); + } + + /** + * Create sequence with metadata and profile + * + * @throws \Exception + * @throws \Magento\Framework\Exception\AlreadyExistsException + * @return void + */ + public function create() + { + $metadata = $this->resourceMetadata->loadByEntityTypeAndStore( + $this->data['entity_type'], + $this->data['store_id'] + ); + if ($metadata->getSequenceTable() == $this->getSequenceName()) { + return; + } + $this->data['sequence_table'] = $this->getSequenceName(); + $this->data['is_active'] = 1; + $profile = $this->profileFactory->create( + [ + 'data' => array_intersect_key( + $this->data, + array_flip( + [ + 'prefix', 'suffix', 'start_value', 'step', 'max_value', 'warning_value', + 'is_active', 'active_profile' + ] + ) + ) + ] + ); + $profile->setHasDataChanges(true); + $this->data['active_profile'] = $profile; + $metadata = $this->metaFactory->create( + [ + 'data' => array_intersect_key( + $this->data, + array_flip(['entity_type', 'store_id', 'sequence_table', 'active_profile']) + ) + ] + ); + $metadata->setHasDataChanges(true); + try { + $this->resourceMetadata->save($metadata); + $adapter = $this->appResource->getConnection('write'); + if (!$adapter->isTableExists($this->data['sequence_table'])) { + $adapter->query( + $this->ddlSequence->getCreateSequenceDdl( + $this->data['sequence_table'], + $this->data['start_value'] + ) + ); + } + } catch (Exception $e) { + $this->resourceMetadata->delete($metadata); + $this->logger->critical($e); + throw $e; + } + $this->data = array_flip($this->pattern); + } +} diff --git a/app/code/Magento/SalesSequence/Model/Config.php b/app/code/Magento/SalesSequence/Model/Config.php new file mode 100644 index 0000000000000000000000000000000000000000..0ba4868b6326f8b837bc9e5d7644bdc3ffab40d1 --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Config.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +/** + * Class Config - configuration container for sequence + */ +class Config +{ + /** + * Default sequence values + * Prefix represents prefix for sequence: AA000 + * Suffix represents suffix: 000AA + * startValue represents initial value + * warning value will be using for alert messages when increment closing to overflow + * maxValue represents last available increment id in system + * + * @var array + */ + protected $defaultValues = [ + 'prefix' => '', + 'suffix' => '', + 'startValue' => 1, + 'step' => 1, + 'warningValue' => 4294966295, + 'maxValue' => 4294967295 + ]; + + /** + * Get configuration field + * + * @param string|null $key + * @return mixed + */ + public function get($key = null) + { + if (!array_key_exists($key, $this->defaultValues)) { + return null; + } + return $this->defaultValues[$key]; + } +} diff --git a/app/code/Magento/SalesSequence/Model/EntityPool.php b/app/code/Magento/SalesSequence/Model/EntityPool.php new file mode 100644 index 0000000000000000000000000000000000000000..00c51f7c79c49ec8c79c6a99f5726679bbb2d41f --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/EntityPool.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +/** + * Class EntityPool + * + * Pool of entities that require sequence + */ +class EntityPool +{ + /** + * @var array + */ + protected $entities; + + /** + * @param array $entities + */ + public function __construct(array $entities = []) + { + $this->entities = $entities; + } + + /** + * Retrieve entities that require sequence + * + * @return array + */ + public function getEntities() + { + return $this->entities; + } +} diff --git a/app/code/Magento/SalesSequence/Model/Manager.php b/app/code/Magento/SalesSequence/Model/Manager.php new file mode 100644 index 0000000000000000000000000000000000000000..d6590d6624ac8342a21e9dfef9eb92f52fb980e8 --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Manager.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +use Magento\SalesSequence\Model\Resource\Meta as ResourceSequenceMeta; + +/** + * Class Manager + */ +class Manager +{ + /** + * @var ResourceSequenceMeta + */ + protected $resourceSequenceMeta; + + /** + * @var SequenceFactory + */ + protected $sequenceFactory; + + /** + * @param ResourceSequenceMeta $resourceSequenceMeta + * @param SequenceFactory $sequenceFactory + */ + public function __construct( + ResourceSequenceMeta $resourceSequenceMeta, + SequenceFactory $sequenceFactory + ) { + $this->resourceSequenceMeta = $resourceSequenceMeta; + $this->sequenceFactory = $sequenceFactory; + } + + /** + * Returns sequence for given entityType and store + * + * @param string $entityType + * @param int $storeId + * @return \Magento\Framework\DB\Sequence\SequenceInterface + */ + public function getSequence($entityType, $storeId) + { + return $this->sequenceFactory->create( + [ + 'meta' => $this->resourceSequenceMeta->loadByEntityTypeAndStore( + $entityType, + $storeId + ) + ] + ); + } +} diff --git a/app/code/Magento/SalesSequence/Model/Meta.php b/app/code/Magento/SalesSequence/Model/Meta.php new file mode 100644 index 0000000000000000000000000000000000000000..8f1c216619f0a0b65125f8fe156b43072f3b8430 --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Meta.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +use Magento\Framework\Model\AbstractModel; + +/** + * Class Meta + */ +class Meta extends AbstractModel +{ + /** + * @inheritdoc + */ + protected function _construct() + { + $this->_init('Magento\SalesSequence\Model\Resource\Meta'); + } +} diff --git a/app/code/Magento/SalesSequence/Model/Observer.php b/app/code/Magento/SalesSequence/Model/Observer.php new file mode 100644 index 0000000000000000000000000000000000000000..979918296ad3e30268f6ed524f6f900f73989cb5 --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Observer.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +use Magento\Framework\Event\Observer as EventObserver; + +/** + * Class CreateSequence + */ +class Observer +{ + /** + * @var Builder + */ + private $sequenceBuilder; + + /** + * @var EntityPool + */ + private $entityPool; + + /** + * @var Config + */ + private $sequenceConfig; + + /** + * Initialization + * + * @param Builder $sequenceBuilder + * @param EntityPool $entityPool + * @param Config $sequenceConfig + */ + public function __construct( + Builder $sequenceBuilder, + EntityPool $entityPool, + Config $sequenceConfig + ) { + $this->sequenceBuilder = $sequenceBuilder; + $this->entityPool = $entityPool; + $this->sequenceConfig = $sequenceConfig; + } + + /** + * @param EventObserver $observer + * @return $this + */ + public function execute(EventObserver $observer) + { + $storeId = $observer->getData('store')->getId(); + foreach ($this->entityPool->getEntities() as $entityType) { + $this->sequenceBuilder->setPrefix($this->sequenceConfig->get('prefix')) + ->setSuffix($this->sequenceConfig->get('suffix')) + ->setStartValue($this->sequenceConfig->get('startValue')) + ->setStoreId($storeId) + ->setStep($this->sequenceConfig->get('step')) + ->setWarningValue($this->sequenceConfig->get('warningValue')) + ->setMaxValue($this->sequenceConfig->get('maxValue')) + ->setEntityType($entityType) + ->create(); + } + return $this; + } +} diff --git a/app/code/Magento/SalesSequence/Model/Profile.php b/app/code/Magento/SalesSequence/Model/Profile.php new file mode 100644 index 0000000000000000000000000000000000000000..b6db02e4805bd53b142566e91d345e536f3d80c8 --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Profile.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +use Magento\Framework\Model\AbstractModel; + +/** + * Class Profile + */ +class Profile extends AbstractModel +{ + /** + * @inheritdoc + */ + protected function _construct() + { + $this->_init('Magento\SalesSequence\Model\Resource\Profile'); + } +} diff --git a/app/code/Magento/SalesSequence/Model/Resource/Meta.php b/app/code/Magento/SalesSequence/Model/Resource/Meta.php new file mode 100644 index 0000000000000000000000000000000000000000..ec3bc612fd71db290c5d7b37f0694e0d1ac7a37f --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Resource/Meta.php @@ -0,0 +1,140 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model\Resource; + +use Magento\Framework\Exception\LocalizedException as Exception; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Model\Resource\Db\Context as DatabaseContext; +use Magento\SalesSequence\Model\Resource\Profile as ResourceProfile; +use Magento\SalesSequence\Model\MetaFactory; +use Magento\SalesSequence\Model\Profile as ModelProfile; + +/** + * Class Meta represents metadata for sequence as sequence table and store id + */ +class Meta extends \Magento\Framework\Model\Resource\Db\AbstractDb +{ + /** + * Event prefix + * + * @var string + */ + protected $_eventPrefix = 'sales_sequence_meta'; + + /** + * @var ResourceProfile + */ + protected $resourceProfile; + + /** + * @var MetaFactory + */ + protected $metaFactory; + + /** + * @param DatabaseContext $context + * @param MetaFactory $metaFactory + * @param ResourceProfile $resourceProfile + * @param string $resourcePrefix + */ + public function __construct( + DatabaseContext $context, + MetaFactory $metaFactory, + ResourceProfile $resourceProfile, + $resourcePrefix = null + ) { + $this->metaFactory = $metaFactory; + $this->resourceProfile = $resourceProfile; + parent::__construct($context, $resourcePrefix); + } + + /** + * Model initialization + * + * @return void + */ + protected function _construct() + { + $this->_init('sales_sequence_meta', 'meta_id'); + } + + /** + * Retrieves Metadata for entity by entity type and store id + * + * @param string $entityType + * @param int $storeId + * @return \Magento\SalesSequence\Model\Meta + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function loadByEntityTypeAndStore($entityType, $storeId) + { + $meta = $this->metaFactory->create(); + $adapter = $this->_getReadAdapter(); + $bind = ['entity_type' => $entityType, 'store_id' => $storeId]; + $select = $adapter->select()->from( + $this->getMainTable(), + [$this->getIdFieldName()] + )->where( + 'entity_type = :entity_type AND store_id = :store_id' + ); + $metaId = $adapter->fetchOne($select, $bind); + + if ($metaId) { + $this->load($meta, $metaId); + } + return $meta; + } + + /** + * Using for load sequence profile and setting it into metadata + * + * @param \Magento\Framework\Model\AbstractModel $object + * @return $this + */ + protected function _afterLoad(\Magento\Framework\Model\AbstractModel $object) + { + $object->setData( + 'active_profile', + $this->resourceProfile->loadActiveProfile($object->getId()) + ); + return $this; + } + + /** + * Validate metadata and sequence before save + * + * @param \Magento\Framework\Model\AbstractModel $object + * @return $this + * @throws Exception + * @throws NoSuchEntityException + */ + protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object) + { + if (!$object->getData('active_profile') instanceof ModelProfile) { + throw new NoSuchEntityException(__('Entity Sequence profile not added to meta active profile')); + } + + if (!$object->getData('entity_type') + || $object->getData('store_id') === null + || !$object->getData('sequence_table') + ) { + throw new Exception(__('Not enough arguments')); + } + + return $this; + } + + /** + * @inheritdoc + */ + protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) + { + $profile = $object->getData('active_profile') + ->setMetaId($object->getId()); + $this->resourceProfile->save($profile); + return $this; + } +} diff --git a/app/code/Magento/SalesSequence/Model/Resource/Profile.php b/app/code/Magento/SalesSequence/Model/Resource/Profile.php new file mode 100644 index 0000000000000000000000000000000000000000..b814388541836222052776ecf67f7e8c1fbe83b1 --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Resource/Profile.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model\Resource; + +use Magento\SalesSequence\Model\Meta as ModelMeta; +use Magento\Framework\Model\Resource\Db\Context as DatabaseContext; +use Magento\SalesSequence\Model\ProfileFactory; + +/** + * Class Profile represents profile data for sequence as prefix, suffix, start value etc. + */ +class Profile extends \Magento\Framework\Model\Resource\Db\AbstractDb +{ + /** + * Event prefix + * + * @var string + */ + protected $_eventPrefix = 'sales_sequence_profile'; + + /** + * Model initialization + * + * @return void + */ + protected function _construct() + { + $this->_init('sales_sequence_profile', 'profile_id'); + } + + /** + * @var ProfileFactory + */ + protected $profileFactory; + + /** + * @param DatabaseContext $context + * @param ProfileFactory $profileFactory + * @param null $resourcePrefix + */ + public function __construct( + DatabaseContext $context, + ProfileFactory $profileFactory, + $resourcePrefix = null + ) { + $this->profileFactory = $profileFactory; + parent::__construct($context, $resourcePrefix); + } + + /** + * Load active profile + * + * @param int $metadataId + * @return \Magento\SalesSequence\Model\Profile + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function loadActiveProfile($metadataId) + { + $profile = $this->profileFactory->create(); + $adapter = $this->_getReadAdapter(); + $bind = ['meta_id' => $metadataId]; + $select = $adapter->select() + ->from($this->getMainTable(), ['profile_id']) + ->where('meta_id = :meta_id') + ->where('is_active = 1'); + + $profileId = $adapter->fetchOne($select, $bind); + + if ($profileId) { + $this->load($profile, $profileId); + } + return $profile; + } +} diff --git a/app/code/Magento/SalesSequence/Model/Sequence.php b/app/code/Magento/SalesSequence/Model/Sequence.php new file mode 100644 index 0000000000000000000000000000000000000000..e7c9a9f3876e516da579c061f9b9568c09f9c01a --- /dev/null +++ b/app/code/Magento/SalesSequence/Model/Sequence.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Model; + +use Magento\Framework\App\Resource as AppResource; +use Magento\Framework\DB\Sequence\SequenceInterface; + +/** + * Class Sequence represents sequence in logic + */ +class Sequence implements SequenceInterface +{ + /** + * Default pattern for Sequence + */ + const DEFAULT_PATTERN = "%s%'.09d%s"; + + /** + * @var string + */ + private $lastIncrementId; + + /** + * @var Meta + */ + private $meta; + + /** + * @var false|\Magento\Framework\DB\Adapter\AdapterInterface + */ + private $adapter; + + /** + * @var string + */ + private $pattern; + + /** + * @param Meta $meta + * @param AppResource $resource + * @param string $pattern + */ + public function __construct( + Meta $meta, + AppResource $resource, + $pattern = self::DEFAULT_PATTERN + ) { + $this->meta = $meta; + $this->adapter = $resource->getConnection('write'); + $this->pattern = $pattern; + } + + /** + * Retrieve current value + * + * @return string + */ + public function getCurrentValue() + { + if (!isset($this->lastIncrementId)) { + return null; + } + + return sprintf( + $this->pattern, + $this->meta->getActiveProfile()->getPrefix(), + $this->calculateCurrentValue(), + $this->meta->getActiveProfile()->getSuffix() + ); + } + + /** + * Retrieve next value + * + * @return string + */ + public function getNextValue() + { + $this->adapter->insert($this->meta->getSequenceTable(), []); + $this->lastIncrementId = $this->adapter->lastInsertId($this->meta->getSequenceTable()); + return $this->getCurrentValue(); + } + + /** + * Calculate current value depends on start value + * + * @return string + */ + private function calculateCurrentValue() + { + return ($this->lastIncrementId - $this->meta->getActiveProfile()->getStartValue()) + * $this->meta->getActiveProfile()->getStep() + $this->meta->getActiveProfile()->getStartValue(); + } +} diff --git a/app/code/Magento/SalesSequence/README.md b/app/code/Magento/SalesSequence/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ab34b8a233e2c4cdb11f66b47aaac2e923d7dc80 --- /dev/null +++ b/app/code/Magento/SalesSequence/README.md @@ -0,0 +1,18 @@ +# Overview +## Purpose of module + +Magento\SalesSequence module is responsible for sequences processing in Sales module, +Magento\SalesSequence module manages sequences for next system entities and flows: +* order; +* invoice; +* shipment; +* credit memos; +Magento\SalesSequence module is required for Magento\Sales module. + +# Deployment +## System requirements + +The Magento_SalesSequence module does not have any specific system requirements. + +## Install +The Magento_SalesSequence module is installed automatically (using the native Magento install mechanism) without any additional actions. diff --git a/app/code/Magento/SalesSequence/Setup/InstallData.php b/app/code/Magento/SalesSequence/Setup/InstallData.php new file mode 100644 index 0000000000000000000000000000000000000000..0f9cff7f09ed825b94b7d76af56ed1f7b179c83e --- /dev/null +++ b/app/code/Magento/SalesSequence/Setup/InstallData.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\SalesSequence\Setup; + +use Magento\Framework\Setup\InstallDataInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\SalesSequence\Model\Builder; +use Magento\SalesSequence\Model\Config as SequenceConfig; +use Magento\SalesSequence\Model\EntityPool; + +/** + * Class InstallData + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @codeCoverageIgnore + */ +class InstallData implements InstallDataInterface +{ + /** + * Sales setup factory + * + * @var EntityPool + */ + private $entityPool; + + /** + * @var Builder + */ + private $sequenceBuilder; + + /** + * @var SequenceConfig + */ + private $sequenceConfig; + + /** + * @param EntityPool $entityPool + * @param Builder $sequenceBuilder + * @param SequenceConfig $sequenceConfig + */ + public function __construct( + EntityPool $entityPool, + Builder $sequenceBuilder, + SequenceConfig $sequenceConfig + ) { + $this->entityPool = $entityPool; + $this->sequenceBuilder = $sequenceBuilder; + $this->sequenceConfig = $sequenceConfig; + } + + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) + { + $defaultStoreIds = [0, 1]; + foreach ($defaultStoreIds as $storeId) { + foreach ($this->entityPool->getEntities() as $entityType) { + $this->sequenceBuilder->setPrefix($this->sequenceConfig->get('prefix')) + ->setSuffix($this->sequenceConfig->get('suffix')) + ->setStartValue($this->sequenceConfig->get('startValue')) + ->setStoreId($storeId) + ->setStep($this->sequenceConfig->get('step')) + ->setWarningValue($this->sequenceConfig->get('warningValue')) + ->setMaxValue($this->sequenceConfig->get('maxValue')) + ->setEntityType($entityType)->create(); + } + } + } +} diff --git a/app/code/Magento/SalesSequence/Setup/InstallSchema.php b/app/code/Magento/SalesSequence/Setup/InstallSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..12454c42d4878c56a96403c6823b4406f06b6c2f --- /dev/null +++ b/app/code/Magento/SalesSequence/Setup/InstallSchema.php @@ -0,0 +1,141 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Setup; + +use Magento\Framework\Setup\InstallSchemaInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; + +/** + * @codeCoverageIgnore + */ +class InstallSchema implements InstallSchemaInterface +{ + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $installer = $setup; + $installer->startSetup(); + /** + * Create table 'sales_sequence_profile' + */ + $table = $installer->getConnection()->newTable( + $installer->getTable('sales_sequence_profile') + )->addColumn( + 'profile_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], + 'Id' + )->addColumn( + 'meta_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['unsigned' => true, 'nullable' => false] + )->addColumn( + 'prefix', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 32, + ['nullable' => true, 'primary' => false], + 'Prefix' + )->addColumn( + 'suffix', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 32, + ['nullable' => true, 'primary' => false], + 'Suffix' + )->addColumn( + 'start_value', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['nullable' => false, 'unsigned' => true, 'primary' => false, 'default' => 1], + 'Start value for sequence' + )->addColumn( + 'step', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['nullable' => false, 'unsigned' => true, 'primary' => false, 'default' => 1], + 'Step for sequence' + )->addColumn( + 'max_value', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['nullable' => false, 'unsigned' => true, 'primary' => false], + 'MaxValue for sequence' + )->addColumn( + 'warning_value', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['nullable' => false, 'unsigned' => true, 'primary' => false], + 'WarningValue for sequence' + )->addColumn( + 'is_active', + \Magento\Framework\DB\Ddl\Table::TYPE_BOOLEAN, + null, + ['nullable' => false, 'default' => 0], + 'isActive flag' + )->addIndex( + $installer->getIdxName( + 'sales_sequence_profile', + ['meta_id', 'prefix', 'suffix'], + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ), + ['meta_id', 'prefix', 'suffix'], + ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE] + )->addForeignKey( + $installer->getFkName('sales_sequence_profile', 'meta_id', 'sales_sequence_meta', 'meta_id'), + 'meta_id', + $installer->getTable('sales_sequence_meta'), + 'meta_id', + \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE + ); + $installer->getConnection()->createTable($table); + + /** + * Create table 'sales_sequence_meta' + */ + $table = $installer->getConnection()->newTable( + $installer->getTable('sales_sequence_meta') + )->addColumn( + 'meta_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], + 'Id' + )->addColumn( + 'entity_type', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 32, + ['nullable' => false, 'primary' => false], + 'Prefix' + )->addColumn( + 'store_id', + \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false, 'primary' => false], + 'Store Id' + )->addColumn( + 'sequence_table', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 32, + ['nullable' => false], + 'table for sequence' + )->addIndex( + $installer->getIdxName( + 'sales_sequence_meta', + ['entity_type', 'store_id'], + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ), + ['entity_type', 'store_id'], + ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE] + ); + $installer->getConnection()->createTable($table); + $installer->endSetup(); + } +} diff --git a/app/code/Magento/SalesSequence/Test/Unit/Model/BuilderTest.php b/app/code/Magento/SalesSequence/Test/Unit/Model/BuilderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..75ae26beb34bbc91a49263921c42fa06965f90e0 --- /dev/null +++ b/app/code/Magento/SalesSequence/Test/Unit/Model/BuilderTest.php @@ -0,0 +1,236 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Test\Unit\Model; + +/** + * Class BuilderTest + */ +class BuilderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\SalesSequence\Model\Builder + */ + private $sequenceBuilder; + + /** + * @var \Magento\SalesSequence\Model\Resource\Meta | \PHPUnit_Framework_MockObject_MockObject + */ + private $resourceSequenceMeta; + + /** + * @var \Magento\SalesSequence\Model\Meta | \PHPUnit_Framework_MockObject_MockObject + */ + private $meta; + + /** + * @var \Magento\SalesSequence\Model\Profile | \PHPUnit_Framework_MockObject_MockObject + */ + private $profile; + + /** + * @var \Magento\SalesSequence\Model\MetaFactory | \PHPUnit_Framework_MockObject_MockObject + */ + private $metaFactory; + + /** + * @var \Magento\SalesSequence\Model\ProfileFactory | \PHPUnit_Framework_MockObject_MockObject + */ + private $profileFactory; + + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $adapter; + + /** + * @var \Magento\Framework\DB\Ddl\Sequence | \PHPUnit_Framework_MockObject_MockObject + */ + private $sequence; + + /** + * @var \Magento\Framework\App\Resource | \PHPUnit_Framework_MockObject_MockObject + */ + private $resourceMock; + + protected function setUp() + { + $this->adapter = $this->getMockForAbstractClass( + 'Magento\Framework\DB\Adapter\AdapterInterface', + [], + '', + false, + false, + true, + ['query'] + ); + $this->resourceSequenceMeta = $this->getMock( + 'Magento\SalesSequence\Model\Resource\Meta', + ['loadByEntityTypeAndStore', 'save', 'createSequence'], + [], + '', + false + ); + $this->meta = $this->getMock( + 'Magento\SalesSequence\Model\Meta', + ['getId', 'setData', 'save', 'getSequenceTable'], + [], + '', + false + ); + $this->sequence = $this->getMock( + 'Magento\Framework\DB\Ddl\Sequence', + [], + [], + '', + false + ); + $this->resourceMock = $this->getMock( + 'Magento\Framework\App\Resource', + [], + [], + '', + false + ); + $this->profile = $this->getMock( + 'Magento\SalesSequence\Model\Profile', + ['getId', 'setData', 'getStartValue'], + [], + '', + false + ); + $this->metaFactory = $this->getMock( + 'Magento\SalesSequence\Model\MetaFactory', + ['create'], + [], + '', + false + ); + $this->metaFactory->expects($this->any())->method('create')->willReturn($this->meta); + $this->profileFactory = $this->getMock( + 'Magento\SalesSequence\Model\ProfileFactory', + ['create'], + [], + '', + false + ); + $this->profileFactory->expects($this->any())->method('create')->willReturn($this->profile); + $this->resourceMock->expects($this->atLeastOnce()) + ->method('getTableName') + ->willReturn('sequence_lalalka_1'); + + $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->sequenceBuilder = $helper->getObject( + 'Magento\SalesSequence\Model\Builder', + [ + 'resourceMetadata' => $this->resourceSequenceMeta, + 'metaFactory' => $this->metaFactory, + 'profileFactory' => $this->profileFactory, + 'appResource' => $this->resourceMock, + 'ddlSequence' => $this->sequence + ] + ); + } + + public function testAddSequenceExistMeta() + { + $entityType = 'lalalka'; + $storeId = 1; + $this->resourceSequenceMeta->expects($this->once()) + ->method('loadByEntityTypeAndStore') + ->with($entityType, $storeId) + ->willReturn($this->meta); + $this->meta->expects($this->once()) + ->method('getSequenceTable') + ->willReturn('sequence_lalalka_1'); + $this->profileFactory->expects($this->never()) + ->method('create'); + $this->sequenceBuilder->setEntityType($entityType) + ->setStoreId($storeId) + ->setSuffix('SUFF') + ->setPrefix('PREF') + ->setStartValue(1) + ->setStep(1) + ->setWarningValue(9999999) + ->setMaxValue(912992192) + ->create(); + } + + public function testAddSequence() + { + $entityType = 'lalalka'; + $storeId = 1; + $prefix = 'PRE'; + $suffix = 'SUF'; + $startValue = 1; + $step = 1; + $maxValue = 120000; + $warningValue = 110000; + $this->resourceSequenceMeta->expects($this->once()) + ->method('loadByEntityTypeAndStore') + ->with($entityType, $storeId) + ->willReturn($this->meta); + $this->meta->expects($this->once()) + ->method('getSequenceTable') + ->willReturn(null); + $this->profileFactory->expects($this->once()) + ->method('create') + ->with([ + 'data' => [ + 'prefix' => $prefix, + 'suffix' => $suffix, + 'start_value' => $startValue, + 'step' => $step, + 'max_value' => $maxValue, + 'warning_value' => $warningValue, + 'is_active' => 1 + ] + ])->willReturn($this->profile); + $sequenceTable = sprintf('sequence_%s_%s', $entityType, $storeId); + $this->metaFactory->expects($this->once()) + ->method('create') + ->with([ + 'data' => [ + 'entity_type' => $entityType, + 'store_id' => $storeId, + 'sequence_table' => $sequenceTable, + 'active_profile' => $this->profile + ] + ])->willReturn($this->meta); + $this->resourceSequenceMeta->expects($this->once())->method('save')->willReturn($this->meta); + $this->stepCreateSequence($sequenceTable, $startValue); + $this->sequenceBuilder->setEntityType($entityType) + ->setStoreId($storeId) + ->setPrefix($prefix) + ->setSuffix($suffix) + ->setStartValue($startValue) + ->setStep($step) + ->setMaxValue($maxValue) + ->setWarningValue($warningValue) + ->create(); + } + + /** + * Step create sequence + * + * @param $sequenceName + * @param $startNumber + */ + private function stepCreateSequence($sequenceName, $startNumber) + { + $sql = "some sql"; + $this->resourceMock->expects($this->atLeastOnce()) + ->method('getTableName'); + $this->resourceMock->expects($this->any()) + ->method('getConnection') + ->with('write') + ->willReturn($this->adapter); + $this->sequence->expects($this->once()) + ->method('getCreateSequenceDdl') + ->with($sequenceName, $startNumber) + ->willReturn($sql); + $this->adapter->expects($this->once())->method('query')->with($sql); + } +} diff --git a/app/code/Magento/SalesSequence/Test/Unit/Model/ManagerTest.php b/app/code/Magento/SalesSequence/Test/Unit/Model/ManagerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..159a3d7b9253852e02f8032aeee53ec13a1963ac --- /dev/null +++ b/app/code/Magento/SalesSequence/Test/Unit/Model/ManagerTest.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Test\Unit\Model; + +/** + * Class ManagerTest + */ +class ManagerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\SalesSequence\Model\Resource\Meta | \PHPUnit_Framework_MockObject_MockObject + */ + private $resourceSequenceMeta; + + /** + * @var \Magento\SalesSequence\Model\SequenceFactory | \PHPUnit_Framework_MockObject_MockObject + */ + private $sequenceFactory; + + /** + * @var \Magento\SalesSequence\Model\Manager + */ + private $sequenceManager; + + /** + * @var \Magento\Store\Model\Store | \PHPUnit_Framework_MockObject_MockObject + */ + private $store; + + /** + * @var \Magento\SalesSequence\Model\Meta | \PHPUnit_Framework_MockObject_MockObject + */ + private $meta; + + /** + * @var \Magento\Framework\DB\Sequence\SequenceInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $sequence; + + /** + * Initialization + */ + protected function setUp() + { + $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->sequence = $this->getMockForAbstractClass( + 'Magento\Framework\DB\Sequence\SequenceInterface', + [], + '', + false, + false, + true, + [] + ); + $this->resourceSequenceMeta = $this->getMock( + 'Magento\SalesSequence\Model\Resource\Meta', + ['loadByEntityTypeAndStore'], + [], + '', + false + ); + $this->sequenceFactory = $this->getMock( + 'Magento\SalesSequence\Model\SequenceFactory', + ['create'], + [], + '', + false + ); + $this->meta = $this->getMock( + 'Magento\SalesSequence\Model\Meta', + [], + [], + '', + false + ); + $this->store = $this->getMock( + 'Magento\Store\Model\Store', + ['getId'], + [], + '', + false + ); + $this->sequenceManager = $helper->getObject( + 'Magento\SalesSequence\Model\Manager', + [ + 'resourceSequenceMeta' => $this->resourceSequenceMeta, + 'sequenceFactory' => $this->sequenceFactory + ] + ); + } + + public function testGetSequence() + { + $entityType = 'order'; + $storeId = 1; + $this->resourceSequenceMeta->expects($this->once()) + ->method('loadByEntityTypeAndStore') + ->with($entityType, $storeId) + ->willReturn($this->meta); + $this->sequenceFactory->expects($this->once())->method('create')->with([ + 'meta' => $this->meta + ])->willReturn($this->sequence); + $this->assertSame($this->sequence, $this->sequenceManager->getSequence($entityType, $storeId)); + } +} diff --git a/app/code/Magento/SalesSequence/Test/Unit/Model/Resource/MetaTest.php b/app/code/Magento/SalesSequence/Test/Unit/Model/Resource/MetaTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0b119066741e8302711a2d8fedaa0154d10063c4 --- /dev/null +++ b/app/code/Magento/SalesSequence/Test/Unit/Model/Resource/MetaTest.php @@ -0,0 +1,183 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Test\Unit\Model\Resource; + +use Magento\Framework\App\Resource; +use Magento\SalesSequence\Model\Resource\Meta; + +/** + * Class MetaTest + */ +class MetaTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $adapter; + + /** + * @var \Magento\Framework\Model\Resource\Db\Context | \PHPUnit_Framework_MockObject_MockObject + */ + private $dbContext; + + /** + * @var \Magento\SalesSequence\Model\MetaFactory | \PHPUnit_Framework_MockObject_MockObject + */ + private $metaFactory; + + /** + * @var \Magento\SalesSequence\Model\Meta | \PHPUnit_Framework_MockObject_MockObject + */ + private $meta; + + /** + * @var \Magento\SalesSequence\Model\Profile | \PHPUnit_Framework_MockObject_MockObject + */ + private $profile; + + /** + * @var \Magento\SalesSequence\Model\Resource\Profile | \PHPUnit_Framework_MockObject_MockObject + */ + private $resourceProfile; + + /** + * @var Meta + */ + private $resource; + + /** + * @var Resource | \PHPUnit_Framework_MockObject_MockObject + */ + protected $resourceMock; + + /** + * @var \Magento\Framework\DB\Select | \PHPUnit_Framework_MockObject_MockObject + */ + private $select; + + /** + * Initialization + */ + protected function setUp() + { + $this->adapter = $this->getMockForAbstractClass( + 'Magento\Framework\DB\Adapter\AdapterInterface', + [], + '', + false, + false, + true, + ['query'] + ); + $this->dbContext = $this->getMock( + 'Magento\Framework\Model\Resource\Db\Context', + [], + [], + '', + false + ); + $this->metaFactory = $this->getMock( + 'Magento\SalesSequence\Model\MetaFactory', + ['create'], + [], + '', + false + ); + $this->resourceProfile = $this->getMock( + 'Magento\SalesSequence\Model\Resource\Profile', + ['loadActiveProfile', 'save'], + [], + '', + false + ); + $this->resourceMock = $this->getMock( + 'Magento\Framework\App\Resource', + ['getConnection', 'getTableName'], + [], + '', + false + ); + $this->dbContext->expects($this->once())->method('getResources')->willReturn($this->resourceMock); + $this->select = $this->getMock( + 'Magento\Framework\DB\Select', + [], + [], + '', + false + ); + $this->meta = $this->getMock( + 'Magento\SalesSequence\Model\Meta', + [], + [], + '', + false + ); + $this->profile = $this->getMock( + 'Magento\SalesSequence\Model\Profile', + [], + [], + '', + false + ); + $this->resource = new Meta( + $this->dbContext, + $this->metaFactory, + $this->resourceProfile + ); + } + + public function testLoadBy() + { + $metaTableName = 'sequence_meta'; + $metaIdFieldName = 'meta_id'; + $entityType = 'order'; + $storeId = 1; + $metaId = 1; + $metaData = [ + 'meta_id' => 1, + 'profile_id' => 2 + ]; + $this->resourceMock->expects($this->any()) + ->method('getConnection') + ->willReturn($this->adapter); + $this->resourceMock->expects($this->once()) + ->method('getTableName') + ->willReturn($metaTableName); + $this->adapter->expects($this->any())->method('select')->willReturn($this->select); + $this->select->expects($this->at(0)) + ->method('from') + ->with($metaTableName, [$metaIdFieldName]) + ->willReturn($this->select); + $this->select->expects($this->at(1)) + ->method('where') + ->with('entity_type = :entity_type AND store_id = :store_id') + ->willReturn($this->select); + $this->adapter->expects($this->once()) + ->method('fetchOne') + ->with($this->select, ['entity_type' => $entityType, 'store_id' => $storeId]) + ->willReturn($metaId); + $this->metaFactory->expects($this->once())->method('create')->willReturn($this->meta); + $this->stepCheckSaveWithActiveProfile($metaData); + $this->assertEquals($this->meta, $this->resource->loadByEntityTypeAndStore($entityType, $storeId)); + } + + /** + * @param $metaData + */ + private function stepCheckSaveWithActiveProfile($metaData) + { + $this->select->expects($this->at(2)) + ->method('from') + ->with('sequence_meta', '*', null) + ->willReturn($this->select); + $this->adapter->expects($this->any()) + ->method('quoteIdentifier'); + $this->adapter->expects($this->once())->method('fetchRow')->willReturn($metaData); + $this->resourceProfile->expects($this->once())->method('loadActiveProfile')->willReturn($this->profile); + $this->meta->expects($this->at(0))->method('setData')->with($metaData); + $this->meta->expects($this->at(2))->method('setData')->with('active_profile', $this->profile); + } +} diff --git a/app/code/Magento/SalesSequence/Test/Unit/Model/Resource/ProfileTest.php b/app/code/Magento/SalesSequence/Test/Unit/Model/Resource/ProfileTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9c3e3a45673db159cc551fac406719b2fc04f5ff --- /dev/null +++ b/app/code/Magento/SalesSequence/Test/Unit/Model/Resource/ProfileTest.php @@ -0,0 +1,162 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Test\Unit\Model\Resource; + +use Magento\SalesSequence\Model\Resource\Profile; + +/** + * Class ProfileTest + */ +class ProfileTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $adapter; + + /** + * @var \Magento\Framework\Model\Resource\Db\Context | \PHPUnit_Framework_MockObject_MockObject + */ + private $dbContext; + + /** + * @var \Magento\SalesSequence\Model\ProfileFactory | \PHPUnit_Framework_MockObject_MockObject + */ + private $profileFactory; + + /** + * @var \Magento\SalesSequence\Model\Meta | \PHPUnit_Framework_MockObject_MockObject + */ + private $meta; + + /** + * @var \Magento\SalesSequence\Model\Profile | \PHPUnit_Framework_MockObject_MockObject + */ + private $profile; + + /** + * @var Profile + */ + private $resource; + + /** + * @var Resource | \PHPUnit_Framework_MockObject_MockObject + */ + protected $resourceMock; + + /** + * @var \Magento\Framework\DB\Select | \PHPUnit_Framework_MockObject_MockObject + */ + private $select; + + /** + * Initialization + */ + protected function setUp() + { + $this->adapter = $this->getMockForAbstractClass( + 'Magento\Framework\DB\Adapter\AdapterInterface', + [], + '', + false, + false, + true, + ['query'] + ); + $this->dbContext = $this->getMock( + 'Magento\Framework\Model\Resource\Db\Context', + [], + [], + '', + false + ); + $this->profileFactory = $this->getMock( + 'Magento\SalesSequence\Model\ProfileFactory', + ['create'], + [], + '', + false + ); + $this->resourceMock = $this->getMock( + 'Magento\Framework\App\Resource', + ['getConnection', 'getTableName'], + [], + '', + false + ); + $this->dbContext->expects($this->once())->method('getResources')->willReturn($this->resourceMock); + $this->select = $this->getMock( + 'Magento\Framework\DB\Select', + [], + [], + '', + false + ); + $this->meta = $this->getMock( + 'Magento\SalesSequence\Model\Meta', + [], + [], + '', + false + ); + $this->profile = $this->getMock( + 'Magento\SalesSequence\Model\Profile', + [], + [], + '', + false + ); + $this->resource = new Profile( + $this->dbContext, + $this->profileFactory + ); + } + + public function testLoadActiveProfile() + { + $profileTableName = 'sequence_profile'; + $profileIdFieldName = 'profile_id'; + $metaId = 1; + $profileId = 20; + $profileData = [ + 'profile_id' => 20, + 'meta_id' => 1 + ]; + $this->profileFactory->expects($this->once())->method('create')->willReturn($this->profile); + $this->resourceMock->expects($this->any()) + ->method('getConnection') + ->willReturn($this->adapter); + $this->resourceMock->expects($this->once()) + ->method('getTableName') + ->willReturn($profileTableName); + $this->adapter->expects($this->any())->method('select')->willReturn($this->select); + $this->select->expects($this->at(0)) + ->method('from') + ->with($profileTableName, [$profileIdFieldName]) + ->willReturn($this->select); + $this->select->expects($this->at(1)) + ->method('where') + ->with('meta_id = :meta_id') + ->willReturn($this->select); + $this->select->expects($this->at(2)) + ->method('where') + ->with('is_active = 1') + ->willReturn($this->select); + $this->adapter->expects($this->once()) + ->method('fetchOne') + ->with($this->select, ['meta_id' => $metaId]) + ->willReturn($profileId); + $this->select->expects($this->at(3)) + ->method('from') + ->with($profileTableName, '*', null) + ->willReturn($this->select); + $this->adapter->expects($this->any()) + ->method('quoteIdentifier'); + $this->adapter->expects($this->once())->method('fetchRow')->willReturn($profileData); + $this->profile->expects($this->at(0))->method('setData')->with($profileData); + $this->assertEquals($this->profile, $this->resource->loadActiveProfile($metaId)); + } +} diff --git a/app/code/Magento/SalesSequence/Test/Unit/Model/SequenceTest.php b/app/code/Magento/SalesSequence/Test/Unit/Model/SequenceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b998bdeccf86db08a8914c15e002fa95a60780e7 --- /dev/null +++ b/app/code/Magento/SalesSequence/Test/Unit/Model/SequenceTest.php @@ -0,0 +1,152 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SalesSequence\Test\Unit\Model; + +use Magento\SalesSequence\Model\Sequence; + +/** + * Class SequenceTest + */ +class SequenceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $adapter; + /** + * @var \Magento\Framework\App\Resource | \PHPUnit_Framework_MockObject_MockObject + */ + private $resource; + + /** + * @var \Magento\SalesSequence\Model\Profile | \PHPUnit_Framework_MockObject_MockObject + */ + private $profile; + + /** + * @var \Magento\SalesSequence\Model\Meta | \PHPUnit_Framework_MockObject_MockObject + */ + private $meta; + + /** + * @var \Magento\SalesSequence\Model\Sequence + */ + private $sequence; + + protected function setUp() + { + $this->meta = $this->getMock( + 'Magento\SalesSequence\Model\Meta', + ['getSequenceTable', 'getActiveProfile'], + [], + '', + false + ); + $this->profile = $this->getMock( + 'Magento\SalesSequence\Model\Profile', + ['getSuffix', 'getPrefix', 'getStep', 'getStartValue'], + [], + '', + false + ); + $this->resource = $this->getMock( + 'Magento\Framework\App\Resource', + ['getConnection'], + [], + '', + false + ); + $this->adapter = $this->getMockForAbstractClass( + 'Magento\Framework\DB\Adapter\AdapterInterface', + [], + '', + false, + false, + true, + ['insert', 'lastInsertId'] + ); + $this->resource->expects($this->any())->method('getConnection')->willReturn($this->adapter); + $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->sequence = $helper->getObject('Magento\SalesSequence\Model\Sequence', [ + 'meta' => $this->meta, + 'resource' => $this->resource, + ]); + } + + public function testSequenceInitialNull() + { + $this->assertNull($this->sequence->getCurrentValue()); + } + + public function testSequenceNextValue() + { + $step = 777; + $startValue = 3; + $lastInsertId = 3; //at this step it will represents 777 + $this->profile->expects($this->atLeastOnce())->method('getStartValue')->willReturn($startValue); + $this->meta->expects($this->atLeastOnce()) + ->method('getActiveProfile') + ->willReturn( + $this->profile + ); + $this->meta->expects($this->atLeastOnce()) + ->method('getSequenceTable') + ->willReturn( + $this->sequenceParameters()->testTable + ); + $this->adapter->expects($this->exactly(3))->method('insert')->with( + $this->sequenceParameters()->testTable, + [] + ); + $this->profile->expects($this->exactly(3))->method('getSuffix')->willReturn( + $this->sequenceParameters()->suffix + ); + $this->profile->expects($this->exactly(3))->method('getPrefix')->willReturn( + $this->sequenceParameters()->prefix + ); + $this->profile->expects($this->exactly(3))->method('getStep')->willReturn($step); + $lastInsertId = $this->nextIncrementStep($lastInsertId, 780); + $lastInsertId = $this->nextIncrementStep($lastInsertId, 1557); + $this->nextIncrementStep($lastInsertId, 2334); + } + + /** + * @param $lastInsertId + * @param $sequenceNumber + * @return mixed + */ + private function nextIncrementStep($lastInsertId, $sequenceNumber) + { + $lastInsertId++; + $this->adapter->expects($this->at(1))->method('lastInsertId')->with( + $this->sequenceParameters()->testTable + )->willReturn( + $lastInsertId + ); + $this->assertEquals( + sprintf( + Sequence::DEFAULT_PATTERN, + $this->sequenceParameters()->prefix, + $sequenceNumber, + $this->sequenceParameters()->suffix + ), + $this->sequence->getNextValue() + ); + return $lastInsertId; + } + + /** + * @return \stdClass + */ + private function sequenceParameters() + { + $data = new \stdClass(); + $data->prefix = 'AA-'; + $data->suffix = '-0'; + $data->testTable = 'testSequence'; + return $data; + } +} diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..c9a209fb0438d852cfef2f805ef1f02451b1368a --- /dev/null +++ b/app/code/Magento/SalesSequence/composer.json @@ -0,0 +1,23 @@ +{ + "name": "magento/module-sales-sequence", + "description": "N/A", + "require": { + "php": "~5.5.0|~5.6.0", + "magento/framework": "0.74.0-beta3", + "magento/magento-composer-installer": "0.74.0-beta3" + }, + "type": "magento2-module", + "version": "0.74.0-beta3", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "extra": { + "map": [ + [ + "*", + "Magento/SalesSequence" + ] + ] + } +} diff --git a/app/code/Magento/SalesSequence/etc/module.xml b/app/code/Magento/SalesSequence/etc/module.xml new file mode 100644 index 0000000000000000000000000000000000000000..c948c4a55aadc433a6aa587d82f2162f7b0bb40a --- /dev/null +++ b/app/code/Magento/SalesSequence/etc/module.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> + <module name="Magento_SalesSequence" setup_version="2.0.1"> + </module> +</config> diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json index 04db045d1fd36024eacc4f9f8d3abc4cfc815682..095b2044a74f578f0ddebf4c671fec1e7732a3c1 100644 --- a/app/code/Magento/Search/composer.json +++ b/app/code/Magento/Search/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog-search": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-reports": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog-search": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-reports": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sendfriend/composer.json b/app/code/Magento/Sendfriend/composer.json index 17f3ff0c27f3cdb4208d4fc6bcfe9e97b57a2a68..ce11fc89a8290813f05403e49de4a7e00be0d434 100644 --- a/app/code/Magento/Sendfriend/composer.json +++ b/app/code/Magento/Sendfriend/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Shipping/Block/Adminhtml/View.php b/app/code/Magento/Shipping/Block/Adminhtml/View.php index ad98a7e5a97c95578bf1316e6e567f24de562390..599b4d2e8313fa5604c77a537327e945af6fc2cd 100644 --- a/app/code/Magento/Shipping/Block/Adminhtml/View.php +++ b/app/code/Magento/Shipping/Block/Adminhtml/View.php @@ -96,7 +96,11 @@ class View extends \Magento\Backend\Block\Widget\Form\Container 'Shipment #%1 | %3 (%2)', $this->getShipment()->getIncrementId(), $emailSent, - $this->formatDate($this->getShipment()->getCreatedAtDate(), \IntlDateFormatter::MEDIUM, true) + $this->formatDate( + $this->_localeDate->date(new \DateTime($this->getShipment()->getCreatedAt())), + \IntlDateFormatter::MEDIUM, + true + ) ); } diff --git a/app/code/Magento/Shipping/Model/Order/Pdf/Packaging.php b/app/code/Magento/Shipping/Model/Order/Pdf/Packaging.php index 2e481201d7f10cb6f2718eff22e947ddf4c48488..0be28fa810b8ec7850482c82f6b7162448fbd77e 100644 --- a/app/code/Magento/Shipping/Model/Order/Pdf/Packaging.php +++ b/app/code/Magento/Shipping/Model/Order/Pdf/Packaging.php @@ -44,7 +44,8 @@ class Packaging extends \Magento\Sales\Model\Order\Pdf\AbstractPdf * @param \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation - * @param \Magento\Shipping\Helper\Carrier $carrierHelper + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer + * @param Carrier $carrierHelper * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\View\LayoutInterface $layout * @param \Magento\Framework\Locale\ResolverInterface $localeResolver @@ -62,6 +63,7 @@ class Packaging extends \Magento\Sales\Model\Order\Pdf\AbstractPdf \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, Carrier $carrierHelper, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\View\LayoutInterface $layout, @@ -83,6 +85,7 @@ class Packaging extends \Magento\Sales\Model\Order\Pdf\AbstractPdf $pdfItemsFactory, $localeDate, $inlineTranslation, + $addressRenderer, $data ); } diff --git a/app/code/Magento/Shipping/Model/Order/Track.php b/app/code/Magento/Shipping/Model/Order/Track.php index 3eadf958b8902664592bab8b7e67be6664e3adea..81b506a7d10d9a821df999357d74a3c914feb8a9 100644 --- a/app/code/Magento/Shipping/Model/Order/Track.php +++ b/app/code/Magento/Shipping/Model/Order/Track.php @@ -35,8 +35,6 @@ class Track extends \Magento\Sales\Model\Order\Shipment\Track * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory * @param \Magento\Shipping\Model\CarrierFactory $carrierFactory @@ -51,8 +49,6 @@ class Track extends \Magento\Sales\Model\Order\Shipment\Track \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory, \Magento\Shipping\Model\CarrierFactory $carrierFactory, @@ -65,8 +61,6 @@ class Track extends \Magento\Sales\Model\Order\Shipment\Track $registry, $extensionFactory, $customAttributeFactory, - $localeDate, - $dateTime, $storeManager, $shipmentFactory, $resource, diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json index a20dd8cc86d23868eb2561b8d12302570fe0f54b..ad42bc9b1ec40619ced558907182ee0fbe1e3408 100644 --- a/app/code/Magento/Shipping/composer.json +++ b/app/code/Magento/Shipping/composer.json @@ -3,27 +3,27 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-contact": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-payment": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-contact": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-payment": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "ext-gd": "*", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-fedex": "0.74.0-beta2", - "magento/module-ups": "0.74.0-beta2" + "magento/module-fedex": "0.74.0-beta3", + "magento/module-ups": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml index b7ca7084bccfe024cd061de896662c95a8a6e62c..28693ed0e0b947dccd7e43c878597d93d9ff29e0 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/create/form.phtml @@ -59,31 +59,6 @@ require([ "mage/mage", "prototype" ], function(jQuery){ - - jQuery('body').one('packageInitialized', function(){ - packaging.setConfirmPackagingCallback(function(){ - packaging.setParamsCreateLabelRequest($('edit_form').serialize(true)); - packaging.sendCreateLabelRequest(); - }); - packaging.setLabelCreatedCallback(function(response){ - setLocation("<?php echo $block->getUrl( - 'sales/order/view', - ['order_id' => $block->getShipment()->getOrderId()] - ); ?>"); - }); - packaging.setCancelCallback(function() { - packaging.cleanPackages(); - $('create_shipping_label').checked = false; - toggleCreateLabelCheckbox(); - }); - packaging.setItemQtyCallback(function(itemId){ - var item = $$('[name="shipment[items]['+itemId+']"]')[0]; - if (item && !isNaN(item.value)) { - return item.value; - } - }); - }); - jQuery('#edit_form').mage('form').mage('validation'); }); diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml index 1a73f56dea862cc478b034816aecc15ef333f603..7876d0ae1b8754efad94938cd984a7e90169f560 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml @@ -26,9 +26,27 @@ require([ $$('select[name=package_container]')[0], <?php echo $girthEnabled; ?> ); - - jQuery('body').trigger('packageInitialized'); - + packaging.setConfirmPackagingCallback(function(){ + packaging.setParamsCreateLabelRequest($('edit_form').serialize(true)); + packaging.sendCreateLabelRequest(); + }); + packaging.setLabelCreatedCallback(function(response){ + setLocation("<?php echo $block->getUrl( + 'sales/order/view', + ['order_id' => $block->getShipment()->getOrderId()] + ); ?>"); + }); + packaging.setCancelCallback(function() { + packaging.cleanPackages(); + $('create_shipping_label').checked = false; + toggleCreateLabelCheckbox(); + }); + packaging.setItemQtyCallback(function(itemId){ + var item = $$('[name="shipment[items]['+itemId+']"]')[0]; + if (item && !isNaN(item.value)) { + return item.value; + } + }); }); </script> <div id="packaging_window" class="packaging-window" style="display:none;"> diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json index 8d0878ec176cf9f2e1430698ee9787e85d7c1b09..dbbd3f365fff9591c9d0934e10e88138b42077a8 100644 --- a/app/code/Magento/Sitemap/composer.json +++ b/app/code/Magento/Sitemap/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog-url-rewrite": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog-url-rewrite": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index c8c35d4401a6e1b73cfc9803080327c9d510aad9..43f81edd7b7d75508cd4c4c18c8e2a44cbc3bd20 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-directory": "0.74.0-beta2", - "magento/module-ui": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-directory": "0.74.0-beta3", + "magento/module-ui": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json index b5795c8cf572ce6e042b9c5303de88a3b3688edb..2fea3c3cfcf81e6528e459a5f28b9324492b876b 100644 --- a/app/code/Magento/Tax/composer.json +++ b/app/code/Magento/Tax/composer.json @@ -3,23 +3,23 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-reports": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-config": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-reports": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json index 8aedb28da45de8215cddff61e630a3e0be1d7224..786b3f2bc72e80dae638713cee19e67aed48b8db 100644 --- a/app/code/Magento/TaxImportExport/composer.json +++ b/app/code/Magento/TaxImportExport/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-tax": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-tax": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index b26672d7ac1b1a7cd5b2d0705ba0a8e11b05962f..e2e7b050ba5a3c2f138037efc8c0c312716d804b 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -3,23 +3,23 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-widget": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/module-media-storage": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-require-js": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-widget": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/module-media-storage": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-require-js": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-translation": "0.74.0-beta2" + "magento/module-translation": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json index 70864da21f8b8c6a8e5a41858cada3c080ebd112..5ef7062c8fdcc6d550fcdce0c74b9460b26cb27a 100644 --- a/app/code/Magento/Translation/composer.json +++ b/app/code/Magento/Translation/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta2", - "magento/module-developer": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-backend": "0.74.0-beta3", + "magento/module-developer": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json index f87854f14f8ce4ad5f97595870996f5e3ae8105f..780618e5cf468870e9eb6f3c3f214e763bfd0b89 100644 --- a/app/code/Magento/Ui/composer.json +++ b/app/code/Magento/Ui/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json index 20f97b0f584c966aa380087464568b83b37d4634..7a04f637ca5570453ce67ce90f49417d93cb28da 100644 --- a/app/code/Magento/Ups/composer.json +++ b/app/code/Magento/Ups/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json index 5c1a1dd683191df1966b8a4097a6916f7e8bfe50..27966c52a03f6097f6fca4ac2570daa35e7a87a9 100644 --- a/app/code/Magento/UrlRewrite/composer.json +++ b/app/code/Magento/UrlRewrite/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog-url-rewrite": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-cms-url-rewrite": "0.74.0-beta2", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog-url-rewrite": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-cms-url-rewrite": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json index b594a2acc6525460f0961f3fad8ccf1c2c77f3c0..73a9a8f8a933f08858a94d808659140112be17b3 100644 --- a/app/code/Magento/User/composer.json +++ b/app/code/Magento/User/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-authorization": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-integration": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-authorization": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-integration": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json index b98f0b6f9aff08165c319b08eea7597015ebb077..0fa47b8a4d31115c1f45ed9b02ac1ff2813786e3 100644 --- a/app/code/Magento/Usps/composer.json +++ b/app/code/Magento/Usps/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-shipping": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/module-config": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-shipping": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/module-config": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json index 3ebd1161f56fe1553a95f86d78d95f41cb53a1bb..faeb3b5b8be31c1f60c77cea447c802f21763b3c 100644 --- a/app/code/Magento/Variable/composer.json +++ b/app/code/Magento/Variable/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.4.11|~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta2", - "magento/module-email": "0.74.0-beta2", - "magento/module-store": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-backend": "0.74.0-beta3", + "magento/module-email": "0.74.0-beta3", + "magento/module-store": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json index 790873f60c90f7a4ccdeb117ff9215e79d0c6b8a..e3ffca2489a20c42bb0e7b6eba89ce5014fee859 100644 --- a/app/code/Magento/Version/composer.json +++ b/app/code/Magento/Version/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json index 737fbb38189e971ee9bc6d29040a741b1ad88c5e..71143ada523b4b3f67cd55340d5ab62da5ca50d6 100644 --- a/app/code/Magento/Webapi/composer.json +++ b/app/code/Magento/Webapi/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-authorization": "0.74.0-beta2", - "magento/module-integration": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-authorization": "0.74.0-beta3", + "magento/module-integration": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-user": "0.74.0-beta2" + "magento/module-user": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json index 25eedfda977a62a7110e0aa1a7193878f846bf34..3639d810e64c5b1e0c48524d1fcb655ce99d60d8 100644 --- a/app/code/Magento/Weee/composer.json +++ b/app/code/Magento/Weee/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-tax": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-directory": "0.74.0-beta2", - "magento/module-eav": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-quote": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-tax": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-directory": "0.74.0-beta3", + "magento/module-eav": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-quote": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json index a1981449435f5125c48e5251ee76eeb14b77ac42..61f36c3399ff8207edb50e19400b3487d4cbef80 100644 --- a/app/code/Magento/Widget/composer.json +++ b/app/code/Magento/Widget/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-cms": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-variable": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-cms": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-variable": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json index 567e48897c9d618d940785d8e587c734c49cdc44..c923804a4dd3af486bb9eee53a52ea4a5ac292a3 100644 --- a/app/code/Magento/Wishlist/composer.json +++ b/app/code/Magento/Wishlist/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta2", - "magento/module-customer": "0.74.0-beta2", - "magento/module-catalog": "0.74.0-beta2", - "magento/module-checkout": "0.74.0-beta2", - "magento/module-theme": "0.74.0-beta2", - "magento/module-catalog-inventory": "0.74.0-beta2", - "magento/module-rss": "0.74.0-beta2", - "magento/module-backend": "0.74.0-beta2", - "magento/module-sales": "0.74.0-beta2", - "magento/module-grouped-product": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", - "magento/module-ui": "0.74.0-beta2", + "magento/module-store": "0.74.0-beta3", + "magento/module-customer": "0.74.0-beta3", + "magento/module-catalog": "0.74.0-beta3", + "magento/module-checkout": "0.74.0-beta3", + "magento/module-theme": "0.74.0-beta3", + "magento/module-catalog-inventory": "0.74.0-beta3", + "magento/module-rss": "0.74.0-beta3", + "magento/module-backend": "0.74.0-beta3", + "magento/module-sales": "0.74.0-beta3", + "magento/module-grouped-product": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", + "magento/module-ui": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-configurable-product": "0.74.0-beta2", - "magento/module-downloadable": "0.74.0-beta2", - "magento/module-bundle": "0.74.0-beta2", - "magento/module-cookie": "0.74.0-beta2" + "magento/module-configurable-product": "0.74.0-beta3", + "magento/module-downloadable": "0.74.0-beta3", + "magento/module-bundle": "0.74.0-beta3", + "magento/module-cookie": "0.74.0-beta3" }, "type": "magento2-module", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json index df9acf8487c6a4c48f51fd7237f17998a2af64bf..2da2d3ee1eb8c2ce021f8d7f1806b8d391823dcf 100644 --- a/app/design/adminhtml/Magento/backend/composer.json +++ b/app/design/adminhtml/Magento/backend/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-theme", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json index c0d99f390e24c49932d3a13c943004b7259241d2..b85a378584ae6fd819832ec76bcf7f66fab15c28 100644 --- a/app/design/frontend/Magento/blank/composer.json +++ b/app/design/frontend/Magento/blank/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-theme", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json index 7c4a0c1ab12379cec4f85df3b34bbb76efc2761e..25be235eaeacf2ee207379d80839b4bdf5c7f3fa 100644 --- a/app/design/frontend/Magento/luma/composer.json +++ b/app/design/frontend/Magento/luma/composer.json @@ -3,12 +3,12 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/theme-frontend-blank": "0.74.0-beta2", - "magento/framework": "0.74.0-beta2", + "magento/theme-frontend-blank": "0.74.0-beta3", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-theme", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/i18n/magento/de_de/composer.json b/app/i18n/magento/de_de/composer.json index 3489faab6623a1096e4bce93c145e2db131f690b..4b072c85efaf96fee47d0199fa1afe296145410e 100644 --- a/app/i18n/magento/de_de/composer.json +++ b/app/i18n/magento/de_de/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-de_de", "description": "German (Germany) language", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/en_us/composer.json b/app/i18n/magento/en_us/composer.json index 03f6fae4438e0e91e923c22312afe699e0df225e..ff1184c2d063cabac461dcb047725ed6719119bd 100644 --- a/app/i18n/magento/en_us/composer.json +++ b/app/i18n/magento/en_us/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-en_us", "description": "English (United States) language", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/es_es/composer.json b/app/i18n/magento/es_es/composer.json index 7b80bcc0f53436a9be865f48c0891a3c44582e39..395abacc618d5f02c5debeae965ca9db887a9ee4 100644 --- a/app/i18n/magento/es_es/composer.json +++ b/app/i18n/magento/es_es/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-es_es", "description": "Spanish (Spain) language", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/fr_fr/composer.json b/app/i18n/magento/fr_fr/composer.json index 56a2643eef7abb99e163df1e69543150cf0543e2..4c11998bcb24a99e6a58d166c50727a7e0351205 100644 --- a/app/i18n/magento/fr_fr/composer.json +++ b/app/i18n/magento/fr_fr/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-fr_fr", "description": "French (France) language", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/nl_nl/composer.json b/app/i18n/magento/nl_nl/composer.json index 700e4cab06051364f4e5306a08f2ec6a0856b0af..b7677a5668ce19514e4d4be962ed4a097c017620 100644 --- a/app/i18n/magento/nl_nl/composer.json +++ b/app/i18n/magento/nl_nl/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-nl_nl", "description": "Dutch (Netherlands) language", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/pt_br/composer.json b/app/i18n/magento/pt_br/composer.json index d6a8fb0b185001e89b576dfbf7d591f0829f39ea..888ac4cc0845b33178045494b7202ee6d9ece9d3 100644 --- a/app/i18n/magento/pt_br/composer.json +++ b/app/i18n/magento/pt_br/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-pt_br", "description": "Portuguese (Brazil) language", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/zh_cn/composer.json b/app/i18n/magento/zh_cn/composer.json index 5d4c631ba8fb2d6c41cdd3751ddd21050058c2b1..1bcc7710e4e884a6d4f91c93ab0e93ab2bdbbbeb 100644 --- a/app/i18n/magento/zh_cn/composer.json +++ b/app/i18n/magento/zh_cn/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-zh_cn", "description": "Chinese (China) language", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta2", + "magento/framework": "0.74.0-beta3", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/composer.json b/composer.json index a0313c405b16650680d1ddecf2588bba16416653..f1055b4586c58903f2ffd3888b2d3a77f73f2cd9 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "magento/project-community-edition", "description": "Magento project (Community Edition)", "type": "project", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0" @@ -122,6 +122,7 @@ "magento/module-rule": "self.version", "magento/module-sales": "self.version", "magento/module-sales-rule": "self.version", + "magento/module-sales-sequence": "self.version", "magento/module-search": "self.version", "magento/module-sendfriend": "self.version", "magento/module-shipping": "self.version", diff --git a/composer.lock b/composer.lock index 00989580f30f29375e5f2fe27c8a2668836854a0..46fb23e53e6036a07207e6089a2add67a3ee549e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2540c30fb9f7ddea359e3a1f9bc67097", + "hash": "511a3e2167683bd8b75f3cb361ded487", "packages": [ { "name": "composer/composer", @@ -471,17 +471,17 @@ }, { "name": "symfony/console", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34" + "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/e44154bfe3e41e8267d7a3794cd9da9a51cfac34", - "reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34", + "url": "https://api.github.com/repos/symfony/Console/zipball/5b91dc4ed5eb08553f57f6df04c4730a73992667", + "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667", "shasum": "" }, "require": { @@ -490,6 +490,7 @@ "require-dev": { "psr/log": "~1.0", "symfony/event-dispatcher": "~2.1", + "symfony/phpunit-bridge": "~2.7", "symfony/process": "~2.1" }, "suggest": { @@ -524,26 +525,29 @@ ], "description": "Symfony Console Component", "homepage": "http://symfony.com", - "time": "2015-01-25 04:39:26" + "time": "2015-03-30 15:54:10" }, { "name": "symfony/finder", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/Finder", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "16513333bca64186c01609961a2bb1b95b5e1355" + "reference": "5dbe2e73a580618f5b4880fda93406eed25de251" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/16513333bca64186c01609961a2bb1b95b5e1355", - "reference": "16513333bca64186c01609961a2bb1b95b5e1355", + "url": "https://api.github.com/repos/symfony/Finder/zipball/5dbe2e73a580618f5b4880fda93406eed25de251", + "reference": "5dbe2e73a580618f5b4880fda93406eed25de251", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -571,26 +575,29 @@ ], "description": "Symfony Finder Component", "homepage": "http://symfony.com", - "time": "2015-01-03 08:01:59" + "time": "2015-03-30 15:54:10" }, { "name": "symfony/process", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/Process", "source": { "type": "git", "url": "https://github.com/symfony/Process.git", - "reference": "ecfc23e89d9967999fa5f60a1e9af7384396e9ae" + "reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/ecfc23e89d9967999fa5f60a1e9af7384396e9ae", - "reference": "ecfc23e89d9967999fa5f60a1e9af7384396e9ae", + "url": "https://api.github.com/repos/symfony/Process/zipball/a8bebaec1a9dc6cde53e0250e32917579b0be552", + "reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -618,7 +625,7 @@ ], "description": "Symfony Process Component", "homepage": "http://symfony.com", - "time": "2015-01-25 04:39:26" + "time": "2015-03-30 15:54:10" }, { "name": "tubalmartin/cssmin", @@ -2000,16 +2007,16 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.5.1", + "version": "v1.6", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "85777ebc6a1dac48c904acf9412b29b58b5dd592" + "reference": "81a46f8a0f92f1ba64587b384a275d0766cf2c70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/85777ebc6a1dac48c904acf9412b29b58b5dd592", - "reference": "85777ebc6a1dac48c904acf9412b29b58b5dd592", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/81a46f8a0f92f1ba64587b384a275d0766cf2c70", + "reference": "81a46f8a0f92f1ba64587b384a275d0766cf2c70", "shasum": "" }, "require": { @@ -2049,7 +2056,7 @@ } ], "description": "A script to automatically fix Symfony Coding Standard", - "time": "2015-03-13 19:33:24" + "time": "2015-03-26 21:09:59" }, { "name": "league/climate", @@ -2203,16 +2210,16 @@ }, { "name": "phpmd/phpmd", - "version": "2.2.1", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "58c4b00f924d301e8c5281f40cfa9a66f3df9eee" + "reference": "7dc4a6b5c07b119ab5da7960b56303fa6855eb84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/58c4b00f924d301e8c5281f40cfa9a66f3df9eee", - "reference": "58c4b00f924d301e8c5281f40cfa9a66f3df9eee", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/7dc4a6b5c07b119ab5da7960b56303fa6855eb84", + "reference": "7dc4a6b5c07b119ab5da7960b56303fa6855eb84", "shasum": "" }, "require": { @@ -2261,7 +2268,7 @@ "phpmd", "pmd" ], - "time": "2015-03-02 10:26:50" + "time": "2015-03-26 07:47:05" }, { "name": "phpunit/php-code-coverage", @@ -2583,25 +2590,25 @@ }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.0", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "c63d2367247365f688544f0d500af90a11a44c65" + "reference": "74ffb87f527f24616f72460e54b595f508dccb5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", - "reference": "c63d2367247365f688544f0d500af90a11a44c65", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c", + "reference": "74ffb87f527f24616f72460e54b595f508dccb5c", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.1", + "doctrine/instantiator": "~1.0,>=1.0.2", "php": ">=5.3.3", "phpunit/php-text-template": "~1.2" }, "require-dev": { - "phpunit/phpunit": "~4.3" + "phpunit/phpunit": "~4.4" }, "suggest": { "ext-soap": "*" @@ -2634,7 +2641,7 @@ "mock", "xunit" ], - "time": "2014-10-03 05:12:11" + "time": "2015-04-02 05:36:41" }, { "name": "sebastian/comparator", @@ -2702,16 +2709,16 @@ }, { "name": "sebastian/diff", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", "shasum": "" }, "require": { @@ -2723,7 +2730,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -2750,32 +2757,32 @@ "keywords": [ "diff" ], - "time": "2014-08-15 10:29:00" + "time": "2015-02-22 15:13:53" }, { "name": "sebastian/environment", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.3" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { @@ -2800,7 +2807,7 @@ "environment", "hhvm" ], - "time": "2014-10-25 08:00:45" + "time": "2015-01-01 10:01:08" }, { "name": "sebastian/exporter", @@ -2923,16 +2930,16 @@ }, { "name": "sebastian/version", - "version": "1.0.4", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" + "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", - "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", + "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", "shasum": "" }, "type": "library", @@ -2954,7 +2961,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-12-15 14:25:24" + "time": "2015-02-24 06:35:25" }, { "name": "sjparkinson/static-review", @@ -3086,23 +3093,26 @@ }, { "name": "symfony/config", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408" + "reference": "d91be01336605db8da21b79bc771e46a7276d1bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/a9f781ba1221067d1f07c8cec0bc50f81b8d7408", - "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408", + "url": "https://api.github.com/repos/symfony/Config/zipball/d91be01336605db8da21b79bc771e46a7276d1bc", + "reference": "d91be01336605db8da21b79bc771e46a7276d1bc", "shasum": "" }, "require": { "php": ">=5.3.3", "symfony/filesystem": "~2.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -3130,21 +3140,21 @@ ], "description": "Symfony Config Component", "homepage": "http://symfony.com", - "time": "2015-01-21 20:57:55" + "time": "2015-03-30 15:54:10" }, { "name": "symfony/dependency-injection", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "42bbb43fab66292a1865dc9616c299904c3d4d14" + "reference": "8e9007012226b4bd41f8afed855c452cf5edc3a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/42bbb43fab66292a1865dc9616c299904c3d4d14", - "reference": "42bbb43fab66292a1865dc9616c299904c3d4d14", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/8e9007012226b4bd41f8afed855c452cf5edc3a6", + "reference": "8e9007012226b4bd41f8afed855c452cf5edc3a6", "shasum": "" }, "require": { @@ -3156,6 +3166,7 @@ "require-dev": { "symfony/config": "~2.2", "symfony/expression-language": "~2.6", + "symfony/phpunit-bridge": "~2.7", "symfony/yaml": "~2.1" }, "suggest": { @@ -3190,21 +3201,21 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "http://symfony.com", - "time": "2015-01-25 04:39:26" + "time": "2015-03-30 15:54:10" }, { "name": "symfony/event-dispatcher", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813" + "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/f75989f3ab2743a82fe0b03ded2598a2b1546813", - "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/70f7c8478739ad21e3deef0d977b38c77f1fb284", + "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284", "shasum": "" }, "require": { @@ -3215,6 +3226,7 @@ "symfony/config": "~2.0,>=2.0.5", "symfony/dependency-injection": "~2.6", "symfony/expression-language": "~2.6", + "symfony/phpunit-bridge": "~2.7", "symfony/stopwatch": "~2.3" }, "suggest": { @@ -3248,26 +3260,29 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com", - "time": "2015-02-01 16:10:57" + "time": "2015-03-13 17:37:22" }, { "name": "symfony/filesystem", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/Filesystem", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7" + "reference": "4983964b3693e4f13449cb3800c64a9112c301b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a1f566d1f92e142fa1593f4555d6d89e3044a9b7", - "reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/4983964b3693e4f13449cb3800c64a9112c301b4", + "reference": "4983964b3693e4f13449cb3800c64a9112c301b4", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -3295,26 +3310,29 @@ ], "description": "Symfony Filesystem Component", "homepage": "http://symfony.com", - "time": "2015-01-03 21:13:09" + "time": "2015-03-22 16:55:57" }, { "name": "symfony/stopwatch", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/Stopwatch", "source": { "type": "git", "url": "https://github.com/symfony/Stopwatch.git", - "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c" + "reference": "5f196e84b5640424a166d2ce9cca161ce1e9d912" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/e8da5286132ba75ce4b4275fbf0f4cd369bfd71c", - "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/5f196e84b5640424a166d2ce9cca161ce1e9d912", + "reference": "5f196e84b5640424a166d2ce9cca161ce1e9d912", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -3342,26 +3360,29 @@ ], "description": "Symfony Stopwatch Component", "homepage": "http://symfony.com", - "time": "2015-01-03 08:01:59" + "time": "2015-03-22 16:55:57" }, { "name": "symfony/yaml", - "version": "v2.6.4", + "version": "v2.6.6", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8" + "reference": "174f009ed36379a801109955fc5a71a49fe62dd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8", - "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/174f009ed36379a801109955fc5a71a49fe62dd4", + "reference": "174f009ed36379a801109955fc5a71a49fe62dd4", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -3389,7 +3410,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2015-01-25 04:39:26" + "time": "2015-03-30 15:54:10" } ], "aliases": [], @@ -3399,6 +3420,7 @@ "phpmd/phpmd": 0 }, "prefer-stable": false, + "prefer-lowest": false, "platform": { "php": "~5.5.0|~5.6.0" }, diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php index 4c3db4f68a620fc9a4cd03aa5011d66d4f312e48..100ac28b9fb0b8af853c51d3b2d713973f7a735d 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php @@ -40,7 +40,8 @@ class CategoryRepositoryTest extends WebapiAbstract $this->assertArrayHasKey('created_at', $result); $this->assertArrayHasKey('updated_at', $result); $this->assertArrayHasKey('children', $result); - unset($result['created_at'], $result['updated_at'], $result['children']); + $this->assertArrayHasKey('custom_attributes', $result); + unset($result['created_at'], $result['updated_at'], $result['children'], $result['custom_attributes']); ksort($expected); ksort($result); $this->assertEquals($expected, $result); diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php index 86a5c051ae44c64a74e5d01b23c84c1ab82e00ea..f39b0c78f14d94e253e5c0c09d325bf3f0fbd5a2 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php @@ -40,7 +40,7 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF { $this->createServiceInfo = [ 'rest' => [ - 'resourcePath' => '/V1/products/media', + 'resourcePath' => '/V1/products/simple/media', 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, ], 'soap' => [ @@ -104,27 +104,19 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF public function testCreate() { $requestData = [ - "sku" => 'simple', - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), - 'mime_type' => 'image/jpeg', - 'name' => 'test_image' - ] - ] - ], - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), + 'mime_type' => 'image/jpeg', + 'name' => 'test_image' + ] ]; - $actualResult = $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $actualResult = $this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]); $targetProduct = $this->getTargetSimpleProduct(); $mediaGallery = $targetProduct->getData('media_gallery'); @@ -144,28 +136,26 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF public function testCreateWithNotDefaultStoreId() { $requestData = [ - 'sku' => 'simple', - 'store_id' => 1, - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), - 'mime_type' => 'image/jpeg', - 'name' => 'test_image', - ] - ] - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), + 'mime_type' => 'image/jpeg', + 'name' => 'test_image', ] ]; - $actualResult = $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $actualResult = $this->_webApiCall( + $this->createServiceInfo, + [ + 'sku' => 'simple', + 'entry' => $requestData, + 'storeId' => 1, + ] + ); $targetProduct = $this->getTargetSimpleProduct(); $mediaGallery = $targetProduct->getData('media_gallery'); $this->assertCount(1, $mediaGallery['images']); @@ -287,28 +277,19 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF public function testCreateThrowsExceptionIfThereIsNoStoreWithProvidedStoreId() { $requestData = [ - 'sku' => 'simple', - 'store_id' => 9999, // target store view does not exist - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), - 'mime_type' => 'image/jpeg', - 'name' => 'test_image', - ] - ] - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), + 'mime_type' => 'image/jpeg', + 'name' => 'test_image', ] ]; - $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData, 'storeId' => 99999]); } /** @@ -320,28 +301,19 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF { $encodedContent = 'not_a_base64_encoded_content'; $requestData = [ - 'sku' => 'simple', - 'store_id' => 0, - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => $encodedContent, - 'mime_type' => 'image/jpeg', - 'name' => 'test_image', - ] - ] - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => $encodedContent, + 'mime_type' => 'image/jpeg', + 'name' => 'test_image', ] ]; - $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]); } /** @@ -353,28 +325,19 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF { $encodedContent = base64_encode('not_an_image'); $requestData = [ - 'sku' => 'simple', - 'store_id' => 0, - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => $encodedContent, - 'mime_type' => 'image/jpeg', - 'name' => 'test_image', - ] - ] - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => $encodedContent, + 'mime_type' => 'image/jpeg', + 'name' => 'test_image', ] ]; - $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]); } /** @@ -386,28 +349,19 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF { $encodedContent = base64_encode(file_get_contents($this->testImagePath)); $requestData = [ - 'sku' => 'simple', - 'store_id' => 0, - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => $encodedContent, - 'mime_type' => 'wrong_mime_type', - 'name' => 'test_image', - ] - ] - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => $encodedContent, + 'mime_type' => 'wrong_mime_type', + 'name' => 'test_image', ] ]; - $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]); } /** @@ -416,31 +370,22 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF */ public function testCreateThrowsExceptionIfTargetProductDoesNotExist() { - $this->createServiceInfo['rest']['resourcePath'] = '/V1/products/media'; + $this->createServiceInfo['rest']['resourcePath'] = '/V1/products/wrong_product_sku/media'; $requestData = [ - 'sku' => 'wrong_product_sku', - 'store_id' => 0, - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), - 'mime_type' => 'image/jpeg', - 'name' => 'test_image', - ] - ] - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), + 'mime_type' => 'image/jpeg', + 'name' => 'test_image', ] ]; - $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]); } /** @@ -451,28 +396,19 @@ class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestF public function testCreateThrowsExceptionIfProvidedImageNameContainsForbiddenCharacters() { $requestData = [ - 'sku' => 'wrong_product_sku', - 'store_id' => 0, - "custom_attributes" => [ - "media_gallery" => [ - 'attribute_code' => 'media_gallery', - 'value' => [ - 'id' => null, - 'label' => 'Image Text', - 'position' => 1, - 'types' => ['image'], - 'disabled' => false, - 'content' => [ - 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), - 'mime_type' => 'image/jpeg', - 'name' => 'test/\\{}|:"<>', // Cannot contain \ / : * ? " < > | - ] - ] - ], + 'id' => null, + 'label' => 'Image Text', + 'position' => 1, + 'types' => ['image'], + 'disabled' => false, + 'content' => [ + 'entry_data' => base64_encode(file_get_contents($this->testImagePath)), + 'mime_type' => 'image/jpeg', + 'name' => 'test/\\{}|:"<>', // Cannot contain \ / : * ? " < > | ] ]; - $this->_webApiCall($this->createServiceInfo, ['product' => $requestData]); + $this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 615675efa90a488421e7d4a4674d51b9355527f5..fb6588a7f4107cf2ff07095ff3820e442ee10a87 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -15,6 +15,9 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract const SERVICE_VERSION = 'V1'; const RESOURCE_PATH = '/V1/products'; + const KEY_GROUP_PRICES = 'group_prices'; + const KEY_TIER_PRICES = 'tier_prices'; + private $productData = [ [ ProductInterface::SKU => 'simple', @@ -36,9 +39,18 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract public function testGet() { $productData = $this->productData[0]; + + $response = $this->getProduct($productData[ProductInterface::SKU]); + foreach ([ProductInterface::SKU, ProductInterface::NAME, ProductInterface::PRICE] as $key) { + $this->assertEquals($productData[$key], $response[$key]); + } + } + + protected function getProduct($sku) + { $serviceInfo = [ 'rest' => [ - 'resourcePath' => self::RESOURCE_PATH . '/' . $productData[ProductInterface::SKU], + 'resourcePath' => self::RESOURCE_PATH . '/' . $sku, 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, ], 'soap' => [ @@ -48,10 +60,8 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract ], ]; - $response = $this->_webApiCall($serviceInfo, ['sku' => $productData[ProductInterface::SKU]]); - foreach ([ProductInterface::SKU, ProductInterface::NAME, ProductInterface::PRICE] as $key) { - $this->assertEquals($productData[$key], $response[$key]); - } + $response = $this->_webApiCall($serviceInfo, ['sku' => $sku]); + return $response; } public function testGetNoSuchEntityException() @@ -114,6 +124,291 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract $this->deleteProduct($product[ProductInterface::SKU]); } + public function testProductLinks() + { + $this->markTestSkipped('Skipped until MAGETWO-35458 is ready'); + // Create simple product + $productData = [ + ProductInterface::SKU => "product_simple_500", + ProductInterface::NAME => "Product Simple 500", + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 100, + ProductInterface::STATUS => 1, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::ATTRIBUTE_SET_ID => 4, + ]; + + $this->saveProduct($productData); + $productLinkData = ["product_sku" => "product_simple_with_related_500", "link_type" => "related", + "linked_product_sku" => "product_simple_500", "linked_product_type" => "simple", + "position" => 0]; + $productWithRelatedData = [ + ProductInterface::SKU => "product_simple_with_related_500", + ProductInterface::NAME => "Product Simple with Related 500", + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 100, + ProductInterface::STATUS => 1, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::ATTRIBUTE_SET_ID => 4, + "product_links" => [$productLinkData] + ]; + + $this->saveProduct($productWithRelatedData); + $response = $this->getProduct("product_simple_with_related_500"); + + $this->assertArrayHasKey('product_links', $response); + $links = $response['product_links']; + $this->assertEquals(1, count($links)); + $this->assertEquals($productLinkData, $links[0]); + + // update link information + $productLinkData = ["product_sku" => "product_simple_with_related_500", "link_type" => "upsell", + "linked_product_sku" => "product_simple_500", "linked_product_type" => "simple", + "position" => 0]; + $productWithUpsellData = [ + ProductInterface::SKU => "product_simple_with_related_500", + ProductInterface::NAME => "Product Simple with Related 500", + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 100, + ProductInterface::STATUS => 1, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::ATTRIBUTE_SET_ID => 4, + "product_links" => [$productLinkData] + ]; + + $this->saveProduct($productWithUpsellData); + $response = $this->getProduct("product_simple_with_related_500"); + + $this->assertArrayHasKey('product_links', $response); + $links = $response['product_links']; + $this->assertEquals(1, count($links)); + $this->assertEquals($productLinkData, $links[0]); + + // Remove link + $productWithNoLinkData = [ + ProductInterface::SKU => "product_simple_with_related_500", + ProductInterface::NAME => "Product Simple with Related 500", + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 100, + ProductInterface::STATUS => 1, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::ATTRIBUTE_SET_ID => 4, + "product_links" => [] + ]; + + $this->saveProduct($productWithNoLinkData); + $response = $this->getProduct("product_simple_with_related_500"); + + $this->assertArrayHasKey('product_links', $response); + $links = $response['product_links']; + $this->assertEquals(1, count($links)); + $this->assertEquals([], $links[0]); + + $this->deleteProduct("product_simple_500"); + $this->deleteProduct("product_simple_with_related_500"); + } + + protected function getOptionsData() + { + return [ + [ + "product_sku" => "simple", + "title" => "DropdownOption", + "type" => "drop_down", + "sort_order" => 0, + "is_require" => true, + "values" => [ + [ + "title" => "DropdownOption2_1", + "sort_order" => 0, + "price" => 3, + "price_type" => "fixed", + ], + ], + ], + [ + "product_sku" => "simple", + "title" => "CheckboxOption", + "type" => "checkbox", + "sort_order" => 1, + "is_require" => false, + "values" => [ + [ + "title" => "CheckBoxValue1", + "price" => 5, + "price_type" => "fixed", + "sort_order" => 1, + ], + ], + ], + ]; + } + + public function testProductOptions() + { + //Create product with options + $productData = $this->getSimpleProductData(); + $optionsDataInput = $this->getOptionsData(); + $productData['options'] = $optionsDataInput; + $this->saveProduct($productData); + $response = $this->getProduct($productData[ProductInterface::SKU]); + + $this->assertArrayHasKey('options', $response); + $options = $response['options']; + $this->assertEquals(2, count($options)); + $this->assertEquals(1, count($options[0]['values'])); + $this->assertEquals(1, count($options[1]['values'])); + + //update the product options, adding a value to option 1, delete an option and create a new option + $options[0]['values'][] = [ + "title" => "Value2", + "price" => 6, + "price_type" => "fixed", + 'sort_order' => 3, + ]; + $option1Id = $options[0]['option_id']; + $option2Id = $options[1]['option_id']; + $options[1] = [ + "product_sku" => "simple", + "title" => "DropdownOption2", + "type" => "drop_down", + "sort_order" => 3, + "is_require" => false, + "values" => [ + [ + "title" => "Value3", + "price" => 7, + "price_type" => "fixed", + "sort_order" => 4, + ], + ], + ]; + $response['options'] = $options; + $response = $this->updateProduct($response); + $this->assertArrayHasKey('options', $response); + $options = $response['options']; + $this->assertEquals(2, count($options)); + $this->assertEquals(2, count($options[0]['values'])); + $this->assertEquals(1, count($options[1]['values'])); + $this->assertEquals($option1Id, $options[0]['option_id']); + $this->assertTrue($option2Id < $options[1]['option_id']); + + //update product without setting options field, option should not be changed + unset($response['options']); + $this->updateProduct($response); + $response = $this->getProduct($productData[ProductInterface::SKU]); + $this->assertArrayHasKey('options', $response); + $options = $response['options']; + $this->assertEquals(2, count($options)); + + //update product with empty options, options should be removed + $response['options'] = []; + $response = $this->updateProduct($response); + $this->assertEmpty($response['options']); + + $this->deleteProduct($productData[ProductInterface::SKU]); + } + + public function testProductWithMediaGallery() + { + $testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg'; + $encodedImage = base64_encode(file_get_contents($testImagePath)); + //create a product with media gallery + $filename1 = 'tiny1' . time(); + $filename2 = 'tiny2' . time(); + $productData = $this->getSimpleProductData(); + $productData['media_gallery_entries'] = [ + [ + 'position' => 1, + 'disabled' => true, + 'label' => 'tiny1', + 'types' => [], + 'content' => [ + 'mime_type' => 'image/jpeg', + 'name' => $filename1, + 'entry_data' => $encodedImage, + ] + ], + [ + 'position' => 2, + 'disabled' => false, + 'label' => 'tiny2', + 'types' => ['image', 'small_image'], + 'content' => [ + 'mime_type' => 'image/jpeg', + 'name' => $filename2, + 'entry_data' => $encodedImage, + ] + ], + ]; + $response = $this->saveProduct($productData); + $this->assertArrayHasKey('media_gallery_entries', $response); + $mediaGalleryEntries = $response['media_gallery_entries']; + $this->assertEquals(2, count($mediaGalleryEntries)); + $id = $mediaGalleryEntries[0]['id']; + foreach ($mediaGalleryEntries as &$entry) { + unset($entry['id']); + } + $expectedValue = [ + [ + 'label' => 'tiny1', + 'position' => 1, + 'disabled' => true, + 'types' => [], + 'file' => '/t/i/' . $filename1 . '.jpg', + ], + [ + 'label' => 'tiny2', + 'position' => 2, + 'disabled' => false, + 'types' => ['image', 'small_image'], + 'file' => '/t/i/' . $filename2 . '.jpg', + ], + ]; + $this->assertEquals($expectedValue, $mediaGalleryEntries); + //update the product media gallery + $response['media_gallery_entries'] = [ + [ + 'id' => $id, + 'label' => 'tiny1_new_label', + 'position' => 1, + 'disabled' => false, + 'types' => ['image', 'small_image'], + 'file' => '/t/i/' . $filename1 . '.jpg', + ], + ]; + $response = $this->updateProduct($response); + $mediaGalleryEntries = $response['media_gallery_entries']; + $this->assertEquals(1, count($mediaGalleryEntries)); + unset($mediaGalleryEntries[0]['id']); + $expectedValue = [ + [ + 'label' => 'tiny1_new_label', + 'position' => 1, + 'disabled' => false, + 'types' => ['image', 'small_image'], + 'file' => '/t/i/' . $filename1 . '.jpg', + ] + ]; + $this->assertEquals($expectedValue, $mediaGalleryEntries); + //don't set the media_gallery_entries field, existing entry should not be touched + unset($response['media_gallery_entries']); + $response = $this->updateProduct($response); + $mediaGalleryEntries = $response['media_gallery_entries']; + $this->assertEquals(1, count($mediaGalleryEntries)); + unset($mediaGalleryEntries[0]['id']); + $this->assertEquals($expectedValue, $mediaGalleryEntries); + //pass empty array, delete all existing media gallery entries + $response['media_gallery_entries'] = []; + $response = $this->updateProduct($response); + $this->assertEquals(true, empty($response['media_gallery_entries'])); + $this->deleteProduct($productData[ProductInterface::SKU]); + } + /** * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php */ @@ -124,13 +419,24 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract ProductInterface::SKU => 'simple', //sku from fixture ]; $product = $this->getSimpleProductData($productData); + $response = $this->updateProduct($product); + + $this->assertArrayHasKey(ProductInterface::SKU, $response); + $this->assertArrayHasKey(ProductInterface::NAME, $response); + $this->assertEquals($productData[ProductInterface::NAME], $response[ProductInterface::NAME]); + $this->assertEquals($productData[ProductInterface::SKU], $response[ProductInterface::SKU]); + } + + protected function updateProduct($product) + { + $sku = $product[ProductInterface::SKU]; if (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) { $product[ProductInterface::SKU] = null; } $serviceInfo = [ 'rest' => [ - 'resourcePath' => self::RESOURCE_PATH . '/' . $productData[ProductInterface::SKU], + 'resourcePath' => self::RESOURCE_PATH . '/' . $sku, 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT, ], 'soap' => [ @@ -141,11 +447,7 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract ]; $requestData = ['product' => $product]; $response = $this->_webApiCall($serviceInfo, $requestData); - - $this->assertArrayHasKey(ProductInterface::SKU, $response); - $this->assertArrayHasKey(ProductInterface::NAME, $response); - $this->assertEquals($productData[ProductInterface::NAME], $response[ProductInterface::NAME]); - $this->assertEquals($productData[ProductInterface::SKU], $response[ProductInterface::SKU]); + return $response; } /** @@ -206,6 +508,51 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract $this->assertEquals('simple', $response['items'][0]['sku']); } + protected function convertCustomAttributesToAssociativeArray($customAttributes) + { + $converted = []; + foreach ($customAttributes as $customAttribute) { + $converted[$customAttribute['attribute_code']] = $customAttribute['value']; + } + return $converted; + } + + protected function convertAssociativeArrayToCustomAttributes($data) + { + $customAttributes = []; + foreach ($data as $attributeCode => $attributeValue) { + $customAttributes[] = ['attribute_code' => $attributeCode, 'value' => $attributeValue]; + } + return $customAttributes; + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testEavAttributes() + { + $response = $this->getProduct('simple'); + + $this->assertNotEmpty($response['custom_attributes']); + $customAttributesData = $this->convertCustomAttributesToAssociativeArray($response['custom_attributes']); + $this->assertNotTrue(isset($customAttributesData['name'])); + $this->assertNotTrue(isset($customAttributesData['tier_price'])); + + //Set description + $descriptionValue = "new description"; + $customAttributesData['description'] = $descriptionValue; + $response['custom_attributes'] = $this->convertAssociativeArrayToCustomAttributes($customAttributesData); + + $response = $this->updateProduct($response); + $this->assertNotEmpty($response['custom_attributes']); + + $customAttributesData = $this->convertCustomAttributesToAssociativeArray($response['custom_attributes']); + $this->assertTrue(isset($customAttributesData['description'])); + $this->assertEquals($descriptionValue, $customAttributesData['description']); + + $this->deleteProduct('simple'); + } + /** * Get Simple Product Data * @@ -276,4 +623,160 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract return (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ? $this->_webApiCall($serviceInfo, ['sku' => $sku]) : $this->_webApiCall($serviceInfo); } + + public function testGroupPrices() + { + // create a product with group prices + $custGroup1 = \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID; + $custGroup2 = \Magento\Customer\Model\Group::CUST_GROUP_ALL; + $productData = $this->getSimpleProductData(); + $productData[self::KEY_GROUP_PRICES] = [ + [ + 'customer_group_id' => $custGroup1, + 'value' => 3.14 + ], + [ + 'customer_group_id' => $custGroup2, + 'value' => 3.45, + ] + ]; + $this->saveProduct($productData); + $response = $this->getProduct($productData[ProductInterface::SKU]); + + $this->assertArrayHasKey(self::KEY_GROUP_PRICES, $response); + $groupPrices = $response[self::KEY_GROUP_PRICES]; + $this->assertNotNull($groupPrices, "CREATE: expected to have group prices"); + $this->assertCount(2, $groupPrices, "CREATE: expected to have 2 'group_prices' objects"); + $this->assertEquals(3.14, $groupPrices[0]['value']); + $this->assertEquals($custGroup1, $groupPrices[0]['customer_group_id']); + $this->assertEquals(3.45, $groupPrices[1]['value']); + $this->assertEquals($custGroup2, $groupPrices[1]['customer_group_id']); + + // update the product's group prices: update 1st group price, (delete the 2nd group price), add a new one + $custGroup3 = 1; + $groupPrices[0]['value'] = 3.33; + $groupPrices[1] = [ + 'customer_group_id' => $custGroup3, + 'value' => 2.10, + ]; + $response[self::KEY_GROUP_PRICES] = $groupPrices; + $response = $this->updateProduct($response); + + $this->assertArrayHasKey(self::KEY_GROUP_PRICES, $response); + $groupPrices = $response[self::KEY_GROUP_PRICES]; + $this->assertNotNull($groupPrices, "UPDATE 1: expected to have group prices"); + $this->assertCount(2, $groupPrices, "UPDATE 1: expected to have 2 'group_prices' objects"); + $this->assertEquals(3.33, $groupPrices[0]['value']); + $this->assertEquals($custGroup1, $groupPrices[0]['customer_group_id']); + $this->assertEquals(2.10, $groupPrices[1]['value']); + $this->assertEquals($custGroup3, $groupPrices[1]['customer_group_id']); + + // update the product without any mention of group prices; no change expected for group pricing + $response = $this->getProduct($productData[ProductInterface::SKU]); + unset($response[self::KEY_GROUP_PRICES]); + $response = $this->updateProduct($response); + + $this->assertArrayHasKey(self::KEY_GROUP_PRICES, $response); + $groupPrices = $response[self::KEY_GROUP_PRICES]; + $this->assertNotNull($groupPrices, "UPDATE 2: expected to have group prices"); + $this->assertCount(2, $groupPrices, "UPDATE 2: expected to have 2 'group_prices' objects"); + $this->assertEquals(3.33, $groupPrices[0]['value']); + $this->assertEquals($custGroup1, $groupPrices[0]['customer_group_id']); + $this->assertEquals(2.10, $groupPrices[1]['value']); + $this->assertEquals($custGroup3, $groupPrices[1]['customer_group_id']); + + // update the product with empty group prices; expect to have the existing group prices removed + $response = $this->getProduct($productData[ProductInterface::SKU]); + $response[self::KEY_GROUP_PRICES] = []; + $response = $this->updateProduct($response); + $this->assertArrayHasKey(self::KEY_GROUP_PRICES, $response, "expected to have the 'group_prices' key"); + $this->assertEmpty($response[self::KEY_GROUP_PRICES], "expected to have an empty array of 'group_prices'"); + + // delete the product with group prices; expect that all goes well + $response = $this->deleteProduct($productData[ProductInterface::SKU]); + $this->assertTrue($response); + } + + public function testTierPrices() + { + // create a product with tier prices + $custGroup1 = \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID; + $custGroup2 = \Magento\Customer\Model\Group::CUST_GROUP_ALL; + $productData = $this->getSimpleProductData(); + $productData[self::KEY_TIER_PRICES] = [ + [ + 'customer_group_id' => $custGroup1, + 'value' => 3.14, + 'qty' => 5, + ], + [ + 'customer_group_id' => $custGroup2, + 'value' => 3.45, + 'qty' => 10, + ] + ]; + $this->saveProduct($productData); + $response = $this->getProduct($productData[ProductInterface::SKU]); + + $this->assertArrayHasKey(self::KEY_TIER_PRICES, $response); + $tierPrices = $response[self::KEY_TIER_PRICES]; + $this->assertNotNull($tierPrices, "CREATE: expected to have tier prices"); + $this->assertCount(2, $tierPrices, "CREATE: expected to have 2 'tier_prices' objects"); + $this->assertEquals(3.14, $tierPrices[0]['value']); + $this->assertEquals(5, $tierPrices[0]['qty']); + $this->assertEquals($custGroup1, $tierPrices[0]['customer_group_id']); + $this->assertEquals(3.45, $tierPrices[1]['value']); + $this->assertEquals(10, $tierPrices[1]['qty']); + $this->assertEquals($custGroup2, $tierPrices[1]['customer_group_id']); + + // update the product's tier prices: update 1st tier price, (delete the 2nd tier price), add a new one + $custGroup3 = 1; + $tierPrices[0]['value'] = 3.33; + $tierPrices[0]['qty'] = 6; + $tierPrices[1] = [ + 'customer_group_id' => $custGroup3, + 'value' => 2.10, + 'qty' => 12, + ]; + $response[self::KEY_TIER_PRICES] = $tierPrices; + $response = $this->updateProduct($response); + + $this->assertArrayHasKey(self::KEY_TIER_PRICES, $response); + $tierPrices = $response[self::KEY_TIER_PRICES]; + $this->assertNotNull($tierPrices, "UPDATE 1: expected to have tier prices"); + $this->assertCount(2, $tierPrices, "UPDATE 1: expected to have 2 'tier_prices' objects"); + $this->assertEquals(3.33, $tierPrices[0]['value']); + $this->assertEquals(6, $tierPrices[0]['qty']); + $this->assertEquals($custGroup1, $tierPrices[0]['customer_group_id']); + $this->assertEquals(2.10, $tierPrices[1]['value']); + $this->assertEquals(12, $tierPrices[1]['qty']); + $this->assertEquals($custGroup3, $tierPrices[1]['customer_group_id']); + + // update the product without any mention of tier prices; no change expected for tier pricing + $response = $this->getProduct($productData[ProductInterface::SKU]); + unset($response[self::KEY_TIER_PRICES]); + $response = $this->updateProduct($response); + + $this->assertArrayHasKey(self::KEY_TIER_PRICES, $response); + $tierPrices = $response[self::KEY_TIER_PRICES]; + $this->assertNotNull($tierPrices, "UPDATE 2: expected to have tier prices"); + $this->assertCount(2, $tierPrices, "UPDATE 2: expected to have 2 'tier_prices' objects"); + $this->assertEquals(3.33, $tierPrices[0]['value']); + $this->assertEquals(6, $tierPrices[0]['qty']); + $this->assertEquals($custGroup1, $tierPrices[0]['customer_group_id']); + $this->assertEquals(2.10, $tierPrices[1]['value']); + $this->assertEquals(12, $tierPrices[1]['qty']); + $this->assertEquals($custGroup3, $tierPrices[1]['customer_group_id']); + + // update the product with empty tier prices; expect to have the existing tier prices removed + $response = $this->getProduct($productData[ProductInterface::SKU]); + $response[self::KEY_TIER_PRICES] = []; + $response = $this->updateProduct($response); + $this->assertArrayHasKey(self::KEY_TIER_PRICES, $response, "expected to have the 'tier_prices' key"); + $this->assertEmpty($response[self::KEY_TIER_PRICES], "expected to have an empty array of 'tier_prices'"); + + // delete the product with tier prices; expect that all goes well + $response = $this->deleteProduct($productData[ProductInterface::SKU]); + $this->assertTrue($response); + } } diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php index 5916ccf99c77e295760b73ecae4bff78f70c2b2a..3d1143c06e0ddabe88f34780dfab36c898d9eda1 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php @@ -14,7 +14,6 @@ return [ 'price_type' => 'fixed', 'sku' => 'sku1', 'max_characters' => 10, - 'values' => [], ], [ 'title' => 'area option', @@ -25,7 +24,6 @@ return [ 'price_type' => 'percent', 'sku' => 'sku2', 'max_characters' => 20, - 'values' => [] ], [ 'title' => 'file option', @@ -38,7 +36,6 @@ return [ 'file_extension' => 'jpg, png, gif', 'image_size_x' => 10, 'image_size_y' => 20, - 'values' => [] ], [ 'title' => 'drop_down option', @@ -137,8 +134,6 @@ return [ 'price' => 80.0, 'price_type' => 'fixed', 'sku' => 'date option sku', - 'values' => [] - ], [ 'title' => 'date_time option', @@ -148,7 +143,6 @@ return [ 'price' => 90.0, 'price_type' => 'fixed', 'sku' => 'date_time option sku', - 'values' => [] ], [ 'title' => 'time option', @@ -158,6 +152,5 @@ return [ 'price' => 100.0, 'price_type' => 'fixed', 'sku' => 'time option sku', - 'values' => [] ], ]; diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php index 1c3eafc752417a0a891e2ec7c0f81583b11c15aa..3496f3d4cc583c40b503bb99e4b95fd15d3066d7 100644 --- a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php @@ -64,12 +64,16 @@ class ConfigurableProductManagementTest extends \Magento\TestFramework\TestCase\ 'store_id' => 1, 'status' => 1, 'visibility' => \Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE, + 'options' => [], + 'product_links' => [], 'custom_attributes' => [ [ 'attribute_code' => 'test_configurable', 'value' => $attributeOptionValue ] - ] + ], + 'group_prices' => [], + 'tier_prices' => [] ] ]; ksort($expectedItems); diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php index 5f4d1fcb73707ea879152f03f20ab4092e9cff67..ffd5e52d7eaa2e47792d8b04636b80198dac9fd3 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php @@ -10,6 +10,7 @@ use Magento\Store\Test\Fixture\Store; use Magento\Mtf\Constraint\AbstractConstraint; use Magento\Backend\Test\Page\Adminhtml\SystemConfig; use Magento\Cms\Test\Page\CmsIndex; +use Magento\Backend\Test\Page\Adminhtml\AdminCache; /** * Assert that store can be localized. @@ -22,12 +23,18 @@ class AssertStoreCanBeLocalized extends AbstractConstraint * @param SystemConfig $systemConfig * @param Store $store * @param CmsIndex $cmsIndex + * @param AdminCache $adminCache * @param string $locale * @param string $welcomeText - * @return void */ - public function processAssert(SystemConfig $systemConfig, Store $store, CmsIndex $cmsIndex, $locale, $welcomeText) - { + public function processAssert( + SystemConfig $systemConfig, + Store $store, + CmsIndex $cmsIndex, + AdminCache $adminCache, + $locale, + $welcomeText + ) { // Set locale options $systemConfig->open(); $systemConfig->getPageActions()->selectStore($store->getGroupId() . "/" . $store->getName()); @@ -37,6 +44,11 @@ class AssertStoreCanBeLocalized extends AbstractConstraint $systemConfig->getPageActions()->save(); $systemConfig->getMessagesBlock()->waitSuccessMessage(); + // Flush cache + $adminCache->open(); + $adminCache->getActionsBlock()->flushMagentoCache(); + $adminCache->getMessagesBlock()->waitSuccessMessage(); + // Check presents income text on index page $cmsIndex->open(); if ($cmsIndex->getFooterBlock()->isStoreGroupSwitcherVisible() diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php index c640f29e7381a2be153bccc2496f41f189884d02..9d12680de86c1c0516fc383d4cf864f3c7499616 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Application.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php @@ -298,6 +298,8 @@ class Application ); $objectManager->removeSharedInstance('Magento\Framework\Logger\Monolog'); $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); @@ -332,6 +334,9 @@ class Application $objectManager->get('Magento\Framework\ObjectManager\DynamicConfigInterface')->getConfiguration() ); \Magento\Framework\Phrase::setRenderer($objectManager->get('Magento\Framework\Phrase\Renderer\Placeholder')); + /** @var \Magento\TestFramework\Db\Sequence $sequence */ + $sequence = $objectManager->get('Magento\TestFramework\Db\Sequence'); + $sequence->generateSequences(); } /** diff --git a/dev/tests/integration/framework/Magento/TestFramework/Db/Sequence.php b/dev/tests/integration/framework/Magento/TestFramework/Db/Sequence.php new file mode 100644 index 0000000000000000000000000000000000000000..74863cf893bbd9f0126130880968aef9f697cd15 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Db/Sequence.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\TestFramework\Db; + +use Magento\Framework\App\Resource as AppResource; +use Magento\Framework\DB\Ddl\Sequence as DdlSequence; + +/** + * Class Sequence + */ +class Sequence +{ + /** + * @var AppResource + */ + protected $appResource; + + /** + * @var DdlSequence + */ + protected $ddlSequence; + + /** + * @var array + */ + protected $entities = [ + 'order', + 'invoice', + 'shipment', + 'rma_item' + ]; + + /** + * @param AppResource $appResource + * @param DdlSequence $ddlSequence + */ + public function __construct( + AppResource $appResource, + DdlSequence $ddlSequence + ) { + $this->appResource = $appResource; + $this->ddlSequence = $ddlSequence; + } + + /** + * @param int $n + * @return void + */ + public function generateSequences($n = 10) + { + $connection = $this->appResource->getConnection('write'); + for ($i = 0; $i < $n; $i++) { + foreach ($this->entities as $entityName) { + $sequenceName = $this->appResource->getTableName(sprintf('sequence_%s_%s', $entityName, $i)); + if (!$connection->isTableExists($sequenceName)) { + $connection->query($this->ddlSequence->getCreateSequenceDdl($sequenceName)); + } + } + } + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Db/Sequence/Builder.php b/dev/tests/integration/framework/Magento/TestFramework/Db/Sequence/Builder.php new file mode 100644 index 0000000000000000000000000000000000000000..95198235670c3fd9ffda1626324e52d42e72cd4e --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Db/Sequence/Builder.php @@ -0,0 +1,262 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\TestFramework\Db\Sequence; + +use Magento\Framework\Webapi\Exception; +use Magento\SalesSequence\Model\Resource\Meta as ResourceMetadata; +use Magento\Framework\App\Resource as AppResource; +use Magento\Framework\DB\Ddl\Sequence as DdlSequence; +use Magento\SalesSequence\Model\ProfileFactory; +use Magento\SalesSequence\Model\MetaFactory; + +/** + * Class Builder + */ +class Builder extends \Magento\SalesSequence\Model\Builder +{ + /** + * @var resourceMetadata + */ + protected $resourceMetadata; + + /** + * @var ProfileFactory + */ + protected $profileFactory; + + /** + * @var MetaFactory + */ + protected $metaFactory; + + /** + * @var AppResource + */ + protected $appResource; + + /** + * @var DdlSequence + */ + protected $ddlSequence; + + /** + * List of required sequence attribute + * + * @var array + */ + protected $required = [ + 'entityType', + 'storeId' + ]; + + /** + * Default pattern for sequence creation, full list of attributes that can be defined by customer + * + * @var array + */ + protected $pattern = [ + 'entity_type', + 'store_id', + 'prefix', + 'suffix', + 'start_value', + 'step', + 'max_value', + 'warning_value', + ]; + + /** + * Concrete data of sequence + * + * @var array + */ + protected $data = []; + + /** + * @param ResourceMetadata $resourceMetadata + * @param MetaFactory $metaFactory + * @param ProfileFactory $profileFactory + * @param AppResource $appResource + * @param DdlSequence $ddlSequence + */ + public function __construct( + ResourceMetadata $resourceMetadata, + MetaFactory $metaFactory, + ProfileFactory $profileFactory, + AppResource $appResource, + DdlSequence $ddlSequence + ) { + $this->resourceMetadata = $resourceMetadata; + $this->metaFactory = $metaFactory; + $this->profileFactory = $profileFactory; + $this->appResource = $appResource; + $this->ddlSequence = $ddlSequence; + $this->data = array_flip($this->pattern); + } + + /** + * @param string $entityType + * @return $this + */ + public function setEntityType($entityType) + { + $this->data['entity_type'] = $entityType; + return $this; + } + + /** + * @param int $storeId + * @return $this + */ + public function setStoreId($storeId) + { + $this->data['store_id'] = $storeId; + return $this; + } + + /** + * @param string $prefix + * @return $this + */ + public function setPrefix($prefix) + { + $this->data['prefix'] = $prefix; + return $this; + } + + /** + * @param string $suffix + * @return $this + */ + public function setSuffix($suffix) + { + $this->data['suffix'] = $suffix; + return $this; + } + + /** + * @param int $startValue + * @return $this + */ + public function setStartValue($startValue) + { + $this->data['start_value'] = $startValue; + return $this; + } + + /** + * @param int $step + * @return $this + */ + public function setStep($step) + { + $this->data['step'] = $step; + return $this; + } + + /** + * @param int $maxValue + * @return $this + */ + public function setMaxValue($maxValue) + { + $this->data['max_value'] = $maxValue; + return $this; + } + + /** + * @param int $warningValue + * @return $this + */ + public function setWarningValue($warningValue) + { + $this->data['warning_value'] = $warningValue; + return $this; + } + + /** + * Validate sequence before save + * + * @throws \Magento\Framework\Exception\AlreadyExistsException + * @return void + */ + protected function validate() + { + $metadata = $this->resourceMetadata->loadByEntityTypeAndStore( + $this->data['entity_type'], + $this->data['store_id'] + ); + $adapter = $this->appResource->getConnection('write'); + if ($metadata->getId() && !$adapter->isTableExists($this->getSequenceName())) { + throw new \Magento\Framework\Exception\AlreadyExistsException( + __('Sequence with this metadata already exists') + ); + } + } + + protected function getSequenceName() + { + return $this->appResource->getTableName( + sprintf( + 'sequence_%s_%s', + $this->data['entity_type'], + $this->data['store_id'] + ) + ); + } + + /** + * Create sequence with metadata and profile + * + * @throws \Exception + * @throws \Magento\Framework\Exception\AlreadyExistsException + * @return void + */ + public function create() + { + $metadata = $this->resourceMetadata->loadByEntityTypeAndStore( + $this->data['entity_type'], + $this->data['store_id'] + ); + if ($metadata->getSequenceTable() == $this->getSequenceName()) { + return; + } + + $this->data['sequence_table'] = $this->getSequenceName(); + $this->data['is_active'] = 1; + $profile = $this->profileFactory->create( + [ + 'data' => array_intersect_key( + $this->data, + array_flip( + [ + 'prefix', 'suffix', 'start_value', 'step', 'max_value', 'warning_value', + 'is_active', 'active_profile' + ] + ) + ) + ] + ); + $profile->setHasDataChanges(true); + $this->data['active_profile'] = $profile; + $metadata = $this->metaFactory->create( + [ + 'data' => array_intersect_key( + $this->data, + array_flip(['entity_type', 'store_id', 'sequence_table', 'active_profile']) + ) + ] + ); + $metadata->setHasDataChanges(true); + try { + $this->resourceMetadata->save($metadata); + } catch (Exception $e) { + $this->resourceMetadata->delete($metadata); + throw $e; + } + $this->data = array_flip($this->pattern); + } +} diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php index 1ae17867f949583648f5e8ea3655056a6fc4e75d..418a282ee53b112bdd1a3834515022a035d2ed56 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php @@ -4,6 +4,14 @@ * See COPYING.txt for license details. */ +$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config'); +$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable'); +if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute + && $attribute->getId() +) { + $attribute->delete(); +} +$eavConfig->clear(); /* Create attribute */ /** @var $installer \Magento\Catalog\Setup\CategorySetup */ $installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php deleted file mode 100644 index 6662b959a183b9c1f7a2f40e347cea5f7a627089..0000000000000000000000000000000000000000 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -/** @var \Magento\Eav\Model\Config $eavConfig */ -$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config'); -$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable'); -if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute - && $attribute->getId() -) { - $attribute->delete(); -} -$eavConfig->clear(); diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php index 952215e4f7fd2d263a090ca58f79ad6b23fc6adc..c1b23ce233c9e09240533d5bc7ee97f90a7510da 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php @@ -29,5 +29,3 @@ if ($product->getId()) { $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -require __DIR__ . '/configurable_attribute_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/Report/Order/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/Report/Order/CollectionTest.php deleted file mode 100644 index 7add98102b2658b6e3694002a26c2323556b4fbd..0000000000000000000000000000000000000000 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/Report/Order/CollectionTest.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Sales\Model\Resource\Report\Order; - -class CollectionTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \Magento\Sales\Model\Resource\Report\Order\Collection - */ - private $_collection; - - protected function setUp() - { - $this->_collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Sales\Model\Resource\Report\Order\Collection' - ); - $this->_collection->setPeriod('day')->setDateRange(null, null)->addStoreFilter([1]); - } - - /** - * @magentoDataFixture Magento/Sales/_files/invoice.php - * @magentoDataFixture Magento/Sales/_files/invoice_fixture_store_order.php - * @magentoDataFixture Magento/Sales/_files/report_order.php - */ - public function testGetItems() - { - $expectedResult = [['orders_count' => 1, 'total_qty_ordered' => 2, 'total_qty_invoiced' => 2]]; - $actualResult = []; - /** @var \Magento\Reports\Model\Item $reportItem */ - foreach ($this->_collection->getItems() as $reportItem) { - $actualResult[] = array_intersect_key($reportItem->getData(), $expectedResult[0]); - } - $this->assertEquals($expectedResult, $actualResult); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/report_order.php b/dev/tests/integration/testsuite/Magento/Sales/_files/report_order.php deleted file mode 100644 index 2129288a6d08dff04692750e715335ee02619b25..0000000000000000000000000000000000000000 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/report_order.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// refresh report statistics -/** @var \Magento\Sales\Model\Resource\Report\Order $reportResource */ -$reportResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Sales\Model\Resource\Report\Order' -); -$reportResource->beginTransaction(); -// prevent table truncation by incrementing the transaction nesting level counter -try { - $reportResource->aggregate(); - $reportResource->commit(); -} catch (\Exception $e) { - $reportResource->rollBack(); - throw $e; -} diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php index ac1a841589326b5d4e4761009a931079deb13556..288ebf3b55dadb8d82bd0f236530ae45260e24c5 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php @@ -5,28 +5,30 @@ */ $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Store\Model\Store'); -$websiteId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - 'Magento\Store\Model\StoreManagerInterface' -)->getWebsite()->getId(); -$groupId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - 'Magento\Store\Model\StoreManagerInterface' -)->getWebsite()->getDefaultGroupId(); -$store->setCode( - 'fixture_second_store' -)->setWebsiteId( - $websiteId -)->setGroupId( - $groupId -)->setName( - 'Fixture Store' -)->setSortOrder( - 10 -)->setIsActive( - 1 -); -$store->save(); +if (!$store->load('fixture_second_store', 'code')->getId()) { + $websiteId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + 'Magento\Store\Model\StoreManagerInterface' + )->getWebsite()->getId(); + $groupId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + 'Magento\Store\Model\StoreManagerInterface' + )->getWebsite()->getDefaultGroupId(); + $store->setCode( + 'fixture_second_store' + )->setWebsiteId( + $websiteId + )->setGroupId( + $groupId + )->setName( + 'Fixture Store' + )->setSortOrder( + 10 + )->setIsActive( + 1 + ); + $store->save(); -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - 'Magento\Store\Model\StoreManagerInterface' -)->reinitStores(); + /* Refresh stores memory cache */ + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + 'Magento\Store\Model\StoreManagerInterface' + )->reinitStores(); +} diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php index 7e321db1a7d002b392c9e235c176a938d585546e..e2b78c6ef704c7bc54132b5f4adfbc02b6a1a897 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php @@ -5,18 +5,18 @@ * See COPYING.txt for license details. */ /** @var \Magento\Framework\Registry $registry */ -$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); - -$registry->unregister('isSecureArea'); -$registry->register('isSecureArea', true); +//$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); +// +//$registry->unregister('isSecureArea'); +//$registry->register('isSecureArea', true); /** @var Magento\Store\Model\Store $store */ -$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Store\Model\Store'); -$store->load('fixture_second_store'); - -if ($store->getId()) { - $store->delete(); -} - -$registry->unregister('isSecureArea'); -$registry->register('isSecureArea', false); +//$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Store\Model\Store'); +//$store->load('fixture_second_store'); +// +//if ($store->getId()) { +// $store->delete(); +//} +// +//$registry->unregister('isSecureArea'); +//$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store.php b/dev/tests/integration/testsuite/Magento/Store/_files/store.php index 1bbc48d82d790b85550bf9b7abf1c9de76640f40..791c091b2ff83edaa46fd43e446cdfd75304c92a 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/store.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/store.php @@ -6,14 +6,16 @@ /** @var $store \Magento\Store\Model\Store */ $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Store\Model\Store'); -$store->setData( - [ - 'code' => 'test', - 'website_id' => '1', - 'group_id' => '1', - 'name' => 'Test Store', - 'sort_order' => '0', - 'is_active' => '1', - ] -); -$store->save(); +if (!$store->load('test', 'code')->getId()) { + $store->setData( + [ + 'code' => 'test', + 'website_id' => '1', + 'group_id' => '1', + 'name' => 'Test Store', + 'sort_order' => '0', + 'is_active' => '1', + ] + ); + $store->save(); +} diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php index 8d7f705d6661566cdaef4c424cdb9a8a351dea29..d0925f82b420f1b013f3c4ef956523227b2d131e 100644 --- a/lib/internal/Magento/Framework/AppInterface.php +++ b/lib/internal/Magento/Framework/AppInterface.php @@ -17,7 +17,7 @@ interface AppInterface /** * Magento version */ - const VERSION = '0.74.0-beta2'; + const VERSION = '0.74.0-beta3'; /** * Launch application diff --git a/lib/internal/Magento/Framework/DB/Ddl/Sequence.php b/lib/internal/Magento/Framework/DB/Ddl/Sequence.php new file mode 100644 index 0000000000000000000000000000000000000000..1f0a4ca99c8079f94c25077ad7cf975a83b1815a --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Ddl/Sequence.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\DB\Ddl; + +/** + * Class Sequence represents DDL for manage sequences + */ +class Sequence +{ + /** + * Return SQL for create sequence + * + * @param string $name + * @param int $startNumber + * @return string + */ + public function getCreateSequenceDdl($name, $startNumber = 1) + { + $format = "CREATE TABLE %s ( + sequence_value %s UNSIGNED NOT NULL AUTO_INCREMENT, + PRIMARY KEY (sequence_value) + ) AUTO_INCREMENT = %d"; + + return sprintf($format, $name, Table::TYPE_INTEGER, $startNumber); + } + + /** + * Return SQL for drop sequence + * + * @param string $name + * @return string + */ + public function dropSequence($name) + { + $format = "DROP TABLE %s"; + return sprintf($format, $name); + } +} diff --git a/lib/internal/Magento/Framework/DB/Sequence/SequenceInterface.php b/lib/internal/Magento/Framework/DB/Sequence/SequenceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..59b5df062e0824ed5697075fe9a48313a7896a81 --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Sequence/SequenceInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\DB\Sequence; + +/** + * Interface represents sequence + */ +interface SequenceInterface +{ + /** + * Retrieve current value + * + * @return string + */ + public function getCurrentValue(); + + /** + * Retrieve next value + * + * @return string + */ + public function getNextValue(); +} diff --git a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php index e5a84c89fa4ef60da3c42df09584990a53a1cced..b90ff7acb3929174c921ac4a7e0ea5c3e464fab7 100644 --- a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php @@ -38,6 +38,11 @@ abstract class AbstractExtensibleModel extends AbstractModel implements */ protected $customAttributesCodes = null; + /** + * @var bool + */ + protected $customAttributesChanged = false; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -91,6 +96,34 @@ abstract class AbstractExtensibleModel extends AbstractModel implements return $data; } + /** + * Initialize customAttributes based on existing data + * + * @return $this + */ + protected function initializeCustomAttributes() + { + if (!isset($this->_data[self::CUSTOM_ATTRIBUTES]) || $this->customAttributesChanged) { + if (!empty($this->_data[self::CUSTOM_ATTRIBUTES])) { + $customAttributes = $this->_data[self::CUSTOM_ATTRIBUTES]; + } else { + $customAttributes = []; + } + $customAttributeCodes = $this->getCustomAttributesCodes(); + + foreach ($customAttributeCodes as $customAttributeCode) { + if (isset($this->_data[$customAttributeCode])) { + $customAttribute = $this->customAttributeFactory->create() + ->setAttributeCode($customAttributeCode) + ->setValue($this->_data[$customAttributeCode]); + $customAttributes[$customAttributeCode] = $customAttribute; + } + } + $this->_data[self::CUSTOM_ATTRIBUTES] = $customAttributes; + $this->customAttributesChanged = false; + } + } + /** * Retrieve custom attributes values. * @@ -98,10 +131,9 @@ abstract class AbstractExtensibleModel extends AbstractModel implements */ public function getCustomAttributes() { + $this->initializeCustomAttributes(); // Returning as a sequential array (instead of stored associative array) to be compatible with the interface - return isset($this->_data[self::CUSTOM_ATTRIBUTES]) - ? array_values($this->_data[self::CUSTOM_ATTRIBUTES]) - : []; + return array_values($this->_data[self::CUSTOM_ATTRIBUTES]); } /** @@ -112,6 +144,7 @@ abstract class AbstractExtensibleModel extends AbstractModel implements */ public function getCustomAttribute($attributeCode) { + $this->initializeCustomAttributes(); return isset($this->_data[self::CUSTOM_ATTRIBUTES][$attributeCode]) ? $this->_data[self::CUSTOM_ATTRIBUTES][$attributeCode] : null; @@ -154,10 +187,24 @@ abstract class AbstractExtensibleModel extends AbstractModel implements $filteredData = $this->filterCustomAttributes([self::CUSTOM_ATTRIBUTES => $value]); $value = $filteredData[self::CUSTOM_ATTRIBUTES]; } + $this->customAttributesChanged = true; parent::setData($key, $value); return $this; } + /** + * {@inheritdoc} + * + * Unset customAttributesChanged flag + */ + public function unsetData($key = null) + { + if (is_string($key) && isset($this->_data[self::CUSTOM_ATTRIBUTES][$key])) { + unset($this->_data[self::CUSTOM_ATTRIBUTES][$key]); + } + return parent::unsetData($key); + } + /** * Object data getter * diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php index df82d6f679446790dd0df79b6cf2633e6070053d..f6065b38af8fc4f4d7c448a113cd8187a55fa740 100644 --- a/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php +++ b/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php @@ -49,6 +49,11 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase */ protected $actionValidatorMock; + /** + * @var AttributeValue + */ + protected $customAttribute; + protected function setUp() { $this->actionValidatorMock = $this->getMock( @@ -115,15 +120,22 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase $this->attributeValueFactoryMock, $this->resourceMock, $this->resourceCollectionMock - ] + ], + '', + true, + true, + true, + ['getCustomAttributesCodes'] ); + $this->customAttribute = new AttributeValue(); } /** * Test implementation of interface for work with custom attributes. */ - public function testCustomAttributes() + public function testCustomAttributesWithEmptyCustomAttributes() { + $this->model->expects($this->any())->method('getCustomAttributesCodes')->willReturn([]); $this->assertEquals( [], $this->model->getCustomAttributes(), @@ -143,11 +155,48 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase ); } + public function testCustomAttributesWithNonEmptyCustomAttributes() + { + $customAttributeCode = 'attribute_code'; + $customAttributeValue = 'attribute_value'; + $this->model->expects($this->any())->method('getCustomAttributesCodes')->willReturn([$customAttributeCode]); + + $this->assertEquals( + [], + $this->model->getCustomAttributes(), + "Empty array is expected as a result of getCustomAttributes() when custom attributes are not set." + ); + $this->attributeValueFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->customAttribute); + $this->customAttribute->setAttributeCode($customAttributeCode)->setValue($customAttributeValue); + $this->model->setData($customAttributeCode, $customAttributeValue); + $this->assertEquals( + [$this->customAttribute], + $this->model->getCustomAttributes(), + "One custom attribute expected" + ); + $this->assertNotNull($this->model->getCustomAttribute($customAttributeCode), 'customer attribute expected'); + $this->assertEquals( + $customAttributeValue, + $this->model->getCustomAttribute($customAttributeCode)->getValue(), + "Custom attribute value is incorrect" + ); + //unset the data + $this->model->unsetData($customAttributeCode); + $this->assertEquals( + [], + $this->model->getCustomAttributes(), + "Empty array is expected as a result of getCustomAttributes() when custom attributes are not set." + ); + } + /** * Test if getData works with custom attributes as expected */ public function testGetDataWithCustomAttributes() { + $this->model->expects($this->any())->method('getCustomAttributesCodes')->willReturn([]); $attributesAsArray = [ 'attribute1' => true, 'attribute2' => 'Attribute Value', @@ -181,6 +230,7 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase public function testSetCustomAttributesAsLiterals() { + $this->model->expects($this->any())->method('getCustomAttributesCodes')->willReturn([]); $attributeCode = 'attribute2'; $attributeValue = 'attribute_value'; $attributeMock = $this->getMockBuilder('\Magento\Framework\Api\AttributeValue') diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 6584da302fbcc5cb180a9921b029beda1a41049b..e2ed26ad26c4c119adca9104a538108c437eb151 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -2,7 +2,7 @@ "name": "magento/framework", "description": "N/A", "type": "magento2-library", - "version": "0.74.0-beta2", + "version": "0.74.0-beta3", "license": [ "OSL-3.0", "AFL-3.0"