Skip to content

Commit

Permalink
Merge pull request #2739 from magento-tsg/2.2-develop-pr31
Browse files Browse the repository at this point in the history
[TSG] Backporting for 2.2 (pr31) (2.2.6)
  • Loading branch information
Alexander Akimov authored Jun 22, 2018
2 parents 1795f67 + 7e4fe82 commit 9f14314
Show file tree
Hide file tree
Showing 40 changed files with 1,228 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public function execute()
{
$data = $this->getRequest()->getPostValue();
if ($data) {
$this->preprocessOptionsData($data);
$setId = $this->getRequest()->getParam('set');

$attributeSet = null;
Expand Down Expand Up @@ -210,7 +211,7 @@ public function execute()

$data['attribute_code'] = $model->getAttributeCode();
$data['is_user_defined'] = $model->getIsUserDefined();
$data['frontend_input'] = $model->getFrontendInput();
$data['frontend_input'] = $data['frontend_input'] ?? $model->getFrontendInput();
} else {
/**
* @todo add to helper and specify all relations for properties
Expand Down Expand Up @@ -311,6 +312,28 @@ public function execute()
return $this->returnResult('catalog/*/', [], ['error' => true]);
}

/**
* Extract options data from serialized options field and append to data array.
*
* This logic is required to overcome max_input_vars php limit
* that may vary and/or be inaccessible to change on different instances.
*
* @param array $data
* @return void
*/
private function preprocessOptionsData(&$data)
{
if (isset($data['serialized_options'])) {
$serializedOptions = json_decode($data['serialized_options'], JSON_OBJECT_AS_ARRAY);
foreach ($serializedOptions as $serializedOption) {
$option = [];
parse_str($serializedOption, $option);
$data = array_replace_recursive($data, $option);
}
}
unset($data['serialized_options']);
}

/**
* @param string $path
* @param array $params
Expand Down
26 changes: 25 additions & 1 deletion app/code/Magento/Catalog/Model/ResourceModel/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*/
namespace Magento\Catalog\Model\ResourceModel;

use Magento\Catalog\Model\Indexer\Category\Product\Processor;
use Magento\Framework\DataObject;
use Magento\Framework\EntityManager\EntityManager;

/**
Expand Down Expand Up @@ -82,6 +84,11 @@ class Category extends AbstractResource
*/
protected $aggregateCount;

/**
* @var Processor
*/
private $indexerProcessor;

/**
* Category constructor.
* @param \Magento\Eav\Model\Entity\Context $context
Expand All @@ -92,6 +99,7 @@ class Category extends AbstractResource
* @param Category\CollectionFactory $categoryCollectionFactory
* @param array $data
* @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
* @param Processor|null $indexerProcessor
*/
public function __construct(
\Magento\Eav\Model\Entity\Context $context,
Expand All @@ -101,7 +109,8 @@ public function __construct(
\Magento\Catalog\Model\ResourceModel\Category\TreeFactory $categoryTreeFactory,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
$data = [],
\Magento\Framework\Serialize\Serializer\Json $serializer = null
\Magento\Framework\Serialize\Serializer\Json $serializer = null,
Processor $indexerProcessor = null
) {
parent::__construct(
$context,
Expand All @@ -115,6 +124,8 @@ public function __construct(
$this->connectionName = 'catalog';
$this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Framework\Serialize\Serializer\Json::class);
$this->indexerProcessor = $indexerProcessor ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(Processor::class);
}

/**
Expand Down Expand Up @@ -197,6 +208,19 @@ protected function _beforeDelete(\Magento\Framework\DataObject $object)
$this->deleteChildren($object);
}

/**
* Mark Category indexer as invalid to be picked up by cron.
*
* @param DataObject $object
* @return $this
*/
protected function _afterDelete(DataObject $object): Category
{
$this->indexerProcessor->markIndexerAsInvalid();

return parent::_afterDelete($object);
}

/**
* Delete children categories of specific category
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Magento\Catalog\Test\Unit\Model\ResourceModel;

use Magento\Catalog\Model\Factory;
use Magento\Catalog\Model\Indexer\Category\Product\Processor;
use Magento\Catalog\Model\ResourceModel\Category;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\Eav\Model\Config;
Expand Down Expand Up @@ -91,6 +92,11 @@ class CategoryTest extends \PHPUnit\Framework\TestCase
*/
private $serializerMock;

/**
* @var Processor|\PHPUnit_Framework_MockObject_MockObject
*/
private $indexerProcessorMock;

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -121,6 +127,9 @@ protected function setUp()
$this->collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
->disableOriginalConstructor()
->getMock();
$this->indexerProcessorMock = $this->getMockBuilder(Processor::class)
->disableOriginalConstructor()
->getMock();

$this->serializerMock = $this->getMockBuilder(Json::class)->getMock();

Expand All @@ -132,7 +141,8 @@ protected function setUp()
$this->treeFactoryMock,
$this->collectionFactoryMock,
[],
$this->serializerMock
$this->serializerMock,
$this->indexerProcessorMock
);
}

Expand Down
3 changes: 3 additions & 0 deletions app/code/Magento/Catalog/i18n/en_US.csv
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ Groups,Groups
"Maximum image width","Maximum image width"
"Maximum image height","Maximum image height"
"Maximum number of characters:","Maximum number of characters:"
"Maximum %1 characters", "Maximum %1 characters"
"too many", "too many"
"remaining", "remaining"
"start typing to search template","start typing to search template"
"Product online","Product online"
"Product offline","Product offline"
Expand Down
34 changes: 31 additions & 3 deletions app/code/Magento/Catalog/view/adminhtml/web/js/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ define([
'jquery/ui',
'prototype',
'form',
'validation'
'validation',
'mage/translate'
], function (jQuery, mageTemplate, rg) {
'use strict';

return function (config) {
var attributeOption = {
var optionPanel = jQuery('#manage-options-panel'),
optionsValues = [],
editForm = jQuery('#edit_form'),
attributeOption = {
table: $('attribute-options-table'),
itemCount: 0,
totalItems: 0,
Expand Down Expand Up @@ -150,7 +154,7 @@ define([
attributeOption.remove(event);
});

jQuery('#manage-options-panel').on('render', function () {
optionPanel.on('render', function () {
attributeOption.ignoreValidate();

if (attributeOption.rendered) {
Expand All @@ -176,7 +180,31 @@ define([
});
});
}
editForm.on('submit', function () {
optionPanel.find('input')
.each(function () {
if (this.disabled) {
return;
}

if (this.type === 'checkbox' || this.type === 'radio') {
if (this.checked) {
optionsValues.push(this.name + '=' + jQuery(this).val());
}
} else {
optionsValues.push(this.name + '=' + jQuery(this).val());
}
});
jQuery('<input>')
.attr({
type: 'hidden',
name: 'serialized_options'
})
.val(JSON.stringify(optionsValues))
.prependTo(editForm);
optionPanel.find('table')
.replaceWith(jQuery('<div>').text(jQuery.mage.__('Sending attribute values as package.')));
});
window.attributeOption = attributeOption;
window.optionDefaultInputType = attributeOption.getOptionInputType();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,23 @@ $class = ($_option->getIsRequire()) ? ' required' : '';
cols="25"><?= $block->escapeHtml($block->getDefaultValue()) ?></textarea>
<?php endif; ?>
<?php if ($_option->getMaxCharacters()): ?>
<p class="note"><?= /* @escapeNotVerified */ __('Maximum number of characters:') ?>
<strong><?= /* @escapeNotVerified */ $_option->getMaxCharacters() ?></strong></p>
<p class="note note_<?= /* @escapeNotVerified */ $_option->getId() ?>">
<?= /* @escapeNotVerified */ __('Maximum %1 characters', $_option->getMaxCharacters()) ?>
<span class="character-counter no-display"></span>
</p>
<?php endif; ?>
</div>
<?php if ($_option->getMaxCharacters()): ?>
<script type="text/x-magento-init">
{
"[data-selector='options[<?= /* @escapeNotVerified */ $_option->getId() ?>]']": {
"Magento_Catalog/js/product/remaining-characters": {
"maxLength": "<?= /* @escapeNotVerified */ $_option->getMaxCharacters() ?>",
"noteSelector": ".note_<?= /* @escapeNotVerified */ $_option->getId() ?>",
"counterSelector": ".note_<?= /* @escapeNotVerified */ $_option->getId() ?> .character-counter"
}
}
}
</script>
<?php endif; ?>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

define([
'jquery',
'mage/translate',
'jquery/ui'
], function ($, $t) {
'use strict';

$.widget('mage.remainingCharacters', {
options: {
remainingText: $t('remaining'),
tooManyText: $t('too many'),
errorClass: 'mage-error',
noDisplayClass: 'no-display'
},

/**
* Initializes custom option component
*
* @private
*/
_create: function () {
this.note = $(this.options.noteSelector);
this.counter = $(this.options.counterSelector);

this.updateCharacterCount();
this.element.on('change keyup paste', this.updateCharacterCount.bind(this));
},

/**
* Updates counter message
*/
updateCharacterCount: function () {
var length = this.element.val().length,
diff = this.options.maxLength - length;

this.counter.text(this._formatMessage(diff));
this.counter.toggleClass(this.options.noDisplayClass, length === 0);
this.note.toggleClass(this.options.errorClass, diff < 0);
},

/**
* Format remaining characters message
*
* @param {int} diff
* @returns {String}
* @private
*/
_formatMessage: function (diff) {
var count = Math.abs(diff),
qualifier = diff < 0 ? this.options.tooManyText : this.options.remainingText;

return '(' + count + ' ' + qualifier + ')';
}
});

return $.mage.remainingCharacters;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin;

use Magento\Catalog\Model\ResourceModel\Category as Resource;
use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor;

/**
* Perform indexer invalidation after a category delete.
*/
class Category
{
/**
* @var Processor
*/
private $fulltextIndexerProcessor;

/**
* @param Processor $fulltextIndexerProcessor
*/
public function __construct(Processor $fulltextIndexerProcessor)
{
$this->fulltextIndexerProcessor = $fulltextIndexerProcessor;
}

/**
* Mark fulltext indexer as invalid post-deletion of category.
*
* @param Resource $subjectCategory
* @param Resource $resultCategory
* @return Resource
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterDelete(Resource $subjectCategory, Resource $resultCategory): Resource
{
$this->fulltextIndexerProcessor->markIndexerAsInvalid();

return $resultCategory;
}
}
8 changes: 8 additions & 0 deletions app/code/Magento/CatalogSearch/etc/adminhtml/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,12 @@
</argument>
</arguments>
</type>
<type name="Magento\Catalog\Model\ProductLink\Search">
<arguments>
<argument name="filter" xsi:type="object">Magento\CatalogSearch\Ui\DataProvider\Product\AddFulltextFilterToCollection</argument>
</arguments>
</type>
<type name="Magento\Catalog\Model\ResourceModel\Category">
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
</type>
</config>
12 changes: 12 additions & 0 deletions app/code/Magento/CatalogSearch/etc/webapi_rest/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\ResourceModel\Category">
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
</type>
</config>
12 changes: 12 additions & 0 deletions app/code/Magento/CatalogSearch/etc/webapi_soap/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\ResourceModel\Category">
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
</type>
</config>
Loading

0 comments on commit 9f14314

Please sign in to comment.