Merge all middlewares from group and parent-group.

@param RouteGroup $group The first route group.
@param array $middleWareList Swap of middlewares.

@return array All middlewares.
13055
private function getMiddleWareFromGroup(RouteGroup $group, array $middleWareList = [])
    {
        if ($group->middleWare) {
            $middleWareList = \array_merge($group->middleWare, $middleWareList);
        }
        if (\is_null($group->parentGroup)) {
            return $middleWareList;
        }
        return $this->getMiddleWareFromGroup($group->parentGroup, $middleWareList);
    }
748172
public function getMiddlewares(array $middlewares = []) : array
	{
		return $this->parent ? 
			$this->parent->getMiddlewares(array_merge($middlewares, $this->middlewares)) :
			array_merge($middlewares, $this->middlewares);
	}
268372
public function generateRoutesData(RouteParser $routeParser, DataGenerator $dataGenerator)
    {
        $routes = [];

        foreach ($this->routes as $name => $route) {
            if ($route['group']) {
                if (!isset($this->groups[$route['group']])) {
                    throw new \LogicException(sprintf(
                        'The route group "%s" is not found',
                        $route['group']
                    ));
                }
                $pattern = $this->groups[$route['group']][0] . $route['pattern'];
                $middlewares = array_merge($this->groups[$route['group']][1], $route['middlewares']);
            } else {
                $pattern = $route['pattern'];
                $middlewares = $route['middlewares'];
            }

            $routeDatas = $routeParser->parse($pattern);
            $this->addToDataGenerator($route['methods'], $routeDatas, $name, $dataGenerator);

            $routes[$name] = [
                'datas' => $routeDatas,
                'methods' => $route['methods'],
                'pattern' => $pattern,
                'middlewares' => $middlewares,
                'handler' => $route['handler'],
                'group' => $route['group']
            ];
        }

        return ['routes' => $routes, 'dispatch_data' => $dataGenerator->getData()];
    }
390047
protected static function parseMiddlewareGroup($name, $map, $middlewareGroups)
    {
        $results = [];

        foreach ($middlewareGroups[$name] as $middleware) {
            // If the middleware is another middleware group we will pull in the group and
            // merge its middleware into the results. This allows groups to conveniently
            // reference other groups without needing to repeat all their middlewares.
            if (isset($middlewareGroups[$middleware])) {
                $results = array_merge($results, static::parseMiddlewareGroup(
                    $middleware, $map, $middlewareGroups
                ));

                continue;
            }

            [$middleware, $parameters] = array_pad(
                explode(':', $middleware, 2), 2, null
            );

            // If this middleware is actually a route middleware, we will extract the full
            // class name out of the middleware list now. Then we'll add the parameters
            // back onto this class' name so the pipeline will properly extract them.
            if (isset($map[$middleware])) {
                $middleware = $map[$middleware];
            }

            $results[] = $middleware.($parameters ? ':'.$parameters : '');
        }

        return $results;
    }
320651
private function readExtraContainerConfiguratorsAndMiddleware(string $routesFolder, string $commandName): array
    {
        $routesFilter = new class ($commandName) implements RoutesInterface
        {
            use CheckCallableTrait;

            /** @var array */
            private $middleware = [];

            /** @var array */
            private $configurators = [];

            /** @var string */
            private $commandName;

            /**
             * @param string $commandName
             */
            public function __construct(string $commandName)
            {
                $this->commandName = $commandName;
            }

            /**
             * @inheritdoc
             */
            public function addGlobalMiddleware(array $middleware): RoutesInterface
            {
                assert($this->checkMiddlewareCallables($middleware) === true);

                $this->middleware = array_merge($this->middleware, $middleware);

                return $this;
            }

            /**
             * @inheritdoc
             */
            public function addGlobalContainerConfigurators(array $configurators): RoutesInterface
            {
                assert($this->checkConfiguratorCallables($configurators) === true);

                $this->configurators = array_merge($this->configurators, $configurators);

                return $this;
            }

            /**
             * @inheritdoc
             */
            public function addCommandMiddleware(string $name, array $middleware): RoutesInterface
            {
                assert($this->checkMiddlewareCallables($middleware) === true);

                if ($this->commandName === $name) {
                    $this->middleware = array_merge($this->middleware, $middleware);
                }

                return $this;
            }

            /**
             * @inheritdoc
             */
            public function addCommandContainerConfigurators(string $name, array $configurators): RoutesInterface
            {
                assert($this->checkConfiguratorCallables($configurators) === true);

                if ($this->commandName === $name) {
                    $this->configurators = array_merge($this->configurators, $configurators);
                }

                return $this;
            }

            /**
             * @return array
             */
            public function getMiddleware(): array
            {
                return $this->middleware;
            }

            /**
             * @return array
             */
            public function getConfigurators(): array
            {
                return $this->configurators;
            }

            /**
             * @param array $mightBeConfigurators
             *
             * @return bool
             */
            private function checkConfiguratorCallables(array $mightBeConfigurators): bool
            {
                $result = true;

                foreach ($mightBeConfigurators as $mightBeCallable) {
                    $result = $result === true &&
                        $this->checkPublicStaticCallable(
                            $mightBeCallable,
                            [LimoncelloContainerInterface::class],
                            'void'
                        );
                }

                return $result;
            }

            /**
             * @param array $mightBeMiddleware
             *
             * @return bool
             */
            private function checkMiddlewareCallables(array $mightBeMiddleware): bool
            {
                $result = true;

                foreach ($mightBeMiddleware as $mightBeCallable) {
                    $result = $result === true && $this->checkPublicStaticCallable(
                        $mightBeCallable,
                        [IoInterface::class, Closure::class, PsrContainerInterface::class],
                        'void'
                    );
                }

                return $result;
            }
        };

        foreach (static::selectClasses($routesFolder, RoutesConfiguratorInterface::class) as $class) {
            /** @var RoutesConfiguratorInterface $class */
            $class::configureRoutes($routesFilter);
        }

        return [$routesFilter->getConfigurators(), $routesFilter->getMiddleware()];
    }
709352
protected function gatherInvokerMiddleware($middleware)
    {
        $nameMiddleware = $this->config['name_middleware'] ?? [];
        $middlewareGroups = $this->config['middleware_groups'] ?? [];

        return Collection::make($middleware)->map(function ($middleware) use ($nameMiddleware, $middlewareGroups) {
            return (array) MiddlewareNameResolver::resolve($middleware, $nameMiddleware, $middlewareGroups);
        })->flatten()->all();
    }
136487
public function addGroup(string $name, string $prefix = '', array $middlewares = [])
    {
        $this->groups[$name] = [$prefix, $middlewares];
    }
136638
public function middleware(...$middleware): Router
    {
        foreach ($middleware as $handler) {
            $this->chains[] = $handler;
        }

        return $this;
    }
698359
private static function collectMiddlewares(
        string $className,
        string $methodName,
        Middlewares $middlewaresAnnotation
    ) {
        $classMiddlewares = [];
        foreach ($middlewaresAnnotation->getMiddlewares() as $middleware) {
            if ($middleware instanceof Middleware) {
                $classMiddlewares[] = $middleware->getClass();
            }
        }
        $classMiddlewares = array_unique($classMiddlewares);

        if (! empty($methodName)) {
            $scanMiddlewares = self::$middlewares[$className]['middlewares']['actions'][$methodName] ?? [];
            self::$middlewares[$className]['middlewares']['actions'][$methodName] = array_unique(array_merge($classMiddlewares,$scanMiddlewares));
        } else {
            $scanMiddlewares = self::$middlewares[$className]['middlewares']['group'] ?? [];
            self::$middlewares[$className]['middlewares']['group'] = array_unique(array_merge($classMiddlewares, $scanMiddlewares));
        }
    }
357040
protected function mergeGroupAttributesIntoRoute($route)
    {
        $action = $this->mergeWithLastGroup($route->getAction());

        $route->setAction($action);
    }
1064380
protected function registerRouteMiddleware(Router $router, Kernel $kernel): void
    {
        foreach ((array) $this->middleware as $middleware) {
            $kernel->pushMiddleware($middleware);
        }

        foreach ((array) $this->middlewareGroups as $key => $middleware) {
            $router->middlewareGroup($key, $middleware);
        }

        foreach ((array) $this->routeMiddleware as $key => $middleware) {
            $router->aliasMiddleware($key, $middleware);
        }
    }
221079
public function applyMiddleware($path, array $middleware)
    {
        foreach ($middleware as $name) {
            if (!$this->hasMiddleware($name) && !$this->hasMiddlewareGroup($name)) {
                $message = "Cannot apply '$name' middleware or middleware group to path '$path'. It has not been registered.";
                throw new RuntimeException($message);
            }
        }
        // Matches route element pattern in Cake\Routing\Route
        $path = '#^' . preg_quote($path, '#') . '#';
        $path = preg_replace('/\\\\:([a-z0-9-_]+(?<![-_]))/i', '[^/]+', $path);

        if (!isset($this->_middlewarePaths[$path])) {
            $this->_middlewarePaths[$path] = [];
        }
        $this->_middlewarePaths[$path] = array_merge($this->_middlewarePaths[$path], $middleware);

        return $this;
    }
627376
public static function group($route, $callback, $options = [])
    {
        app()->router->group($route, $callback, $options);
    }
944416
public function setMiddleware($middleware)
    {
        if($this->route)
            $this->route->setMiddleware($middleware);
        else
            $this->middlewares = array(array($middleware));

        return $this;
    }
1251886
public function getRouteGroup(string $groupName)
  {
    foreach ($this->routeGroups as $routeGroup)
    {
      if ( \strcasecmp($routeGroup->getName(),$groupName)==0 ) {
        return $routeGroup;
      }
    }

    return null;
  }
1037190
public function group(string $prefix, \Closure $callback, array $middleware = [], array $opts = []): void
    {
        // Backups
        $previousGroupPrefix = $this->currentGroupPrefix;
        $previousGroupOption = $this->currentGroupOption;
        $previousGroupChains = $this->currentGroupChains;

        $this->currentGroupOption = $opts;
        $this->currentGroupChains = $middleware;
        $this->currentGroupPrefix = $previousGroupPrefix . '/' . \trim($prefix, '/');

        // Run callback.
        $callback($this);

        // Reverts
        $this->currentGroupPrefix = $previousGroupPrefix;
        $this->currentGroupOption = $previousGroupOption;
        $this->currentGroupChains = $previousGroupChains;
    }
1170825
private function createExecutionChain($middlewareList)
    {
        $lastCallable = function () {
            // the final callable is a no-op
        };

        while ($middleware = array_pop($middlewareList)) {
            if (! $middleware instanceof Middleware) {
                throw InvalidMiddlewareException::forMiddleware($middleware);
            }

            $lastCallable = function ($command) use ($middleware, $lastCallable) {
                return $middleware->execute($command, $lastCallable);
            };
        }

        return $lastCallable;
    }