diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php index 24d81f0054c5a1bde1f90ab1212bd629e36c81ec..8f0e6e9c0cdb5c60d1a065f4176a2aed829071d8 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php @@ -369,25 +369,55 @@ class AbstractAction } $values = []; - foreach ($entityIds as $entityId) { - $values[$entityId] = []; + $linkIds = $this->getLinkIds($entityIds); + foreach ($linkIds as $linkId) { + $values[$linkId] = []; } + $attributes = $this->getAttributes(); $attributesType = ['varchar', 'int', 'decimal', 'text', 'datetime']; + $linkField = $this->getCategoryMetadata()->getLinkField(); foreach ($attributesType as $type) { foreach ($this->getAttributeTypeValues($type, $entityIds, $storeId) as $row) { - if (isset($row[$this->getCategoryMetadata()->getLinkField()]) && isset($row['attribute_id'])) { + if (isset($row[$linkField]) && isset($row['attribute_id'])) { $attributeId = $row['attribute_id']; if (isset($attributes[$attributeId])) { $attributeCode = $attributes[$attributeId]['attribute_code']; - $values[$row[$this->getCategoryMetadata()->getLinkField()]][$attributeCode] = $row['value']; + $values[$row[$linkField]][$attributeCode] = $row['value']; } } } } + return $values; } + /** + * Translate entity ids into link ids + * + * Used for rows with no EAV attributes set. + * + * @param array $entityIds + * @return array + */ + private function getLinkIds(array $entityIds) + { + $linkField = $this->getCategoryMetadata()->getLinkField(); + if ($linkField === 'entity_id') { + return $entityIds; + } + + $select = $this->connection->select()->from( + ['e' => $this->connection->getTableName($this->getTableName('catalog_category_entity'))], + [$linkField] + )->where( + 'e.entity_id IN (?)', + $entityIds + ); + + return $this->connection->fetchCol($select); + } + /** * Return attribute values for given entities and store of specific attribute type * diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index eeac2e80af97e355233457518db92cf9ea86d31d..64a8f930d83ee4ab2298bb69fd0f597ad0f53755 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -64,18 +64,22 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction } /** @TODO Do something with chunks */ $categoriesIdsChunks = array_chunk($categoriesIds[$store->getRootCategoryId()], 500); + foreach ($categoriesIdsChunks as $categoriesIdsChunk) { $attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId()); + $linkField = $this->categoryMetadata->getLinkField(); + $data = []; foreach ($categories[$store->getRootCategoryId()] as $category) { - if (!isset($attributesData[$category[$this->categoryMetadata->getLinkField()]])) { + if (!isset($attributesData[$category[$linkField]])) { continue; } $category['store_id'] = $store->getId(); $data[] = $this->prepareValuesToInsert( - array_merge($category, $attributesData[$category[$this->categoryMetadata->getLinkField()]]) + array_merge($category, $attributesData[$category[$linkField]]) ); } + $this->connection->insertMultiple( $this->addTemporaryTableSuffix($this->getMainStoreTable($store->getId())), $data diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php index 2368c27e02d72b1e64fcc5c23a29b01e0f10436e..bc17d731f04c0a00cf1c0e62300bbba33230de68 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php @@ -69,22 +69,24 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction $categoriesIdsChunk = $this->filterIdsByStore($categoriesIdsChunk, $store); $attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId()); + $linkField = $this->categoryMetadata->getLinkField(); $data = []; foreach ($categoriesIdsChunk as $categoryId) { - if (!isset($attributesData[$categoryId])) { - continue; - } - try { $category = $this->categoryRepository->get($categoryId); } catch (NoSuchEntityException $e) { continue; } + $categoryData = $category->getData(); + if (!isset($attributesData[$categoryData[$linkField]])) { + continue; + } + $data[] = $this->prepareValuesToInsert( array_merge( - $category->getData(), - $attributesData[$categoryId], + $categoryData, + $attributesData[$categoryData[$linkField]], ['store_id' => $store->getId()] ) ); diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php index 0e86510ebcee7f82f96fc250e07940e664ca5971..d4c78772e7c0be357ac95845dc8f3f1f56d1a72f 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php @@ -190,6 +190,7 @@ class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCu public function saveValues() { foreach ($this->getValues() as $value) { + $this->isDeleted(false); $this->setData( $value )->setData( diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index f1384ba188a0a113abb269e0621082a531ff3293..8664e0cbf87ea3abdcf36a16340ead10fd432c74 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -13,6 +13,8 @@ use Magento\Framework\App\ObjectManager; use Magento\Customer\Model\Account\Redirect as AccountRedirect; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Stdlib\CookieManagerInterface; +use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory; /** * Login controller @@ -58,6 +60,16 @@ class Login extends \Magento\Framework\App\Action\Action */ protected $scopeConfig; + /** + * @var CookieManagerInterface + */ + private $cookieManager; + + /** + * @var CookieMetadataFactory + */ + private $cookieMetadataFactory; + /** * Initialize Login controller * @@ -67,6 +79,8 @@ class Login extends \Magento\Framework\App\Action\Action * @param AccountManagementInterface $customerAccountManagement * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory + * @param CookieManagerInterface $cookieManager + * @param CookieMetadataFactory $cookieMetadataFactory */ public function __construct( \Magento\Framework\App\Action\Context $context, @@ -74,7 +88,9 @@ class Login extends \Magento\Framework\App\Action\Action \Magento\Framework\Json\Helper\Data $helper, AccountManagementInterface $customerAccountManagement, \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, - \Magento\Framework\Controller\Result\RawFactory $resultRawFactory + \Magento\Framework\Controller\Result\RawFactory $resultRawFactory, + CookieManagerInterface $cookieManager = null, + CookieMetadataFactory $cookieMetadataFactory = null ) { parent::__construct($context); $this->customerSession = $customerSession; @@ -82,6 +98,12 @@ class Login extends \Magento\Framework\App\Action\Action $this->customerAccountManagement = $customerAccountManagement; $this->resultJsonFactory = $resultJsonFactory; $this->resultRawFactory = $resultRawFactory; + $this->cookieManager = $cookieManager ?: ObjectManager::getInstance()->get( + CookieManagerInterface::class + ); + $this->cookieMetadataFactory = $cookieMetadataFactory ?: ObjectManager::getInstance()->get( + CookieMetadataFactory::class + ); } /** @@ -169,6 +191,11 @@ class Login extends \Magento\Framework\App\Action\Action $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSession->regenerateId(); $redirectRoute = $this->getAccountRedirect()->getRedirectCookie(); + if ($this->cookieManager->getCookie('mage-cache-sessid')) { + $metadata = $this->cookieMetadataFactory->createCookieMetadata(); + $metadata->setPath('/'); + $this->cookieManager->deleteCookie('mage-cache-sessid', $metadata); + } if (!$this->getScopeConfig()->getValue('customer/startup/redirect_dashboard') && $redirectRoute) { $response['redirectUrl'] = $this->_redirect->success($redirectRoute); $this->getAccountRedirect()->clearRedirectCookie(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php index b759b1a62573f45d6621bcc7a786e25ff03ec993..2fca6c99be31993f6e1cd59ce53b849cbb04ad9c 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php @@ -73,6 +73,21 @@ class LoginTest extends \PHPUnit\Framework\TestCase */ protected $redirectMock; + /** + * @var \Magento\Framework\Stdlib\CookieManagerInterface| \PHPUnit_Framework_MockObject_MockObject + */ + private $cookieManager; + + /** + * @var \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory| \PHPUnit_Framework_MockObject_MockObject + */ + private $cookieMetadataFactory; + + /** + * @var \Magento\Framework\Stdlib\Cookie\CookieMetadata| \PHPUnit_Framework_MockObject_MockObject + */ + private $cookieMetadata; + protected function setUp() { $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) @@ -100,6 +115,16 @@ class LoginTest extends \PHPUnit\Framework\TestCase ->setMethods(['create']) ->getMock(); + $this->cookieManager = $this->getMockBuilder(\Magento\Framework\Stdlib\CookieManagerInterface::class) + ->setMethods(['getCookie', 'deleteCookie']) + ->getMockForAbstractClass(); + $this->cookieMetadataFactory = $this->getMockBuilder(\Magento\Framework\Stdlib\Cookie\CookieMetadataFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->cookieMetadata = $this->getMockBuilder(\Magento\Framework\Stdlib\Cookie\CookieMetadata::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resultRaw = $this->getMockBuilder(\Magento\Framework\Controller\Result\Raw::class) ->disableOriginalConstructor() ->getMock(); @@ -128,6 +153,8 @@ class LoginTest extends \PHPUnit\Framework\TestCase 'resultJsonFactory' => $this->resultJsonFactory, 'objectManager' => $this->objectManager, 'customerAccountManagement' => $this->customerAccountManagementMock, + 'cookieManager' => $this->cookieManager, + 'cookieMetadataFactory' => $this->cookieMetadataFactory ] ); } @@ -179,6 +206,22 @@ class LoginTest extends \PHPUnit\Framework\TestCase $this->object->setAccountRedirect($redirectMock); $redirectMock->expects($this->once())->method('getRedirectCookie')->willReturn('some_url1'); + $this->cookieManager->expects($this->once()) + ->method('getCookie') + ->with('mage-cache-sessid') + ->willReturn(true); + $this->cookieMetadataFactory->expects($this->once()) + ->method('createCookieMetadata') + ->willReturn($this->cookieMetadata); + $this->cookieMetadata->expects($this->once()) + ->method('setPath') + ->with('/') + ->willReturnSelf(); + $this->cookieManager->expects($this->once()) + ->method('deleteCookie') + ->with('mage-cache-sessid', $this->cookieMetadata) + ->willReturnSelf(); + $scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); $this->object->setScopeConfig($scopeConfigMock); $scopeConfigMock->expects($this->once())->method('getValue')