-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Update data_transformers.rst #5307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,29 +111,100 @@ for converting to and from the issue number and the ``Issue`` object:: | |
Using the Transformer | ||
--------------------- | ||
|
||
Now that you have the transformer built, you just need to add it to your | ||
issue field in some form. | ||
As seen above our transformer requires an instance of an object manager. While for most | ||
use-cases using the default manager is fine we will let you pick the manager by it's name. | ||
In order to achieve this we will add a factory:: | ||
|
||
// src/Acme/TaskBundle/Form/DataTransformer/IssueToNumberTransformerFactory.php | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the AppBundle here. |
||
namespace Acme\TaskBundle\Form\DataTransformer; | ||
|
||
use Symfony\Bridge\Doctrine\ManagerRegistry; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you have any reason why you don't use |
||
|
||
class IssueToNumberTransformerFactory | ||
{ | ||
/** | ||
* @var ManagerRegistry | ||
*/ | ||
private $registry; | ||
|
||
public function __construct(ManagerRegistry $registry) | ||
{ | ||
$this->registry = $registry; | ||
} | ||
|
||
public function create($om) | ||
{ | ||
return new IssueToNumberTransformer($this->registry->getManager($om)); | ||
} | ||
} | ||
|
||
.. configuration-block:: | ||
|
||
.. code-block:: yaml | ||
|
||
services: | ||
acme_demo.factory.issue_transformer: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Imho "factory" should be reflected in the service id. |
||
class: Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformerFactory | ||
arguments: ["@doctrine"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can make the transformer factory private. |
||
|
||
acme_demo.type.task: | ||
class: Acme\TaskBundle\Form\TaskType | ||
arguments: ["@acme_demo.factory.issue_transformer"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to tag this as a form type: tag:
- { name: form.type, alias: app_task } |
||
|
||
.. code-block:: xml | ||
|
||
<service id="acme_demo.factory.issue_transformer" class="Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformerFactory"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should add the class attribute on a new line, to prevent horizontal scrolling (same below): <service id="app.factory.issue_transformer"
class="AppBundle\Form\DataTransformer\IssueToNumberTransformerFactory"> |
||
<argument type="service" id="doctrine"/> | ||
</service> | ||
|
||
<service id="acme_demo.type.task" class="Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformerFactory"> | ||
<argument type="service" id="acme_demo.factory.issue_transformer"/> | ||
</service> | ||
|
||
.. code-block:: php | ||
|
||
$container | ||
->setDefinition('acme_demo.factory.issue_transformer', array( | ||
new Reference('doctrine'), | ||
)) | ||
; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is invalid (same below). It should be something like: use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
// ...
$definition = new Definition(
'AppBundle\Form\DataTransformer\IssueToNumberTransformerFactory',
array(new Reference('doctrine'))
);
$container->setDefinition('app.factory.issue_transformer', $definition); |
||
|
||
$container | ||
->setDefinition('acme_demo.type.task', array( | ||
new Reference('acme_demo.factory.issue_transformer'), | ||
)) | ||
; | ||
|
||
Now that you have capability to build the transformer with the desired object manager, you | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Now that you have the capability [...]" |
||
just need to create it from your issue field in some form. | ||
|
||
You can also use transformers without creating a new custom form type | ||
by calling ``addModelTransformer`` (or ``addViewTransformer`` - see | ||
`Model and View Transformers`_) on any field builder:: | ||
|
||
// src/Acme/TaskBundle/Form/TaskType.php | ||
namespace Acme\TaskBundle\Form; | ||
|
||
use Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformerFactory; | ||
use Symfony\Component\Form\FormBuilderInterface; | ||
use Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformer; | ||
use Symfony\Component\OptionsResolver\OptionsResolverInterface; | ||
|
||
class TaskType extends AbstractType | ||
{ | ||
public function buildForm(FormBuilderInterface $builder, array $options) | ||
/** | ||
* @var IssueToNumberTransformerFactory | ||
*/ | ||
private $factory; | ||
|
||
public function __construct(IssueToNumberTransformerFactory $factory) | ||
{ | ||
// ... | ||
$this->factory = $factory; | ||
} | ||
|
||
// the "em" is an option that you pass when creating your form. Check out | ||
// the 3rd argument to createForm in the next code block to see how this | ||
// is passed to the form (also see setDefaultOptions). | ||
$entityManager = $options['em']; | ||
$transformer = new IssueToNumberTransformer($entityManager); | ||
public function buildForm(FormBuilderInterface $builder, array $options) | ||
{ | ||
$transformer = $this->factory->create($options['om']); | ||
|
||
// add a normal text field, but add your transformer to it | ||
$builder->add( | ||
$builder->create('issue', 'text') | ||
->addModelTransformer($transformer) | ||
|
@@ -146,25 +217,18 @@ by calling ``addModelTransformer`` (or ``addViewTransformer`` - see | |
->setDefaults(array( | ||
'data_class' => 'Acme\TaskBundle\Entity\Task', | ||
)) | ||
->setRequired(array( | ||
'em', | ||
)) | ||
->setAllowedTypes(array( | ||
'em' => 'Doctrine\Common\Persistence\ObjectManager', | ||
)); | ||
|
||
// ... | ||
->setRequired(array('om')) | ||
; | ||
} | ||
|
||
// ... | ||
} | ||
|
||
This example requires that you pass in the entity manager as an option | ||
when creating your form. Later, you'll learn how you could create a custom | ||
``issue`` field type to avoid needing to do this in your controller:: | ||
|
||
$taskForm = $this->createForm(new TaskType(), $task, array( | ||
'em' => $this->getDoctrine()->getManager(), | ||
$taskType = $this->get('acme_demo.type.task'); | ||
$taskForm = $this->createForm($taskType, $task, array( | ||
'om' => 'default', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can just be: $taskForm = $this->createForm('app_task', $task, array(
'om' => 'default',
)); |
||
)); | ||
|
||
Cool, you're done! Your user will be able to enter an issue number into the | ||
|
@@ -257,37 +321,31 @@ First, create the custom field type class:: | |
// src/Acme/TaskBundle/Form/Type/IssueSelectorType.php | ||
namespace Acme\TaskBundle\Form\Type; | ||
|
||
use Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformerFactory; | ||
use Symfony\Component\Form\AbstractType; | ||
use Symfony\Component\Form\FormBuilderInterface; | ||
use Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformer; | ||
use Doctrine\Common\Persistence\ObjectManager; | ||
use Symfony\Component\OptionsResolver\OptionsResolverInterface; | ||
|
||
class IssueSelectorType extends AbstractType | ||
{ | ||
/** | ||
* @var ObjectManager | ||
*/ | ||
private $om; | ||
|
||
/** | ||
* @param ObjectManager $om | ||
*/ | ||
public function __construct(ObjectManager $om) | ||
private $factory; | ||
|
||
public function __construct(IssueToNumberTransformerFactory $factory) | ||
{ | ||
$this->om = $om; | ||
$this->factory = $factory; | ||
} | ||
|
||
public function buildForm(FormBuilderInterface $builder, array $options) | ||
{ | ||
$transformer = new IssueToNumberTransformer($this->om); | ||
$transformer = $this->factory->create($options['om']); | ||
$builder->addModelTransformer($transformer); | ||
} | ||
|
||
public function setDefaultOptions(OptionsResolverInterface $resolver) | ||
{ | ||
$resolver->setDefaults(array( | ||
'invalid_message' => 'The selected issue does not exist', | ||
'om' => 'default' | ||
)); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[...] is fine, we will [...]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We avoid the first person perspective in the docs. So we should reword the sentence a bit like the following: