staempfli/magento2-module-rebuild-url-rewrite

View on GitHub
Console/Command/RebuildCommand.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php
declare(strict_types=1);
/**
 * Copyright © 2018 Stämpfli AG. All rights reserved.
 * @author marcel.hauri@staempfli.com
 */

namespace Staempfli\RebuildUrlRewrite\Console\Command;

use Magento\Framework\App\State;
use Magento\Store\Api\StoreRepositoryInterface;
use Staempfli\RebuildUrlRewrite\Model\UrlRewrite\Entity\ProductFactory;
use Staempfli\RebuildUrlRewrite\Model\UrlRewrite\Entity\CategoryFactory;
use Staempfli\RebuildUrlRewrite\Model\UrlRewrite\Entity\CmsFactory;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

final class RebuildCommand extends Command
{
    const INPUT_STORES = 'stores';
    const INPUT_PRODUCTS = 'products';
    const INPUT_CATEGORIES = 'categories';
    const INPUT_ENTITY = 'entities';

    /**
     * @var State
     */
    private $appState;
    /**
     * @var StoreRepositoryInterface
     */
    private $storeRepository;
    /**
     * @var ProductFactory
     */
    private $productFactory;
    /**
     * @var CategoryFactory
     */
    private $categoryFactory;
    /**
     * @var CmsFactory
     */
    private $cmsFactory;
    /**
     * @var InputInterface
     */
    private $input;

    public function __construct(
        State $appState,
        StoreRepositoryInterface $storeRepository,
        ProductFactory $productFactory,
        CategoryFactory $categoryFactory,
        CmsFactory $cmsFactory,
        $name = null
    ) {
        $this->appState = $appState;
        $this->storeRepository = $storeRepository;
        $this->productFactory = $productFactory;
        $this->categoryFactory = $categoryFactory;
        $this->cmsFactory = $cmsFactory;
        parent::__construct($name);
    }

    protected function configure()
    {
        $this->setName('urlrewrite:rebuild')
            ->setDescription('Rebuild url rewrites of products and categories')
            ->setDefinition([
                new InputOption(
                    self::INPUT_STORES,
                    's',
                    InputArgument::OPTIONAL,
                    "Store ID's"
                ),
                new InputOption(
                    self::INPUT_PRODUCTS,
                    'p',
                    InputArgument::OPTIONAL,
                    "Product ID's"
                ),
                new InputOption(
                    self::INPUT_CATEGORIES,
                    'c',
                    InputArgument::OPTIONAL,
                    "Category ID's"
                ),
                new InputArgument(
                    self::INPUT_ENTITY,
                    InputArgument::REQUIRED,
                    "Available entities [categories,products,cms-pages]"
                ),
            ]);
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;

        try {
            $this->appState->getAreaCode();
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $this->appState->setAreaCode('adminhtml');
        }

        $stores = $this->getAllStoreIds();
        $argument = $this->getArgumentValue(self::INPUT_ENTITY);

        foreach ($stores as $storeId => $storeCode) {
            if ($argument && in_array('categories', $argument)) {
                $output->writeln(sprintf('Rebuild category urls for store: [%s]', $storeCode));
                $this->categoryFactory->create()->rebuild($storeId, $this->getOptionValue(self::INPUT_CATEGORIES));
            }

            if ($argument && in_array('products', $argument)) {
                $output->writeln(sprintf('Rebuild product urls for store: [%s]', $storeCode));
                $this->productFactory->create()->rebuild($storeId, $this->getOptionValue(self::INPUT_PRODUCTS));
            }

            if ($argument && in_array('cms-pages', $argument)) {
                $output->writeln(sprintf('Rebuild cms urls for store: [%s]', $storeCode));
                $this->cmsFactory->create()->rebuild($storeId);
            }
        }
    }

    /**
     * @return array
     */
    private function getAllStoreIds(): array
    {
        $data = [];
        $stores = $this->storeRepository->getList() ?? [];
        $storeOptions = $this->getOptionValue(self::INPUT_STORES);

        foreach ($stores as $store) {
            if ((int)$store->getId() === 0 || !$store->isActive()) {
                continue;
            }
            if ($storeOptions && !\in_array($store->getId(), $storeOptions, false)) {
                continue;
            }
            $data[(int)$store->getId()] = $store->getCode();
        }
        return $data;
    }

    /**
     * @param string $option
     * @return array
     */
    private function getOptionValue(string $option): array
    {
        $value = $this->input->getOption($option) ?? '';
        return $this->getFilteredValue($value);
    }

    /**
     * @param string $argument
     * @return array
     */
    private function getArgumentValue(string $argument) : array
    {
        $value = $this->input->getArgument($argument) ?? '';
        return $this->getFilteredValue($value);
    }

    /**
     * @param string $value
     * @return array
     */
    private function getFilteredValue(string $value) : array
    {
        return array_filter(explode(',', trim($value, '= ')));
    }
}