Skip to content

Commit ce8a93e

Browse files
author
Alex Paliarush
committed
Merge remote-tracking branch 'remotes/mainline/2.3-develop' into ENGCOM-1833-magento-graphql-ce-83
2 parents 9efebd7 + e279d2c commit ce8a93e

File tree

19 files changed

+488
-7
lines changed

19 files changed

+488
-7
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Category.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
*/
1212
namespace Magento\Catalog\Model\ResourceModel;
1313

14+
use Magento\Catalog\Model\Indexer\Category\Product\Processor;
15+
use Magento\Framework\DataObject;
1416
use Magento\Framework\EntityManager\EntityManager;
1517

1618
/**
@@ -82,6 +84,11 @@ class Category extends AbstractResource
8284
*/
8385
protected $aggregateCount;
8486

87+
/**
88+
* @var Processor
89+
*/
90+
private $indexerProcessor;
91+
8592
/**
8693
* Category constructor.
8794
* @param \Magento\Eav\Model\Entity\Context $context
@@ -90,6 +97,7 @@ class Category extends AbstractResource
9097
* @param \Magento\Framework\Event\ManagerInterface $eventManager
9198
* @param Category\TreeFactory $categoryTreeFactory
9299
* @param Category\CollectionFactory $categoryCollectionFactory
100+
* @param Processor $indexerProcessor
93101
* @param array $data
94102
* @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
95103
*/
@@ -100,6 +108,7 @@ public function __construct(
100108
\Magento\Framework\Event\ManagerInterface $eventManager,
101109
\Magento\Catalog\Model\ResourceModel\Category\TreeFactory $categoryTreeFactory,
102110
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
111+
Processor $indexerProcessor,
103112
$data = [],
104113
\Magento\Framework\Serialize\Serializer\Json $serializer = null
105114
) {
@@ -113,6 +122,7 @@ public function __construct(
113122
$this->_categoryCollectionFactory = $categoryCollectionFactory;
114123
$this->_eventManager = $eventManager;
115124
$this->connectionName = 'catalog';
125+
$this->indexerProcessor = $indexerProcessor;
116126
$this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
117127
->get(\Magento\Framework\Serialize\Serializer\Json::class);
118128
}
@@ -197,6 +207,18 @@ protected function _beforeDelete(\Magento\Framework\DataObject $object)
197207
$this->deleteChildren($object);
198208
}
199209

210+
/**
211+
* Mark Category indexer as invalid to be picked up by cron.
212+
*
213+
* @param DataObject $object
214+
* @return $this
215+
*/
216+
protected function _afterDelete(DataObject $object)
217+
{
218+
$this->indexerProcessor->markIndexerAsInvalid();
219+
return parent::_afterDelete($object);
220+
}
221+
200222
/**
201223
* Delete children categories of specific category
202224
*

app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/CategoryTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\Catalog\Test\Unit\Model\ResourceModel;
88

99
use Magento\Catalog\Model\Factory;
10+
use Magento\Catalog\Model\Indexer\Category\Product\Processor;
1011
use Magento\Catalog\Model\ResourceModel\Category;
1112
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
1213
use Magento\Eav\Model\Config;
@@ -91,6 +92,11 @@ class CategoryTest extends \PHPUnit\Framework\TestCase
9192
*/
9293
private $serializerMock;
9394

95+
/**
96+
* @var Processor|\PHPUnit_Framework_MockObject_MockObject
97+
*/
98+
private $indexerProcessorMock;
99+
94100
/**
95101
* {@inheritDoc}
96102
*/
@@ -121,6 +127,9 @@ protected function setUp()
121127
$this->collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
122128
->disableOriginalConstructor()
123129
->getMock();
130+
$this->indexerProcessorMock = $this->getMockBuilder(Processor::class)
131+
->disableOriginalConstructor()
132+
->getMock();
124133

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

@@ -131,6 +140,7 @@ protected function setUp()
131140
$this->managerMock,
132141
$this->treeFactoryMock,
133142
$this->collectionFactoryMock,
143+
$this->indexerProcessorMock,
134144
[],
135145
$this->serializerMock
136146
);

app/code/Magento/Catalog/i18n/en_US.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,9 @@ Groups,Groups
516516
"Maximum image width","Maximum image width"
517517
"Maximum image height","Maximum image height"
518518
"Maximum number of characters:","Maximum number of characters:"
519+
"Maximum %1 characters", "Maximum %1 characters"
520+
"too many", "too many"
521+
"remaining", "remaining"
519522
"start typing to search template","start typing to search template"
520523
"Product online","Product online"
521524
"Product offline","Product offline"

app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/text.phtml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,23 @@ $class = ($_option->getIsRequire()) ? ' required' : '';
6161
cols="25"><?= $block->escapeHtml($block->getDefaultValue()) ?></textarea>
6262
<?php endif; ?>
6363
<?php if ($_option->getMaxCharacters()): ?>
64-
<p class="note"><?= /* @escapeNotVerified */ __('Maximum number of characters:') ?>
65-
<strong><?= /* @escapeNotVerified */ $_option->getMaxCharacters() ?></strong></p>
64+
<p class="note note_<?= /* @escapeNotVerified */ $_option->getId() ?>">
65+
<?= /* @escapeNotVerified */ __('Maximum %1 characters', $_option->getMaxCharacters()) ?>
66+
<span class="character-counter no-display"></span>
67+
</p>
6668
<?php endif; ?>
6769
</div>
70+
<?php if ($_option->getMaxCharacters()): ?>
71+
<script type="text/x-magento-init">
72+
{
73+
"[data-selector='options[<?= /* @escapeNotVerified */ $_option->getId() ?>]']": {
74+
"Magento_Catalog/js/product/remaining-characters": {
75+
"maxLength": "<?= /* @escapeNotVerified */ $_option->getMaxCharacters() ?>",
76+
"noteSelector": ".note_<?= /* @escapeNotVerified */ $_option->getId() ?>",
77+
"counterSelector": ".note_<?= /* @escapeNotVerified */ $_option->getId() ?> .character-counter"
78+
}
79+
}
80+
}
81+
</script>
82+
<?php endif; ?>
6883
</div>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'jquery',
8+
'mage/translate',
9+
'jquery/ui'
10+
], function ($, $t) {
11+
'use strict';
12+
13+
$.widget('mage.remainingCharacters', {
14+
options: {
15+
remainingText: $t('remaining'),
16+
tooManyText: $t('too many'),
17+
errorClass: 'mage-error',
18+
noDisplayClass: 'no-display'
19+
},
20+
21+
/**
22+
* Initializes custom option component
23+
*
24+
* @private
25+
*/
26+
_create: function () {
27+
this.note = $(this.options.noteSelector);
28+
this.counter = $(this.options.counterSelector);
29+
30+
this.updateCharacterCount();
31+
this.element.on('change keyup paste', this.updateCharacterCount.bind(this));
32+
},
33+
34+
/**
35+
* Updates counter message
36+
*/
37+
updateCharacterCount: function () {
38+
var length = this.element.val().length,
39+
diff = this.options.maxLength - length;
40+
41+
this.counter.text(this._formatMessage(diff));
42+
this.counter.toggleClass(this.options.noDisplayClass, length === 0);
43+
this.note.toggleClass(this.options.errorClass, diff < 0);
44+
},
45+
46+
/**
47+
* Format remaining characters message
48+
*
49+
* @param {int} diff
50+
* @returns {String}
51+
* @private
52+
*/
53+
_formatMessage: function (diff) {
54+
var count = Math.abs(diff),
55+
qualifier = diff < 0 ? this.options.tooManyText : this.options.remainingText;
56+
57+
return '(' + count + ' ' + qualifier + ')';
58+
}
59+
});
60+
61+
return $.mage.remainingCharacters;
62+
});
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin;
9+
10+
use Magento\Catalog\Model\ResourceModel\Category as Resource;
11+
use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor;
12+
13+
/**
14+
* Perform indexer invalidation after a category delete.
15+
*/
16+
class Category
17+
{
18+
/**
19+
* @var Processor
20+
*/
21+
private $fulltextIndexerProcessor;
22+
23+
/**
24+
* @param Processor $fulltextIndexerProcessor
25+
*/
26+
public function __construct(Processor $fulltextIndexerProcessor)
27+
{
28+
$this->fulltextIndexerProcessor = $fulltextIndexerProcessor;
29+
}
30+
31+
/**
32+
* Mark fulltext indexer as invalid post-deletion of category.
33+
*
34+
* @param Resource $subjectCategory
35+
* @param Resource $resultCategory
36+
* @return Resource
37+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
38+
*/
39+
public function afterDelete(Resource $subjectCategory, Resource $resultCategory) : Resource
40+
{
41+
$this->fulltextIndexerProcessor->markIndexerAsInvalid();
42+
43+
return $resultCategory;
44+
}
45+
}

app/code/Magento/CatalogSearch/etc/adminhtml/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,7 @@
3131
<argument name="filter" xsi:type="object">Magento\CatalogSearch\Ui\DataProvider\Product\AddFulltextFilterToCollection</argument>
3232
</arguments>
3333
</type>
34+
<type name="Magento\Catalog\Model\ResourceModel\Category">
35+
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
36+
</type>
3437
</config>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="Magento\Catalog\Model\ResourceModel\Category">
10+
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
11+
</type>
12+
</config>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="Magento\Catalog\Model\ResourceModel\Category">
10+
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
11+
</type>
12+
</config>

app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@
336336
.lib-css(margin-top, @indent__xs);
337337
}
338338
}
339+
.field {
340+
.note.mage-error {
341+
color: @error__color;
342+
}
343+
}
339344
}
340345

341346
.product-options-bottom .price-box,
@@ -789,7 +794,7 @@
789794
clear: both;
790795
max-width: 100%;
791796
overflow-x: auto;
792-
position: relative; // Needed for Safari(iOS) to properly render "overflow-x" rule.
797+
position: relative; // Needed for Safari(iOS) to properly render 'overflow-x' rule.
793798

794799
.table-comparison > tbody > tr {
795800
> th,

0 commit comments

Comments
 (0)