├── Block └── Backend │ └── Grid │ └── Column │ └── Renderer │ └── ModeLocked.php ├── Console └── Command │ └── IndexerLockAll.php ├── Cron └── SetIndexerMode.php ├── Exception └── IndexerConfigurationException.php ├── LICENSE.txt ├── Model ├── Config │ ├── Importer.php │ └── Validator.php └── IndexerConfig.php ├── Plugin ├── SetIndexerMode.php ├── SetIndexerModeRealtime.php └── SetIndexerModeSchedule.php ├── README.md ├── Scope └── ModuleConfig.php ├── composer.json ├── etc ├── adminhtml │ ├── di.xml │ └── system.xml ├── config.xml ├── crontab.xml ├── crontab │ └── di.xml ├── di.xml ├── frontend │ └── di.xml ├── graphql │ └── di.xml ├── module.xml ├── webapi_rest │ └── di.xml └── webapi_soap │ └── di.xml ├── registration.php └── view └── adminhtml └── layout └── indexer_indexer_list_grid.xml /Block/Backend/Grid/Column/Renderer/ModeLocked.php: -------------------------------------------------------------------------------- 1 | indexerConfig = $indexerConfig; 34 | } 35 | 36 | /** 37 | * @param DataObject $row 38 | * @return Phrase 39 | */ 40 | public function render(DataObject $row): Phrase 41 | { 42 | $indexerConfig = $this->indexerConfig->getIndexerConfig(); 43 | $saveIndexers = $this->indexerConfig->getIndexersByMode(IndexerMode::INPUT_KEY_REALTIME, $indexerConfig); 44 | $scheduleIndexers = $this->indexerConfig->getIndexersByMode(IndexerMode::INPUT_KEY_SCHEDULE, $indexerConfig); 45 | 46 | $indexerId = $row->getData('indexer_id'); 47 | 48 | return in_array($indexerId, $scheduleIndexers) || in_array($indexerId, $saveIndexers) 49 | ? __('Yes') 50 | : __('No'); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Console/Command/IndexerLockAll.php: -------------------------------------------------------------------------------- 1 | configWriter = $configWriter; 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | protected function execute( 53 | InputInterface $input, 54 | OutputInterface $output 55 | ) { 56 | $modeInput = $input->getOption(IndexerSetModeCommand::INPUT_KEY_MODE); 57 | 58 | if (!is_null($modeInput) && !in_array($modeInput, $this->modes, true)) { 59 | throw new InvalidArgumentException( 60 | 'Passed mode must be one of: ' . implode(', ', $this->modes) 61 | ); 62 | } 63 | 64 | $indexerConfig = []; 65 | 66 | /** @var Indexer $indexer */ 67 | foreach ($this->getAllIndexers() as $indexer) { 68 | $mode = $modeInput; 69 | 70 | if (is_null($modeInput)) { 71 | $mode = $indexer->isScheduled() 72 | ? IndexerSetModeCommand::INPUT_KEY_SCHEDULE 73 | : IndexerSetModeCommand::INPUT_KEY_REALTIME; 74 | } 75 | 76 | $indexerConfig[$mode][] = $indexer->getIndexerId(); 77 | 78 | $output->writeln(sprintf( 79 | '%s indexer has been locked to %s', 80 | $indexer->getTitle(), 81 | $mode === IndexerSetModeCommand::INPUT_KEY_SCHEDULE ? 'Update on Schedule' : 'Update on Save' 82 | )); 83 | } 84 | 85 | $this->configWriter->saveConfig([ConfigFilePool::APP_CONFIG => ['indexers' => $indexerConfig]], true); 86 | $output->writeln("\nIndexers locked. Please run app:config:import."); 87 | 88 | return Cli::RETURN_SUCCESS; 89 | } 90 | 91 | /** 92 | * {@inheritdoc} 93 | */ 94 | protected function configure() 95 | { 96 | $this->setName('indexer:lock-all'); 97 | $this->setDescription('Lock all indexers'); 98 | $this->setDefinition([ 99 | new InputOption( 100 | IndexerSetModeCommand::INPUT_KEY_MODE, 101 | 'm', 102 | InputArgument::OPTIONAL, 103 | sprintf( 104 | 'Passing one of two modes (%s) will lock all indexers to that mode.', 105 | implode(', ', $this->modes) 106 | ), 107 | null 108 | ), 109 | ]); 110 | 111 | parent::configure(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Cron/SetIndexerMode.php: -------------------------------------------------------------------------------- 1 | indexerConfig = $indexerConfig; 38 | $this->moduleConfig = $moduleConfig; 39 | $this->indexerCollectionFactory = $indexerCollectionFactory; 40 | } 41 | 42 | /** 43 | * Ensure indexers are in the mode they are configured to be locked to. 44 | * 45 | * Can be disabled in the admin: 46 | * Stores -> Settings -> Configuration -> Advanced -> System -> Indexer Mode Locking -> Enable Cron Fallback -> No 47 | * 48 | * @return void 49 | */ 50 | public function execute(): void 51 | { 52 | if (!$this->moduleConfig->isCronFallbackEnabled() 53 | || !($indexerConfig = $this->indexerConfig->getFlatIndexerConfig()) 54 | ) { 55 | return; // fallback disabled or indexers are not locked, nothing to do 56 | } 57 | 58 | /** @var Indexer[] $allIndexers */ 59 | $allIndexers = $this->indexerCollectionFactory->create()->getItems(); 60 | 61 | foreach ($allIndexers as $indexer) { 62 | foreach ($indexerConfig as $indexerId => $lockedMode) { 63 | if ($indexer->getId() !== $indexerId) { 64 | continue; // ensure we're looking at the same indexer in both loops 65 | } 66 | 67 | $indexerMode = $indexer->isScheduled() 68 | ? IndexerMode::INPUT_KEY_SCHEDULE 69 | : IndexerMode::INPUT_KEY_REALTIME; 70 | 71 | if ($indexerMode !== $lockedMode) { 72 | $indexer->setScheduled($lockedMode === IndexerMode::INPUT_KEY_SCHEDULE); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Exception/IndexerConfigurationException.php: -------------------------------------------------------------------------------- 1 | " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. 48 | -------------------------------------------------------------------------------- /Model/Config/Importer.php: -------------------------------------------------------------------------------- 1 | indexerRegistry = $indexerRegistry; 27 | } 28 | 29 | /** 30 | * Import indexer config. 31 | * 32 | * @param array $indexerConfig 33 | * @return string[] 34 | */ 35 | public function import(array $indexerConfig): array 36 | { 37 | $messages = []; 38 | 39 | foreach ($indexerConfig as $mode => $indexers) { 40 | foreach ($indexers as $indexerId) { 41 | try { 42 | $indexer = $this->indexerRegistry->get($indexerId); 43 | } catch (InvalidArgumentException $e) { 44 | $messages[] = "{$indexerId} does not exist, skipping"; 45 | 46 | continue; 47 | } 48 | 49 | $isRealTimeMode = $mode === IndexerMode::INPUT_KEY_REALTIME; 50 | $isScheduleMode = $mode === IndexerMode::INPUT_KEY_SCHEDULE; 51 | 52 | // only change index mode when different, slightly more performant 53 | if ($indexer->isScheduled() && $isRealTimeMode) { 54 | $indexer->setScheduled(false); 55 | $messages[] = "{$indexerId} updated to \"Update on Save\"."; 56 | } elseif (!$indexer->isScheduled() && $isScheduleMode) { 57 | $indexer->setScheduled(true); 58 | $messages[] = "{$indexerId} updated to \"Update by Schedule\"."; 59 | } 60 | } 61 | } 62 | 63 | return $messages; 64 | } 65 | 66 | /** 67 | * Provide user with information regarding what will change after importing indexer config. 68 | * 69 | * @param array $indexerConfig 70 | * @return array|string[] 71 | */ 72 | public function getWarningMessages(array $indexerConfig): array 73 | { 74 | $messages = []; 75 | 76 | $indexersToChangeToRealtime = []; 77 | $indexersToChangeToSchedule = []; 78 | 79 | $realtimeLockedIndexers = []; 80 | $scheduleLockedIndexers = []; 81 | 82 | foreach ($indexerConfig as $mode => $indexers) { 83 | foreach ($indexers as $indexerId) { 84 | try { 85 | $indexer = $this->indexerRegistry->get($indexerId); 86 | } catch (InvalidArgumentException $e) { 87 | continue; 88 | } 89 | 90 | $isRealTimeMode = $mode === IndexerMode::INPUT_KEY_REALTIME; 91 | $isScheduleMode = $mode === IndexerMode::INPUT_KEY_SCHEDULE; 92 | 93 | if ($indexer->isScheduled() && $isRealTimeMode) { 94 | $indexersToChangeToRealtime[] = $indexerId; 95 | } elseif (!$indexer->isScheduled() && $isScheduleMode) { 96 | $indexersToChangeToSchedule[] = $indexerId; 97 | } 98 | 99 | if ($isRealTimeMode) { 100 | $realtimeLockedIndexers[] = $indexerId; 101 | } elseif ($isScheduleMode) { 102 | $scheduleLockedIndexers[] = $indexerId; 103 | } 104 | } 105 | } 106 | 107 | if ($indexersToChangeToRealtime) { 108 | $messages[] = "The following indexers will be changed to \"Update on Save\":\n" 109 | . implode("\n", $indexersToChangeToRealtime); 110 | 111 | // new line separator, "\n" didn't work for some reason ¯\_(ツ)_/¯ 112 | $messages[] = ''; 113 | } 114 | 115 | if ($indexersToChangeToSchedule) { 116 | $messages[] = "The following indexers will be changed to \"Update by Schedule\":\n" 117 | . implode("\n", $indexersToChangeToSchedule); 118 | 119 | // new line separator, "\n" didn't work for some reason ¯\_(ツ)_/¯ 120 | $messages[] = ''; 121 | } 122 | 123 | if ($realtimeLockedIndexers) { 124 | $messages[] = "The following indexers will be locked to \"Update on Save\":\n" 125 | . implode("\n", $realtimeLockedIndexers); 126 | 127 | // new line separator, "\n" didn't work for some reason ¯\_(ツ)_/¯ 128 | $messages[] = ''; 129 | } 130 | 131 | if ($scheduleLockedIndexers) { 132 | $messages[] = "The following indexers will be locked to \"Update by Schedule\":\n" 133 | . implode("\n", $scheduleLockedIndexers); 134 | 135 | // new line separator, "\n" didn't work for some reason ¯\_(ツ)_/¯ 136 | $messages[] = ''; 137 | } 138 | 139 | if ($messages) { 140 | $messages[] = 'All other indexers will be unlocked.'; 141 | } 142 | 143 | return $messages; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Model/Config/Validator.php: -------------------------------------------------------------------------------- 1 | deploymentConfig = $deploymentConfig; 49 | $this->indexerCollectionFactory = $indexerCollectionFactory; 50 | $this->logger = $logger; 51 | } 52 | 53 | /** 54 | * Read indexer configuration from app/etc/config.php 55 | * 56 | * @return array 57 | */ 58 | public function getIndexerConfig(): array 59 | { 60 | if (!$this->indexerConfig) { 61 | try { 62 | $this->indexerConfig = $this->deploymentConfig->get('indexers') ?? []; 63 | } catch (FileSystemException|RunTimeException $e) { 64 | $this->logger->error(__('Could not load indexer configuration from app/etc/config.php')); 65 | $this->indexerConfig = []; 66 | } 67 | } 68 | 69 | return $this->indexerConfig; 70 | } 71 | 72 | /** 73 | * Get indexer config as indexerId => lockedMode pairs. 74 | * 75 | * @return array 76 | */ 77 | public function getFlatIndexerConfig(): array 78 | { 79 | if (!$this->flatIndexerConfig) { 80 | $flatIndexerConfig = []; 81 | $indexerConfig = $this->getIndexerConfig(); 82 | 83 | foreach ($indexerConfig as $mode => $indexers) { 84 | foreach ($indexers as $indexer) { 85 | $flatIndexerConfig[$indexer] = $mode; 86 | } 87 | } 88 | 89 | $this->flatIndexerConfig = $flatIndexerConfig; 90 | } 91 | 92 | return $this->flatIndexerConfig; 93 | } 94 | 95 | /** 96 | * Determine whether a given indexer ID should be locked to a particular mode. 97 | * 98 | * @param string $indexerId 99 | * @return bool 100 | */ 101 | public function isIndexerLocked(string $indexerId): bool 102 | { 103 | return array_key_exists($indexerId, $this->getFlatIndexerConfig()); 104 | } 105 | 106 | /** 107 | * Map view ID to indexer ID. 108 | * 109 | * @return array 110 | */ 111 | public function getViewIdToIndexerIdMap(): array 112 | { 113 | if (!$this->viewIdToIndexerIdMap) { 114 | /** @var Indexer $indexer */ 115 | foreach ($this->indexerCollectionFactory->create()->getItems() as $indexer) { 116 | $this->viewIdToIndexerIdMap[$indexer->getViewId()] = $indexer->getId(); 117 | } 118 | } 119 | 120 | return $this->viewIdToIndexerIdMap; 121 | } 122 | 123 | /** 124 | * Get the indexer ID for the given view ID. 125 | * 126 | * @param string|null $viewId 127 | * @return string 128 | */ 129 | public function getIndexerIdForViewId(?string $viewId): string 130 | { 131 | $map = $this->getViewIdToIndexerIdMap(); 132 | 133 | return array_key_exists($viewId, $map) ? $map[$viewId] : ''; 134 | } 135 | 136 | /** 137 | * Get the indexers configured to be in the given mode. 138 | * 139 | * @param string $mode 140 | * @param array $indexerConfig 141 | * @return array 142 | */ 143 | public function getIndexersByMode(string $mode, array $indexerConfig = []): array 144 | { 145 | $indexerConfig = $indexerConfig ?: $this->getIndexerConfig(); 146 | 147 | return array_key_exists($mode, $indexerConfig) 148 | ? $indexerConfig[$mode] 149 | : []; 150 | } 151 | 152 | /** 153 | * Determine if a given indexer is in a given mode, according to a set of given indexer configuration. 154 | * 155 | * @param string $indexerId 156 | * @param string $mode 157 | * @param array $indexerConfig 158 | * @return bool 159 | */ 160 | public function indexerHasMode(string $indexerId, string $mode, array $indexerConfig = []): bool 161 | { 162 | $indexerConfig = $indexerConfig ?: $this->getIndexerConfig(); 163 | $modeIndexers = array_key_exists($mode, $indexerConfig) ? $indexerConfig[$mode] : []; 164 | 165 | return in_array($indexerId, $modeIndexers); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /Plugin/SetIndexerMode.php: -------------------------------------------------------------------------------- 1 | indexerConfig = $indexerConfig; 39 | $this->messageManager = $messageManager; 40 | $this->indexerMode = $indexerMode; 41 | } 42 | 43 | /** 44 | * Ensure indexer mode remains in the mode defined by deploy config. 45 | * 46 | * @param StateInterface $subject 47 | * @param string $mode 48 | * @return string[] 49 | */ 50 | public function beforeSetMode( 51 | StateInterface $subject, 52 | string $mode 53 | ): array { 54 | if (!$this->indexerConfig->getIndexerConfig() 55 | || !($indexerId = $this->indexerConfig->getIndexerIdForViewId($subject->getViewId())) 56 | || !$this->indexerConfig->isIndexerLocked($indexerId) 57 | ) { 58 | return [$mode]; // no indexers should be locked, could not find indexer ID, or indexer is not mode-locked 59 | } 60 | 61 | $isBeingScheduled = $mode === 'enabled'; 62 | $shouldBeScheduled = $this->indexerConfig->indexerHasMode($indexerId, IndexerMode::INPUT_KEY_SCHEDULE); 63 | $shouldBeRealTime = $this->indexerConfig->indexerHasMode($indexerId, IndexerMode::INPUT_KEY_REALTIME); 64 | 65 | if ($shouldBeScheduled && !$isBeingScheduled) { 66 | return ['enabled']; // maintain on schedule status 67 | } else if ($shouldBeRealTime && $isBeingScheduled) { 68 | return ['disabled']; // maintain on save status 69 | } 70 | 71 | return [$mode]; 72 | } 73 | 74 | /** 75 | * Ensure indexer mode remains in the mode defined by deploy config. 76 | * 77 | * @param $subject 78 | * @param $key 79 | * @param $value 80 | * @return array 81 | */ 82 | public function beforeSetData( 83 | $subject, 84 | $key, 85 | $value = null 86 | ) { 87 | if (!($subject instanceof StateInterface) 88 | || $key !== 'mode' 89 | || !$this->indexerConfig->getIndexerConfig() 90 | || !($indexerId = $this->indexerConfig->getIndexerIdForViewId($subject->getViewId())) 91 | || !$this->indexerConfig->isIndexerLocked($indexerId) 92 | ) { 93 | // not an indexer state, not setting mode data, no indexers should be locked, cannot find indexer ID, or indexer is not mode-locked 94 | return [$key, $value]; 95 | } 96 | 97 | $isBeingScheduled = null; 98 | $shouldBeScheduled = $this->indexerConfig->indexerHasMode($indexerId, IndexerMode::INPUT_KEY_SCHEDULE); 99 | $shouldBeRealTime = $this->indexerConfig->indexerHasMode($indexerId, IndexerMode::INPUT_KEY_REALTIME); 100 | 101 | if ($key === (array)$key) { 102 | $mode = array_key_exists('mode', $key) ? $key['mode'] : null; 103 | 104 | if ($mode !== null) { 105 | $isBeingScheduled = $mode === 'enabled'; 106 | } 107 | } elseif ($value !== null) { 108 | $isBeingScheduled = $value === 'enabled'; 109 | } 110 | 111 | if ($isBeingScheduled !== null) { 112 | if ($shouldBeScheduled && !$isBeingScheduled) { 113 | $value = 'enabled'; // maintain on schedule status 114 | } else if ($shouldBeRealTime && $isBeingScheduled) { 115 | $value = 'disabled'; // maintain on save status 116 | } 117 | } 118 | 119 | return [$key, $value]; 120 | } 121 | 122 | /** 123 | * Prevent indexers from changing modes via the admin based on deploy configuration. 124 | * 125 | * @param MassChangelog|MassOnTheFly $subject 126 | * @param callable $proceed 127 | * @return void 128 | */ 129 | public function aroundExecute( 130 | $subject, 131 | callable $proceed 132 | ) { 133 | if (!($configuredIndexers = $this->indexerConfig->getIndexerConfig())) { 134 | return $proceed(); 135 | } 136 | 137 | $removedIndexers = []; 138 | $indexerIdsToUpdate = $subject->getRequest()->getParam('indexer_ids'); 139 | 140 | foreach ($indexerIdsToUpdate as $key => $indexerToUpdate) { 141 | if ($this->indexerConfig->indexerHasMode($indexerToUpdate, $this->indexerMode, $configuredIndexers)) { 142 | unset($indexerIdsToUpdate[$key]); 143 | $removedIndexers[] = $indexerToUpdate; 144 | } 145 | } 146 | 147 | if ($removedIndexers) { 148 | $subject->getRequest()->setParam('indexer_ids', $indexerIdsToUpdate); 149 | $this->messageManager->addErrorMessage( 150 | __( 151 | 'Cannot update the following indexer(s) because they are locked by configuration: %1', 152 | implode(', ', $removedIndexers) 153 | ) 154 | ); 155 | } 156 | 157 | $proceed(); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /Plugin/SetIndexerModeRealtime.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

element119 | Indexer Deploy Config

8 | 9 |

A Magento 2 module that allows developers to lock indexer modes via deployment config.

10 | 11 |
12 | 13 |
14 | 15 | ![github release](https://img.shields.io/github/v/release/pykettk/module-indexer-deploy-config?color=ffbf00&label=version) 16 | ![github release date](https://img.shields.io/github/release-date/pykettk/module-indexer-deploy-config?color=8b32a8&label=last%20release) 17 | ![license](https://img.shields.io/badge/license-OSL-ff00dd.svg) 18 | ![packagist downloads](https://img.shields.io/packagist/dt/element119/module-indexer-deploy-config?color=ff0000) 19 | 20 |
21 | 22 | ## 📝 Features 23 | ✔️ Allows you to selectively lock indexer modes via the `app/etc/config.php` file 24 | 25 | ✔️ Indexer configuration validated and imported as part of `app:config:import` 26 | 27 | ✔️ Supports custom indexers 28 | 29 | ✔️ Provides messaging for admins to see which indexers are locked via deploy config 30 | 31 | ✔️ Informs admins when they try to change indexer modes that are locked via deploy config 32 | 33 | ✔️ Supports Magento Open Source and Adobe Commerce 34 | 35 | ✔️ Supports Hyvä and Luma based themes 36 | 37 | ✔️ Seamless integration with Magento 38 | 39 | ✔️ Built with developers and extensibility in mind to make customisations as easy as possible 40 | 41 | ✔️ Installable via Composer 42 | 43 |
44 | 45 | ## 🔌 Installation 46 | Run the following command to *install* this module: 47 | ```bash 48 | composer require element119/module-indexer-deploy-config 49 | php bin/magento setup:upgrade 50 | ``` 51 | 52 |
53 | 54 | ## ⏫ Updating 55 | Run the following command to *update* this module: 56 | ```bash 57 | composer update element119/module-indexer-deploy-config 58 | php bin/magento setup:upgrade 59 | ``` 60 | 61 |
62 | 63 | ## ❌ Uninstallation 64 | Run the following command to *uninstall* this module: 65 | ```bash 66 | composer remove element119/module-indexer-deploy-config 67 | php bin/magento setup:upgrade 68 | ``` 69 | 70 |
71 | 72 | ## 📚 User Guide 73 | ### Locking Indexer Modes 74 | 1. Add a new `indexers` array to the `app/etc/config.php` file 75 | 2. Add the `realtime` or `schedule` arrays to the `indexers` array as required 76 | 3. Specify the indexer IDs you want to lock to a specific mode within the respective mode array 77 | 78 | ### Example 79 | ```php 80 | 'indexers' => [ 81 | 'realtime' => [ 82 | 'catalogrule_rule', 83 | 'design_config_grid', 84 | ], 85 | 'schedule' => [ 86 | 'catalog_category_product', 87 | 'catalog_product_category', 88 | 'catalog_product_attribute', 89 | 'catalog_product_price', 90 | ], 91 | ], 92 | ``` 93 | 94 |
95 | 96 | > **Note** 97 | > 98 | > Empty indexer mode arrays may be omitted in the cases where you don't want to lock any indexers to that mode. 99 | 100 |
101 | 102 | ### Indexer Mode Locking Cron Fallback 103 | A new system configuration option allows you to enable a cron job that will ensure indexers are in the mode they are 104 | supposed to be in, according to deployment config. This option can be found in `Stores -> Configuration -> Advanced -> 105 | System -> Indexer Mode Locking`. 106 | 107 | ![indexer-mode-locking-cron-config](https://user-images.githubusercontent.com/40261741/221367876-d04e812d-9628-4bb2-a335-8532dd27299e.png) 108 | 109 |
110 | 111 | ### `indexer:lock-all` Command 112 | The module adds a new `indexer:lock-all` command that you can use to lock the indexer modes via the command line. 113 | 114 | ``` 115 | Description: 116 | Lock all indexers 117 | 118 | Usage: 119 | indexer:lock-all [options] 120 | 121 | Options: 122 | -m, --mode=MODE Passing one of two modes (schedule, realtime) will lock all indexers to that mode. 123 | -h, --help Display this help message 124 | -q, --quiet Do not output any message 125 | -V, --version Display this application version 126 | --ansi Force ANSI output 127 | --no-ansi Disable ANSI output 128 | -n, --no-interaction Do not ask any interactive question 129 | -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug 130 | ``` 131 | 132 | > **Note** 133 | > 134 | > You will need to run `app:config:import` after indexer modes have been set, unset, or changed in the deploy config. 135 | > 136 | > Due to the fact that this new command writes to the deploy config files and this module makes 137 | [additions to the deploy config pool](https://github.com/pykettk/module-indexer-deploy-config/blob/master/etc/di.xml#L26-L39), 138 | any automated deployment pipelines will need to run `app:config:import` in non-interactive mode by passing either 139 | `-n` or `--no-interaction` as command options to avoid [the usual prompt](https://github.com/pykettk/module-indexer-deploy-config/blob/master/Model/Config/Importer.php#L72-L144). 140 | 141 |
142 | 143 | ![no command arguments](https://user-images.githubusercontent.com/40261741/200428379-36934940-cf7a-43f7-9ba3-3358dd97a0de.png) 144 | 145 | *No arguments locks the indexer modes to their current state.* 146 | 147 |
148 | 149 | ![realtime argument](https://user-images.githubusercontent.com/40261741/200428676-cdb44054-19a8-4421-a4f8-bf9fbc93cbb6.png) 150 | 151 | *Passing `-m realtime` as the argument sets all indexers to `Update on Save`.* 152 | 153 |
154 | 155 | ![schedule argument](https://user-images.githubusercontent.com/40261741/200428778-f4441b0d-67ec-4911-b612-ad1a47a96558.png) 156 | 157 | *Passing `-m schedule` as the argument sets all indexers to `Update by Schedule`.* 158 | 159 |
160 | 161 | ### Restricted Admin Controls 162 | ![restrictded-admin-controls](https://user-images.githubusercontent.com/40261741/200190327-5e9f5204-d294-4a27-a27e-74fb6ea6b968.png) 163 | 164 |
165 | -------------------------------------------------------------------------------- /Scope/ModuleConfig.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 26 | } 27 | 28 | /** 29 | * @return bool 30 | */ 31 | public function isCronFallbackEnabled(): bool 32 | { 33 | return $this->scopeConfig->isSetFlag(self::XML_PATH_CRON_FALLBACK_ENABLED); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element119/module-indexer-deploy-config", 3 | "type": "magento2-module", 4 | "description": "A Magento 2 module that allows developers to lock indexer modes via deployment config.", 5 | "license": "OSL-3.0", 6 | "authors": [ 7 | { 8 | "name": "Kiel Pykett", 9 | "email": "pykettk@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "magento/module-indexer": "^100.0", 14 | "php": "^7.4 || ^8.0" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Element119\\IndexerDeployConfig\\": "" 19 | }, 20 | "files": [ 21 | "registration.php" 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /etc/adminhtml/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /etc/adminhtml/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 |
12 | 19 | 20 | 28 | 29 | 30 | 33 | This is a fallback mechanism designed to catch unexpected behaviour that causes indexer modes to change. 34 | ]]> 35 | 36 | Magento\Config\Model\Config\Source\Yesno 37 | 38 | 39 |
40 |
41 |
42 | -------------------------------------------------------------------------------- /etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 13 | 0 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /etc/crontab.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 14 | * * * * * 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /etc/crontab/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 13 | 14 | Element119\IndexerDeployConfig\Console\Command\IndexerLockAll 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Element119\IndexerDeployConfig\Model\Config\Importer 26 | 27 | 28 | Element119\IndexerDeployConfig\Model\Config\Validator 29 | 30 | 1000 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /etc/frontend/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /etc/graphql/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /etc/webapi_rest/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /etc/webapi_soap/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 15 | 16 | Mode Locked 17 | 18 | Element119\IndexerDeployConfig\Block\Backend\Grid\Column\Renderer\ModeLocked 19 | 20 | 0 21 | 22 | 23 | 24 | 25 | 26 | --------------------------------------------------------------------------------