Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[WIP][2.4][Form] Add option "widget" to ChoiceType #8112

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ class EntityChoiceList extends ObjectChoiceList
*/
private $preferredEntities = array();

/**
* Whether or not the choice list shoud be loaded.
*
* @var Boolean
*/
private $lazy;

/**
* Creates a new entity choice list.
*
Expand All @@ -97,22 +104,27 @@ class EntityChoiceList extends ObjectChoiceList
* to group the choices. Only allowed if
* the choices are given as flat array.
* @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
* @param Boolean $lazy Whether or not the choice list shoud be loaded.
*/
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null, PropertyAccessorInterface $propertyAccessor = null)
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null, PropertyAccessorInterface $propertyAccessor = null, $lazy = false)
{
$this->em = $manager;
$this->entityLoader = $entityLoader;
$this->classMetadata = $manager->getClassMetadata($class);
$this->class = $this->classMetadata->getName();
$this->loaded = is_array($entities) || $entities instanceof \Traversable;
$this->lazy = $lazy;
$this->preferredEntities = $preferredEntities;

$identifier = $this->classMetadata->getIdentifierFieldNames();

if (1 === count($identifier)) {
$this->idField = $identifier[0];
$this->idAsValue = true;

if (!$lazy) {
$this->idField = $identifier[0];
$this->idAsValue = true;
} else {
$this->idField = (string) $labelPath;
}
if (in_array($this->classMetadata->getTypeOfField($this->idField), array('integer', 'smallint', 'bigint'))) {
$this->idAsIndex = true;
}
Expand All @@ -124,7 +136,7 @@ public function __construct(ObjectManager $manager, $class, $labelPath = null, E
$entities = array();
}

parent::__construct($entities, $labelPath, $preferredEntities, $groupPath, null, $propertyAccessor);
parent::__construct($entities, $labelPath, $preferredEntities, $groupPath, $labelPath, $propertyAccessor);
}

/**
Expand Down Expand Up @@ -215,6 +227,10 @@ public function getChoicesForValues(array $values)
return $this->entityLoader->getEntitiesByIds($this->idField, $values);
}

if ($this->lazy) {
return $this->em->getRepository($this->class)->findBy(array($this->idField => $values));
}

$this->load();
}

Expand All @@ -237,13 +253,13 @@ public function getValuesForChoices(array $entities)
// know that the IDs are used as values

// Attention: This optimization does not check choices for existence
if ($this->idAsValue) {
if ($this->idAsValue || $this->lazy) {
$values = array();

foreach ($entities as $entity) {
if ($entity instanceof $this->class) {
// Make sure to convert to the right format
$values[] = $this->fixValue(current($this->getIdentifierValues($entity)));
$values[] = $this->fixValue($this->createValue($entity));
}
}

Expand Down Expand Up @@ -379,6 +395,10 @@ protected function fixIndex($index)
*/
private function load()
{
if ($this->lazy) {
return;
}

if ($this->entityLoader) {
$entities = $this->entityLoader->getEntities();
} else {
Expand Down
10 changes: 8 additions & 2 deletions src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Bridge\Doctrine\Form\Type;

use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\Form\Exception\LogicException;
use Symfony\Component\Form\Exception\RuntimeException;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\FormBuilderInterface;
Expand Down Expand Up @@ -50,6 +51,9 @@ public function __construct(ManagerRegistry $registry, PropertyAccessorInterface

public function buildForm(FormBuilderInterface $builder, array $options)
{
if ('text' === $options['widget'] && !$options['property']) {
throw new LogicException('When using a text widget, the "property" option must be defined.');
}
if ($options['multiple']) {
$builder
->addEventSubscriber(new MergeDoctrineCollectionListener())
Expand Down Expand Up @@ -116,7 +120,8 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
$loaderHash,
$choiceHashes,
$preferredChoiceHashes,
$groupByHash
$groupByHash,
'text' === $options['widget']
)));

if (!isset($choiceListCache[$hash])) {
Expand All @@ -128,7 +133,8 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
$options['choices'],
$options['preferred_choices'],
$options['group_by'],
$propertyAccessor
$propertyAccessor,
'text' === $options['widget']
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@

{% block choice_widget %}
{% spaceless %}
{% if expanded %}
{% if widget == 'checkbox' or widget == 'radio' %}
{{ block('choice_widget_expanded') }}
{% elseif widget == 'select' %}
{{ block('choice_widget_select') }}
{% else %}
{{ block('choice_widget_collapsed') }}
{{ block('form_widget_simple') }}
{% endif %}
{% endspaceless %}
{% endblock choice_widget %}
Expand All @@ -65,7 +67,7 @@
{% endspaceless %}
{% endblock choice_widget_expanded %}

{% block choice_widget_collapsed %}
{% block choice_widget_select %}
{% spaceless %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if empty_value is not none %}
Expand All @@ -82,7 +84,7 @@
{{ block('choice_widget_options') }}
</select>
{% endspaceless %}
{% endblock choice_widget_collapsed %}
{% endblock choice_widget_select %}

{% block choice_widget_options %}
{% spaceless %}
Expand Down Expand Up @@ -388,3 +390,7 @@
{% for attrname, attrvalue in attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
{% endspaceless %}
{% endblock button_attributes %}

{# Deprecated in Symfony 2.4, to be removed in 3.0 #}

{% block choice_widget_collapsed %}{{ block('choice_widget_select') }}{% endblock %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a BC break: you are maintaining the compatibility for people calling {{ block('choice_widget_collapsed') }} but not for people extending choice_widget_collapsed in their custom theme (which is probably more common) as you never call this block .

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Form\Extension\Core\DataTransformer;

use Symfony\Component\Form\Exception\TransformationFailedException;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException;

/**
* Converts an array of values to a string with multiple values separated by a delimiter.
*
* @author Bilal Amarni <[email protected]>
*/
class ValuesToStringTransformer implements DataTransformerInterface
{
private $delimiter;
private $trim;

public function __construct($delimiter, $trim)
{
$this->delimiter = $delimiter;
$this->trim = $trim;
}

/**
* @param array $array
*
* @return string
*
* @throws UnexpectedTypeException if the given value is not an array
*/
public function transform($array)
{
if (null === $array) {
return array();
}

if (!is_array($array)) {
throw new UnexpectedTypeException($array, 'array');
}

return implode($this->delimiter, $array);
}

/**
* @param string $string
*
* @return array
*
* @throws UnexpectedTypeException if the given value is not a string
*/
public function reverseTransform($string)
{
if (empty($string)) {
return array();
}

if (!is_string($string)) {
throw new UnexpectedTypeException($string, 'string');
}

$values = explode($this->delimiter, $string);

if ($this->trim) {
$values = array_map('trim', $values);
}

return $values;
}
}
Loading