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

namespace IlluminateRouting;

use 
Closure;
use 
IlluminateSupportArr;
use 
IlluminateSupportStr;
use 
IlluminateHttpRequest;
use 
IlluminateHttpResponse;
use 
IlluminateSupportCollection;
use 
IlluminateContainerContainer;
use 
IlluminateDatabaseEloquentModel;
use 
IlluminateSupportTraitsMacroable;
use 
IlluminateContractsEventsDispatcher;
use 
PsrHttpMessageResponseInterface as PsrResponseInterface;
use 
SymfonyBridgePsrHttpMessageFactoryHttpFoundationFactory;
use 
IlluminateContractsRoutingRegistrar as RegistrarContract;
use 
SymfonyComponentHttpFoundationResponse as SymfonyResponse;
use 
SymfonyComponentHttpKernelExceptionNotFoundHttpException;

class 
Router implements RegistrarContract
{
    use 
Macroable;

    
/**
     * The event dispatcher instance.
     *
     * @var IlluminateContractsEventsDispatcher
     */
    
protected $events;

    
/**
     * The IoC container instance.
     *
     * @var IlluminateContainerContainer
     */
    
protected $container;

    
/**
     * The route collection instance.
     *
     * @var IlluminateRoutingRouteCollection
     */
    
protected $routes;

    
/**
     * The currently dispatched route instance.
     *
     * @var IlluminateRoutingRoute
     */
    
protected $current;

    
/**
     * The request currently being dispatched.
     *
     * @var IlluminateHttpRequest
     */
    
protected $currentRequest;

    
/**
     * All of the short-hand keys for middlewares.
     *
     * @var array
     */
    
protected $middleware = [];

    
/**
     * All of the middleware groups.
     *
     * @var array
     */
    
protected $middlewareGroups = [];

    
/**
     * The registered route value binders.
     *
     * @var array
     */
    
protected $binders = [];

    
/**
     * The globally available parameter patterns.
     *
     * @var array
     */
    
protected $patterns = [];

    
/**
     * The route group attribute stack.
     *
     * @var array
     */
    
protected $groupStack = [];

    
/**
     * All of the verbs supported by the router.
     *
     * @var array
     */
    
public static $verbs = ['GET''HEAD''POST''PUT''PATCH''DELETE''OPTIONS'];

    
/**
     * Create a new Router instance.
     *
     * @param  IlluminateContractsEventsDispatcher  $events
     * @param  IlluminateContainerContainer  $container
     * @return void
     */
    
public function __construct(Dispatcher $eventsContainer $container null)
    {
        
$this->events $events;
        
$this->routes = new RouteCollection;
        
$this->container $container ?: new Container;

        
$this->bind('_missing', function ($v) {
            return 
explode('/'$v);
        });
    }

    
/**
     * Register a new GET route with the router.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function get($uri$action null)
    {
        return 
$this->addRoute(['GET''HEAD'], $uri$action);
    }

    
/**
     * Register a new POST route with the router.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function post($uri$action null)
    {
        return 
$this->addRoute('POST'$uri$action);
    }

    
/**
     * Register a new PUT route with the router.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function put($uri$action null)
    {
        return 
$this->addRoute('PUT'$uri$action);
    }

    
/**
     * Register a new PATCH route with the router.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function patch($uri$action null)
    {
        return 
$this->addRoute('PATCH'$uri$action);
    }

    
/**
     * Register a new DELETE route with the router.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function delete($uri$action null)
    {
        return 
$this->addRoute('DELETE'$uri$action);
    }

    
/**
     * Register a new OPTIONS route with the router.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function options($uri$action null)
    {
        return 
$this->addRoute('OPTIONS'$uri$action);
    }

    
/**
     * Register a new route responding to all verbs.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function any($uri$action null)
    {
        
$verbs = ['GET''HEAD''POST''PUT''PATCH''DELETE'];

        return 
$this->addRoute($verbs$uri$action);
    }

    
/**
     * Register a new route with the given verbs.
     *
     * @param  array|string  $methods
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    
public function match($methods$uri$action null)
    {
        return 
$this->addRoute(array_map('strtoupper', (array) $methods), $uri$action);
    }

    
/**
     * Register an array of controllers with wildcard routing.
     *
     * @param  array  $controllers
     * @return void
     *
     * @deprecated since version 5.2.
     */
    
public function controllers(array $controllers)
    {
        foreach (
$controllers as $uri => $controller) {
            
$this->controller($uri$controller);
        }
    }

    
/**
     * Route a controller to a URI with wildcard routing.
     *
     * @param  string  $uri
     * @param  string  $controller
     * @param  array  $names
     * @return void
     *
     * @deprecated since version 5.2.
     */
    
public function controller($uri$controller$names = [])
    {
        
$prepended $controller;

        
// First, we will check to see if a controller prefix has been registered in
        // the route group. If it has, we will need to prefix it before trying to
        // reflect into the class instance and pull out the method for routing.
        
if (! empty($this->groupStack)) {
            
$prepended $this->prependGroupUses($controller);
        }

        
$routable = (new ControllerInspector)
                            ->
getRoutable($prepended$uri);

        
// When a controller is routed using this method, we use Reflection to parse
        // out all of the routable methods for the controller, then register each
        // route explicitly for the developers, so reverse routing is possible.
        
foreach ($routable as $method => $routes) {
            foreach (
$routes as $route) {
                
$this->registerInspected($route$controller$method$names);
            }
        }

        
$this->addFallthroughRoute($controller$uri);
    }

    
/**
     * Register an inspected controller route.
     *
     * @param  array   $route
     * @param  string  $controller
     * @param  string  $method
     * @param  array  $names
     * @return void
     *
     * @deprecated since version 5.2.
     */
    
protected function registerInspected($route$controller$method, &$names)
    {
        
$action = ['uses' => $controller.'@'.$method];

        
// If a given controller method has been named, we will assign the name to the
        // controller action array, which provides for a short-cut to method naming
        // so you don't have to define an individual route for these controllers.
        
$action['as'] = Arr::get($names$method);

        
$this->{$route['verb']}($route['uri'], $action);
    }

    
/**
     * Add a fallthrough route for a controller.
     *
     * @param  string  $controller
     * @param  string  $uri
     * @return void
     *
     * @deprecated since version 5.2.
     */
    
protected function addFallthroughRoute($controller$uri)
    {
        
$missing $this->any($uri.'/{_missing}'$controller.'@missingMethod');

        
$missing->where('_missing''(.*)');
    }

    
/**
     * Set the unmapped global resource parameters to singular.
     *
     * @return void
     */
    
public function singularResourceParameters()
    {
        
ResourceRegistrar::singularParameters();
    }

    
/**
     * Set the global resource parameter mapping.
     *
     * @param  array  $parameters
     * @return void
     */
    
public function resourceParameters(array $parameters = [])
    {
        
ResourceRegistrar::setParameters($parameters);
    }

    
/**
     * Register an array of resource controllers.
     *
     * @param  array  $resources
     * @return void
     */
    
public function resources(array $resources)
    {
        foreach (
$resources as $name => $controller) {
            
$this->resource($name$controller);
        }
    }

    
/**
     * Route a resource to a controller.
     *
     * @param  string  $name
     * @param  string  $controller
     * @param  array  $options
     * @return void
     */
    
public function resource($name$controller, array $options = [])
    {
        if (
$this->container && $this->container->bound('IlluminateRoutingResourceRegistrar')) {
            
$registrar $this->container->make('IlluminateRoutingResourceRegistrar');
        } else {
            
$registrar = new ResourceRegistrar($this);
        }

        
$registrar->register($name$controller$options);
    }

    
/**
     * Register the typical authentication routes for an application.
     *
     * @return void
     */
    
public function auth()
    {
        
// Authentication Routes...
        
$this->get('login''AuthAuthController@showLoginForm');
        
$this->post('login''AuthAuthController@login');
        
$this->get('logout''AuthAuthController@logout');

        
// Registration Routes...
        
$this->get('register''AuthAuthController@showRegistrationForm');
        
$this->post('register''AuthAuthController@register');

        
// Password Reset Routes...
        
$this->get('password/reset/{token?}''AuthPasswordController@showResetForm');
        
$this->post('password/email''AuthPasswordController@sendResetLinkEmail');
        
$this->post('password/reset''AuthPasswordController@reset');
    }

    
/**
     * Create a route group with shared attributes.
     *
     * @param  array  $attributes
     * @param  Closure  $callback
     * @return void
     */
    
public function group(array $attributesClosure $callback)
    {
        
$this->updateGroupStack($attributes);

        
// Once we have updated the group stack, we will execute the user Closure and
        // merge in the groups attributes when the route is created. After we have
        // run the callback, we will pop the attributes off of this group stack.
        
call_user_func($callback$this);

        
array_pop($this->groupStack);
    }

    
/**
     * Update the group stack with the given attributes.
     *
     * @param  array  $attributes
     * @return void
     */
    
protected function updateGroupStack(array $attributes)
    {
        if (! empty(
$this->groupStack)) {
            
$attributes $this->mergeGroup($attributesend($this->groupStack));
        }

        
$this->groupStack[] = $attributes;
    }

    
/**
     * Merge the given array with the last group stack.
     *
     * @param  array  $new
     * @return array
     */
    
public function mergeWithLastGroup($new)
    {
        return 
$this->mergeGroup($newend($this->groupStack));
    }

    
/**
     * Merge the given group attributes.
     *
     * @param  array  $new
     * @param  array  $old
     * @return array
     */
    
public static function mergeGroup($new$old)
    {
        
$new['namespace'] = static::formatUsesPrefix($new$old);

        
$new['prefix'] = static::formatGroupPrefix($new$old);

        if (isset(
$new['domain'])) {
            unset(
$old['domain']);
        }

        
$new['where'] = array_merge(
            isset(
$old['where']) ? $old['where'] : [],
            isset(
$new['where']) ? $new['where'] : []
        );

        if (isset(
$old['as'])) {
            
$new['as'] = $old['as'].(isset($new['as']) ? $new['as'] : '');
        }

        return 
array_merge_recursive(Arr::except($old, ['namespace''prefix''where''as']), $new);
    }

    
/**
     * Format the uses prefix for the new group attributes.
     *
     * @param  array  $new
     * @param  array  $old
     * @return string|null
     */
    
protected static function formatUsesPrefix($new$old)
    {
        if (isset(
$new['namespace'])) {
            return isset(
$old['namespace'])
                    ? 
trim($old['namespace'], '\').'\'.trim($new['namespace'], '\')
                    : trim($new['
namespace'], '\');
        }

        return isset($old['
namespace']) ? $old['namespace'] : null;
    }

    /**
     * Format the prefix for the new group attributes.
     *
     * @param  array  $new
     * @param  array  $old
     * @return string|null
     */
    protected static function formatGroupPrefix($new, $old)
    {
        $oldPrefix = isset($old['
prefix']) ? $old['prefix'] : null;

        if (isset($new['
prefix'])) {
            return trim($oldPrefix, '
/').'/'.trim($new['prefix'], '/');
        }

        return $oldPrefix;
    }

    /**
     * Get the prefix from the last group on the stack.
     *
     * @return string
     */
    public function getLastGroupPrefix()
    {
        if (! empty($this->groupStack)) {
            $last = end($this->groupStack);

            return isset($last['
prefix']) ? $last['prefix'] : '';
        }

        return '';
    }

    /**
     * Add a route to the underlying route collection.
     *
     * @param  array|string  $methods
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    protected function addRoute($methods, $uri, $action)
    {
        return $this->routes->add($this->createRoute($methods, $uri, $action));
    }

    /**
     * Create a new route instance.
     *
     * @param  array|string  $methods
     * @param  string  $uri
     * @param  mixed  $action
     * @return IlluminateRoutingRoute
     */
    protected function createRoute($methods, $uri, $action)
    {
        // If the route is routing to a controller we will parse the route action into
        // an acceptable array format before registering it and creating this route
        // instance itself. We need to build the Closure that will call this out.
        if ($this->actionReferencesController($action)) {
            $action = $this->convertToControllerAction($action);
        }

        $route = $this->newRoute(
            $methods, $this->prefix($uri), $action
        );

        // If we have groups that need to be merged, we will merge them now after this
        // route has already been created and is ready to go. After we'
re done with
        
// the merge we will be ready to return the route back out to the caller.
        
if ($this->hasGroupStack()) {
            
$this->mergeGroupAttributesIntoRoute($route);
        }

        
$this->addWhereClausesToRoute($route);

        return 
$route;
    }

    
/**
     * Create a new Route object.
     *
     * @param  array|string  $methods
     * @param  string  $uri
     * @param  mixed  $action
     * @return IlluminateRoutingRoute
     */
    
protected function newRoute($methods$uri$action)
    {
        return (new 
Route($methods$uri$action))
                    ->
setRouter($this)
                    ->
setContainer($this->container);
    }

    
/**
     * Prefix the given URI with the last prefix.
     *
     * @param  string  $uri
     * @return string
     */
    
protected function prefix($uri)
    {
        return 
trim(trim($this->getLastGroupPrefix(), '/').'/'.trim($uri'/'), '/') ?: '/';
    }

    
/**
     * Add the necessary where clauses to the route based on its initial registration.
     *
     * @param  IlluminateRoutingRoute  $route
     * @return IlluminateRoutingRoute
     */
    
protected function addWhereClausesToRoute($route)
    {
        
$where = isset($route->getAction()['where']) ? $route->getAction()['where'] : [];

        
$route->where(array_merge($this->patterns$where));

        return 
$route;
    }

    
/**
     * Merge the group stack with the controller action.
     *
     * @param  IlluminateRoutingRoute  $route
     * @return void
     */
    
protected function mergeGroupAttributesIntoRoute($route)
    {
        
$action $this->mergeWithLastGroup($route->getAction());

        
$route->setAction($action);
    }

    
/**
     * Determine if the action is routing to a controller.
     *
     * @param  array  $action
     * @return bool
     */
    
protected function actionReferencesController($action)
    {
        if (
$action instanceof Closure) {
            return 
false;
        }

        return 
is_string($action) || (isset($action['uses']) && is_string($action['uses']));
    }

    
/**
     * Add a controller based route action to the action array.
     *
     * @param  array|string  $action
     * @return array
     */
    
protected function convertToControllerAction($action)
    {
        if (
is_string($action)) {
            
$action = ['uses' => $action];
        }

        
// Here we'll merge any group "uses" statement if necessary so that the action
        // has the proper clause for this property. Then we can simply set the name
        // of the controller on the action and return the action array for usage.
        
if (! empty($this->groupStack)) {
            
$action['uses'] = $this->prependGroupUses($action['uses']);
        }

        
// Here we will set this controller name on the action array just so we always
        // have a copy of it for reference if we need it. This can be used while we
        // search for a controller name or do some other type of fetch operation.
        
$action['controller'] = $action['uses'];

        return 
$action;
    }

    
/**
     * Prepend the last group uses onto the use clause.
     *
     * @param  string  $uses
     * @return string
     */
    
protected function prependGroupUses($uses)
    {
        
$group end($this->groupStack);

        return isset(
$group['namespace']) && strpos($uses'\') !== 0 ? $group['namespace'].'\'.$uses : $uses;
    }

    /**
     * Dispatch the request to the application.
     *
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateHttpResponse
     */
    public function dispatch(Request $request)
    {
        $this->currentRequest = $request;

        $response = $this->dispatchToRoute($request);

        return $this->prepareResponse($request, $response);
    }

    /**
     * Dispatch the request to a route and return the response.
     *
     * @param  IlluminateHttpRequest  $request
     * @return mixed
     */
    public function dispatchToRoute(Request $request)
    {
        // First we will find a route that matches this request. We will also set the
        // route resolver on the request so middlewares assigned to the route will
        // receive access to this route instance for checking of the parameters.
        $route = $this->findRoute($request);

        $request->setRouteResolver(function () use ($route) {
            return $route;
        });

        $this->events->fire(new EventsRouteMatched($route, $request));

        $response = $this->runRouteWithinStack($route, $request);

        return $this->prepareResponse($request, $response);
    }

    /**
     * Run the given route within a Stack "onion" instance.
     *
     * @param  IlluminateRoutingRoute  $route
     * @param  IlluminateHttpRequest  $request
     * @return mixed
     */
    protected function runRouteWithinStack(Route $route, Request $request)
    {
        $shouldSkipMiddleware = $this->container->bound('
middleware.disable') &&
                                $this->container->make('
middleware.disable') === true;

        $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddlewares($route);

        return (new Pipeline($this->container))
                        ->send($request)
                        ->through($middleware)
                        ->then(function ($request) use ($route) {
                            return $this->prepareResponse(
                                $request,
                                $route->run($request)
                            );
                        });
    }

    /**
     * Gather the middleware for the given route.
     *
     * @param  IlluminateRoutingRoute  $route
     * @return array
     */
    public function gatherRouteMiddlewares(Route $route)
    {
        return Collection::make($route->middleware())->map(function ($name) {
            return Collection::make($this->resolveMiddlewareClassName($name));
        })
        ->flatten()->all();
    }

    /**
     * Resolve the middleware name to a class name(s) preserving passed parameters.
     *
     * @param  string  $name
     * @return string|array
     */
    public function resolveMiddlewareClassName($name)
    {
        $map = $this->middleware;

        // If the middleware is the name of a middleware group, we will return the array
        // of middlewares that belong to the group. This allows developers to group a
        // set of middleware under single keys that can be conveniently referenced.
        if (isset($this->middlewareGroups[$name])) {
            return $this->parseMiddlewareGroup($name);
        // When the middleware is simply a Closure, we will return this Closure instance
        // directly so that Closures can be registered as middleware inline, which is
        // convenient on occasions when the developers are experimenting with them.
        } elseif (isset($map[$name]) && $map[$name] instanceof Closure) {
            return $map[$name];
        // Finally, when the middleware is simply a string mapped to a class name the
        // middleware name will get parsed into the full class name and parameters
        // which may be run using the Pipeline which accepts this string format.
        } else {
            list($name, $parameters) = array_pad(explode('
:', $name, 2), 2, null);

            return (isset($map[$name]) ? $map[$name] : $name).
                   ($parameters !== null ? '
:'.$parameters : '');
        }
    }

    /**
     * Parse the middleware group and format it for usage.
     *
     * @param  string  $name
     * @return array
     */
    protected function parseMiddlewareGroup($name)
    {
        $results = [];

        foreach ($this->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($this->middlewareGroups[$middleware])) {
                $results = array_merge(
                    $results, $this->parseMiddlewareGroup($middleware)
                );

                continue;
            }

            list($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($this->middleware[$middleware])) {
                
$middleware $this->middleware[$middleware];
            }

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

        return 
$results;
    }

    
/**
     * Find the route matching a given request.
     *
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateRoutingRoute
     */
    
protected function findRoute($request)
    {
        
$this->current $route $this->routes->match($request);

        
$this->container->instance('IlluminateRoutingRoute'$route);

        return 
$this->substituteBindings($route);
    }

    
/**
     * Substitute the route bindings onto the route.
     *
     * @param  IlluminateRoutingRoute  $route
     * @return IlluminateRoutingRoute
     */
    
protected function substituteBindings($route)
    {
        foreach (
$route->parameters() as $key => $value) {
            if (isset(
$this->binders[$key])) {
                
$route->setParameter($key$this->performBinding($key$value$route));
            }
        }

        
$this->substituteImplicitBindings($route);

        return 
$route;
    }

    
/**
     * Substitute the implicit Eloquent model bindings for the route.
     *
     * @param  IlluminateRoutingRoute  $route
     * @return void
     */
    
protected function substituteImplicitBindings($route)
    {
        
$parameters $route->parameters();

        foreach (
$route->signatureParameters(Model::class) as $parameter) {
            
$class $parameter->getClass();

            if (
array_key_exists($parameter->name$parameters) &&
                ! 
$route->getParameter($parameter->name) instanceof Model) {
                
$method $parameter->isDefaultValueAvailable() ? 'first' 'firstOrFail';

                
$model $class->newInstance();

                
$route->setParameter(
                    
$parameter->name$model->where(
                        
$model->getRouteKeyName(), $parameters[$parameter->name]
                    )->{
$method}()
                );
            }
        }
    }

    
/**
     * Call the binding callback for the given key.
     *
     * @param  string  $key
     * @param  string  $value
     * @param  IlluminateRoutingRoute  $route
     * @return mixed
     */
    
protected function performBinding($key$value$route)
    {
        return 
call_user_func($this->binders[$key], $value$route);
    }

    
/**
     * Register a route matched event listener.
     *
     * @param  string|callable  $callback
     * @return void
     */
    
public function matched($callback)
    {
        
$this->events->listen(EventsRouteMatched::class, $callback);
    }

    
/**
     * Get all of the defined middleware short-hand names.
     *
     * @return array
     */
    
public function getMiddleware()
    {
        return 
$this->middleware;
    }

    
/**
     * Register a short-hand name for a middleware.
     *
     * @param  string  $name
     * @param  string  $class
     * @return $this
     */
    
public function middleware($name$class)
    {
        
$this->middleware[$name] = $class;

        return 
$this;
    }

    
/**
     * Register a group of middleware.
     *
     * @param  string  $name
     * @param  array  $middleware
     * @return $this
     */
    
public function middlewareGroup($name, array $middleware)
    {
        
$this->middlewareGroups[$name] = $middleware;

        return 
$this;
    }

    
/**
     * Add a middleware to the beginning of a middleware group.
     *
     * If the middleware is already in the group, it will not be added again.
     *
     * @param  string  $group
     * @param  string  $middleware
     * @return $this
     */
    
public function prependMiddlewareToGroup($group$middleware)
    {
        if (isset(
$this->middlewareGroups[$group]) && ! in_array($middleware$this->middlewareGroups[$group])) {
            
array_unshift($this->middlewareGroups[$group], $middleware);
        }

        return 
$this;
    }

    
/**
     * Add a middleware to the end of a middleware group.
     *
     * If the middleware is already in the group, it will not be added again.
     *
     * @param  string  $group
     * @param  string  $middleware
     * @return $this
     */
    
public function pushMiddlewareToGroup($group$middleware)
    {
        if (isset(
$this->middlewareGroups[$group]) && ! in_array($middleware$this->middlewareGroups[$group])) {
            
$this->middlewareGroups[$group][] = $middleware;
        }

        return 
$this;
    }

    
/**
     * Register a model binder for a wildcard.
     *
     * @param  string  $key
     * @param  string  $class
     * @param  Closure|null  $callback
     * @return void
     *
     * @throws SymfonyComponentHttpKernelExceptionNotFoundHttpException
     */
    
public function model($key$classClosure $callback null)
    {
        
$this->bind($key, function ($value) use ($class$callback) {
            if (
is_null($value)) {
                return;
            }

            
// For model binders, we will attempt to retrieve the models using the first
            // method on the model instance. If we cannot retrieve the models we'll
            // throw a not found exception otherwise we will return the instance.
            
$instance $this->container->make($class);

            if (
$model $instance->where($instance->getRouteKeyName(), $value)->first()) {
                return 
$model;
            }

            
// If a callback was supplied to the method we will call that to determine
            // what we should do when the model is not found. This just gives these
            // developer a little greater flexibility to decide what will happen.
            
if ($callback instanceof Closure) {
                return 
call_user_func($callback$value);
            }

            throw new 
NotFoundHttpException;
        });
    }

    
/**
     * Add a new route parameter binder.
     *
     * @param  string  $key
     * @param  string|callable  $binder
     * @return void
     */
    
public function bind($key$binder)
    {
        if (
is_string($binder)) {
            
$binder $this->createClassBinding($binder);
        }

        
$this->binders[str_replace('-''_'$key)] = $binder;
    }

    
/**
     * Create a class based binding using the IoC container.
     *
     * @param  string  $binding
     * @return Closure
     */
    
public function createClassBinding($binding)
    {
        return function (
$value$route) use ($binding) {
            
// If the binding has an @ sign, we will assume it's being used to delimit
            // the class name from the bind method name. This allows for bindings
            // to run multiple bind methods in a single class for convenience.
            
$segments explode('@'$binding);

            
$method count($segments) == $segments[1] : 'bind';

            
$callable = [$this->container->make($segments[0]), $method];

            return 
call_user_func($callable$value$route);
        };
    }

    
/**
     * Set a global where pattern on all routes.
     *
     * @param  string  $key
     * @param  string  $pattern
     * @return void
     */
    
public function pattern($key$pattern)
    {
        
$this->patterns[$key] = $pattern;
    }

    
/**
     * Set a group of global where patterns on all routes.
     *
     * @param  array  $patterns
     * @return void
     */
    
public function patterns($patterns)
    {
        foreach (
$patterns as $key => $pattern) {
            
$this->pattern($key$pattern);
        }
    }

    
/**
     * Create a response instance from the given value.
     *
     * @param  SymfonyComponentHttpFoundationRequest  $request
     * @param  mixed  $response
     * @return IlluminateHttpResponse
     */
    
public function prepareResponse($request$response)
    {
        if (
$response instanceof PsrResponseInterface) {
            
$response = (new HttpFoundationFactory)->createResponse($response);
        } elseif (! 
$response instanceof SymfonyResponse) {
            
$response = new Response($response);
        }

        return 
$response->prepare($request);
    }

    
/**
     * Determine if the router currently has a group stack.
     *
     * @return bool
     */
    
public function hasGroupStack()
    {
        return ! empty(
$this->groupStack);
    }

    
/**
     * Get the current group stack for the router.
     *
     * @return array
     */
    
public function getGroupStack()
    {
        return 
$this->groupStack;
    }

    
/**
     * Get a route parameter for the current route.
     *
     * @param  string  $key
     * @param  string  $default
     * @return mixed
     */
    
public function input($key$default null)
    {
        return 
$this->current()->parameter($key$default);
    }

    
/**
     * Get the currently dispatched route instance.
     *
     * @return IlluminateRoutingRoute
     */
    
public function getCurrentRoute()
    {
        return 
$this->current();
    }

    
/**
     * Get the currently dispatched route instance.
     *
     * @return IlluminateRoutingRoute
     */
    
public function current()
    {
        return 
$this->current;
    }

    
/**
     * Check if a route with the given name exists.
     *
     * @param  string  $name
     * @return bool
     */
    
public function has($name)
    {
        return 
$this->routes->hasNamedRoute($name);
    }

    
/**
     * Get the current route name.
     *
     * @return string|null
     */
    
public function currentRouteName()
    {
        return 
$this->current() ? $this->current()->getName() : null;
    }

    
/**
     * Alias for the "currentRouteName" method.
     *
     * @param  mixed  string
     * @return bool
     */
    
public function is()
    {
        foreach (
func_get_args() as $pattern) {
            if (
Str::is($pattern$this->currentRouteName())) {
                return 
true;
            }
        }

        return 
false;
    }

    
/**
     * Determine if the current route matches a given name.
     *
     * @param  string  $name
     * @return bool
     */
    
public function currentRouteNamed($name)
    {
        return 
$this->current() ? $this->current()->getName() == $name false;
    }

    
/**
     * Get the current route action.
     *
     * @return string|null
     */
    
public function currentRouteAction()
    {
        if (! 
$this->current()) {
            return;
        }

        
$action $this->current()->getAction();

        return isset(
$action['controller']) ? $action['controller'] : null;
    }

    
/**
     * Alias for the "currentRouteUses" method.
     *
     * @param  mixed  string
     * @return bool
     */
    
public function uses()
    {
        foreach (
func_get_args() as $pattern) {
            if (
Str::is($pattern$this->currentRouteAction())) {
                return 
true;
            }
        }

        return 
false;
    }

    
/**
     * Determine if the current route action matches a given action.
     *
     * @param  string  $action
     * @return bool
     */
    
public function currentRouteUses($action)
    {
        return 
$this->currentRouteAction() == $action;
    }

    
/**
     * Get the request currently being dispatched.
     *
     * @return IlluminateHttpRequest
     */
    
public function getCurrentRequest()
    {
        return 
$this->currentRequest;
    }

    
/**
     * Get the underlying route collection.
     *
     * @return IlluminateRoutingRouteCollection
     */
    
public function getRoutes()
    {
        return 
$this->routes;
    }

    
/**
     * Set the route collection instance.
     *
     * @param  IlluminateRoutingRouteCollection  $routes
     * @return void
     */
    
public function setRoutes(RouteCollection $routes)
    {
        foreach (
$routes as $route) {
            
$route->setRouter($this)->setContainer($this->container);
        }

        
$this->routes $routes;

        
$this->container->instance('routes'$this->routes);
    }

    
/**
     * Get the global "where" patterns.
     *
     * @return array
     */
    
public function getPatterns()
    {
        return 
$this->patterns;
    }
}
Онлайн: 2
Реклама