Skip to content

Instantly share code, notes, and snippets.

@lagbox
Last active May 12, 2016 00:11
Show Gist options
  • Save lagbox/6de90318a5127811ae4d to your computer and use it in GitHub Desktop.
Save lagbox/6de90318a5127811ae4d to your computer and use it in GitHub Desktop.
ResourceRegistrar with custom wildcards and global wildcard mapping
<?php
namespace Illuminate\Routing;
use Illuminate\Support\Str;
class ResourceRegistrar
{
protected static $wildcardMap = [];
protected static $singularWildcards = false;
public $wildcards;
/**
* Route a resource to a controller.
*
* @param string $name
* @param string $controller
* @param array $options
* @return void
*/
public function register($name, $controller, array $options = [])
{
if (isset($options['wildcards']) && ! isset($this->wildcards)) {
$this->wildcards = $options['wildcards'];
}
// If the resource name contains a slash, we will assume the developer wishes to
// register these resource routes with a prefix so we will set that up out of
// the box so they don't have to mess with it. Otherwise, we will continue.
if (Str::contains($name, '/')) {
$this->prefixedResource($name, $controller, $options);
return;
}
// We need to extract the base resource from the resource name. Nested resources
// are supported in the framework, but we need to know what name to use for a
// place-holder on the route wildcards, which should be the base resources.
$base = $this->getResourceWildcard(last(explode('.', $name)));
$defaults = $this->resourceDefaults;
foreach ($this->getResourceMethods($defaults, $options) as $m) {
$this->{'addResource'.ucfirst($m)}($name, $base, $controller, $options);
}
}
/**
* Format a resource wildcard for usage.
*
* @param string $value
* @return string
*/
public function getResourceWildcard($value)
{
if (isset($this->wildcards[$value])) {
$value = $this->wildcards[$value];
} elseif (isset(static::$wildcardMap[$value])) {
$value = static::$wildcardMap[$value];
} elseif ($this->wildcards === 'singular' || static::$singularWildcards) {
$value = Str::singular($value);
}
return str_replace('-', '_', $value);
}
/**
* Set the global state for wildcard plurality
*
* @param mixed $wildcard singular or null
*/
public static function setWildcards($arg = null)
{
if (!$arg) return static::$singularWildcards = false;
foreach (func_get_args() as $arg) {
if (is_array($arg)) {
static::$wildcardMap = $arg;
} else {
static::$singularWildcards = $arg === 'singular';
}
}
}
}
<?php
Route::resource('users', 'UserController');
Route::resource('users.photos', 'PhotoController', ['wildcards' => [
'users' => 'person', 'photos' => 'image'
]]);
Route::resource('tags', 'TagController', ['wildcards' => 'singular']);
<?php
namespace App\Providers;
use Illuminate\Routing\Router;
use Illuminate\Routing\ResourceRegistrar;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to the controller routes in your routes file.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @param \Illuminate\Routing\Router $router
* @return void
*/
public function boot(Router $router)
{
ResourceRegistrar::setWildcards('singular');
// or add global wildcard mapping
ResourceRegistrar::setWildcards([
'players' => 'person'
]);
// or both
ResourceRegistrar::setWildcards('singular', [
'players' => 'person'
]);
parent::boot($router);
}
/**
* Define the routes for the application.
*
* @param \Illuminate\Routing\Router $router
* @return void
*/
public function map(Router $router)
{
$router->group(['namespace' => $this->namespace], function ($router) {
require app_path('Http/routes.php');
});
}
public function register() {
// bind your extended ResourceRegistrar to the container
$this->app->bind(
\Illuminate\Routing\ResourceRegistrar::class,
\App\Lib\ResourceRegistrar::class
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment