This repository has been archived by the owner on Jul 4, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 719
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #1330 Add the possibility to register forms as services (skalpa)
This PR was squashed before being merged into the 2.0.x-dev branch (closes #1330). Discussion ---------- Add the possibility to register forms as services This allows you to register your form types / form types extensions / form types guessers as Silex services: ```php $app['your.type.service'] = function ($app) { return new YourServiceFormType(); }; $app->extend('form.types', function ($types) use ($app) { $types[] = 'your.type.service'; return $types; })); ... $builder = $app['form.factory']->createBuilder('your.type.service'); ``` This is particularly useful for users of Symfony 3.x, now that `FormFactory::createBuilder()` and friends don't allow you to pass an instance of `FormTypeInterface` anymore, preventing you from loading form types that require constructor arguments lazily (without the patch you have to add objects to the `form.types` / `form.type.extensions` / `form.type.guessers` parameters which means every single form of your application will have to get instantiated whenever you use the form component). The patch contains a new `SilexFormExtension` extension class that handles the dereferencing of services names / lazy loading, new tests, and documentation fixes. Other quick notes: * No type checking is performed by the extension, but that's consistent with the way the `FormServiceProvider` works without the patch. Nevertheless, I believe this should be enhanced and will be ready to work on this after the merge if you reckon that would be a good idea. * I had to change the `DummyFormType` declaration in the tests. You used a class with a `getName()` method with Symfony < 2.8 and one without the method with 2.8+. Now the problem is that the `FormRegistry` from 2.8.x still uses the `getName()` method to store form types, which means it is still needed in some cases. Thus for my tests to pass I had to make sure the class with `getName()` was used with any 2.x version while the one without it was only used with 3.x Commits ------- cfcfa14 Add the possibility to register forms as services
- Loading branch information
Showing
4 changed files
with
283 additions
and
6 deletions.
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,122 @@ | ||
<?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\Provider\Form; | ||
|
||
use Pimple\Container; | ||
use Symfony\Component\Form\Exception\InvalidArgumentException; | ||
use Symfony\Component\Form\FormExtensionInterface; | ||
use Symfony\Component\Form\FormTypeGuesserChain; | ||
|
||
class SilexFormExtension implements FormExtensionInterface | ||
{ | ||
private $app; | ||
private $types; | ||
private $typeExtensions; | ||
private $guessers; | ||
private $guesserLoaded = false; | ||
private $guesser; | ||
|
||
public function __construct(Container $app, array $types, array $typeExtensions, array $guessers) | ||
{ | ||
$this->app = $app; | ||
$this->setTypes($types); | ||
$this->setTypeExtensions($typeExtensions); | ||
$this->setGuessers($guessers); | ||
} | ||
|
||
public function getType($name) | ||
{ | ||
if (!isset($this->types[$name])) { | ||
throw new InvalidArgumentException(sprintf('The type "%s" is not the name of a registered form type.', $name)); | ||
} | ||
if (!is_object($this->types[$name])) { | ||
$this->types[$name] = $this->app[$this->types[$name]]; | ||
} | ||
|
||
return $this->types[$name]; | ||
} | ||
|
||
public function hasType($name) | ||
{ | ||
return isset($this->types[$name]); | ||
} | ||
|
||
public function getTypeExtensions($name) | ||
{ | ||
return isset($this->typeExtensions[$name]) ? $this->typeExtensions[$name] : []; | ||
} | ||
|
||
public function hasTypeExtensions($name) | ||
{ | ||
return isset($this->typeExtensions[$name]); | ||
} | ||
|
||
public function getTypeGuesser() | ||
{ | ||
if (!$this->guesserLoaded) { | ||
$this->guesserLoaded = true; | ||
|
||
if ($this->guessers) { | ||
$guessers = []; | ||
foreach ($this->guessers as $guesser) { | ||
if (!is_object($guesser)) { | ||
$guesser = $this->app[$guesser]; | ||
} | ||
$guessers[] = $guesser; | ||
} | ||
$this->guesser = new FormTypeGuesserChain($guessers); | ||
} | ||
} | ||
|
||
return $this->guesser; | ||
} | ||
|
||
private function setTypes(array $types) | ||
{ | ||
$this->types = []; | ||
foreach ($types as $type) { | ||
if (!is_object($type)) { | ||
if (!isset($this->app[$type])) { | ||
throw new InvalidArgumentException(sprintf('Invalid form type. The silex service "%s" does not exist.', $type)); | ||
} | ||
$this->types[$type] = $type; | ||
} else { | ||
$this->types[get_class($type)] = $type; | ||
} | ||
} | ||
} | ||
|
||
private function setTypeExtensions(array $typeExtensions) | ||
{ | ||
$this->typeExtensions = []; | ||
foreach ($typeExtensions as $extension) { | ||
if (!is_object($extension)) { | ||
if (!isset($this->app[$extension])) { | ||
throw new InvalidArgumentException(sprintf('Invalid form type extension. The silex service "%s" does not exist.', $extension)); | ||
} | ||
$extension = $this->app[$extension]; | ||
} | ||
$this->typeExtensions[$extension->getExtendedType()][] = $extension; | ||
} | ||
} | ||
|
||
private function setGuessers(array $guessers) | ||
{ | ||
$this->guessers = []; | ||
foreach ($guessers as $guesser) { | ||
if (!is_object($guesser) && !isset($this->app[$guesser])) { | ||
throw new InvalidArgumentException(sprintf('Invalid form type guesser. The silex service "%s" does not exist.', $guesser)); | ||
} | ||
$this->guessers[] = $guesser; | ||
} | ||
} | ||
} |
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