-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e72c53c
commit 105dad3
Showing
18 changed files
with
676 additions
and
1 deletion.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
Decouple from CRUDController | ||
============================ | ||
|
||
.. versionadded:: 3.x | ||
|
||
The ability to inject an Admin to an action and ``AdminFetcherInterface`` service were introduced in 3.x. | ||
|
||
When creating custom actions, we can create our controllers without extending ``CRUDController``. What we usually need | ||
is to access the ``admin`` instance associated to the action, to do so we can use a param converter or | ||
the ``AdminFetcherInterface`` service. | ||
|
||
If you are using ``SensioFrameworkExtraBundle``, then you can add your Admin as parameter of the action:: | ||
|
||
// src/Controller/CarAdminController.php | ||
|
||
namespace App\Controller; | ||
|
||
use Symfony\Component\HttpFoundation\RedirectResponse; | ||
|
||
final class CarAdminController | ||
{ | ||
public function clone(CarAdmin $admin, Request $request) | ||
{ | ||
$object = $admin->getSubject(); | ||
|
||
// ... | ||
|
||
$request->getSession()->getFlashBag()->add('sonata_flash_success', 'Cloned successfully'); | ||
|
||
return new RedirectResponse($admin->generateUrl('list')); | ||
} | ||
} | ||
|
||
Or you can use ``AdminFetcherInterface`` service to fetch the admin from the request, in this example we transformed | ||
the controller to make it Invokable:: | ||
|
||
// src/Controller/CarAdminController.php | ||
|
||
namespace App\Controller; | ||
|
||
use Symfony\Component\HttpFoundation\RedirectResponse; | ||
|
||
final class CarAdminSoldAction | ||
{ | ||
/** | ||
* @var AdminFetcherInterface | ||
*/ | ||
private $adminFetcher; | ||
|
||
public function __construct(AdminFetcherInterface $adminFetcher) | ||
{ | ||
$this->adminFetcher = $adminFetcher; | ||
} | ||
|
||
public function __invoke(Request $request) | ||
{ | ||
$admin = $this->adminFetcher->get($request); | ||
|
||
$object = $admin->getSubject(); | ||
|
||
// ... | ||
|
||
$request->getSession()->getFlashBag()->add('sonata_flash_success', 'Sold successfully'); | ||
|
||
return new RedirectResponse($admin->generateUrl('list')); | ||
} | ||
} | ||
|
||
Now we only need to add the new route in ``configureRoutes``:: | ||
|
||
use App\Controller\CarAdminCloneAction; | ||
use Sonata\AdminBundle\Route\RouteCollection; | ||
|
||
protected function configureRoutes(RouteCollection $collection) | ||
{ | ||
$collection | ||
->add('clone', $this->getRouterIdParameter().'/clone', [ | ||
'_controller' => 'App\Controller\CarAdminController::clone', | ||
]) | ||
|
||
// Using invokable controller: | ||
->add('sold', $this->getRouterIdParameter().'/sold', [ | ||
'_controller' => CarAdminSoldAction::class, | ||
]); | ||
} |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\AdminBundle\Request; | ||
|
||
use Sonata\AdminBundle\Admin\AdminInterface; | ||
use Sonata\AdminBundle\Admin\Pool; | ||
use Sonata\AdminBundle\Exception\AdminCodeNotFoundException; | ||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
final class AdminFetcher implements AdminFetcherInterface | ||
{ | ||
/** | ||
* @var Pool | ||
*/ | ||
private $pool; | ||
|
||
public function __construct(Pool $pool) | ||
{ | ||
$this->pool = $pool; | ||
} | ||
|
||
public function get(Request $request): AdminInterface | ||
{ | ||
$adminCode = (string) $request->get('_sonata_admin'); | ||
|
||
if ('' === $adminCode) { | ||
throw new \InvalidArgumentException(sprintf( | ||
'There is no `_sonata_admin` defined for the current route `%s`.', | ||
(string) $request->get('_route') | ||
)); | ||
} | ||
|
||
$admin = $this->pool->getAdminByAdminCode($adminCode); | ||
|
||
// NEXT_MAJOR: Remove this block. | ||
if (false === $admin) { | ||
throw new AdminCodeNotFoundException(sprintf( | ||
'Unable to find the admin class related to the admin code: "%s".', | ||
$adminCode | ||
)); | ||
} | ||
|
||
$rootAdmin = $admin; | ||
|
||
while ($rootAdmin->isChild()) { | ||
$rootAdmin->setCurrentChild(true); | ||
$rootAdmin = $rootAdmin->getParent(); | ||
} | ||
|
||
$rootAdmin->setRequest($request); | ||
|
||
if ($request->get('uniqid')) { | ||
$admin->setUniqid($request->get('uniqid')); | ||
} | ||
|
||
return $admin; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\AdminBundle\Request; | ||
|
||
use Sonata\AdminBundle\Admin\AdminInterface; | ||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
interface AdminFetcherInterface | ||
{ | ||
public function get(Request $request): AdminInterface; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\AdminBundle\Request\ParamConverter; | ||
|
||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | ||
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface; | ||
use Sonata\AdminBundle\Admin\AdminInterface; | ||
use Sonata\AdminBundle\Exception\AdminCodeNotFoundException; | ||
use Sonata\AdminBundle\Request\AdminFetcherInterface; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||
|
||
final class AdminParamConverter implements ParamConverterInterface | ||
{ | ||
/** | ||
* @var AdminFetcherInterface | ||
*/ | ||
private $adminFetcher; | ||
|
||
public function __construct(AdminFetcherInterface $adminFetcher) | ||
{ | ||
$this->adminFetcher = $adminFetcher; | ||
} | ||
|
||
public function apply(Request $request, ParamConverter $configuration): bool | ||
{ | ||
try { | ||
$admin = $this->adminFetcher->get($request); | ||
} catch (AdminCodeNotFoundException $exception) { | ||
throw new NotFoundHttpException($exception->getMessage()); | ||
} | ||
|
||
if (!is_a($admin, $configuration->getClass())) { | ||
throw new \LogicException(sprintf( | ||
'"%s" MUST be an instance of "%s", "%s" given.', | ||
$configuration->getName(), | ||
$configuration->getClass(), | ||
\get_class($admin) | ||
)); | ||
} | ||
|
||
$request->attributes->set($configuration->getName(), $admin); | ||
|
||
return true; | ||
} | ||
|
||
public function supports(ParamConverter $configuration): bool | ||
{ | ||
return is_subclass_of($configuration->getClass(), AdminInterface::class); | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
use Sonata\AdminBundle\Request\ParamConverter\AdminParamConverter; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; | ||
|
||
return static function (ContainerConfigurator $containerConfigurator): void { | ||
// Use "service" function for creating references to services when dropping support for Symfony 4.4 | ||
$containerConfigurator->services() | ||
|
||
->set('sonata.admin.param_converter', AdminParamConverter::class) | ||
->tag('request.param_converter', ['converter' => 'sonata_admin']) | ||
->args([ | ||
new ReferenceConfigurator('sonata.admin.request.fetcher'), | ||
]); | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\AdminBundle\Tests\App\Admin; | ||
|
||
use Sonata\AdminBundle\Admin\AbstractAdmin; | ||
use Sonata\AdminBundle\Route\RouteCollection; | ||
use Sonata\AdminBundle\Tests\App\Controller\InvokableController; | ||
|
||
final class TestingParamConverterAdmin extends AbstractAdmin | ||
{ | ||
protected $baseRoutePattern = 'tests/app/testing-param-converter'; | ||
protected $baseRouteName = 'admin_testing_param_converter'; | ||
|
||
protected function configureRoutes(RouteCollection $collection): void | ||
{ | ||
$collection->add('withAnnotation', null, [ | ||
'_controller' => 'Sonata\AdminBundle\Tests\App\Controller\ParamConverterController::withAnnotation', | ||
]); | ||
|
||
$collection->add('withoutAnnotation', null, [ | ||
'_controller' => 'Sonata\AdminBundle\Tests\App\Controller\ParamConverterController::withoutAnnotation', | ||
]); | ||
|
||
$collection->add('invokable', null, [ | ||
'_controller' => InvokableController::class, | ||
]); | ||
} | ||
} |
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
Oops, something went wrong.