diff --git a/app/code/Magento/Backend/view/adminhtml/layout/default.xml b/app/code/Magento/Backend/view/adminhtml/layout/default.xml index 8feb4d5163cb..ead5dae773e1 100644 --- a/app/code/Magento/Backend/view/adminhtml/layout/default.xml +++ b/app/code/Magento/Backend/view/adminhtml/layout/default.xml @@ -11,8 +11,6 @@ - - diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php index 291ca3566b2e..b61ec798fb81 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php @@ -93,7 +93,10 @@ public function getCalendarDateHtml() $yearStart = $this->_catalogProductOptionTypeDate->getYearStart(); $yearEnd = $this->_catalogProductOptionTypeDate->getYearEnd(); - $dateFormat = $this->_localeDate->getDateFormatWithLongYear(); + $fieldsSeparator = '/'; + $fieldsOrder = $this->_catalogProductOptionTypeDate->getConfigData('date_fields_order') ?? ''; + $fieldsOrder = str_replace(",", $fieldsSeparator, $fieldsOrder); + $dateFormat = $fieldsOrder !== "m/d/y" ? $fieldsOrder : $this->_localeDate->getDateFormatWithLongYear(); /** Escape RTL characters which are present in some locales and corrupt formatting */ $escapedDateFormat = preg_replace('/[^MmDdYy\/\.\-]/', '', $dateFormat); $value = null; diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 453148d88ae2..bd31eafc7635 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -813,7 +813,7 @@ private function getCollectionProcessor() { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - // phpstan:ignore "Class Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor not found." + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml \Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor::class ); } diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminAddCustomizableOptionToSimpleProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminAddCustomizableOptionToSimpleProductActionGroup.xml new file mode 100644 index 000000000000..911f6b2cf454 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminAddCustomizableOptionToSimpleProductActionGroup.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminConfigExpandDateAndTimeTabActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminConfigExpandDateAndTimeTabActionGroup.xml new file mode 100644 index 000000000000..f257232a0d21 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminConfigExpandDateAndTimeTabActionGroup.xml @@ -0,0 +1,19 @@ + + + + + + + Expand date and time options tab. + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductDateFormatInStorefrontActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductDateFormatInStorefrontActionGroup.xml new file mode 100644 index 000000000000..88bbd788bfdb --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductDateFormatInStorefrontActionGroup.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + dateValue + currentDate + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SelectDropdownDateAndTimeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SelectDropdownDateAndTimeActionGroup.xml new file mode 100644 index 000000000000..3a59b6a08e4f --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SelectDropdownDateAndTimeActionGroup.xml @@ -0,0 +1,32 @@ + + + + + + + Select options for Use JavaScript Calendar and Date Fields Order dropdown + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCustomizeDateAndTimeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCustomizeDateAndTimeSection.xml new file mode 100644 index 000000000000..14e773341e3c --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCustomizeDateAndTimeSection.xml @@ -0,0 +1,17 @@ + + + + +
+ + + + +
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionSection.xml new file mode 100644 index 000000000000..01315acc0af2 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionSection.xml @@ -0,0 +1,22 @@ + + + + +
+ + + + + + + + + +
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml index f13b53830489..b0347d33cc90 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml @@ -114,5 +114,8 @@ + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminJsCalenderDateFormatTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminJsCalenderDateFormatTest.xml new file mode 100644 index 000000000000..f9fd70cd3c15 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminJsCalenderDateFormatTest.xml @@ -0,0 +1,83 @@ + + + + + + + + + + <description value="Check if js calender format configured in backend is reflected on storefront" /> + <severity value="AVERAGE"/> + <testCaseId value="AC-12164"/> + <group value="Catalog"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + </before> + + <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteProduct"> + <argument name="sku" value="{{_defaultProduct.sku}}"/> + </actionGroup> + <actionGroup ref="ResetAdminDataGridToDefaultViewActionGroup" stepKey="clearFilter"/> + + <actionGroup ref="AdminOpenStoreConfigCatalogPageActionGroup" stepKey="navigateToConfigurationPage2"/> + <actionGroup ref="AdminConfigExpandDateAndTimeTabActionGroup" stepKey="expandDateAndTimeCustomOptionsTab2"/> + <actionGroup ref="SelectDropdownDateAndTimeActionGroup" stepKey="RevertDateAndTimeFieldOrder"> + <argument name="useJsCalender" value="No"/> + <argument name="firstFieldOfDateOrder" value="Month"/> + <argument name="secondFieldOfDateOrder" value="Day"/> + </actionGroup> + <actionGroup ref="AdminCheckUseSystemValueActionGroup" stepKey="checkUseSystemValueForDateFieldsOrder"> + <argument name="rowId" value="row_catalog_custom_options_date_fields_order"/> + </actionGroup> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveDateAndTimeConfig2"/> + + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutOfAdmin"/> + </after> + + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + + <!-- Open admin configuration, got to catalog, expand date and time tab --> + <actionGroup ref="AdminOpenStoreConfigCatalogPageActionGroup" stepKey="navigateToConfigurationPage"/> + <actionGroup ref="AdminConfigExpandDateAndTimeTabActionGroup" stepKey="expandDateAndTimeCustomOptionsTab"/> + + <!-- Customize date and time configuration to D/M/Y --> + <actionGroup ref="AdminUncheckUseSystemValueActionGroup" stepKey="uncheckUseSystemValueForDateFieldsOrder"> + <argument name="rowId" value="row_catalog_custom_options_date_fields_order"/> + </actionGroup> + <actionGroup ref="SelectDropdownDateAndTimeActionGroup" stepKey="CustomizeDateAndTimeFieldOrder"> + <argument name="useJsCalender" value="Yes"/> + <argument name="firstFieldOfDateOrder" value="Day"/> + <argument name="secondFieldOfDateOrder" value="Month"/> + </actionGroup> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveDateAndTimeConfig"/> + + <!-- Create simple product on storefront --> + <actionGroup ref="FillAdminSimpleProductFormActionGroup" stepKey="fillProductFieldsInAdmin"> + <argument name="category" value="$$createPreReqCategory$$"/> + <argument name="simpleProduct" value="_defaultProduct"/> + </actionGroup> + + <!-- Add customizable date option --> + <actionGroup ref="AdminAddCustomizableOptionToSimpleProductActionGroup" stepKey="AddCustomizableDateOption"/> + + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="runCronIndex"> + <argument name="indices" value=""/> + </actionGroup> + + <!-- Assert date on storefront --> + <actionGroup ref="AssertProductDateFormatInStorefrontActionGroup" stepKey="assertDateFormat"> + <argument name="product" value="_defaultProduct"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php index 03df022229c9..a4f5c697c7b5 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php @@ -7,16 +7,16 @@ namespace Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier; -use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Categories; -use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory; +use Magento\Authorization\Model\Role; +use Magento\Backend\Model\Auth\Session; use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection; +use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory; +use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Categories; use Magento\Framework\App\CacheInterface; use Magento\Framework\AuthorizationInterface; use Magento\Framework\DB\Helper as DbHelper; use Magento\Framework\UrlInterface; use Magento\Store\Model\Store; -use Magento\Backend\Model\Auth\Session; -use Magento\Authorization\Model\Role; use Magento\User\Model\User; use PHPUnit\Framework\MockObject\MockObject; @@ -91,6 +91,9 @@ protected function setUp(): void $this->categoryCollectionMock->expects($this->any()) ->method('addAttributeToSelect') ->willReturnSelf(); + $this->categoryCollectionMock->expects($this->any()) + ->method('addAttributeToSort') + ->willReturnSelf(); $this->categoryCollectionMock->expects($this->any()) ->method('addAttributeToFilter') ->willReturnSelf(); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php index f9efaec20186..b7dc6fc86f6e 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php @@ -7,18 +7,20 @@ namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier; +use Magento\Backend\Model\Auth\Session; +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Catalog\Model\Category as CategoryModel; use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory; -use Magento\Framework\App\ObjectManager; use Magento\Framework\App\CacheInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\AuthorizationInterface; +use Magento\Framework\Data\Collection; use Magento\Framework\DB\Helper as DbHelper; -use Magento\Catalog\Model\Category as CategoryModel; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\UrlInterface; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Framework\AuthorizationInterface; -use Magento\Backend\Model\Auth\Session; +use Magento\Framework\UrlInterface; /** * Data provider for categories field of product page @@ -51,6 +53,7 @@ class Categories extends AbstractModifier /** * @var array * @deprecated 101.0.0 + * @see Nothing * @since 101.0.0 */ protected $categoriesTrees = []; @@ -128,6 +131,7 @@ public function __construct( * * @return CacheInterface * @deprecated 101.0.3 + * @see getCategoriesTree */ private function getCacheManager(): CacheInterface { @@ -442,6 +446,8 @@ private function retrieveCategoriesTree(int $storeId, array $shownCategoriesIds) $collection->addAttributeToFilter('entity_id', ['in' => array_keys($shownCategoriesIds)]) ->addAttributeToSelect(['name', 'is_active', 'parent_id']) + ->addAttributeToSort(CategoryInterface::KEY_LEVEL, Collection::SORT_ORDER_ASC) + ->addAttributeToSort(CategoryInterface::KEY_POSITION, Collection::SORT_ORDER_ASC) ->setStoreId($storeId); $categoryById = [ diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index 548fcff079b8..aa691dee3308 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -147,7 +147,7 @@ class Option extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity 'radio' => true, 'checkbox' => true, 'multiple' => true, - 'file' => ['sku', 'file_extension', 'image_size_x', 'image_size_y'], + 'file' => ['price', 'sku', 'file_extension', 'image_size_x', 'image_size_y'], ]; /** @@ -2093,10 +2093,26 @@ protected function _parseCustomOptions($rowData) $k = 0; $name = ''; foreach ($optionValues as $optionValue) { + $separator = preg_quote($this->_productEntity->getMultipleValueSeparator(), '/'); + $pattern = '/(?:^|' . $separator . ')file_extension=([a-zA-Z' . $separator . ']+)(?:' . $separator . '|$)/'; + + if (preg_match($pattern, $optionValue, $matches)) { + $fileExtNameAndValue = $matches[0]; + $fileExtNameAndValue = ltrim($fileExtNameAndValue, $separator); + $optionValue = str_replace($fileExtNameAndValue, '', $optionValue); + $fileExtNameAndValue = rtrim($fileExtNameAndValue, $separator); + $optionValue = rtrim($optionValue, $separator); + } + $optionValueParams = explode($this->_productEntity->getMultipleValueSeparator(), $optionValue); + + if (isset($fileExtNameAndValue)) { + $optionValueParams[] = $fileExtNameAndValue; + } + foreach ($optionValueParams as $nameAndValue) { $nameAndValue = explode('=', $nameAndValue); - $value = isset($nameAndValue[1]) ? $nameAndValue[1] : ''; + $value = $nameAndValue[1] ?? ''; $value = trim($value); $fieldName = isset($nameAndValue[0]) ? trim($nameAndValue[0]) : ''; if ($value && ($fieldName === 'name')) { diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/OptionTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/OptionTest.php index dd324df8a9a9..9fafb81b3411 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/OptionTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/OptionTest.php @@ -924,6 +924,120 @@ public static function validateRowStoreViewCodeFieldDataProvider(): array ]; } + /** + * Test parsing different option's type with _parseCustomOptions() method. + * + * @param array $rowData + * @param array $responseData + * + * @return void + * @dataProvider validateParseCustomOptionsDataProvider + * @throws \ReflectionException + */ + public function testValidateParseCustomOptions(array $rowData, array $responseData): void + { + $reflection = new \ReflectionClass(Option::class); + $reflectionMethod = $reflection->getMethod('_parseCustomOptions'); + $result = $reflectionMethod->invoke($this->model, $rowData); + $this->assertEquals($responseData, $result); + } + + /** + * Data provider for testValidateParseCustomOptions. + * + * @return array + */ + public static function validateParseCustomOptionsDataProvider(): array + { + return [ + 'file_type' => [ + '$rowData' => [ + 'custom_options' => 'name=Test Field Title,type=file,required=1,' + . 'sku=1-text,price=12,file_extension=png,jpeg,jpg,gif,image_size_x=1024,' + . 'image_size_y=1024,price_type=fixed' + ], + '$responseData' => [ + 'custom_options' => [ + 'Test Field Title' => [ + [ + 'name' => 'Test Field Title', + 'type' => 'file', + 'required' => '1', + 'sku' => '1-text', + 'price' => '12', + 'file_extension' => 'png,jpeg,jpg,gif', + 'image_size_x' => '1024', + 'image_size_y' => '1024', + 'price_type' => 'fixed' + ] + ] + ] + ] + ], + 'drop_down' => [ + '$rowData' => [ + 'custom_options' => 'name=Test Field Title,type=drop_down,required=0,' + . 'sku=1-text,price=10,price_type=fixed' + ], + '$responseData' => [ + 'custom_options' => [ + 'Test Field Title' => [ + [ + 'name' => 'Test Field Title', + 'type' => 'drop_down', + 'required' => '0', + 'sku' => '1-text', + 'price' => '10', + 'price_type' => 'fixed' + ] + ] + ] + ] + ], + 'area' => [ + '$rowData' => [ + 'custom_options' => 'name=Test Field Title,type=area,required=1,' + . 'sku=1-text,price=20,max_characters=150,price_type=fixed' + ], + '$responseData' => [ + 'custom_options' => [ + 'Test Field Title' => [ + [ + 'name' => 'Test Field Title', + 'type' => 'area', + 'required' => '1', + 'sku' => '1-text', + 'price' => '20', + 'max_characters' => '150', + 'price_type' => 'fixed' + ] + ] + ] + ] + ], + 'date_time' => [ + '$rowData' => [ + 'custom_options' => 'name=Test Field Title,type=date_time,required=0,' + . 'sku=1-text,price=30,price_type=fixed' + ], + '$responseData' => [ + 'custom_options' => [ + 'Test Field Title' => [ + [ + 'name' => 'Test Field Title', + 'type' => 'date_time', + 'required' => '0', + 'sku' => '1-text', + 'price' => '30', + 'price_type' => 'fixed' + ] + ] + ] + ] + ] + ]; + } + /** * Data provider of row data and errors. * diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Full.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Full.php index d8bf4f858047..b9da6b56e627 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Full.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Full.php @@ -1,7 +1,5 @@ <?php /** - * @category Magento - * @package Magento_CatalogInventory * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -11,25 +9,24 @@ namespace Magento\CatalogInventory\Model\Indexer\Stock\Action; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product\Type as ProductType; use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher; -use Magento\CatalogInventory\Model\Indexer\Stock\BatchSizeManagement; +use Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction; +use Magento\CatalogInventory\Model\Indexer\Stock\Processor; use Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\DefaultStock; -use Magento\Framework\App\ResourceConnection; +use Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\StockInterface; use Magento\CatalogInventory\Model\ResourceModel\Indexer\StockFactory; -use Magento\Catalog\Model\Product\Type as ProductType; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Query\BatchIteratorInterface; use Magento\Framework\DB\Query\Generator as QueryGenerator; -use Magento\Framework\Indexer\CacheContext; -use Magento\Framework\Event\ManagerInterface as EventManager; use Magento\Framework\EntityManager\MetadataPool; -use Magento\Framework\Indexer\BatchSizeManagementInterface; -use Magento\Framework\Indexer\BatchProviderInterface; -use Magento\Framework\App\ObjectManager; +use Magento\Framework\Event\ManagerInterface as EventManager; use Magento\Framework\Exception\LocalizedException; -use Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction; -use Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\StockInterface; -use Magento\Framework\App\DeploymentConfig; -use Magento\CatalogInventory\Model\Indexer\Stock\Processor; +use Magento\Framework\Indexer\BatchProviderInterface; +use Magento\Framework\Indexer\BatchSizeManagementInterface; +use Magento\Framework\Indexer\CacheContext; /** * Class Full reindex action @@ -41,7 +38,7 @@ class Full extends AbstractAction /** * Action type representation */ - const ACTION_TYPE = 'full'; + public const ACTION_TYPE = 'full'; /** * @var MetadataPool @@ -125,7 +122,7 @@ public function __construct( $this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class); $this->batchProvider = $batchProvider ?: ObjectManager::getInstance()->get(BatchProviderInterface::class); $this->batchSizeManagement = $batchSizeManagement ?: ObjectManager::getInstance()->get( - BatchSizeManagement::class + BatchSizeManagementInterface::class ); $this->batchRowsCount = $batchRowsCount; $this->activeTableSwitcher = $activeTableSwitcher ?: ObjectManager::getInstance() @@ -151,6 +148,7 @@ public function execute($ids = null): void $entityMetadata = $this->metadataPool->getMetadata(ProductInterface::class); $columns = array_keys($this->_getConnection()->describeTable($this->_getIdxTable())); + $indexerTables = []; /** @var DefaultStock $indexer */ foreach ($this->_getTypeIndexers() as $indexer) { @@ -165,7 +163,7 @@ public function execute($ids = null): void ) ); - if (is_null($batchRowCount)) { + if ($batchRowCount === null) { $batchRowCount = isset($this->batchRowsCount[$indexer->getTypeId()]) ? $this->batchRowsCount[$indexer->getTypeId()] : $this->batchRowsCount['default']; @@ -202,8 +200,12 @@ public function execute($ids = null): void $connection->query($query); } } + + $indexerTables[] = $indexer->getMainTable(); } - $this->activeTableSwitcher->switchTable($indexer->getConnection(), [$indexer->getMainTable()]); + + $indexerTables = array_unique($indexerTables); + $this->activeTableSwitcher->switchTable($this->_getConnection(), $indexerTables); } catch (\Exception $e) { throw new LocalizedException(__($e->getMessage()), $e); } diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Rule.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Rule.php index a4bc13559c7c..45a9d27076ff 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Rule.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Rule.php @@ -129,9 +129,10 @@ public function __construct( $this->priceCurrency = $priceCurrency; $this->entityManager = $entityManager ?? ObjectManager::getInstance()->get(EntityManager::class); $this->_associatedEntitiesMap = $associatedEntityMap ?? ObjectManager::getInstance() - // phpstan:ignore this is a virtual class + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml ->get(\Magento\CatalogRule\Model\ResourceModel\Rule\AssociatedEntityMap::class) ->getData(); + parent::__construct($context, $connectionName); } @@ -216,12 +217,8 @@ public function getRulesFromProduct($date, $websiteId, $customerGroupId, $produc } /** - * Load an object + * @inheritDoc * - * @param \Magento\Framework\Model\AbstractModel $object - * @param mixed $value - * @param string $field - * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function load(\Magento\Framework\Model\AbstractModel $object, $value, $field = null) diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Rule/Collection.php index 6042f24e0b43..e4164b2319b3 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Rule/Collection.php @@ -159,12 +159,13 @@ public function addCustomerGroupFilter($customerGroupId) * * @return array * @deprecated 100.1.0 + * @see https://github.com/magento/magento2/commit/d063251cf0ce6717795fdb646a534cc0c2b22c05 */ private function getAssociatedEntitiesMap() { if (!$this->_associatedEntitiesMap) { $this->_associatedEntitiesMap = \Magento\Framework\App\ObjectManager::getInstance() - // phpstan:ignore + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml ->get(\Magento\CatalogRule\Model\ResourceModel\Rule\AssociatedEntityMap::class) ->getData(); } diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv index 7e87fe3f7e00..42a080b6a787 100644 --- a/app/code/Magento/Checkout/i18n/en_US.csv +++ b/app/code/Magento/Checkout/i18n/en_US.csv @@ -192,3 +192,4 @@ Are you sure you want to leave the page?,Are you sure you want to leave the page Changes you made to the cart will not be saved.,Changes you made to the cart will not be saved. Leave,Leave Cancel,Cancel +VAT,VAT diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index 9cdd84f5915c..9005e4816b43 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -17,7 +17,7 @@ <text args="getCountryName(currentBillingAddress().countryId)"></text><br> <a if="currentBillingAddress().telephone" attr="'href': 'tel:' + currentBillingAddress().telephone" text="currentBillingAddress().telephone"></a><br> <if args="currentBillingAddress().vatId"> - VAT: <text args="currentBillingAddress().vatId"></text><br> + <translate args="'VAT'"></translate>: <text args="currentBillingAddress().vatId"></text><br> </if> <each args="data: currentBillingAddress().customAttributes, as: 'element'"> <text args="$parent.getCustomAttributeLabel(element)"></text> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index 80a2e63cdb25..c5cc997d8cc8 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -15,7 +15,7 @@ <text args="getCountryName(address().countryId)"></text><br> <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br> <if args="address().vatId"> - VAT: <text args="address().vatId"></text><br> + <translate args="'VAT'"></translate>: <text args="address().vatId"></text><br> </if> <each args="data: address().customAttributes, as: 'element'"> <text args="$parent.getCustomAttributeLabel(element)"></text> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index 1c4ab02b9b03..292edbc13708 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -15,7 +15,7 @@ <text args="getCountryName(address().countryId)"></text><br> <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br> <if args="address().vatId"> - VAT: <text args="address().vatId"></text><br> + <translate args="'VAT'"></translate>: <text args="address().vatId"></text><br> </if> <each args="data: address().customAttributes, as: 'element'"> <text args="$parent.getCustomAttributeLabel(element)"></text> diff --git a/app/code/Magento/Cms/Model/PageRepository.php b/app/code/Magento/Cms/Model/PageRepository.php index 7e84b93f5a1e..79e68560654f 100644 --- a/app/code/Magento/Cms/Model/PageRepository.php +++ b/app/code/Magento/Cms/Model/PageRepository.php @@ -285,13 +285,13 @@ public function deleteById($pageId) * * @deprecated 102.0.0 * @return CollectionProcessorInterface + * @see https://github.com/magento/magento2/commit/eacac63d35b97961e3304dc007cd6b78519a93d0 */ private function getCollectionProcessor() { if (!$this->collectionProcessor) { - // phpstan:ignore "Class Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessor not found." - $this->collectionProcessor = ObjectManager::getInstance() - ->get(PageCollectionProcessor::class); + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml + $this->collectionProcessor = ObjectManager::getInstance()->get(PageCollectionProcessor::class); } return $this->collectionProcessor; } diff --git a/app/code/Magento/Config/Test/Mftf/Section/CatalogSection/CatalogSection.xml b/app/code/Magento/Config/Test/Mftf/Section/CatalogSection/CatalogSection.xml index f5172e080bbe..9a96eb5d2560 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/CatalogSection/CatalogSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/CatalogSection/CatalogSection.xml @@ -27,5 +27,7 @@ <element name="productsPerPageOnGridAllowedValues" type="input" selector="//input[@id='catalog_frontend_grid_per_page_values']"/> <element name="productsPerPageOnGridDefaultValue" type="input" selector="//input[@id='catalog_frontend_grid_per_page']"/> <element name="productsPerPageOnGridDefaultValueUseConfigCheckbox" type="checkbox" selector="//input[@id='catalog_frontend_grid_per_page_inherit']"/> + <element name="dateAndTimeCustomOptions" type="select" selector="#catalog_custom_options-head"/> + <element name="CheckIfTabExpandForDateAndTimeCustomOptions" type="button" selector="#catalog_custom_options-head:not(.open)"/> </section> </sections> diff --git a/app/code/Magento/Customer/i18n/en_US.csv b/app/code/Magento/Customer/i18n/en_US.csv index 181a64d62634..3ee3aeba550b 100644 --- a/app/code/Magento/Customer/i18n/en_US.csv +++ b/app/code/Magento/Customer/i18n/en_US.csv @@ -546,3 +546,6 @@ Addresses,Addresses "Partial Match","Partial Match" "Full Match","Full Match" "Prefix Match","Prefix Match" +T,T +F,F +VAT,VAT diff --git a/app/code/Magento/Customer/view/adminhtml/web/template/default-address.html b/app/code/Magento/Customer/view/adminhtml/web/template/default-address.html index f600e2867ce8..c405392cbe62 100644 --- a/app/code/Magento/Customer/view/adminhtml/web/template/default-address.html +++ b/app/code/Magento/Customer/view/adminhtml/web/template/default-address.html @@ -38,13 +38,13 @@ </if> <text args="address.country"></text> <if args="address.telephone"> - <br>T: <a attr="href: 'tel:' + address.telephone" text="address.telephone"></a> + <br><translate args="'T'"></translate>: <a attr="href: 'tel:' + address.telephone" text="address.telephone"></a> </if> <if args="address.fax"> - <br>F: <text args="address.fax"></text> + <br><translate args="'F'"></translate>: <text args="address.fax"></text> </if> <if args="address.vat_id"> - <br>VAT: <text args="address.vat_id"></text> + <br><translate args="'VAT'"></translate>: <text args="address.vat_id"></text> </if> </div> <translate args="notExistsMessage" if="_.isEmpty($data.address)"></translate> diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/GetCustomSelectedOptionAttributes.php b/app/code/Magento/CustomerGraphQl/Model/Customer/GetCustomSelectedOptionAttributes.php index 0ffe8b7b5d58..7d8131e9cfff 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/GetCustomSelectedOptionAttributes.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/GetCustomSelectedOptionAttributes.php @@ -55,7 +55,7 @@ public function execute(string $entityType, array $customAttribute): ?array continue; } $result[] = [ - 'uid' => $this->uid->encode($option->getValue()), + 'uid' => $this->uid->encode((string) $option->getValue()), 'value' => $option->getValue(), 'label' => $option->getLabel() ]; diff --git a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml index de3f2b97d5c3..47c284710814 100644 --- a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml +++ b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml @@ -7,8 +7,6 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <head> - <remove src="extjs/resources/css/ext-all.css"/> - <remove src="extjs/resources/css/ytheme-magento.css"/> <remove src="css/styles-old.css"/> <remove src="css/styles.css"/> <remove src="jquery/jstree/themes/default/style.css"/> diff --git a/app/code/Magento/Paypal/Observer/AddPaypalShortcutsObserver.php b/app/code/Magento/Paypal/Observer/AddPaypalShortcutsObserver.php index 861ca7406068..46e275da9f03 100644 --- a/app/code/Magento/Paypal/Observer/AddPaypalShortcutsObserver.php +++ b/app/code/Magento/Paypal/Observer/AddPaypalShortcutsObserver.php @@ -57,9 +57,13 @@ public function execute(EventObserver $observer) SmartButton::class => PaypalConfig::METHOD_WPS_EXPRESS, \Magento\Paypal\Block\Express\Shortcut::class => PaypalConfig::METHOD_WPP_EXPRESS, \Magento\Paypal\Block\Bml\Shortcut::class => PaypalConfig::METHOD_WPP_EXPRESS, + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml \Magento\Paypal\Block\WpsExpress\Shortcut::class => PaypalConfig::METHOD_WPS_EXPRESS, + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml \Magento\Paypal\Block\WpsBml\Shortcut::class => PaypalConfig::METHOD_WPS_EXPRESS, + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml \Magento\Paypal\Block\PayflowExpress\Shortcut::class => PaypalConfig::METHOD_WPP_PE_EXPRESS, + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml \Magento\Paypal\Block\Payflow\Bml\Shortcut::class => PaypalConfig::METHOD_WPP_PE_EXPRESS ]; foreach ($blocks as $blockInstanceName => $paymentMethodCode) { diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/PrintAction.php index c5902aac3335..86e27260ea8c 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/PrintAction.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/PrintAction.php @@ -5,18 +5,19 @@ */ namespace Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\App\ResponseInterface; use Magento\Sales\Api\CreditmemoRepositoryInterface; -class PrintAction extends \Magento\Backend\App\Action +class PrintAction extends \Magento\Backend\App\Action implements HttpGetActionInterface { /** * Authorization level of a basic admin session * * @see _isAllowed() */ - const ADMIN_RESOURCE = 'Magento_Sales::sales_creditmemo'; + public const ADMIN_RESOURCE = 'Magento_Sales::sales_creditmemo'; /** * @var \Magento\Framework\App\Response\Http\FileFactory @@ -52,6 +53,8 @@ public function __construct( } /** + * Execute action based on request and return result + * * @return ResponseInterface|\Magento\Backend\Model\View\Result\Forward * @throws \Exception */ @@ -73,7 +76,7 @@ public function execute() $fileContent = ['type' => 'string', 'value' => $pdf->render(), 'rm' => true]; return $this->_fileFactory->create( - \creditmemo::class . $date . '.pdf', + 'creditmemo' . $date . '.pdf', $fileContent, DirectoryList::VAR_DIR, 'application/pdf' diff --git a/app/code/Magento/Sales/Test/Unit/Helper/ReorderTest.php b/app/code/Magento/Sales/Test/Unit/Helper/ReorderTest.php index a24aeccff0b8..01dd2984a2e4 100644 --- a/app/code/Magento/Sales/Test/Unit/Helper/ReorderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Helper/ReorderTest.php @@ -31,7 +31,7 @@ class ReorderTest extends TestCase protected $scopeConfigMock; /** - * @var MockObject|\Magento\Sales\Model\Store + * @var MockObject|\Magento\Store\Model\Store */ protected $storeParam; @@ -78,7 +78,7 @@ protected function setUp(): void $this->repositoryMock ); - $this->storeParam = $this->getMockBuilder(\Magento\Sales\Model\Store::class) + $this->storeParam = $this->getMockBuilder(\Magento\Store\Model\Store::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php index 4ed17d7ef815..cc543f18f023 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php @@ -84,7 +84,7 @@ public function __construct( $this->string = $string; $this->_resourceCoupon = $resourceCoupon; $associatedEntitiesMapInstance = $associatedEntityMapInstance ?: ObjectManager::getInstance()->get( - // phpstan:ignore "Class Magento\SalesRule\Model\ResourceModel\Rule\AssociatedEntityMap not found." + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml \Magento\SalesRule\Model\ResourceModel\Rule\AssociatedEntityMap::class ); $this->_associatedEntitiesMap = $associatedEntitiesMapInstance->getData(); diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 7e37e0ac4bea..d24767eddfb1 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -463,7 +463,7 @@ private function getAssociatedEntitiesMap() { if (!$this->_associatedEntitiesMap) { $this->_associatedEntitiesMap = \Magento\Framework\App\ObjectManager::getInstance() - // phpstan:ignore "Class Magento\SalesRule\Model\ResourceModel\Rule\AssociatedEntityMap not found." + // @phpstan-ignore-next-line - this is a virtual type defined in di.xml ->get(\Magento\SalesRule\Model\ResourceModel\Rule\AssociatedEntityMap::class) ->getData(); } diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml index 1f5ce694939f..ca192351e4ce 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking.phtml @@ -8,6 +8,7 @@ /** * @var $block Magento\Shipping\Block\Adminhtml\Order\Tracking * @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer + * @var $escaper \Magento\Framework\Escaper */ ?> <?php $scriptString = <<<script @@ -29,7 +30,7 @@ require(['prototype'], function(){ $('trackingC' + this.index).disabled = false; $('trackingT' + this.index).disabled = false; $('trackingN' + this.index).disabled = false; - this.bindCurrierOnchange(); + this.bindCarrierOnchange(); }, deleteRow : function(event) { var row = Event.findElement(event, 'tr'); @@ -37,17 +38,17 @@ require(['prototype'], function(){ row.parentNode.removeChild(row) } }, - bindCurrierOnchange : function() { + bindCarrierOnchange : function() { var elems = $('tracking_numbers_table').select('.select'); elems.each(function (elem) { if (!elem.onchangeBound) { elem.onchangeBound = true; elem.valueInput = $(elem.parentNode.parentNode).select('.number-title')[0]; - elem.observe('change', this.currierOnchange); + elem.observe('change', this.carrierOnchange); } }.bind(this)); }, - currierOnchange : function(event) { + carrierOnchange : function(event) { var elem = Event.element(event); var option = elem.options[elem.selectedIndex]; if (option.value && option.value != 'custom') { @@ -76,7 +77,7 @@ script; class="select admin__control-select carrier" disabled="disabled"> <?php foreach ($block->getCarriers() as $_code => $_name): ?> - <option value="<?= $block->escapeHtmlAttr($_code) ?>"><?= $block->escapeHtml($_name) ?></option> + <option value="<?= $escaper->escapeHtmlAttr($_code) ?>"><?= $escaper->escapeHtml($_name) ?></option> <?php endforeach; ?> </select> </td> @@ -101,7 +102,7 @@ script; type="button" class="action-default action-delete" onclick="trackingControl.deleteRow(event);return false"> - <span><?= $block->escapeHtml(__('Delete')) ?></span> + <span><?= $escaper->escapeHtml(__('Delete')) ?></span> </button> </td> </tr> @@ -111,10 +112,10 @@ script; <table class="data-table admin__control-table" id="tracking_numbers_table"> <thead> <tr class="headings"> - <th class="col-carrier"><?= $block->escapeHtml(__('Carrier')) ?></th> - <th class="col-title"><?= $block->escapeHtml(__('Title')) ?></th> - <th class="col-number"><?= $block->escapeHtml(__('Number')) ?></th> - <th class="col-delete"><?= $block->escapeHtml(__('Action')) ?></th> + <th class="col-carrier"><?= $escaper->escapeHtml(__('Carrier')) ?></th> + <th class="col-title"><?= $escaper->escapeHtml(__('Title')) ?></th> + <th class="col-number"><?= $escaper->escapeHtml(__('Number')) ?></th> + <th class="col-delete"><?= $escaper->escapeHtml(__('Action')) ?></th> </tr> </thead> <tfoot> diff --git a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js index 948bd2a57c30..504bd86bfb04 100644 --- a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js +++ b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js @@ -5,13 +5,6 @@ var config = { 'shim': { - 'extjs/ext-tree': [ - 'prototype' - ], - 'extjs/ext-tree-checkbox': [ - 'extjs/ext-tree', - 'extjs/defaults' - ], 'jquery/editableMultiselect/js/jquery.editable': [ 'jquery' ] diff --git a/app/code/Magento/Ui/etc/di.xml b/app/code/Magento/Ui/etc/di.xml index b0cef3b90d43..65253ab8279d 100644 --- a/app/code/Magento/Ui/etc/di.xml +++ b/app/code/Magento/Ui/etc/di.xml @@ -361,6 +361,11 @@ <argument name="componentManager" xsi:type="object">Magento\Ui\Model\Manager\Proxy</argument> </arguments> </type> + <type name="Magento\Ui\Config\Reader\Definition\Data"> + <arguments> + <argument name="cache" xsi:type="object">Magento\Framework\App\Interception\Cache\CompiledConfig</argument> + </arguments> + </type> <type name="Magento\Ui\Config\Argument\Parser\ArrayType"> <arguments> <argument name="itemParser" xsi:type="object">Magento\Ui\Config\Argument\Parser\Composite\Proxy</argument> diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml deleted file mode 100644 index df8780343376..000000000000 --- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ /dev/null @@ -1,208 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -/** @var \Magento\Catalog\Block\Adminhtml\Category\Widget\Chooser $block */ -/** @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer */ -?> - -<?php $_divId = 'tree' . $block->getId() ?> -<div id="<?= $block->escapeHtmlAttr($_divId) ?>" class="tree"></div> -<?php -$useMassaction = /* @noEscape */ $block->getUseMassaction() ? 1 : 0; -$isAnchorOnly = /* @noEscape */ $block->getIsAnchorOnly() ? 1 : 0; -$nodeClickListener = /* @noEscape */ $block->getNodeClickListener(); -$withEmpltyNode = /* @noEscape */ ($block->getWithEmptyNode() ? 'false' : 'true'); -$isVisible = (bool) $block->getRoot()->getIsVisible(); -$categoryId = (int) $block->getCategoryId(); -$rootId = (int) $block->getRoot()->getId(); -$isWasExpanded = (int) $block->getIsWasExpanded(); -$treeJson = /* @noEscape */ $block->getTreeJson(); -$scriptString = <<<script - -require(['jquery', "prototype", "extjs/ext-tree-checkbox"], function(jQuery){ - -var tree{$block->escapeJs($block->getId())}; - -var useMassaction = {$useMassaction}; - -var isAnchorOnly = {$isAnchorOnly}; - -Ext.tree.TreePanel.Enhanced = function(el, config) -{ - Ext.tree.TreePanel.Enhanced.superclass.constructor.call(this, el, config); -}; - -Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, { - - loadTree : function(config, firstLoad) - { - var parameters = config['parameters']; - var data = config['data']; - - if ((typeof parameters['root_visible']) != 'undefined') { - this.rootVisible = parameters['root_visible']*1; - } - - var root = new Ext.tree.TreeNode(parameters); - - this.nodeHash = {}; - this.setRootNode(root); - - if (firstLoad) { - -script; -if ($block->getNodeClickListener()): - $scriptString .= <<<script - - this.addListener('click', {$nodeClickListener}.createDelegate(this)); - -script; -endif; -$scriptString .= <<<script - - } - - this.loader.buildCategoryTree(root, data); - this.el.dom.innerHTML = ''; - // render the tree - this.render(); - } -}); - -jQuery(function() -{ - var emptyNodeAdded = {$withEmpltyNode}; - - var categoryLoader = new Ext.tree.TreeLoader({ - dataUrl: '{$block->escapeJs($block->getLoadTreeUrl())}' - }); - - categoryLoader.buildCategoryTree = function(parent, config) - { - if (!config) return null; - - - if (parent && config && config.length){ - for (var i = 0; i < config.length; i++) { - var node; - if (useMassaction && config[i].level != 1) { - config[i].uiProvider = Ext.tree.CheckboxNodeUI; - } - var _node = Object.clone(config[i]); - - // Add empty node to reset category filter - if(!emptyNodeAdded) { - var empty = Object.clone(_node); - empty.text = '{$block->escapeJs($block->escapeHtml(__('None')))}'; - empty.children = []; - empty.id = 'none'; - empty.path = '1/none'; - empty.cls = 'leaf'; - parent.appendChild(new Ext.tree.TreeNode(empty)); - emptyNodeAdded = true; - } - - if (_node.children && !_node.children.length) { - delete(_node.children); - node = new Ext.tree.AsyncTreeNode(_node); - } else { - node = new Ext.tree.TreeNode(config[i]); - } - parent.appendChild(node); - node.loader = node.getOwnerTree().loader; - node.loader = node.getOwnerTree().loader; - if (_node.children) { - this.buildCategoryTree(node, _node.children); - } - } - } - }; - - categoryLoader.createNode = function(config) { - var node; - if (useMassaction && config.level != 1) { - config.uiProvider = Ext.tree.CheckboxNodeUI; - } - var _node = Object.clone(config); - if (config.children && !config.children.length) { - delete(config.children); - node = new Ext.tree.AsyncTreeNode(config); - } else { - node = new Ext.tree.TreeNode(config); - } - return node; - }; - - categoryLoader.buildHash = function(node) - { - var hash = {}; - - hash = this.toArray(node.attributes); - - if (node.childNodes.length>0 || (node.loaded==false && node.loading==false)) { - hash['children'] = new Array; - - for (var i = 0, len = node.childNodes.length; i < len; i++) { - if (!hash['children']) { - hash['children'] = new Array; - } - hash['children'].push(this.buildHash(node.childNodes[i])); - } - } - - return hash; - }; - - categoryLoader.toArray = function(attributes) { - var data = {}; - for (var key in attributes) { - var value = attributes[key]; - data[key] = value; - } - - return data; - }; - - categoryLoader.on("beforeload", function(treeLoader, node) { - $('{$block->escapeJs($_divId)}').fire('category:beforeLoad', {treeLoader:treeLoader}); - treeLoader.baseParams.id = node.attributes.id; - }); - - tree{$block->escapeJs($block->getId())} = new Ext.tree.TreePanel.Enhanced('{$block->escapeJs($_divId)}', { - animate: false, - loader: categoryLoader, - enableDD: false, - containerScroll: true, - rootVisible: '{$isVisible}', - useAjax: true, - currentNodeId: {$categoryId}, - addNodeTo: false - }); - - if (useMassaction) { - tree{$block->escapeJs($block->getId())}.on('check', function(node) { - $('{$block->escapeJs($_divId)}').fire('node:changed', {node:node}); - }, tree{$block->escapeJs($block->getId())}); - } - - // set the root node - var parameters = { - text: 'Psw', - draggable: false, - id: {$rootId}, - expanded: {$isWasExpanded}, - category_id: {$categoryId} - }; - - tree{$block->escapeJs($block->getId())}.loadTree({parameters:parameters, data:{$treeJson}},true); - -}); - -}); - -script; -?> -<?= /* @noEscape */ $secureRenderer->renderTag('script', [], $scriptString, false) ?> diff --git a/app/etc/di.xml b/app/etc/di.xml index e707d97dc684..1e047d6041df 100644 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -418,6 +418,11 @@ </arguments> </type> <type name="Magento\Framework\Acl" shared="false" /> + <type name="Magento\Framework\App\Router\ActionList"> + <arguments> + <argument name="cache" xsi:type="object">Magento\Framework\App\Interception\Cache\CompiledConfig</argument> + </arguments> + </type> <type name="Magento\Framework\App\ObjectManager\ConfigLoader"> <arguments> <argument name="cache" xsi:type="object">Magento\Framework\App\Cache\Type\Config</argument> @@ -449,7 +454,7 @@ </type> <type name="Magento\Framework\Interception\PluginList\PluginList"> <arguments> - <argument name="cache" xsi:type="object">Magento\Framework\App\Cache\Type\Config</argument> + <argument name="cache" xsi:type="object">Magento\Framework\App\Interception\Cache\CompiledConfig\Proxy</argument> <argument name="reader" xsi:type="object">Magento\Framework\ObjectManager\Config\Reader\Dom\Proxy</argument> <argument name="cacheId" xsi:type="string">plugin-list</argument> <argument name="scopePriorityScheme" xsi:type="array"> @@ -878,6 +883,7 @@ </type> <type name="Magento\Framework\Event\Config\Data"> <arguments> + <argument name="cache" xsi:type="object">Magento\Framework\App\Interception\Cache\CompiledConfig</argument> <argument name="reader" xsi:type="object">Magento\Framework\Event\Config\Reader\Proxy</argument> </arguments> </type> diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt index 817397fbf03f..5269aae7041a 100644 --- a/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt +++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt @@ -2,7 +2,6 @@ app/code/**/*.js app/design/**/*.js dev/tests/js/jasmine/tests/**/*.js lib/web/css/docs/source/js/dropdown.js -lib/web/extjs/defaults.js lib/web/less/config.less.js lib/web/mage/**/*.js lib/web/magnifier/**/*.js diff --git a/dev/tools/grunt/configs/less.js b/dev/tools/grunt/configs/less.js index 9ae376b9e21b..b1b87b6adc55 100644 --- a/dev/tools/grunt/configs/less.js +++ b/dev/tools/grunt/configs/less.js @@ -3,50 +3,49 @@ * See COPYING.txt for license details. */ -'use strict'; +(function () { + 'use strict'; + var combo = require('./combo'), + themes = require('../tools/files-router').get('themes'), + _ = require('underscore'), + themeOptions = {}, + lessOptions = { + options: { + sourceMap: true, + strictImports: false, + sourceMapRootpath: '/', + sourceMapBasepath: function () { + this.sourceMapURL = this.sourceMapFilename.substr(this.sourceMapFilename.lastIndexOf('/') + 1); + return 'pub/'; + }, + dumpLineNumbers: false, // use 'comments' instead false to output line comments for source + ieCompat: false + }, + setup: { + files: { + '<%= path.css.setup %>/setup.css': '<%= path.less.setup %>/_setup.less' + } + }, + updater: { + files: { + '<%= path.css.updater %>/updater.css': '<%= path.less.setup %>/_setup.less' + } + }, + documentation: { + files: { + '<%= path.doc %>/docs.css': '<%= path.doc %>/source/docs.less' + } + } + }; -var combo = require('./combo'), - themes = require('../tools/files-router').get('themes'), - _ = require('underscore'); + _.each(themes, function (theme, name) { + themeOptions[name] = { + files: combo.lessFiles(name) + }; + }); -var themeOptions = {}; - -_.each(themes, function(theme, name) { - themeOptions[name] = { - files: combo.lessFiles(name) - }; -}); - -var lessOptions = { - options: { - sourceMap: true, - strictImports: false, - sourceMapRootpath: '/', - sourceMapBasepath: function (f) { - this.sourceMapURL = this.sourceMapFilename.substr(this.sourceMapFilename.lastIndexOf('/') + 1); - return "/"; - }, - dumpLineNumbers: false, // use 'comments' instead false to output line comments for source - ieCompat: false - }, - setup: { - files: { - '<%= path.css.setup %>/setup.css': '<%= path.less.setup %>/_setup.less' - } - }, - updater: { - files: { - '<%= path.css.updater %>/updater.css': '<%= path.less.setup %>/_setup.less' - } - }, - documentation: { - files: { - '<%= path.doc %>/docs.css': '<%= path.doc %>/source/docs.less' - } - } -}; - -/** - * Compiles Less to CSS and generates necessary files if requested. - */ -module.exports = _.extend(themeOptions, lessOptions); + /** + * Compiles Less to CSS and generates necessary files if requested. + */ + module.exports = _.extend(themeOptions, lessOptions); +})(); diff --git a/lib/internal/Magento/Framework/Acl/etc/acl.xsd b/lib/internal/Magento/Framework/Acl/etc/acl.xsd index 147b94cb68cb..8273281a8ac2 100644 --- a/lib/internal/Magento/Framework/Acl/etc/acl.xsd +++ b/lib/internal/Magento/Framework/Acl/etc/acl.xsd @@ -57,7 +57,7 @@ <xs:simpleType name="typeId"> <xs:annotation> <xs:documentation> - Item id attribute can has only [a-z0-9/_]. Minimal length 3 symbol. Case insensitive. + Item id attribute can have only [a-z0-9/_]. Minimal length 3 characters. Case insensitive. </xs:documentation> </xs:annotation> diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php index 58a690a230b5..75e552281ba3 100644 --- a/lib/internal/Magento/Framework/App/Area.php +++ b/lib/internal/Magento/Framework/App/Area.php @@ -241,7 +241,7 @@ protected function _initConfig() */ protected function _initTranslate() { - $this->_translator->loadData(null, false); + $this->_translator->loadData($this->_code, false); \Magento\Framework\Phrase::setRenderer( $this->_objectManager->get(\Magento\Framework\Phrase\RendererInterface::class) diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php index 065493818050..9c6a0e1ed52e 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php +++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php @@ -439,6 +439,12 @@ private function avoidReusingParentProcessConnection() $this->parentConnections[] = $this->_connection; $this->_connection = null; $this->pid = getmypid(); + + // Reset config host to avoid issue with multiple connections + if (!empty($this->_config['port']) && strpos($this->_config['host'], ':') === false) { + $this->_config['host'] = implode(':', [$this->_config['host'], $this->_config['port']]); + unset($this->_config['port']); + } } } diff --git a/lib/internal/Magento/Framework/MessageQueue/Consumer/Config/Validator/ConsumerInstance.php b/lib/internal/Magento/Framework/MessageQueue/Consumer/Config/Validator/ConsumerInstance.php index 5d38fddc8f60..3c69d69969a0 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Consumer/Config/Validator/ConsumerInstance.php +++ b/lib/internal/Magento/Framework/MessageQueue/Consumer/Config/Validator/ConsumerInstance.php @@ -15,7 +15,7 @@ class ConsumerInstance implements ValidatorInterface { /** - * {@inheritdoc} + * @inheritdoc */ public function validate($configData) { @@ -43,7 +43,6 @@ private function validateConsumerInstance($consumerConfig) "'%s' does not exist and thus cannot be used as 'consumerInstance' for '%s' consumer.", $consumerInstance, $consumerConfig['name'], - ConsumerInterface::class ) ); }