Вход Регистрация
Файл: vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php
Строк: 329
<?php

namespace IlluminateRouting;

use 
ArrayIterator;
use 
Countable;
use 
IlluminateHttpRequest;
use 
IlluminateHttpResponse;
use 
IlluminateSupportStr;
use 
IteratorAggregate;
use 
LogicException;
use 
SymfonyComponentHttpKernelExceptionMethodNotAllowedHttpException;
use 
SymfonyComponentHttpKernelExceptionNotFoundHttpException;
use 
SymfonyComponentRoutingMatcherDumperCompiledUrlMatcherDumper;
use 
SymfonyComponentRoutingRouteCollection as SymfonyRouteCollection;
use 
Traversable;

abstract class 
AbstractRouteCollection implements CountableIteratorAggregateRouteCollectionInterface
{
    
/**
     * Handle the matched route.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  IlluminateRoutingRoute|null  $route
     * @return IlluminateRoutingRoute
     *
     * @throws SymfonyComponentHttpKernelExceptionNotFoundHttpException
     */
    
protected function handleMatchedRoute(Request $request$route)
    {
        if (! 
is_null($route)) {
            return 
$route->bind($request);
        }

        
// If no route was found we will now check if a matching route is specified by
        // another HTTP verb. If it is we will need to throw a MethodNotAllowed and
        // inform the user agent of which HTTP verb it should use for this route.
        
$others $this->checkForAlternateVerbs($request);

        if (
count($others) > 0) {
            return 
$this->getRouteForMethods($request$others);
        }

        throw new 
NotFoundHttpException(sprintf(
            
'The route %s could not be found.',
            
$request->path()
        ));
    }

    
/**
     * Determine if any routes match on another HTTP verb.
     *
     * @param  IlluminateHttpRequest  $request
     * @return array
     */
    
protected function checkForAlternateVerbs($request)
    {
        
$methods array_diff(Router::$verbs, [$request->getMethod()]);

        
// Here we will spin through all verbs except for the current request verb and
        // check to see if any routes respond to them. If they do, we will return a
        // proper error response with the correct headers on the response string.
        
return array_values(array_filter(
            
$methods,
            function (
$method) use ($request) {
                return ! 
is_null($this->matchAgainstRoutes($this->get($method), $requestfalse));
            }
        ));
    }

    
/**
     * Determine if a route in the array matches the request.
     *
     * @param  IlluminateRoutingRoute[]  $routes
     * @param  IlluminateHttpRequest  $request
     * @param  bool  $includingMethod
     * @return IlluminateRoutingRoute|null
     */
    
protected function matchAgainstRoutes(array $routes$request$includingMethod true)
    {
        [
$fallbacks$routes] = collect($routes)->partition(function ($route) {
            return 
$route->isFallback;
        });

        return 
$routes->merge($fallbacks)->first(
            
fn (Route $route) => $route->matches($request$includingMethod)
        );
    }

    
/**
     * Get a route (if necessary) that responds when other available methods are present.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  string[]  $methods
     * @return IlluminateRoutingRoute
     *
     * @throws SymfonyComponentHttpKernelExceptionMethodNotAllowedHttpException
     */
    
protected function getRouteForMethods($request, array $methods)
    {
        if (
$request->isMethod('OPTIONS')) {
            return (new 
Route('OPTIONS'$request->path(), function () use ($methods) {
                return new 
Response(''200, ['Allow' => implode(','$methods)]);
            }))->
bind($request);
        }

        
$this->requestMethodNotAllowed($request$methods$request->method());
    }

    
/**
     * Throw a method not allowed HTTP exception.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  array  $others
     * @param  string  $method
     * @return void
     *
     * @throws SymfonyComponentHttpKernelExceptionMethodNotAllowedHttpException
     */
    
protected function requestMethodNotAllowed($request, array $others$method)
    {
        throw new 
MethodNotAllowedHttpException(
            
$others,
            
sprintf(
                
'The %s method is not supported for route %s. Supported methods: %s.',
                
$method,
                
$request->path(),
                
implode(', '$others)
            )
        );
    }

    
/**
     * Throw a method not allowed HTTP exception.
     *
     * @param  array  $others
     * @param  string  $method
     * @return void
     *
     * @deprecated use requestMethodNotAllowed
     *
     * @throws SymfonyComponentHttpKernelExceptionMethodNotAllowedHttpException
     */
    
protected function methodNotAllowed(array $others$method)
    {
        throw new 
MethodNotAllowedHttpException(
            
$others,
            
sprintf(
                
'The %s method is not supported for this route. Supported methods: %s.',
                
$method,
                
implode(', '$others)
            )
        );
    }

    
/**
     * Compile the routes for caching.
     *
     * @return array
     */
    
public function compile()
    {
        
$compiled $this->dumper()->getCompiledRoutes();

        
$attributes = [];

        foreach (
$this->getRoutes() as $route) {
            
$attributes[$route->getName()] = [
                
'methods' => $route->methods(),
                
'uri' => $route->uri(),
                
'action' => $route->getAction(),
                
'fallback' => $route->isFallback,
                
'defaults' => $route->defaults,
                
'wheres' => $route->wheres,
                
'bindingFields' => $route->bindingFields(),
                
'lockSeconds' => $route->locksFor(),
                
'waitSeconds' => $route->waitsFor(),
                
'withTrashed' => $route->allowsTrashedBindings(),
            ];
        }

        return 
compact('compiled''attributes');
    }

    
/**
     * Return the CompiledUrlMatcherDumper instance for the route collection.
     *
     * @return SymfonyComponentRoutingMatcherDumperCompiledUrlMatcherDumper
     */
    
public function dumper()
    {
        return new 
CompiledUrlMatcherDumper($this->toSymfonyRouteCollection());
    }

    
/**
     * Convert the collection to a Symfony RouteCollection instance.
     *
     * @return SymfonyComponentRoutingRouteCollection
     */
    
public function toSymfonyRouteCollection()
    {
        
$symfonyRoutes = new SymfonyRouteCollection;

        
$routes $this->getRoutes();

        foreach (
$routes as $route) {
            if (! 
$route->isFallback) {
                
$symfonyRoutes $this->addToSymfonyRoutesCollection($symfonyRoutes$route);
            }
        }

        foreach (
$routes as $route) {
            if (
$route->isFallback) {
                
$symfonyRoutes $this->addToSymfonyRoutesCollection($symfonyRoutes$route);
            }
        }

        return 
$symfonyRoutes;
    }

    
/**
     * Add a route to the SymfonyRouteCollection instance.
     *
     * @param  SymfonyComponentRoutingRouteCollection  $symfonyRoutes
     * @param  IlluminateRoutingRoute  $route
     * @return SymfonyComponentRoutingRouteCollection
     *
     * @throws LogicException
     */
    
protected function addToSymfonyRoutesCollection(SymfonyRouteCollection $symfonyRoutesRoute $route)
    {
        
$name $route->getName();

        if (
            ! 
is_null($name)
            && 
str_ends_with($name'.')
            && ! 
is_null($symfonyRoutes->get($name))
        ) {
            
$name null;
        }

        if (! 
$name) {
            
$route->name($this->generateRouteName());

            
$this->add($route);
        } elseif (! 
is_null($symfonyRoutes->get($name))) {
            throw new 
LogicException("Unable to prepare route [{$route->uri}] for serialization. Another route has already been assigned name [{$name}].");
        }

        
$symfonyRoutes->add($route->getName(), $route->toSymfonyRoute());

        return 
$symfonyRoutes;
    }

    
/**
     * Get a randomly generated route name.
     *
     * @return string
     */
    
protected function generateRouteName()
    {
        return 
'generated::'.Str::random();
    }

    
/**
     * Get an iterator for the items.
     *
     * @return ArrayIterator
     */
    
public function getIterator(): Traversable
    
{
        return new 
ArrayIterator($this->getRoutes());
    }

    
/**
     * Count the number of items in the collection.
     *
     * @return int
     */
    
public function count(): int
    
{
        return 
count($this->getRoutes());
    }
}
Онлайн: 0
Реклама