public function fillController($controller)
{
$router = app('router');
$controllerClass = get_classname($controller);
$paramsFilterPrefix = "router.filter: ";
$paramsFilterName = "controller.parameters." . $controllerClass;
if (!Event::hasListeners($paramsFilterPrefix . $paramsFilterName)) {
Event::listen($paramsFilterPrefix . $paramsFilterName, function () use($controller, $router) {
$currentRoute = $router->current();
$resourceParams = [];
list($resourceParams['controller'], $resourceParams['action']) = explode('@', $router->currentRouteAction());
$resourceParams['controller'] = $this->normalizeControllerName($resourceParams['controller']);
$resourceId = str_singular($resourceParams['controller']);
if (request()->has($resourceId)) {
$params = request()->all();
} else {
$specialInputKeys = $this->specialInputKeys();
$params = [$resourceId => request()->except($specialInputKeys)] + request()->only($specialInputKeys);
}
$routeParams = $currentRoute->parametersWithoutNulls();
// In Laravel, unlike Rails, by default 'id' parameter of a 'Product' resource is 'products'
// And 'shop_id' parameter of a 'Shop' parent resource is 'shops'
// So we need to reaffect correct parameter name before any controller's actions or filters.
$routeParamsParsed = [];
$keysToRemove = [];
$lastRouteParamKey = last(array_keys($routeParams));
if ($lastRouteParamKey === 'id' || $resourceId === str_singular($lastRouteParamKey)) {
$id = last($routeParams);
if (is_a($id, 'Illuminate\\Database\\Eloquent\\Model')) {
$id = $id->getKey();
}
if (is_string($id) || is_numeric($id)) {
array_pop($routeParams);
$routeParamsParsed['id'] = $id;
}
}
foreach ($routeParams as $parentIdKey => $parentIdValue) {
if (is_a($parentIdValue, 'Illuminate\\Database\\Eloquent\\Model')) {
$parentIdValue = $parentIdValue->getKey();
}
if (is_string($parentIdValue) || is_numeric($parentIdValue)) {
if (!ends_with($parentIdKey, '_id')) {
$parentIdKey = str_singular($parentIdKey) . '_id';
}
$routeParamsParsed[$parentIdKey] = $parentIdValue;
$keysToRemove[] = $parentIdKey;
}
}
$routeParams = array_except($routeParams, $keysToRemove);
/**
* You can escape or purify these parameters. For example:
*
* class ProductsController extends Controller
* {
* public function __construct()
* {
* $self = $this;
* $this->beforeFilter(function () use($self) {
* if (array_get($self->params, 'product')) {
* $productParams = $this->yourPurifyOrEscapeMethod('product');
* $self->params['product'] = $productParams;
* }
* });
* }
* }
*
*/
$this->params = array_filter(array_merge($params, $routeParams, $routeParamsParsed, $resourceParams));
if (property_exists($controller, 'params')) {
set_property($controller, 'params', $this->params);
} else {
$controller->params = $this->params;
}
});
$controller->paramsBeforeFilter($paramsFilterName);
}
}