1<?php
2/**
3 * Copyright since 2007 PrestaShop SA and Contributors
4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5 *
6 * NOTICE OF LICENSE
7 *
8 * This source file is subject to the Open Software License (OSL 3.0)
9 * that is bundled with this package in the file LICENSE.md.
10 * It is also available through the world-wide-web at this URL:
11 * https://opensource.org/licenses/OSL-3.0
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@prestashop.com so we can send you a copy immediately.
15 *
16 * DISCLAIMER
17 *
18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19 * versions in the future. If you wish to customize PrestaShop for your
20 * needs please refer to https://devdocs.prestashop.com/ for more information.
21 *
22 * @author    PrestaShop SA and Contributors <contact@prestashop.com>
23 * @copyright Since 2007 PrestaShop SA and Contributors
24 * @license   https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25 */
26
27namespace PrestaShopBundle\Routing\Converter;
28
29use PrestaShopBundle\Routing\Converter\Exception\RouteNotFoundException;
30
31/**
32 * Class AbstractLegacyRouteProvider.
33 */
34abstract class AbstractLegacyRouteProvider implements LegacyRouteProviderInterface
35{
36    /**
37     * @var array|null
38     */
39    protected $controllersActions;
40
41    /**
42     * This is the only method that child classes need to implement.
43     *
44     * @return LegacyRoute[]
45     */
46    abstract public function getLegacyRoutes();
47
48    /**
49     * @return array
50     */
51    public function getControllersActions()
52    {
53        $this->initControllerActions();
54
55        return $this->controllersActions;
56    }
57
58    /**
59     * {@inheritdoc}
60     */
61    public function getActionsByController($controller)
62    {
63        $this->initControllerActions();
64
65        $controllerActions = $this->getControllerActions($controller);
66        if (null === $controllerActions) {
67            throw new RouteNotFoundException(sprintf('Could not find a route matching for legacy controller: %s', $controller));
68        }
69
70        return array_keys($controllerActions);
71    }
72
73    /**
74     * {@inheritdoc}
75     */
76    public function getLegacyRouteByAction($controller, $action)
77    {
78        $this->initControllerActions();
79
80        $controllerActions = $this->getControllerActions($controller);
81        if (null === $controllerActions) {
82            throw new RouteNotFoundException(sprintf('Could not find a route matching for legacy controller: %s', $controller));
83        }
84
85        $action = LegacyRoute::isIndexAction($action) ? 'index' : $action;
86        $routeName = $this->getRouteName($controllerActions, $action);
87        if (null === $routeName) {
88            throw new RouteNotFoundException(sprintf('Could not find a route matching for legacy action: %s', $controller . ':' . $action));
89        }
90
91        return $this->getLegacyRoutes()[$routeName];
92    }
93
94    /**
95     * Get the route name.
96     *
97     * @param array $controllerActions
98     * @param string $action
99     *
100     * @return string|null
101     */
102    private function getRouteName(array $controllerActions, $action)
103    {
104        $routeName = null;
105        foreach ($controllerActions as $controllerAction => $actionRoute) {
106            if (strtolower($controllerAction) == strtolower($action)) {
107                $routeName = $actionRoute;
108                break;
109            }
110        }
111
112        if (is_array($routeName)) {
113            return $routeName[0];
114        }
115
116        return $routeName;
117    }
118
119    /**
120     * Init the controller actions has map.
121     */
122    private function initControllerActions()
123    {
124        if (null === $this->controllersActions) {
125            $this->controllersActions = [];
126            /** @var LegacyRoute $legacyRoute */
127            foreach ($this->getLegacyRoutes() as $legacyRoute) {
128                $this->controllersActions = array_merge_recursive($this->controllersActions, $legacyRoute->getControllersActions());
129            }
130        }
131    }
132
133    /**
134     * @param string $controller
135     *
136     * @return array|null
137     */
138    private function getControllerActions($controller)
139    {
140        $controllerActions = null;
141        foreach ($this->controllersActions as $listController => $actions) {
142            if (strtolower($listController) == strtolower($controller)) {
143                $controllerActions = $actions;
144                break;
145            }
146        }
147
148        return $controllerActions;
149    }
150}
151