Created
September 8, 2015 09:07
-
-
Save jishcem/e8febe0ce2d2146e690e to your computer and use it in GitHub Desktop.
PHP League Router Custom Strategy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"require": { | |
"league/route": "^1.2", | |
"twig/twig": "~1.0", | |
"illuminate/database": "5.0", | |
"symfony/validator": "^2.7", | |
"intervention/image": "^2.3", | |
"jasongrimes/paginator": "~1.0", | |
"symfony/filesystem": "^2.7" | |
}, | |
"autoload": { | |
"psr-4": { | |
"MyApp\\Controllers\\": "app\\Controllers\\", | |
"MyApp\\Strategies\\": "app\\Strategy\\" | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Create</title> | |
<!-- Latest compiled and minified CSS & JS --> | |
<link rel="stylesheet" media="screen" href="//netdna.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> | |
<script src="//code.jquery.com/jquery.js"></script> | |
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> | |
</head> | |
<body> | |
<div style="padding-top: 50px; padding-bottom: 50px;" class="container"> | |
<div class="row"> | |
<div class="col-md-6 col-md-offset-1"> | |
<legend>Create Deal</legend> | |
<br/><br/> | |
<form action="/admin/deals/create" method="POST" role="form"> | |
<div class="form-group"> | |
<label for="name">Name</label> | |
<input type="text" class="form-control" id="name" name="name" placeholder="Name" value="{% if input.name %}{{ input.name }}{% endif %}"> | |
</div> | |
<div class="form-group"> | |
<label for="price">Price</label> | |
<input type="text" class="form-control" id="price" name="price" placeholder="Price" value="{% if input.price %}{{ input.price }}{% endif %}"> | |
</div> | |
<div class="form-group"> | |
<label for="old_price">Old Price</label> | |
<input type="text" class="form-control" id="old_price" name="old_price" placeholder="Old Price" value="{% if input.old_price %}{{ input.old_price }}{% endif %}"> | |
</div> | |
<div class="form-group"> | |
<label for="title">Title</label> | |
<input type="text" class="form-control" id="title" name="title" placeholder="Title" value="{% if input.title %}{{ input.title }}{% endif %}"> | |
</div> | |
<div class="form-group"> | |
<label for="small_description">Small Description</label> | |
<input type="text" class="form-control" id="small_description" name="small_description" placeholder="Small Description" value="{% if input.small_description %}{{ input.small_description }}{% endif %}"> | |
</div> | |
<div class="form-group"> | |
<label for="description">Description</label> | |
<br/> | |
<textarea name="description" id="description" cols="30" rows="10">{% if input.description %}{{ input.description }}{% endif %}</textarea> | |
</div> | |
<div class="form-group"> | |
<label for="link">Link</label> | |
<input type="url" class="form-control" id="link" name="link" placeholder="Link" value="{% if input.link %}{{ input.link }}{% endif %}"> | |
</div> | |
<div class="form-group"> | |
<label>Is Featured</label> | |
<div class="radio"> | |
<label> | |
<input type="radio" name="is_featured" value="0" {% if not input.is_featured %}checked{% endif %} > | |
Is Not Featured | |
</label> | |
</div> | |
<div class="radio"> | |
<label> | |
<input type="radio" name="is_featured" value="1" {% if input.is_featured %}checked{% endif %} > | |
Is Featured | |
</label> | |
</div> | |
</div> | |
<div class="form-group"> | |
<label>Is Popular</label> | |
<div class="radio"> | |
<label> | |
<input type="radio" name="is_popular" value="0" {% if not input.is_popular %}checked{% endif %} > | |
Is Not Popular | |
</label> | |
</div> | |
<div class="radio"> | |
<label> | |
<input type="radio" name="is_popular" value="1" {% if input.is_popular %}checked{% endif %} > | |
Is Popular | |
</label> | |
</div> | |
</div> | |
<div class="form-group"> | |
<label>Is Best Rated</label> | |
<div class="radio"> | |
<label> | |
<input type="radio" name="is_best_rated" value="0" {% if not input.is_best_rated %}checked{% endif %} > | |
Is Not Best Rated | |
</label> | |
</div> | |
<div class="radio"> | |
<label> | |
<input type="radio" name="is_best_rated" value="1" {% if input.is_best_rated %}checked{% endif %} > | |
Is Best Rated | |
</label> | |
</div> | |
</div> | |
<!-- Uploaded Files --> | |
<input name="files" id="files" type="hidden"/> | |
<!-- Uploaded Files --> | |
<button type="submit" class="btn btn-primary">Submit</button> | |
</form> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace MyApp\Strategies; | |
use League\Route\Strategy\AbstractStrategy; | |
use League\Route\Strategy\StrategyInterface; | |
class CustomStrategy extends AbstractStrategy implements StrategyInterface { | |
/** | |
* Dispatch the controller, the return value of this method will bubble out and be | |
* returned by \League\Route\Dispatcher::dispatch, it does not require a response, however, | |
* beware that there is no output buffering by default in the router | |
* | |
* $controller can be one of three types but based on the type you can infer what the | |
* controller actually is: | |
* - string (controller is a named function) | |
* - array (controller is a class method [0 => ClassName, 1 => MethodName]) | |
* - \Closure (controller is an anonymous function) | |
* | |
* @param string|array|\Closure $controller | |
* @param array $vars - named wildcard segments of the matched route | |
* @return mixed | |
*/ | |
public function dispatch($controller, array $vars) | |
{ | |
if (is_array($controller)) { | |
$controller = [ | |
$this->container->get($controller[0]), | |
$controller[1] | |
]; | |
} | |
$response = $this->container->call($controller, $vars); | |
return $this->determineResponse($response); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace MyApp\Controllers; | |
use Symfony\Component\HttpFoundation\Response as Response; | |
use Symfony\Component\HttpFoundation\Request as Request; | |
class DealController { | |
public function __construct() | |
{ | |
$loader = new \Twig_Loader_Filesystem('templates'); | |
$this->twig = new \Twig_Environment($loader); | |
$this->response = Response::create(); | |
$this->request = Request::createFromGlobals(); | |
} | |
public function create() | |
{ | |
$this->response->setContent($this->twig->render('create.twig')); | |
return $this->response; | |
} | |
public function createAction($request, $response, $args) | |
{ | |
echo '<pre>'; var_dump($request); | |
echo '<pre>'; var_dump($response); | |
echo '<pre>'; var_dump($args); | |
exit; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require 'vendor/autoload.php'; | |
use MyApp\Strategies\CustomStrategy; | |
use Illuminate\Database\Capsule\Manager as Capsule; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpFoundation\Response; | |
// Routing | |
$router = new League\Route\RouteCollection; | |
$router->setStrategy(new CustomStrategy); | |
$router->addRoute('GET', '/admin/deals/create', '\MyApp\Controllers\DealController::create'); | |
$router->addRoute('POST', '/admin/deals/create', '\MyApp\Controllers\DealController::createAction'); | |
$dispatcher = $router->getDispatcher(); | |
$request = Request::createFromGlobals(); | |
$response = $dispatcher->dispatch($request->getMethod(), $request->getPathInfo()); | |
$response->send(); |
Your custom strategy is using the League\Container\Container::call
method which attempts to resolve the arguments of the method it is invoking. The problem here is that your MyApp\Controllers\DealController::createAction
just accepts $request
and $response
. If you were to type hint the request and response objects then this would work.
public function createAction(Request $request, Response $response, array $args = [])
{
echo '<pre>'; var_dump($request);
echo '<pre>'; var_dump($response);
echo '<pre>'; var_dump($args);
exit;
}
👍 It worked.
I used the RequestResponseStrategy in the CustomStrategy's dispatch method, and it worked as well 👍
Thank you so much!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is the error displayed -
Warning: array_map(): An error occurred while invoking the map callback in C:\laragon\www\asdasd\vendor\league\container\src\Container.php on line 495
( ! ) Fatal error: Uncaught exception 'RuntimeException' with message 'Cannot resolve argument [request], it should be provided within an array of arguments passed to [League\Container\Container::call], have a default value or be type hinted' in C:\laragon\www\asdasd\vendor\league\container\src\Container.php on line 488
( ! ) RuntimeException: Cannot resolve argument [request], it should be provided within an array of arguments passed to [League\Container\Container::call], have a default value or be type hinted in C:\laragon\www\asdasd\vendor\league\container\src\Container.php on line 488
This happens while the route $router->addRoute('POST', '/admin/deals/create', '\MyApp\Controllers\DealController::createAction');
is executed.