diff --git a/src/Illuminate/Routing/ImplicitRouteBinding.php b/src/Illuminate/Routing/ImplicitRouteBinding.php new file mode 100644 index 000000000000..6af8934ae95b --- /dev/null +++ b/src/Illuminate/Routing/ImplicitRouteBinding.php @@ -0,0 +1,37 @@ +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}() + ); + } + } + } +} diff --git a/src/Illuminate/Routing/RouteBinding.php b/src/Illuminate/Routing/RouteBinding.php new file mode 100644 index 000000000000..35113e03d357 --- /dev/null +++ b/src/Illuminate/Routing/RouteBinding.php @@ -0,0 +1,82 @@ +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); + }; + } +}