Magento 2: How to add reindex option to Index Management grid?
Several times during the development and testing phase of your store you may have wanted to reindex your store for the your products,
their prices, promotion rules etc. to show up correctly in the frontend. But Magento does not allow you to reindex direclty from the admin. You either have to wait for the cron to run or, you need to run command php bin/magento
indexer:reindex
to manually reindex. This can be a tedious task, once that sucks the life out of you when you have to do it over and over again, especially when you don’t know how to run a command in your CLI (Command line interface) and
you have to wait for the cron job to run.
In this article, I will show you how to add a reindex option to your Magento 2 Index management grid in the admin. This will require you to create a custom module which is very simple to develop.
Note: Any of you, who are only interested in the final module and not how to build it can purchase it for free from our store. You can also find the code in our github repository.
Let’s begin by creating a directory under app/code/HS/AdminReindex
(in the format app/code/{VendorName}/{ModuleName}) in the Magento 2 installation Everything from here
will be added inside this directory. You can replace HS
with your own VendorName
and same goes for the ModuleName, but make sure you replace it everywhere in the code as well.
Next, we create all the files required for a custom module:
composer.json
{
"name": "hs/module-admin-reindex",
"description": "N/A",
"require": {
"php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0|~7.2.0"
},
"type": "magento2-module",
"version": "1.0.0",
"license": "Apache-2.0",
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"HS\\AdminReindex\\": ""
}
}
}
registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'HS_AdminReindex',
__DIR__
);
etc/module.xml
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="HS_AdminReindex" setup_version="1.0.0" />
</config>
Now that we have that covered, we will start with the code specific to this extension. This extension will need the following 3 things:
- Add
Reindex
option to the Index Management grid in Magento admin which will call the route hs_indexer/indexer/reindex - Define a route
hs_indexer
in the admin. - Create a controller to handle
hs_indexer/indexer/reindex
action.
First, we add Reindex
option to grid:
Create a
file view/adminhtml/layout/indexer_indexer_list_grid.xml
and add the following:
<?xml version="1.0" ?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="adminhtml.indexer.grid.grid.massaction">
<arguments>
<argument name="options" xsi:type="array">
<item name="hs_admin_reindex" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Reindex</item>
<item name="url" xsi:type="string">hs_indexer/indexer/reindex</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
This is the layout definition for the index
management grid. We reference the massaction
dropdown block in the grid layout and add a new option hs_admin_reindex
. We define a label for the option and for URL we specify our route hs_indexer/indexer/reindex
to go to when the dropdown item is selected.
Next, we define the route hs_indexer
so that the route that our reindex option refers to, actually exists. We do this by
creating the file routes.xml
under etc/adminhtml/
directory. We then add the following content into the file and save it.
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route frontName="hs_indexer" id="hs_indexer">
<module before="Magento_Backend" name="HS_AdminReindex"/>
</route>
</router>
</config>
We want this route to be in the admin which is why create the file inside etc/adminhtml
directory and we add it under the router with id admin
.
Finally, we create our controller to handle the action hs_indexer/indexer/reindex
by creating the file Controller/Adminhtml/Indexer/Reindex.php
and adding the following
content.
<?php
namespace HS\AdminReindex\Controller\Adminhtml\Indexer;
class Reindex extends \Magento\Backend\App\Action
{
private $indexerFactory;
private $logger;
/**
* Constructor
*
* @param \Magento\Backend\App\Action\Context $context
* @param \Magento\Indexer\Model\IndexerFactory $indexerFactory
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Indexer\Model\IndexerFactory $indexerFactory,
\Psr\Log\LoggerInterface $logger
) {
$this->indexerFactory = $indexerFactory;
parent::__construct($context);
}
/**
* Execute view action
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
$indexerIds = $this->getRequest()->getParam('indexer_ids');
if (!is_array($indexerIds)) {
$this->messageManager->addErrorMessage(__('Please select indexers.'));
} else {
try {
foreach ($indexerIds as $indexerId) {
$indexer = $this->indexerFactory->create();
$indexer->load($indexerId);
$indexer->reindexAll();
}
$this->messageManager->addSuccessMessage(__('Reindex %1 indexer(s).', count($indexerIds)));
} catch (Exception $e) {
$this->logger->critical($e);
$this->messageManager->addErrorMessage(__('We couldn\'t reindex because of an error.'));
}
}
$this->_redirect('indexer/indexer/list');
}
}
We get Magento\Indexer\Model\IndexerFactory
in our constructor which will let us load the selected indexer(s)
and reindex them. The execute
function is where all the magic happens. We first get the selected indexer ids
and we load each indexer by passing the indexer id
to the indexerFactory
, once that is
loaded we can reindex the loaded indexer. If at least one indexer was selected and all the selected indexers reindex successfully, we show the success message, otherwise we throw an error.