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