Smile-SA/magento2-module-custom-entity

View on GitHub
Controller/Router.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php

declare(strict_types=1);

namespace Smile\CustomEntity\Controller;

use Exception;
use Magento\Framework\App\Action\Forward;
use Magento\Framework\App\ActionFactory;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\Request\Http as HttpRequest;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\RouterInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\UrlInterface;
use Smile\CustomEntity\Model\CustomEntity;
use Smile\CustomEntity\Model\CustomEntity\AttributeSet\Url;

/**
 * Custom entity router.
 */
class Router implements RouterInterface
{
    private Url $urlSetModel;

    private ActionFactory $actionFactory;

    private CustomEntity $customEntity;

    /**
     * Router constructor.
     *
     * @param ActionFactory $actionFactory Action factory.
     * @param Url $urlSetModel Attribute set url model.
     * @param CustomEntity $customEntity Custom entity model.
     */
    public function __construct(
        ActionFactory $actionFactory,
        Url $urlSetModel,
        CustomEntity $customEntity
    ) {
        $this->urlSetModel = $urlSetModel;
        $this->actionFactory = $actionFactory;
        $this->customEntity = $customEntity;
    }

    /**
     * Match application action by request
     *
     * @param RequestInterface|HttpRequest $request Request.
     * @return ActionInterface|null
     */
    // @codingStandardsIgnoreLine Match function is allow in router (MEQP2.Classes.PublicNonInterfaceMethods.PublicMethodFound)
    public function match(RequestInterface $request)
    {
        /** @var HttpRequest $request */
        $requestPath = trim($request->getPathInfo(), '/');
        $requestPathArray = explode('/', $requestPath);
        if (
            !$this->isValidPath($requestPathArray)
            || $request->getAlias(UrlInterface::REWRITE_REQUEST_PATH_ALIAS)
        ) {
            // Continuing with processing of this URL.
            return null;
        }

        try {
            $entityId = $this->matchCustomEntity($requestPathArray);
            $request->setAlias(UrlInterface::REWRITE_REQUEST_PATH_ALIAS, $requestPath)
                ->setModuleName('custom_entity')
                ->setControllerName($this->getControllerName($requestPathArray))
                ->setActionName('view')
                ->setParam('entity_id', $entityId);
        } catch (Exception $e) {
            // Continuing with processing of this URL.
            return null;
        }

        return $this->actionFactory->create(
            Forward::class
        );
    }

    /**
     * Match custom entity.
     *
     * @param array $requestPathArray Request path array
     * @return mixed
     * @throws NoSuchEntityException
     * @throws NotFoundException
     */
    private function matchCustomEntity(array $requestPathArray)
    {
        $entityId = $customEntitySetId = $this->urlSetModel->checkIdentifier(array_shift($requestPathArray));
        if (!empty($requestPathArray) && $customEntitySetId) {
            $entityId = $this->customEntity->checkIdentifier(current($requestPathArray), $entityId);
        }

        return $entityId;
    }

    /**
     * Return controller name.
     *
     * @param array $requestPathArray Request path array.
     */
    private function getControllerName(array $requestPathArray): string
    {
        return $this->isCustomEntitySet($requestPathArray) ? 'set' : 'entity';
    }

    /**
     * Return true if we want to see a set of custom entity.
     *
     * @param array $requestPathArray Request path array.
     */
    private function isCustomEntitySet(array $requestPathArray): bool
    {
        return count($requestPathArray) == 1;
    }

    /**
     * Return true if current request is allow into this router.
     *
     * @param array $requestPathArray Request path array.
     */
    private function isValidPath(array $requestPathArray): bool
    {
        return count($requestPathArray) > 0 && count($requestPathArray) <= 2;
    }
}