Skip to content

Commit

Permalink
add files
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Dec 21, 2016
1 parent 21de409 commit e75730e
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/Illuminate/Routing/ImplicitRouteBinding.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Illuminate\Routing;

use Illuminate\Database\Eloquent\Model;

class ImplicitRouteBinding
{
/**
* Resolve the implicit route bindings for the given route.
*
* @param \Illuminate\Container\Container $container
* @param \Illuminate\Routing\Route $route
* @return void
*/
public static function resolveForRoute($container, $route)
{
$parameters = $route->parameters();

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

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

$model = $container->make($class->name);

$route->setParameter(
$parameter->name, $model->where(
$model->getRouteKeyName(), $parameters[$parameter->name]
)->{$method}()
);
}
}
}
}
82 changes: 82 additions & 0 deletions src/Illuminate/Routing/RouteBinding.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace Illuminate\Routing;

use Closure;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class RouteBinding
{
/**
* Create a Route model binding for a given callback.
*
* @param \Illuminate\Container\Container $container
* @param \Closure|string $binder
* @return \Closure
*/
public static function forCallback($container, $binder)
{
if (is_string($binder)) {
return static::createClassBinding($container, $binder);
}

return $binder;
}

/**
* Create a class based binding using the IoC container.
*
* @param string $binding
* @return \Closure
*/
protected static function createClassBinding($container, $binding)
{
return function ($value, $route) use ($container, $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) == 2 ? $segments[1] : 'bind';

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

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

/**
* Create a Route model binding for a model.
*
* @param \Illuminate\Container\Container $container
* @param string $class
* @param \Closure|null $callback
* @return \Closure
*/
public static function forModel($container, $class, $callback = null)
{
return function ($value) use ($container, $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 = $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 ModelNotFoundException)->setModel($class);
};
}
}

0 comments on commit e75730e

Please sign in to comment.