Commit 934bf3ea authored by Fabien Potencier's avatar Fabien Potencier

added a way to get the Application in a Controller without using 'use' (that...

added a way to get the Application in a Controller without using 'use' (that also allows the usage of class methods as controllers)
parent 5609fb8a
...@@ -122,7 +122,7 @@ Dynamic routing ...@@ -122,7 +122,7 @@ Dynamic routing
Now, you can create another controller for viewing individual blog Now, you can create another controller for viewing individual blog
posts:: posts::
$app->get('/blog/show/{id}', function ($id) use ($app, $blogPosts) { $app->get('/blog/show/{id}', function (Silex\Application $app, $id) use ($blogPosts) {
if (!isset($blogPosts[$id])) { if (!isset($blogPosts[$id])) {
$app->abort(404, "Post $id does not exist."); $app->abort(404, "Post $id does not exist.");
} }
...@@ -152,11 +152,10 @@ feedback form. We will use `Swift Mailer ...@@ -152,11 +152,10 @@ feedback form. We will use `Swift Mailer
require_once __DIR__.'/vendor/swiftmailer/lib/swift_required.php'; require_once __DIR__.'/vendor/swiftmailer/lib/swift_required.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
$app->post('/feedback', function () use ($app) { $app->post('/feedback', function (Request $request) {
$request = $app['request'];
$message = \Swift_Message::newInstance() $message = \Swift_Message::newInstance()
->setSubject('[YourSite] Feedback') ->setSubject('[YourSite] Feedback')
->setFrom(array('noreply@yoursite.com')) ->setFrom(array('noreply@yoursite.com'))
...@@ -173,9 +172,8 @@ feedback form. We will use `Swift Mailer ...@@ -173,9 +172,8 @@ feedback form. We will use `Swift Mailer
It is pretty straight forward. We include the Swift Mailer library, It is pretty straight forward. We include the Swift Mailer library,
set up a message and send that message. set up a message and send that message.
The current ``request`` service is retrieved using the array key syntax. The current ``request`` is automatically injected by Silex to the Closure
You can find more information about services in the *Services* chapter. thanks to the type hinting. It is an instance of `Request
The request is an instance of `Request
<http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html>`_, <http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html>`_,
so you can fetch variables using the request's ``get`` method. so you can fetch variables using the request's ``get`` method.
...@@ -239,6 +237,21 @@ While it's not suggested, you could also do this (note the switched arguments):: ...@@ -239,6 +237,21 @@ While it's not suggested, you could also do this (note the switched arguments)::
... ...
}); });
You can also ask for the current Request and Application object::
$app->get('/blog/show/{id}', function (Application $app, Request $request, $id) {
...
});
.. note::
Note for the Application and Request objects, Silex does the injection
based on the type hinting and not on the variable name::
$app->get('/blog/show/{id}', function (Application $foo, Request $bar, $id) {
...
});
Route variables converters Route variables converters
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -405,7 +418,7 @@ once a response is returned, the following handlers are ignored. ...@@ -405,7 +418,7 @@ once a response is returned, the following handlers are ignored.
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
$app->error(function (\Exception $e, $code) { $app->error(function (\Exception $e, $code) use ($app) {
if ($app['debug']) { if ($app['debug']) {
return; return;
} }
...@@ -416,7 +429,7 @@ once a response is returned, the following handlers are ignored. ...@@ -416,7 +429,7 @@ once a response is returned, the following handlers are ignored.
The error handlers are also called when you use ``abort`` to abort a request The error handlers are also called when you use ``abort`` to abort a request
early:: early::
$app->get('/blog/show/{id}', function ($id) use ($app, $blogPosts) { $app->get('/blog/show/{id}', function (Silex\Application $app, $id) use ($blogPosts) {
if (!isset($blogPosts[$id])) { if (!isset($blogPosts[$id])) {
$app->abort(404, "Post $id does not exist."); $app->abort(404, "Post $id does not exist.");
} }
...@@ -430,7 +443,9 @@ Redirects ...@@ -430,7 +443,9 @@ Redirects
You can redirect to another page by returning a redirect response, which You can redirect to another page by returning a redirect response, which
you can create by calling the ``redirect`` method:: you can create by calling the ``redirect`` method::
$app->get('/', function () use ($app) { use Silex\Application;
$app->get('/', function (Silex\Application $app) {
return $app->redirect('/hello'); return $app->redirect('/hello');
}); });
...@@ -451,7 +466,7 @@ correctly, to prevent Cross-Site-Scripting attacks. ...@@ -451,7 +466,7 @@ correctly, to prevent Cross-Site-Scripting attacks.
* **Escaping HTML**: PHP provides the ``htmlspecialchars`` function for this. * **Escaping HTML**: PHP provides the ``htmlspecialchars`` function for this.
Silex provides a shortcut ``escape`` method:: Silex provides a shortcut ``escape`` method::
$app->get('/name', function () use ($app) { $app->get('/name', function (Silex\Application $app) {
$name = $app['request']->get('name'); $name = $app['request']->get('name');
return "You provided the name {$app->escape($name)}."; return "You provided the name {$app->escape($name)}.";
}); });
...@@ -464,7 +479,7 @@ correctly, to prevent Cross-Site-Scripting attacks. ...@@ -464,7 +479,7 @@ correctly, to prevent Cross-Site-Scripting attacks.
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
$app->get('/name.json', function () use ($app) { $app->get('/name.json', function (Silex\Application $app) {
$name = $app['request']->get('name'); $name = $app['request']->get('name');
return new Response( return new Response(
json_encode(array('name' => $name)), json_encode(array('name' => $name)),
......
...@@ -13,7 +13,6 @@ namespace Silex; ...@@ -13,7 +13,6 @@ namespace Silex;
use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
...@@ -36,6 +35,7 @@ use Symfony\Component\Routing\Exception\MethodNotAllowedException; ...@@ -36,6 +35,7 @@ use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\ClassLoader\UniversalClassLoader; use Symfony\Component\ClassLoader\UniversalClassLoader;
use Silex\RedirectableUrlMatcher; use Silex\RedirectableUrlMatcher;
use Silex\ControllerResolver;
/** /**
* The Silex framework class. * The Silex framework class.
...@@ -82,8 +82,8 @@ class Application extends \Pimple implements HttpKernelInterface, EventSubscribe ...@@ -82,8 +82,8 @@ class Application extends \Pimple implements HttpKernelInterface, EventSubscribe
return $dispatcher; return $dispatcher;
}); });
$this['resolver'] = $this->share(function () { $this['resolver'] = $this->share(function () use ($app) {
return new ControllerResolver(); return new ControllerResolver($app);
}); });
$this['kernel'] = $this->share(function () use ($app) { $this['kernel'] = $this->share(function () use ($app) {
......
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Silex;
use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* ControllerResolver.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ControllerResolver extends BaseControllerResolver
{
protected $app;
/**
* Constructor.
*
* @param Application $app An Application instance
* @param LoggerInterface $logger A LoggerInterface instance
*/
public function __construct(Application $app, LoggerInterface $logger = null)
{
$this->app = $app;
parent::__construct($logger);
}
protected function doGetArguments(Request $request, $controller, array $parameters)
{
foreach ($parameters as $param) {
if ($param->getClass() && $param->getClass()->isInstance($this->app)) {
$request->attributes->set($param->getName(), $this->app);
break;
}
}
return parent::doGetArguments($request, $controller, $parameters);
}
}
...@@ -137,4 +137,21 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase ...@@ -137,4 +137,21 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
array('abc', 'abc'), array('abc', 'abc'),
); );
} }
public function testControllersAsMethods()
{
$app = new Application();
unset($app['exception_handler']);
$app->get('/{name}', 'Silex\Tests\FooController::barAction');
$this->assertEquals('Hello Fabien', $app->handle(Request::create('/Fabien'))->getContent());
}
}
class FooController
{
public function barAction(Application $app, $name)
{
return 'Hello '.$app->escape($name);
}
} }
<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Silex\Tests;
use Silex\ControllerResolver;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
/**
* ControllerResolver test cases.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ControllerResolverTest extends \PHPUnit_Framework_TestCase
{
public function testGetArguments()
{
$app = new Application();
$resolver = new ControllerResolver($app);
$controller = function (Application $app) {};
$args = $resolver->getArguments(Request::create('/'), $controller);
$this->assertSame($app, $args[0]);
}
}
Subproject commit 86041b3655471ca4ac9eb02cb18b08456f8d8389 Subproject commit c1810ca1028e80485d10d695bc10a9574ac03e82
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment