diff --git a/app/code/Magento/Backend/Block/Widget/Button/Item.php b/app/code/Magento/Backend/Block/Widget/Button/Item.php index a500f836312fb3edacd942cc80e24e0582d2094e..73ed2c5f50e6993e5ebbff026d0b89194abcc52b 100644 --- a/app/code/Magento/Backend/Block/Widget/Button/Item.php +++ b/app/code/Magento/Backend/Block/Widget/Button/Item.php @@ -7,12 +7,12 @@ namespace Magento\Backend\Block\Widget\Button; /** - * @method string getButtonKey - * @method string getRegion - * @method string getName - * @method int getLevel - * @method int getSortOrder - * @method string getTitle + * @method string getButtonKey() + * @method string getRegion() + * @method string getName() + * @method int getLevel() + * @method int getSortOrder() + * @method string getTitle() */ class Item extends \Magento\Framework\DataObject { diff --git a/app/code/Magento/Backend/Block/Widget/Button/Toolbar/Container.php b/app/code/Magento/Backend/Block/Widget/Button/Toolbar/Container.php index e7c199cf4787ff9aedca6aa13061fddfafe5d20c..959ef806acfa15571046dbaf9e8b6b3055ef6d0b 100644 --- a/app/code/Magento/Backend/Block/Widget/Button/Toolbar/Container.php +++ b/app/code/Magento/Backend/Block/Widget/Button/Toolbar/Container.php @@ -9,8 +9,8 @@ namespace Magento\Backend\Block\Widget\Button\Toolbar; use Magento\Backend\Block\Widget\Button\ContextInterface; /** - * @method \Magento\Backend\Block\Widget\Button\Item getButtonItem - * @method ContextInterface getContext + * @method \Magento\Backend\Block\Widget\Button\Item getButtonItem() + * @method ContextInterface getContext() * @method ContextInterface setContext(ContextInterface $context) */ class Container extends \Magento\Framework\View\Element\AbstractBlock diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php index dec89ab52ff89d9275791fde97f7f2d4024de97d..5ed9016a59f6a799258ad17cee50c43c614ead97 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php @@ -31,12 +31,18 @@ class Advanced extends Generic */ protected $_yesNo; + /** + * @var array + */ + protected $disableScopeChangeList; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Data\FormFactory $formFactory * @param Yesno $yesNo * @param Data $eavData + * @param array $disableScopeChangeList * @param array $data */ public function __construct( @@ -45,10 +51,12 @@ class Advanced extends Generic \Magento\Framework\Data\FormFactory $formFactory, Yesno $yesNo, Data $eavData, + array $disableScopeChangeList = ['sku'], array $data = [] ) { $this->_yesNo = $yesNo; $this->_eavData = $eavData; + $this->disableScopeChangeList = $disableScopeChangeList; parent::__construct($context, $registry, $formFactory, $data); } @@ -229,7 +237,7 @@ class Advanced extends Generic ); $this->_eventManager->dispatch('product_attribute_form_build', ['form' => $form]); - if ($attributeObject->getId() && !$attributeObject->getIsUserDefined()) { + if (in_array($attributeObject->getAttributeCode(), $this->disableScopeChangeList)) { $form->getElement('is_global')->setDisabled(1); } $this->setForm($form); diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Options.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Options.php index eabcac9f715747f01c211f9d5fc7d6fcee0bf718..b08fdb85de106f3cb0197da629036350c5f90571 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Options.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Options.php @@ -8,7 +8,7 @@ * Product attribute add/edit form options tab * * @method \Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Options setReadOnly(bool $value) - * @method null|bool getReadOnly + * @method null|bool getReadOnly() * * @author Magento Core Team <core@magentocommerce.com> */ 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 f507d9ee30ec0bf3a8094bdc5fd7796f047e3cd3..7dbacd96990b59888da7ecccb736760b1836c5a4 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 @@ -461,4 +461,14 @@ class Option extends Widget { return $this->getUrl('catalog/*/customOptions'); } + + /** + * Return current product id + * + * @return null|int + */ + public function getCurrentProductId() + { + return $this->getProduct()->getId(); + } } diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Popup/Grid.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Popup/Grid.php index 53bcc298732f9d804846b252f950e4e9c5d3b936..646db241f82248d612d0d34e8d1dd74745cd85ef 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Popup/Grid.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Popup/Grid.php @@ -62,7 +62,19 @@ class Grid extends \Magento\Catalog\Block\Adminhtml\Product\Grid protected function _prepareCollection() { parent::_prepareCollection(); - $this->getCollection()->addFieldToFilter('has_options', 1); + + if (null !== $this->getRequest()->getParam('current_product_id')) { + $this->getCollection()->getSelect()->where( + 'e.entity_id != ?', + $this->getRequest()->getParam('current_product_id') + ); + } + + $this->getCollection()->getSelect()->distinct()->join( + ['opt' => $this->getCollection()->getTable('catalog_product_option')], + 'opt.product_id = e.entity_id', + null + ); return $this; } diff --git a/app/code/Magento/Catalog/Model/CategoryLinkManagement.php b/app/code/Magento/Catalog/Model/CategoryLinkManagement.php index 0c2c324bd8e2c931b57babe59147837b4feb193b..4ff351dc3d735b79ad3ee2adf3d9275ceb54c0c3 100644 --- a/app/code/Magento/Catalog/Model/CategoryLinkManagement.php +++ b/app/code/Magento/Catalog/Model/CategoryLinkManagement.php @@ -36,20 +36,20 @@ class CategoryLinkManagement implements \Magento\Catalog\Api\CategoryLinkManagem public function getAssignedProducts($categoryId) { $category = $this->categoryRepository->get($categoryId); - $productsPosition = $category->getProductsPosition(); - /** @var \Magento\Framework\Data\Collection\AbstractDb $products */ + /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $products */ $products = $category->getProductCollection(); + $products->addFieldToSelect('position'); /** @var \Magento\Catalog\Api\Data\CategoryProductLinkInterface[] $links */ $links = []; /** @var \Magento\Catalog\Model\Product $product */ - foreach ($products->getItems() as $productId => $product) { + foreach ($products->getItems() as $product) { /** @var \Magento\Catalog\Api\Data\CategoryProductLinkInterface $link */ $link = $this->productLinkFactory->create(); $link->setSku($product->getSku()) - ->setPosition($productsPosition[$productId]) + ->setPosition($product->getData('cat_index_position')) ->setCategoryId($category->getId()); $links[] = $link; } diff --git a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Type.php b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Type.php index 5d0c1f24872a76b3345d9a4995535c180f4931e8..ca62402f23a378129cac9cd10f43a42a5a463aa7 100644 --- a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Type.php +++ b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Type.php @@ -43,7 +43,7 @@ class Type implements \Magento\Framework\Option\ArrayInterface $types[] = ['label' => __($type['label']), 'value' => $type['name']]; } if (count($types)) { - $groups[] = ['label' => __($option['label']), 'value' => $types]; + $groups[] = ['label' => __($option['label']), 'value' => $types, 'optgroup-name' => $option['label']]; } } diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 99709b513ca2cf08167a07f76ac22169ec2001b7..63045d6d5e26f0be48e8602ff7aa5b0430ed263e 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -25,7 +25,7 @@ use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionFactory; * @method array getAssociatedProductIds() * @method Product setNewVariationsAttributeSetId(int $value) * @method int getNewVariationsAttributeSetId() - * @method int getPriceType + * @method int getPriceType() * @method \Magento\Catalog\Model\ResourceModel\Product\Collection getCollection() * @method string getUrlKey() * @method Product setUrlKey(string $urlKey) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php index 8ca5ffbc429e567ddc1b37f5c24b482e62ec5335..f7fd135a134061614cbbc4b7d6c8557289cd0ad8 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php @@ -85,7 +85,7 @@ class Media extends Product\Attribute\Backend\AbstractMedia // For duplicating we need copy original images. $duplicate = []; foreach ($value['images'] as &$image) { - if (empty($image['value_id'])) { + if (empty($image['value_id']) || !empty($image['removed'])) { continue; } $duplicate[$image['value_id']] = $this->copyImage($image['file']); diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php index a9f7a1188c554ddfbd13abfd7aa2d57bdbc37ba1..1b3b2c5f0d8f3f2f824b16e2dde53d08e91a5505 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php @@ -21,21 +21,21 @@ class ValidatorFile extends Validator * * @var string */ - protected $path = '/custom_options'; + protected $path = 'custom_options'; /** * Relative path for quote folder * * @var string */ - protected $quotePath = '/custom_options/quote'; + protected $quotePath = 'custom_options/quote'; /** * Relative path for order folder * * @var string */ - protected $orderPath = '/custom_options/order'; + protected $orderPath = 'custom_options/order'; /** * @var \Magento\Framework\Filesystem\Directory\WriteInterface @@ -175,12 +175,12 @@ class ValidatorFile extends Validator $_height = $imageSize[1]; } } - $uri = $this->filesystem->getUri(DirectoryList::MEDIA); + $userValue = [ 'type' => $fileInfo['type'], 'title' => $fileInfo['name'], - 'quote_path' => $uri . $this->quotePath . $filePath, - 'order_path' => $uri . $this->orderPath . $filePath, + 'quote_path' => $this->quotePath . $filePath, + 'order_path' => $this->orderPath . $filePath, 'fullpath' => $fileFullPath, 'size' => $fileInfo['size'], 'width' => $_width, diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category/Flat.php b/app/code/Magento/Catalog/Model/ResourceModel/Category/Flat.php index 82000fb03d1703e6e34dfeb854e6d1ad6aca80ee..30c9476931f10aa0daf23dbbf1ff389bb02d2abd 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category/Flat.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category/Flat.php @@ -671,4 +671,23 @@ class Flat extends \Magento\Indexer\Model\ResourceModel\AbstractResource return $this->getConnection()->fetchCol($select); } + + /** + * Get positions of associated to category products + * + * @param \Magento\Catalog\Model\Category $category + * @return array + */ + public function getProductsPosition($category) + { + $select = $this->getConnection()->select()->from( + $this->getTable('catalog_category_product'), + ['product_id', 'position'] + )->where( + 'category_id = :category_id' + ); + $bind = ['category_id' => (int)$category->getId()]; + + return $this->getConnection()->fetchPairs($select, $bind); + } } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Media.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Media.php index a77ea68ae16d5e42855e7e422ff3662eeba5bcf6..0ac7a8c1a7bf612d352c6ea352a879c40f303abe 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Media.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Media.php @@ -324,11 +324,12 @@ class Media extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb foreach ($this->getConnection()->fetchAll($select) as $row) { $data = [ 'attribute_id' => $attributeId, - 'entity_id' => $newProductId, 'value' => isset($newFiles[$row['value_id']]) ? $newFiles[$row['value_id']] : $row['value'], ]; $valueIdMap[$row['value_id']] = $this->insertGallery($data); + $this->bindValueToEntity($valueIdMap[$row['value_id']], $newProductId); + } if (count($valueIdMap) == 0) { @@ -344,6 +345,8 @@ class Media extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb ); foreach ($this->getConnection()->fetchAll($select) as $row) { + unset($row['record_id']); + $row['entity_id'] = $newProductId; $row['value_id'] = $valueIdMap[$row['value_id']]; $this->insertGalleryValueInStore($row); } diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/Tab/AdvancedTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/Tab/AdvancedTest.php index a54834d4f56966f448480c1000f1f98ba45c4356..7408df0ede1d678644939f92c9055007e97e3759 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/Tab/AdvancedTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Attribute/Edit/Tab/AdvancedTest.php @@ -89,7 +89,7 @@ class AdvancedTest extends \PHPUnit_Framework_TestCase $this->localeDate->expects($this->any())->method('getDateFormat')->willReturn('mm/dd/yy'); $entityType->expects($this->any())->method('getEntityTypeCode')->willReturn('entity_type_code'); $this->eavData->expects($this->any())->method('getFrontendClasses')->willReturn([]); - $formElement->expects($this->exactly(3))->method('setDisabled')->willReturnSelf(); + $formElement->expects($this->exactly(2))->method('setDisabled')->willReturnSelf(); $this->yesNo->expects($this->any())->method('toOptionArray')->willReturn(['yes', 'no']); $this->filesystem->expects($this->any())->method('getDirectoryRead')->willReturn($directoryReadInterface); $directoryReadInterface->expects($this->any())->method('getRelativePath')->willReturn('relative_path'); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/CategoryLinkManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/CategoryLinkManagementTest.php index 9e75726f9dfa284355307d81760d848aa2d7de6e..4be4d33c4fcf2852cb23586fbdf505e387b0682b 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/CategoryLinkManagementTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/CategoryLinkManagementTest.php @@ -44,7 +44,7 @@ class CategoryLinkManagementTest extends \PHPUnit_Framework_TestCase { $categoryId = 42; $productId = 55; - $productsPosition = [$productId => 25]; + $position = 25; $productSku = 'testSku'; $categoryProductLinkMock = $this->getMock('\Magento\Catalog\Api\Data\CategoryProductLinkInterface'); $categoryMock = $this->getMock( @@ -56,13 +56,14 @@ class CategoryLinkManagementTest extends \PHPUnit_Framework_TestCase ); $productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false); $productMock->expects($this->once())->method('getSku')->willReturn($productSku); + $productMock->expects($this->once())->method('getData')->with('cat_index_position')->willReturn($position); $items = [$productId => $productMock]; - $productsMock = $this->getMock('\Magento\Framework\Data\Collection\AbstractDb', [], [], '', false); + $productsMock = $this->getMock('Magento\Catalog\Model\ResourceModel\Product\Collection', [], [], '', false); $this->categoryRepositoryMock->expects($this->once())->method('get')->with($categoryId) ->willReturn($categoryMock); - $categoryMock->expects($this->once())->method('getProductsPosition')->willReturn($productsPosition); $categoryMock->expects($this->once())->method('getProductCollection')->willReturn($productsMock); $categoryMock->expects($this->once())->method('getId')->willReturn($categoryId); + $productsMock->expects($this->once())->method('addFieldToSelect')->with('position')->willReturnSelf(); $productsMock->expects($this->once())->method('getItems')->willReturn($items); $this->productLinkFactoryMock->expects($this->once())->method('create')->willReturn($categoryProductLinkMock); $categoryProductLinkMock->expects($this->once()) @@ -71,7 +72,7 @@ class CategoryLinkManagementTest extends \PHPUnit_Framework_TestCase ->willReturnSelf(); $categoryProductLinkMock->expects($this->once()) ->method('setPosition') - ->with(25) + ->with($position) ->willReturnSelf(); $categoryProductLinkMock->expects($this->once()) ->method('setCategoryId') diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Config/Source/Product/Options/TypeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Config/Source/Product/Options/TypeTest.php index aa686d39ce8d9e1bcc08a00a1bcc6ab1bbb997c7..0696faaa9343593ec21d5108a3ccd5c8e98f1850 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Config/Source/Product/Options/TypeTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Config/Source/Product/Options/TypeTest.php @@ -51,7 +51,11 @@ class TypeTest extends \PHPUnit_Framework_TestCase ]; $expect = [ ['value' => '', 'label' => __('-- Please select --')], - ['label' => 'optionLabel', 'value' => [['label' => 'typeLabel', 'value' => 'typeName']]], + [ + 'label' => 'optionLabel', + 'optgroup-name' => 'optionLabel', + 'value' => [['label' => 'typeLabel', 'value' => 'typeName']] + ], ]; $this->productOptionConfig->expects($this->any())->method('getAll')->will($this->returnValue($allOptions)); diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Price.php b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Price.php index 2c4af877568c3d9d33dfb033d034c254e03b376f..bcfef825f53453c3df348a1ea0313aebca153cac 100644 --- a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Price.php +++ b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Price.php @@ -53,14 +53,12 @@ class Price extends \Magento\Ui\Component\Listing\Columns\Column $store = $this->storeManager->getStore( $this->context->getFilterParam('store_id', \Magento\Store\Model\Store::DEFAULT_STORE_ID) ); - $currencyCode = $store->getCurrentCurrencyCode(); - $currencyRate = $store->getCurrentCurrencyRate(); - $currency = $this->localeCurrency->getCurrency($currencyCode); + $currency = $this->localeCurrency->getCurrency($store->getBaseCurrencyCode()); $fieldName = $this->getData('name'); foreach ($dataSource['data']['items'] as & $item) { if (isset($item[$fieldName])) { - $item[$fieldName] = $currency->toCurrency(sprintf("%f", $item[$fieldName] * $currencyRate)); + $item[$fieldName] = $currency->toCurrency(sprintf("%f", $item[$fieldName])); } } } diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml index 3bce181616dab3a8a99102a7105ba6dea9bd880e..30048cce246460ab521b5d608865acea320ea488 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml @@ -21,7 +21,7 @@ </button> <ul class="dropdown-menu"> <li><input type="text" id="product-template-suggest" class="search" - placeholder="start typing to search template"/></li> + placeholder="<?php /* @noEscape */ echo __('start typing to search template'); ?>"/></li> </ul> </div> </div> diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml index 67b1e95e3084663f375efad98714f295ac897c41..6ed486f4c0b4ae21234947626e3f2749aa226d57 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml @@ -9,7 +9,7 @@ ?> <?php /** @var $block \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options */ ?> -<div class="fieldset-wrapper" id="product-custom-options-wrapper"> +<div class="fieldset-wrapper" id="product-custom-options-wrapper" data-block="product-custom-options"> <div class="fieldset-wrapper-title"> <strong class="title"> <span><?php /* @escapeNotVerified */ echo __('Custom Options') ?></span> diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/option.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/option.phtml index 3403d4447f82f705375a32e5467793aabd2dff4d..778c8657a83c25d67548a80f156d9f3e674cd39c 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/option.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/option.phtml @@ -88,7 +88,7 @@ require([ ], function(jQuery){ jQuery(function ($) { - var fieldSet = $('#Custom_Options'); + var fieldSet = $('[data-block=product-custom-options]'); fieldSet.customOptions(<?php /* @escapeNotVerified */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode( [ 'fieldId' => $block->getFieldId(), @@ -97,6 +97,7 @@ jQuery(function ($) { 'customOptionsUrl' => $block->getCustomOptionsUrl(), 'isReadonly' => $block->isReadonly(), 'itemCount' => $block->getItemCount(), + 'currentProductId' => $block->getCurrentProductId(), ] )?>); //adding data to templates diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/attribute/search.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/attribute/search.phtml index d3c382f9276b8a2d9df9ec1473fbe1707779fc42..8d2cca19f20cae71303e2da1d50f12569dfd41fe 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/attribute/search.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/attribute/search.phtml @@ -17,7 +17,7 @@ <input data-role="product-attribute-search" data-group="<?php echo $block->escapeHtml($block->getGroupCode()); ?>" class="search" type="text" - placeholder="start typing to search attribute"/> + placeholder="<?php /* @noEscape */ echo __('start typing to search attribute'); ?>" /> </div> </div> diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/custom-options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/custom-options.js index d68497046a5bf00619fc2db9109ffb8869b7eed2..ae23c3476b8b71df0fd2ff600672c80279247b3b 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/custom-options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/custom-options.js @@ -179,7 +179,7 @@ define([ }); importContainer.load( this.options.productGridUrl, - {form_key: this.options.formKey}, + {form_key: this.options.formKey, current_product_id : this.options.currentProductId}, function () { importContainer.modal('openModal'); } @@ -194,7 +194,8 @@ define([ var widget = this, currentElement = $(event.target), parentId = '#' + currentElement.closest('.fieldset-alt').attr('id'), - group = currentElement.find('[value="' + currentElement.val() + '"]').closest('optgroup').attr('label'), + group = currentElement.find('[value="' + currentElement.val() + '"]') + .closest('optgroup').attr('data-optgroup-name'), previousGroup = $(parentId + '_previous_group').val(), previousBlock = $(parentId + '_type_' + previousGroup), tmpl; diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php new file mode 100644 index 0000000000000000000000000000000000000000..cd094719838136b954de00b78e411e0ee7148461 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogUrlRewrite\Observer; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Event\ObserverInterface; +use Magento\Store\Model\Store; +use Magento\UrlRewrite\Model\UrlPersistInterface; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; + +class ProductToWebsiteChangeObserver implements ObserverInterface +{ + /** + * @var ProductUrlRewriteGenerator + */ + protected $productUrlRewriteGenerator; + + /** + * @var UrlPersistInterface + */ + protected $urlPersist; + + /** + * @var ProductRepositoryInterface + */ + protected $productRepository; + + /** + * @var RequestInterface + */ + protected $request; + + /** + * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator + * @param UrlPersistInterface $urlPersist + * @param ProductRepositoryInterface $productRepository + * @param RequestInterface $request + */ + public function __construct( + ProductUrlRewriteGenerator $productUrlRewriteGenerator, + UrlPersistInterface $urlPersist, + ProductRepositoryInterface $productRepository, + RequestInterface $request + ) { + $this->productUrlRewriteGenerator = $productUrlRewriteGenerator; + $this->urlPersist = $urlPersist; + $this->productRepository = $productRepository; + $this->request = $request; + } + + /** + * Generate urls for UrlRewrite and save it in storage + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + */ + public function execute(\Magento\Framework\Event\Observer $observer) + { + foreach ($observer->getEvent()->getProducts() as $productId) { + $product = $this->productRepository->getById( + $productId, + false, + $this->request->getParam('store_id', Store::DEFAULT_STORE_ID) + ); + + $this->urlPersist->deleteByData([ + UrlRewrite::ENTITY_ID => $product->getId(), + UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, + ]); + $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); + } + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml index 194b45d59a41ab1754da85805935bb7d82e968ea..477a6cf338b1ba397c3559533c8957c617519017 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml @@ -27,4 +27,7 @@ <event name="catalog_category_move_after"> <observer name="process_url_rewrite_moving" instance="Magento\CatalogUrlRewrite\Observer\CategoryProcessUrlRewriteMovingObserver"/> </event> + <event name="catalog_product_to_website_change"> + <observer name="catalog_product_to_website_change" instance="Magento\CatalogUrlRewrite\Observer\ProductToWebsiteChangeObserver"/> + </event> </config> diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php index e48634a2c7d54cc513997d3b742ed612f9594c8b..bf336cbf87059b52ac2a024c8368d99e30aafe28 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php @@ -54,6 +54,11 @@ class Matrix extends \Magento\Backend\Block\Template /** @var null|array */ private $productAttributes; + /** + * @var \Magento\Framework\Locale\CurrencyInterface + */ + protected $localeCurrency; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType @@ -62,6 +67,7 @@ class Matrix extends \Magento\Backend\Block\Template * @param \Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix $variationMatrix * @param ProductRepositoryInterface $productRepository * @param \Magento\Catalog\Helper\Image $image + * @param \Magento\Framework\Locale\CurrencyInterface $localeCurrency * @param array $data */ public function __construct( @@ -72,6 +78,7 @@ class Matrix extends \Magento\Backend\Block\Template \Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix $variationMatrix, ProductRepositoryInterface $productRepository, \Magento\Catalog\Helper\Image $image, + \Magento\Framework\Locale\CurrencyInterface $localeCurrency, array $data = [] ) { parent::__construct($context, $data); @@ -80,6 +87,7 @@ class Matrix extends \Magento\Backend\Block\Template $this->stockRegistry = $stockRegistry; $this->variationMatrix = $variationMatrix; $this->productRepository = $productRepository; + $this->localeCurrency = $localeCurrency; $this->image = $image; } @@ -88,7 +96,7 @@ class Matrix extends \Magento\Backend\Block\Template */ public function getCurrencySymbol() { - return $this->_storeManager->getStore()->getCurrentCurrency()->getCurrencySymbol(); + return $this->localeCurrency->getCurrency($this->_storeManager->getStore()->getBaseCurrencyCode())->getSymbol(); } /** diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Steps/Bulk.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Steps/Bulk.php index 69960ac40a6f37ab455591503f20b524c8244d99..d440b7347b6e65ad1b825b9e66fb43ad31ad2f80 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Steps/Bulk.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Steps/Bulk.php @@ -39,12 +39,4 @@ class Bulk extends \Magento\Ui\Block\Component\StepsWizard\StepAbstract { return $this->image->getDefaultPlaceholderUrl('thumbnail'); } - - /** - * @return string - */ - public function getCurrencySymbol() - { - return $this->_storeManager->getStore()->getCurrentCurrency()->getCurrencySymbol(); - } } diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml index 8a1b3edc8053e65e07b1f9c59dd2887d0f5c1bb0..df8785085dea3ec27b267ac6835a42e6f75bebf8 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml @@ -655,7 +655,6 @@ "component": "Magento_ConfigurableProduct/js/variations/steps/bulk", "appendTo": "<?= /* @escapeNotVerified */ $block->getParentComponentName()?>", "noImage": "<?= /* @escapeNotVerified */ $block->getNoImageUrl() ?>", - "currencySymbol": "<?= /* @escapeNotVerified */ $block->getCurrencySymbol() ?>", "variationsComponent": "configurableVariations" } } diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml index b71eadea028641416be173ce6700cb0b860e8561..b1d12ed35ed1e3912a12ab4f13e910489f938595 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml @@ -16,7 +16,7 @@ You need to create a simple product for each configuration (Ex: a product for each color).');?> </div> </div> - <div class="product-create-configuration-actions"> + <div class="product-create-configuration-actions" data-action="product-create-configuration-buttons"> <div class="product-create-configuration-action"> <button type="button" data-action="open-steps-wizard" title="Create Product Configurations" class="action-secondary" data-bind="click: open"> diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml index e962963ccac6ca28245e4e25edc5b0917c01bfd9..a56ee49266f28a19835338c4da287ea02b745f3d 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml @@ -144,7 +144,7 @@ $currencySymbol = $block->getCurrencySymbol(); </td> <td class="col-price" data-column="price"> <!-- ko ifnot: variation.editable --> - <!-- ko text: '<?= /* @noEscape */ $currencySymbol?>' + variation.price --><!--/ko--> + <!-- ko text: $parent.getCurrencySymbol() + variation.price --><!--/ko--> <!-- /ko --> <!-- ko if: variation.editable --> <div class="addon"> @@ -156,7 +156,7 @@ $currencySymbol = $block->getCurrencySymbol(); value: variation.price}"/> <label class="addafter" data-bind="attr: {for: $parent.getRowId(variation, 'price')"> - <strong>$</strong> + <strong data-bind="text: $parent.getCurrencySymbol()"></strong> </label> </div> <!-- /ko --> @@ -255,6 +255,7 @@ $currencySymbol = $block->getCurrencySymbol(); "variations": <?= /* @noEscape */ $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($productMatrix) ?>, "productAttributes": <?= /* @noEscape */ $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($attributes) ?>, "productUrl": "<?= /* @noEscape */ $block->getUrl('catalog/product/edit', ['id' => '%id%']) ?>", + "currencySymbol": "<?= /* @noEscape */ $currencySymbol ?>", "configurableProductGrid": "configurableProductGrid" } } diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js index 5f4af9cd5e3e2e777c05fe58bd5760e938654661..499962f8e59f8f68e598ce4800ac90ff824f7578 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js @@ -55,7 +55,7 @@ define([ type: ko.observable('none'), value: ko.observable(), attribute: ko.observable(), - currencySymbol: this.currencySymbol + currencySymbol: this.variationsComponent().getCurrencySymbol() }, quantity: { label: 'quantity', diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js index 0da35357808085b8fe91792cd7bdac8e523a3e37..0a1088393c04f8b50c48c2405c6668477b2eb95f 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js @@ -40,7 +40,7 @@ define([ nextLabelText: $.mage.__('Generate Products'), variations: [], generateGrid: function (variations, getSectionValue) { - var productName = this.variationsComponent().getProductValue('name'), + var productSku = this.variationsComponent().getProductValue('sku'), productPrice = this.variationsComponent().getProductValue('price'), productWeight = this.variationsComponent().getProductValue('weight'), variationsKeys = [], @@ -59,7 +59,7 @@ define([ }); } images = getSectionValue('images', options); - sku = productName + _.reduce(options, function (memo, option) { + sku = productSku + _.reduce(options, function (memo, option) { return memo + '-' + option.label; }, ''); quantity = getSectionValue('quantity', options); @@ -129,7 +129,7 @@ define([ _.each(variation.options, function (option) { row.push(option.label); }); - row.push('$ ' + variation.price); + row.push(this.variationsComponent().getCurrencySymbol() + ' ' + variation.price); return row; }, diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js index 862ffe05a6cfc78bfa750cce52b2c2fef1258273..150326b3fabaf055dbf1184c363635c7b4b16db8 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js @@ -368,6 +368,14 @@ define([ .addClass('disabled-configurable-elements') .prop('disabled', true); }); + }, + + /** + * Get currency symbol + * @returns {*} + */ + getCurrencySymbol: function () { + return this.currencySymbol; } }); }); diff --git a/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php b/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php index d456491e5c33462e25d49386eb0c77fbf7674684..7ac2be353e6a403afbb46ee599a880e0704a4bc5 100644 --- a/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php +++ b/app/code/Magento/Customer/Model/Config/Backend/Address/Street.php @@ -10,7 +10,7 @@ use Magento\Framework\App\Config\ScopeConfigInterface; /** * Line count config model for customer address street attribute * - * @method string getWebsiteCode + * @method string getWebsiteCode() */ class Street extends \Magento\Framework\App\Config\Value { diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml index 0c4077543059fd746f88a67b946889ca286ce287..dac2edad7be49ec47e029d391901da6842ed6154 100644 --- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml +++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable.phtml @@ -67,9 +67,9 @@ var uploaderTemplate = '<div class="no-display" id="[[idName]]-template">' + } }; - var configurationSectionMessageHandler = (new function(attributeTitle, attributeTab) { + var configurationSectionMessageHandler = (new function(attributeTitle, buttons) { this.title = jQuery(attributeTitle); - this.buttons = jQuery('button', attributeTab); + this.buttons = jQuery(buttons); this.newText = '<?= /* @noEscape */ __('Configurations cannot be created for a standard product with downloadable files.' . ' To create configurations, first remove all downloadable files.');?>'; this.oldText = this.title.text(); @@ -86,7 +86,7 @@ var uploaderTemplate = '<div class="no-display" id="[[idName]]-template">' + this.title.text(this.newText); this.buttons.hide(); } - }('[data-role="product-create-configuration-info"]', '[data-tab="super_config"]')); + }('[data-role="product-create-configuration-info"]', '[data-action="product-create-configuration-buttons"]')); downloadableCheckbox.on('change', function () { switchConfigurationSectionMessage(!jQuery(this).is(':checked')); diff --git a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned/Grid.php b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned/Grid.php index 648db357ee120790bda999e2c009e6c21bfdd8ba..99d5ea9e11b1c04d7c0554aa6011dc32347b2fa7 100644 --- a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned/Grid.php +++ b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned/Grid.php @@ -8,7 +8,7 @@ namespace Magento\Reports\Block\Adminhtml\Shopcart\Abandoned; /** * Adminhtml abandoned shopping carts report grid block * - * @method \Magento\Reports\Model\ResourceModel\Quote\Collection getCollection + * @method \Magento\Reports\Model\ResourceModel\Quote\Collection getCollection() * * @author Magento Core Team <core@magentocommerce.com> * @SuppressWarnings(PHPMD.DepthOfInheritance) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php index cf69855c1489cf99d438b9892f7b0b38da97870c..5918bdb0326b94b22357a02afa89e3551b245ae4 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php @@ -14,14 +14,14 @@ use \Magento\Sales\Model\Order\CreditmemoFactory; * Class CreditmemoLoader * * @package Magento\Sales\Controller\Adminhtml\Order - * @method CreditmemoLoader setCreditmemoId - * @method CreditmemoLoader setCreditmemo - * @method CreditmemoLoader setInvoiceId - * @method CreditmemoLoader setOrderId - * @method int getCreditmemoId - * @method string getCreditmemo - * @method int getInvoiceId - * @method int getOrderId + * @method CreditmemoLoader setCreditmemoId($id) + * @method CreditmemoLoader setCreditmemo($creditMemo) + * @method CreditmemoLoader setInvoiceId($id) + * @method CreditmemoLoader setOrderId($id) + * @method int getCreditmemoId() + * @method string getCreditmemo() + * @method int getInvoiceId() + * @method int getOrderId() */ class CreditmemoLoader extends DataObject { diff --git a/app/code/Magento/Sales/Model/Download.php b/app/code/Magento/Sales/Model/Download.php index be8054315ea9ccf7ffaa42e4ffeaf86864f571bf..0f2649d7de582651d8ab65af4866b2cca21139d4 100644 --- a/app/code/Magento/Sales/Model/Download.php +++ b/app/code/Magento/Sales/Model/Download.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Model; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\LocalizedException; class Download { @@ -29,19 +30,27 @@ class Download */ protected $_fileFactory; + /** + * @var string + */ + protected $rootDirBasePath; + /** * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDatabase * @param \Magento\MediaStorage\Model\File\Storage\DatabaseFactory $storageDatabaseFactory * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory + * @param string $rootDirBasePath */ public function __construct( \Magento\Framework\Filesystem $filesystem, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDatabase, \Magento\MediaStorage\Model\File\Storage\DatabaseFactory $storageDatabaseFactory, - \Magento\Framework\App\Response\Http\FileFactory $fileFactory + \Magento\Framework\App\Response\Http\FileFactory $fileFactory, + $rootDirBasePath = DirectoryList::MEDIA ) { - $this->_rootDir = $filesystem->getDirectoryWrite(DirectoryList::ROOT); + $this->rootDirBasePath = $rootDirBasePath; + $this->_rootDir = $filesystem->getDirectoryWrite($this->rootDirBasePath); $this->_fileStorageDatabase = $fileStorageDatabase; $this->_storageDatabaseFactory = $storageDatabaseFactory; $this->_fileFactory = $fileFactory; @@ -57,18 +66,19 @@ class Download public function downloadFile($info) { $relativePath = $info['order_path']; - if ($this->_isCanProcessed($relativePath)) { + if (!$this->_isCanProcessed($relativePath)) { //try get file from quote $relativePath = $info['quote_path']; - if ($this->_isCanProcessed($relativePath)) { - throw new \Exception(); + if (!$this->_isCanProcessed($relativePath)) { + throw new LocalizedException( + __('Path "%1" is not part of allowed directory "%2"', $relativePath, $this->rootDirBasePath) + ); } } - $this->_fileFactory->create( $info['title'], ['value' => $this->_rootDir->getRelativePath($relativePath), 'type' => 'filename'], - DirectoryList::ROOT + $this->rootDirBasePath ); } @@ -79,32 +89,28 @@ class Download protected function _isCanProcessed($relativePath) { $filePath = $this->_rootDir->getAbsolutePath($relativePath); - return (!$this->_rootDir->isFile( - $relativePath - ) || !$this->_rootDir->isReadable( - $relativePath - )) && !$this->_processDatabaseFile( - $filePath - ); + return (strpos($this->_rootDir->getDriver()->getRealPath($filePath), $relativePath) !== false + && $this->_rootDir->isFile($relativePath) && $this->_rootDir->isReadable($relativePath)) + || $this->_processDatabaseFile($filePath, $relativePath); } /** * Check file in database storage if needed and place it on file system * * @param string $filePath + * @param string $relativePath * @return bool */ - protected function _processDatabaseFile($filePath) + protected function _processDatabaseFile($filePath, $relativePath) { if (!$this->_fileStorageDatabase->checkDbUsage()) { return false; } - $relativePath = $this->_fileStorageDatabase->getMediaRelativePath($filePath); $file = $this->_storageDatabaseFactory->create()->loadByFilename($relativePath); if (!$file->getId()) { return false; } - $stream = $this->_rootDir->openFile($filePath, 'w+'); + $stream = $this->_rootDir->openFile($relativePath, 'w+'); $stream->lock(); $stream->write($filePath, $file->getContent()); $stream->unlock(); diff --git a/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php b/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php index e7410b411bfa6de5ca497929115cf224d31f45f6..295981ef91ed16cb6102014764155615ae87b492 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php @@ -39,6 +39,11 @@ class DownloadTest extends \PHPUnit_Framework_TestCase */ protected $writeDirectoryMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $driverMock; + protected function setUp() { $this->writeDirectoryMock = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\Write') @@ -49,9 +54,10 @@ class DownloadTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->filesystemMock->expects($this->any()) ->method('getDirectoryWrite') - ->with(DirectoryList::ROOT) + ->with(DirectoryList::MEDIA) ->will($this->returnValue($this->writeDirectoryMock)); + $this->driverMock = $this->getMockForAbstractClass('Magento\Framework\Filesystem\DriverInterface'); $this->storageMock = $this->getMockBuilder('Magento\MediaStorage\Helper\File\Storage\Database') ->disableOriginalConstructor() ->getMock(); @@ -83,17 +89,23 @@ class DownloadTest extends \PHPUnit_Framework_TestCase } /** - * @expectedException \Exception + * @param $realPatchCheck + * @param $isFile + * @param $isReadable + * @expectedException \Magento\Framework\Exception\LocalizedException + * @dataProvider dataProviderForTestDownloadFileException */ - public function testDownloadFileException() + public function testDownloadFileException($realPatchCheck, $isFile, $isReadable) { $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title']; - $isFile = true; - $isReadable = false; $this->writeDirectoryMock->expects($this->any()) ->method('getAbsolutePath') ->will($this->returnArgument(0)); + $this->writeDirectoryMock->expects($this->any()) + ->method('getDriver') + ->willReturn($this->driverMock); + $this->driverMock->expects($this->any())->method('getRealPath')->willReturn($realPatchCheck); $this->writeDirectoryMock->expects($this->any()) ->method('isFile') ->will($this->returnValue($isFile)); @@ -104,12 +116,25 @@ class DownloadTest extends \PHPUnit_Framework_TestCase $this->storageFactoryMock->expects($this->any()) ->method('checkDbUsage') ->will($this->returnValue(false)); + $this->httpFileFactoryMock->expects($this->never())->method('create'); $this->model->downloadFile($info); } /** - * @expectedException \Exception + * @return array + */ + public function dataProviderForTestDownloadFileException() + { + return [ + [1, true, false], + [1, false, true], + [false, true, true], + ]; + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException */ public function testDownloadFileNoStorage() { @@ -120,6 +145,11 @@ class DownloadTest extends \PHPUnit_Framework_TestCase $this->writeDirectoryMock->expects($this->any()) ->method('getAbsolutePath') ->will($this->returnArgument(0)); + $this->writeDirectoryMock->expects($this->any()) + ->method('getDriver') + ->willReturn($this->driverMock); + $this->driverMock->expects($this->any())->method('getRealPath')->willReturn(true); + $this->writeDirectoryMock->expects($this->any()) ->method('isFile') ->will($this->returnValue($isFile)); @@ -130,9 +160,6 @@ class DownloadTest extends \PHPUnit_Framework_TestCase $this->storageMock->expects($this->any()) ->method('checkDbUsage') ->will($this->returnValue(true)); - $this->storageMock->expects($this->any()) - ->method('getMediaRelativePath') - ->will($this->returnArgument(0)); $storageDatabaseMock = $this->getMockBuilder('Magento\MediaStorage\Model\File\Storage\Database') ->disableOriginalConstructor() @@ -153,6 +180,7 @@ class DownloadTest extends \PHPUnit_Framework_TestCase $this->storageFactoryMock->expects($this->any()) ->method('create') ->will($this->returnValue($storageDatabaseMock)); + $this->httpFileFactoryMock->expects($this->never())->method('create'); $this->model->downloadFile($info); } @@ -178,6 +206,11 @@ class DownloadTest extends \PHPUnit_Framework_TestCase $this->writeDirectoryMock->expects($this->any()) ->method('getAbsolutePath') ->will($this->returnArgument(0)); + $this->writeDirectoryMock->expects($this->any()) + ->method('getDriver') + ->willReturn($this->driverMock); + $this->driverMock->expects($this->any())->method('getRealPath')->willReturn(true); + $this->writeDirectoryMock->expects($this->any()) ->method('isFile') ->will($this->returnValue($isFile)); @@ -195,9 +228,6 @@ class DownloadTest extends \PHPUnit_Framework_TestCase $this->storageMock->expects($this->any()) ->method('checkDbUsage') ->will($this->returnValue(true)); - $this->storageMock->expects($this->any()) - ->method('getMediaRelativePath') - ->will($this->returnArgument(0)); $storageDatabaseMock = $this->getMockBuilder('Magento\MediaStorage\Model\File\Storage\Database') ->disableOriginalConstructor() @@ -220,7 +250,7 @@ class DownloadTest extends \PHPUnit_Framework_TestCase ->with( $info['title'], ['value' => $info['order_path'], 'type' => 'filename'], - DirectoryList::ROOT, + DirectoryList::MEDIA, 'application/octet-stream', null ); diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index 6bbaac5a04d4a34331323019cc7cbd4f03fbf704..c837623ac8ffd99323b1b116bbb8648db83f7433 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -12,14 +12,14 @@ use Magento\Framework\DataObject; * Class ShipmentLoader * * @package Magento\Shipping\Controller\Adminhtml\Order - * @method ShipmentLoader setOrderId - * @method ShipmentLoader setShipmentId - * @method ShipmentLoader setShipment - * @method ShipmentLoader setTracking - * @method int getOrderId - * @method int getShipmentId - * @method array getShipment - * @method array getTracking + * @method ShipmentLoader setOrderId($id) + * @method ShipmentLoader setShipmentId($id) + * @method ShipmentLoader setShipment($shipment) + * @method ShipmentLoader setTracking($tracking) + * @method int getOrderId() + * @method int getShipmentId() + * @method array getShipment() + * @method array getTracking() */ class ShipmentLoader extends DataObject { diff --git a/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Files.php b/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Files.php index 9b11f465787d75ba95c8349733e76ad6d7668790..1af3ea8e4bc986b49e0c718e0a3e9b4bb9006ead 100644 --- a/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Files.php +++ b/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content/Files.php @@ -9,7 +9,7 @@ * * @method * \Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Content\Files setStorage(\Magento\Theme\Model\Wysiwyg\Storage $storage) - * @method \Magento\Theme\Model\Wysiwyg\Storage getStorage + * @method \Magento\Theme\Model\Wysiwyg\Storage getStorage() */ namespace Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Content; diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php index 611e8c839d477cf9ad31672dbf27f387b61d4d14..b005c52813a7b987df53f64d5083c8a43f1434d9 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php @@ -16,7 +16,7 @@ class ValidatorFileTest extends \PHPUnit_Framework_TestCase protected $model; /** - * @var \Magento\Framework\ObjectManager + * @var \Magento\Framework\ObjectManagerInterface */ protected $objectManager; @@ -241,8 +241,8 @@ class ValidatorFileTest extends \PHPUnit_Framework_TestCase return [ 'type' => 'image/jpeg', 'title' => 'test.jpg', - 'quote_path' => 'pub/media/custom_options/quote/t/e/e1d601731b4b1a84163cd0e9370a4fcb.jpg', - 'order_path' => 'pub/media/custom_options/order/t/e/e1d601731b4b1a84163cd0e9370a4fcb.jpg', + 'quote_path' => 'custom_options/quote/t/e/e1d601731b4b1a84163cd0e9370a4fcb.jpg', + 'order_path' => 'custom_options/order/t/e/e1d601731b4b1a84163cd0e9370a4fcb.jpg', 'size' => '3300', 'width' => 136, 'height' => 131, diff --git a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html index 15e322c12df580c58724b6193208e99bd8481cb8..ec08d09ec6bc5642bc18966ceda3196abb900ff4 100644 --- a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html +++ b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html @@ -6,9 +6,9 @@ --> <select name="design_abstractions" id="design_abstraction_select" class="design-abstraction-select" title="Design Abstraction Select"> <option value="">-- Please Select --</option> - <optgroup label="Custom Layouts"> + <optgroup data-optgroup-name="Custom Layouts" label="Custom Layouts"> <option value="customer_account" >Customer My Account (All Pages)</option> </optgroup> - <optgroup label="Page Layouts"> + <optgroup data-optgroup-name="Page Layouts" label="Page Layouts"> <option value="page_empty" >All Empty Layout Pages</option> </optgroup></select> diff --git a/lib/internal/Magento/Framework/View/Element/Html/Select.php b/lib/internal/Magento/Framework/View/Element/Html/Select.php index ab54697632aceffbda35a6fee7debca60dc6e3d8..884c11fe91950eca05b450eb1a8ea6b12114a23a 100644 --- a/lib/internal/Magento/Framework/View/Element/Html/Select.php +++ b/lib/internal/Magento/Framework/View/Element/Html/Select.php @@ -125,6 +125,7 @@ class Select extends \Magento\Framework\View\Element\AbstractBlock * @return string * * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _toHtml() { @@ -151,9 +152,11 @@ class Select extends \Magento\Framework\View\Element\AbstractBlock $isArrayOption = true; foreach ($this->getOptions() as $key => $option) { + $optgroupName = ''; if ($isArrayOption && is_array($option)) { $value = $option['value']; $label = (string)$option['label']; + $optgroupName = isset($option['optgroup-name']) ? $option['optgroup-name'] : $label; $params = !empty($option['params']) ? $option['params'] : []; } else { $value = (string)$key; @@ -163,7 +166,7 @@ class Select extends \Magento\Framework\View\Element\AbstractBlock } if (is_array($value)) { - $html .= '<optgroup label="' . $label . '">'; + $html .= '<optgroup label="' . $label . '" data-optgroup-name="' . $optgroupName . '">'; foreach ($value as $keyGroup => $optionGroup) { if (!is_array($optionGroup)) { $optionGroup = ['value' => $keyGroup, 'label' => $optionGroup]; diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php index d3660f32178ac024283b682bc5d93f93f00a5e39..3321d1eeaf8b6d1b1c1136faceaf08239c8413db 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php @@ -127,7 +127,7 @@ class SelectTest extends \PHPUnit_Framework_TestCase . '<option value="testValue" paramKey="paramValue" >testLabel</option>' . '<option value="selectedValue" selected="selected" paramKey="paramValue" ' . ' paramKey2="paramValue2" >selectedLabel</option>' - . '<optgroup label="groupLabel">' + . '<optgroup label="groupLabel" data-optgroup-name="groupLabel">' . '<option value="groupElementValue" >GroupElementLabel</option>' . '<option value="selectedGroupElementValue" selected="selected" >SelectedGroupElementLabel</option>' . '</optgroup>'