/usr/share/php/Symfony/Component/Form/Extension/Core/ChoiceList/ObjectChoiceList.php is in php-symfony-form 2.3.21+dfsg-4+deb8u3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | <?php
/*
* This file is part of the Symfony package.
*
* (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 Symfony\Component\Form\Extension\Core\ChoiceList;
use Symfony\Component\Form\Exception\StringCastException;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* A choice list for object choices.
*
* Supports generation of choice labels, choice groups and choice values
* by calling getters of the object (or associated objects).
*
* <code>
* $choices = array($user1, $user2);
*
* // call getName() to determine the choice labels
* $choiceList = new ObjectChoiceList($choices, 'name');
* </code>
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ObjectChoiceList extends ChoiceList
{
/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;
/**
* The property path used to obtain the choice label.
*
* @var PropertyPath
*/
private $labelPath;
/**
* The property path used for object grouping.
*
* @var PropertyPath
*/
private $groupPath;
/**
* The property path used to obtain the choice value.
*
* @var PropertyPath
*/
private $valuePath;
/**
* Creates a new object choice list.
*
* @param array|\Traversable $choices The array of choices. Choices may also be given
* as hierarchy of unlimited depth by creating nested
* arrays. The title of the sub-hierarchy can be
* stored in the array key pointing to the nested
* array. The topmost level of the hierarchy may also
* be a \Traversable.
* @param string $labelPath A property path pointing to the property used
* for the choice labels. The value is obtained
* by calling the getter on the object. If the
* path is NULL, the object's __toString() method
* is used instead.
* @param array $preferredChoices A flat array of choices that should be
* presented to the user with priority.
* @param string $groupPath A property path pointing to the property used
* to group the choices. Only allowed if
* the choices are given as flat array.
* @param string $valuePath A property path pointing to the property used
* for the choice values. If not given, integers
* are generated instead.
* @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
*/
public function __construct($choices, $labelPath = null, array $preferredChoices = array(), $groupPath = null, $valuePath = null, PropertyAccessorInterface $propertyAccessor = null)
{
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
$this->labelPath = null !== $labelPath ? new PropertyPath($labelPath) : null;
$this->groupPath = null !== $groupPath ? new PropertyPath($groupPath) : null;
$this->valuePath = null !== $valuePath ? new PropertyPath($valuePath) : null;
parent::__construct($choices, array(), $preferredChoices);
}
/**
* Initializes the list with choices.
*
* Safe to be called multiple times. The list is cleared on every call.
*
* @param array|\Traversable $choices The choices to write into the list.
* @param array $labels Ignored.
* @param array $preferredChoices The choices to display with priority.
*
* @throws InvalidArgumentException When passing a hierarchy of choices and using
* the "groupPath" option at the same time.
*/
protected function initialize($choices, array $labels, array $preferredChoices)
{
if (null !== $this->groupPath) {
$groupedChoices = array();
foreach ($choices as $i => $choice) {
if (is_array($choice)) {
throw new InvalidArgumentException('You should pass a plain object array (without groups) when using the "groupPath" option.');
}
try {
$group = $this->propertyAccessor->getValue($choice, $this->groupPath);
} catch (NoSuchPropertyException $e) {
// Don't group items whose group property does not exist
// see https://github.com/symfony/symfony/commit/d9b7abb7c7a0f28e0ce970afc5e305dce5dccddf
$group = null;
}
if (null === $group) {
$groupedChoices[$i] = $choice;
} else {
$groupName = (string) $group;
if (!isset($groupedChoices[$groupName])) {
$groupedChoices[$groupName] = array();
}
$groupedChoices[$groupName][$i] = $choice;
}
}
$choices = $groupedChoices;
}
$labels = array();
$this->extractLabels($choices, $labels);
parent::initialize($choices, $labels, $preferredChoices);
}
/**
* Creates a new unique value for this choice.
*
* If a property path for the value was given at object creation,
* the getter behind that path is now called to obtain a new value.
* Otherwise a new integer is generated.
*
* @param mixed $choice The choice to create a value for
*
* @return int|string A unique value without character limitations.
*/
protected function createValue($choice)
{
if ($this->valuePath) {
return (string) $this->propertyAccessor->getValue($choice, $this->valuePath);
}
return parent::createValue($choice);
}
private function extractLabels($choices, array &$labels)
{
foreach ($choices as $i => $choice) {
if (is_array($choice)) {
$labels[$i] = array();
$this->extractLabels($choice, $labels[$i]);
} elseif ($this->labelPath) {
$labels[$i] = $this->propertyAccessor->getValue($choice, $this->labelPath);
} elseif (method_exists($choice, '__toString')) {
$labels[$i] = (string) $choice;
} else {
throw new StringCastException(sprintf('A "__toString()" method was not found on the objects of type "%s" passed to the choice field. To read a custom getter instead, set the argument $labelPath to the desired property path.', get_class($choice)));
}
}
}
}
|