Skip to content

Commit a590e96

Browse files
ENGCOM-6490: Add mass action to invalidate indexes via admin #25860
- Merge Pull Request #25860 from fredden/magento2:admin-indexer-massinvalidte - Merged commits: 1. 67cf8d5 2. ed04009 3. b6e58ad 4. d8bcc15 5. 5b5a194 6. 2da0d9d 7. ad381ef 8. 79f3fc8 9. 6c321ef 10. 777f409 11. 6c47a75 12. a86d795 13. 45bb428 14. 365e4da 15. 31cf179 16. c17b5fb 17. 1fa6f08 18. 76e32bb 19. dac3548
2 parents 2c553dd + dac3548 commit a590e96

File tree

9 files changed

+370
-0
lines changed

9 files changed

+370
-0
lines changed

app/code/Magento/Indexer/Controller/Adminhtml/Indexer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Indexer\Controller\Adminhtml;
77

8+
/**
9+
* Abstract class used as part of inheritance tree for Indexer controllers
10+
*/
811
abstract class Indexer extends \Magento\Backend\App\Action
912
{
1013
/**
@@ -20,6 +23,8 @@ protected function _isAllowed()
2023
case 'massOnTheFly':
2124
case 'massChangelog':
2225
return $this->_authorization->isAllowed('Magento_Indexer::changeMode');
26+
case 'massInvalidate':
27+
return $this->_authorization->isAllowed('Magento_Indexer::invalidate');
2328
}
2429
return false;
2530
}

app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
1010

11+
/**
12+
* Controller for indexer grid
13+
*/
1114
class ListAction extends \Magento\Indexer\Controller\Adminhtml\Indexer implements HttpGetActionInterface
1215
{
1316
/**

app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassChangelog.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
1010

11+
/**
12+
* Controller endpoint for mass action: set index mode as 'Update by Schedule'
13+
*/
1114
class MassChangelog extends \Magento\Indexer\Controller\Adminhtml\Indexer implements HttpPostActionInterface
1215
{
1316
/**
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Indexer\Controller\Adminhtml\Indexer;
7+
8+
use Magento\Backend\App\Action\Context;
9+
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
10+
use Magento\Framework\Indexer\IndexerRegistry;
11+
12+
/**
13+
* Controller endpoint for mass action: invalidate index
14+
*/
15+
class MassInvalidate extends \Magento\Indexer\Controller\Adminhtml\Indexer implements HttpPostActionInterface
16+
{
17+
/**
18+
* @var IndexerRegistry $indexerRegistry
19+
*/
20+
private $indexerRegistry;
21+
22+
/**
23+
* @param Context $context
24+
* @param IndexerRegistry $indexerRegistry
25+
*/
26+
public function __construct(
27+
Context $context,
28+
IndexerRegistry $indexerRegistry
29+
) {
30+
parent::__construct($context);
31+
$this->indexerRegistry = $indexerRegistry;
32+
}
33+
34+
/**
35+
* Turn mview on for the given indexers
36+
*
37+
* @return void
38+
*/
39+
public function execute()
40+
{
41+
$indexerIds = $this->getRequest()->getParam('indexer_ids');
42+
if (!is_array($indexerIds)) {
43+
$this->messageManager->addError(__('Please select indexers.'));
44+
} else {
45+
try {
46+
foreach ($indexerIds as $indexerId) {
47+
/** @var \Magento\Framework\Indexer\IndexerInterface $model */
48+
$model = $this->indexerRegistry->get($indexerId);
49+
$model->invalidate();
50+
}
51+
$this->messageManager->addSuccess(
52+
__('%1 indexer(s) were invalidated.', count($indexerIds))
53+
);
54+
} catch (\Magento\Framework\Exception\LocalizedException $e) {
55+
$this->messageManager->addError($e->getMessage());
56+
} catch (\Exception $e) {
57+
$this->messageManager->addException(
58+
$e,
59+
__("We couldn't invalidate indexer(s) because of an error.")
60+
);
61+
}
62+
}
63+
return $this->resultRedirectFactory->create()->setPath('*/*/list');
64+
}
65+
}

app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassOnTheFly.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
1010

11+
/**
12+
* Controller endpoint for mass action: set index mode as 'Update on Save'
13+
*/
1114
class MassOnTheFly extends \Magento\Indexer\Controller\Adminhtml\Indexer implements HttpPostActionInterface
1215
{
1316
/**
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Indexer\Test\Unit\Controller\Adminhtml\Indexer;
7+
8+
/**
9+
* Test for Mass invalidate action
10+
*
11+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
12+
*/
13+
class MassInvalidateTest extends \PHPUnit\Framework\TestCase
14+
{
15+
/**
16+
* @var \Magento\Indexer\Controller\Adminhtml\Indexer\MassInvalidate
17+
*/
18+
protected $controller;
19+
20+
/**
21+
* @var \Magento\Backend\App\Action\Context
22+
*/
23+
protected $contextMock;
24+
25+
/**
26+
* @var \Magento\Framework\App\ViewInterface
27+
*/
28+
protected $view;
29+
30+
/**
31+
* @var \Magento\Framework\View\Result\Page
32+
*/
33+
protected $page;
34+
35+
/**
36+
* @var \Magento\Framework\View\Page\Config
37+
*/
38+
protected $config;
39+
40+
/**
41+
* @var \Magento\Framework\View\Page\Title
42+
*/
43+
protected $title;
44+
45+
/**
46+
* @var \Magento\Framework\App\RequestInterface
47+
*/
48+
protected $request;
49+
50+
/**
51+
* @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
52+
*/
53+
protected $objectManager;
54+
55+
/**
56+
* @var \Magento\Framework\Message\ManagerInterface
57+
*/
58+
protected $messageManager;
59+
60+
/**
61+
* @var \Magento\Framework\Indexer\IndexerRegistry
62+
*/
63+
protected $indexReg;
64+
65+
/**
66+
* @var \Magento\Framework\App\ResponseInterface
67+
*/
68+
protected $response;
69+
70+
/**
71+
* @var \Magento\Framework\App\ActionFlag
72+
*/
73+
protected $actionFlag;
74+
75+
/**
76+
* @var \Magento\Backend\Helper\Data
77+
*/
78+
protected $helper;
79+
80+
/**
81+
* @var \Magento\Backend\Model\Session
82+
*/
83+
protected $session;
84+
85+
/**
86+
* @var \Magento\Framework\Controller\Result\Redirect
87+
*/
88+
protected $resultRedirect;
89+
90+
/**
91+
* Set up test
92+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
93+
*/
94+
protected function setUp()
95+
{
96+
$this->contextMock = $this->createPartialMock(
97+
\Magento\Backend\App\Action\Context::class,
98+
[
99+
'getAuthorization',
100+
'getSession',
101+
'getActionFlag',
102+
'getAuth',
103+
'getView',
104+
'getHelper',
105+
'getBackendUrl',
106+
'getFormKeyValidator',
107+
'getLocaleResolver',
108+
'getCanUseBaseUrl',
109+
'getRequest',
110+
'getResponse',
111+
'getObjectManager',
112+
'getMessageManager',
113+
'getResultRedirectFactory',
114+
]
115+
);
116+
117+
$this->response = $this->createPartialMock(
118+
\Magento\Framework\App\ResponseInterface::class,
119+
['setRedirect', 'sendResponse']
120+
);
121+
122+
$this->view = $this->createPartialMock(
123+
\Magento\Framework\App\ViewInterface::class,
124+
[
125+
'loadLayout',
126+
'getPage',
127+
'getConfig',
128+
'getTitle',
129+
'renderLayout',
130+
'loadLayoutUpdates',
131+
'getDefaultLayoutHandle',
132+
'addPageLayoutHandles',
133+
'generateLayoutBlocks',
134+
'generateLayoutXml',
135+
'getLayout',
136+
'addActionLayoutHandles',
137+
'setIsLayoutLoaded',
138+
'isLayoutLoaded'
139+
]
140+
);
141+
142+
$this->session = $this->createPartialMock(\Magento\Backend\Model\Session::class, ['setIsUrlNotice']);
143+
$this->session->expects($this->any())->method('setIsUrlNotice')->willReturn($this->objectManager);
144+
$this->actionFlag = $this->createPartialMock(\Magento\Framework\App\ActionFlag::class, ['get']);
145+
$this->actionFlag->expects($this->any())->method("get")->willReturn($this->objectManager);
146+
$this->objectManager = $this->createPartialMock(
147+
\Magento\Framework\TestFramework\Unit\Helper\ObjectManager::class,
148+
['get']
149+
);
150+
$this->request = $this->getMockForAbstractClass(
151+
\Magento\Framework\App\RequestInterface::class,
152+
['getParam', 'getRequest'],
153+
'',
154+
false
155+
);
156+
157+
$resultRedirectFactory = $this->createPartialMock(
158+
\Magento\Backend\Model\View\Result\RedirectFactory::class,
159+
['create']
160+
);
161+
$this->resultRedirect = $this->createPartialMock(
162+
\Magento\Framework\Controller\Result\Redirect::class,
163+
['setPath']
164+
);
165+
$this->contextMock->expects($this->any())->method('getResultRedirectFactory')
166+
->willReturn($resultRedirectFactory);
167+
$resultRedirectFactory->expects($this->any())->method('create')
168+
->willReturn($this->resultRedirect);
169+
170+
$this->response->expects($this->any())->method("setRedirect")->willReturn(1);
171+
$this->page = $this->createMock(\Magento\Framework\View\Result\Page::class);
172+
$this->config = $this->createMock(\Magento\Framework\View\Result\Page::class);
173+
$this->title = $this->createMock(\Magento\Framework\View\Page\Title::class);
174+
$this->messageManager = $this->getMockForAbstractClass(
175+
\Magento\Framework\Message\ManagerInterface::class,
176+
['addError', 'addSuccess'],
177+
'',
178+
false
179+
);
180+
181+
$this->indexReg = $this->createPartialMock(
182+
\Magento\Framework\Indexer\IndexerRegistry::class,
183+
['get', 'setScheduled']
184+
);
185+
$this->helper = $this->createPartialMock(\Magento\Backend\Helper\Data::class, ['getUrl']);
186+
$this->contextMock->expects($this->any())->method("getObjectManager")->willReturn($this->objectManager);
187+
$this->contextMock->expects($this->any())->method("getRequest")->willReturn($this->request);
188+
$this->contextMock->expects($this->any())->method("getResponse")->willReturn($this->response);
189+
$this->contextMock->expects($this->any())->method("getMessageManager")->willReturn($this->messageManager);
190+
$this->contextMock->expects($this->any())->method("getSession")->willReturn($this->session);
191+
$this->contextMock->expects($this->any())->method("getActionFlag")->willReturn($this->actionFlag);
192+
$this->contextMock->expects($this->any())->method("getHelper")->willReturn($this->helper);
193+
}
194+
195+
/**
196+
* @param array $indexerIds
197+
* @param \Exception $exception
198+
* @dataProvider executeDataProvider
199+
*/
200+
public function testExecute($indexerIds, $exception)
201+
{
202+
$this->controller = new \Magento\Indexer\Controller\Adminhtml\Indexer\MassInvalidate(
203+
$this->contextMock,
204+
$this->indexReg
205+
);
206+
$this->request->expects($this->any())
207+
->method('getParam')->with('indexer_ids')
208+
->will($this->returnValue($indexerIds));
209+
210+
if (!is_array($indexerIds)) {
211+
$this->messageManager->expects($this->once())
212+
->method('addError')->with(__('Please select indexers.'))
213+
->will($this->returnValue(1));
214+
} else {
215+
$indexerInterface = $this->getMockForAbstractClass(
216+
\Magento\Framework\Indexer\IndexerInterface::class,
217+
['invalidate'],
218+
'',
219+
false
220+
);
221+
$this->indexReg->expects($this->any())
222+
->method('get')->with(1)
223+
->will($this->returnValue($indexerInterface));
224+
225+
$indexerInterface->expects($this->any())
226+
->method('invalidate')->with(true)
227+
->will($this->returnValue(1));
228+
229+
$this->messageManager->expects($this->any())
230+
->method('addSuccess')
231+
->will($this->returnValue(1));
232+
233+
if ($exception) {
234+
$this->indexReg->expects($this->any())
235+
->method('get')->with(2)
236+
->will($this->throwException($exception));
237+
238+
if ($exception instanceof \Magento\Framework\Exception\LocalizedException) {
239+
$this->messageManager->expects($this->once())
240+
->method('addError')
241+
->with($exception->getMessage());
242+
} else {
243+
$this->messageManager->expects($this->once())
244+
->method('addException')
245+
->with($exception, "We couldn't invalidate indexer(s) because of an error.");
246+
}
247+
}
248+
}
249+
250+
$this->helper->expects($this->any())->method("getUrl")->willReturn("magento.com");
251+
$this->response->expects($this->any())->method("setRedirect")->willReturn(1);
252+
$this->resultRedirect->expects($this->once())->method('setPath')->with('*/*/list');
253+
254+
$this->controller->execute();
255+
}
256+
257+
/**
258+
* @return array
259+
*/
260+
public function executeDataProvider()
261+
{
262+
return [
263+
'set1' => [
264+
'indexers' => 1,
265+
'exception' => null,
266+
],
267+
'set2' => [
268+
'indexers' => [1],
269+
'exception' => null,
270+
],
271+
'set3' => [
272+
'indexers' => [2],
273+
'exception' => new \Magento\Framework\Exception\LocalizedException(__('Test Phrase')),
274+
],
275+
'set4' => [
276+
'indexers' => [2],
277+
'exception' => new \Exception(),
278+
]
279+
];
280+
}
281+
}

0 commit comments

Comments
 (0)