<?php namespace Pterodactyl\Http\Middleware\Api; use Closure; use Pterodactyl\Models\Egg; use Pterodactyl\Models\Nest; use Pterodactyl\Models\Node; use Pterodactyl\Models\User; use Pterodactyl\Models\Server; use Pterodactyl\Models\Database; use Pterodactyl\Models\Location; use Pterodactyl\Models\Allocation; use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Database\Eloquent\ModelNotFoundException; class ApiSubstituteBindings extends SubstituteBindings { /** * Mappings to automatically assign route parameters to a model. * * @var array */ protected static $mappings = [ 'allocation' => Allocation::class, 'database' => Database::class, 'egg' => Egg::class, 'location' => Location::class, 'nest' => Nest::class, 'node' => Node::class, 'server' => Server::class, 'user' => User::class, ]; /** * @var \Illuminate\Routing\Router */ protected $router; /** * Perform substitution of route parameters without triggering * a 404 error if a model is not found. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $route = $request->route(); foreach (self::$mappings as $key => $model) { if (! is_null($this->router->getBindingCallback($key))) { continue; } $this->router->model($key, $model, function () use ($request) { $request->attributes->set('is_missing_model', true); }); } $this->router->substituteBindings($route); // Attempt to resolve bindings for this route. If one of the models // cannot be resolved do not immediately return a 404 error. Set a request // attribute that can be checked in the base API request class to only // trigger a 404 after validating that the API key making the request is valid // and even has permission to access the requested resource. try { $this->router->substituteImplicitBindings($route); } catch (ModelNotFoundException $exception) { $request->attributes->set('is_missing_model', true); } return $next($request); } /** * Return the registered mappings. * * @return array */ public static function getMappings() { return self::$mappings; } }