PageRenderTime 28ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/symfony/symfony/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php

https://gitlab.com/matijabelec/bigpandadev
PHP | 268 lines | 187 code | 34 blank | 47 comment | 25 complexity | 3d80a75ab9c1f05d7fc54b738a207e5b MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Form\ChoiceList\Factory;
  11. use Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList;
  12. use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
  13. use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
  14. use Symfony\Component\Form\ChoiceList\LazyChoiceList;
  15. use Symfony\Component\Form\ChoiceList\LegacyChoiceListAdapter;
  16. use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
  17. use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
  18. use Symfony\Component\Form\ChoiceList\View\ChoiceListView;
  19. use Symfony\Component\Form\ChoiceList\View\ChoiceView;
  20. use Symfony\Component\Form\Extension\Core\View\ChoiceView as LegacyChoiceView;
  21. /**
  22. * Default implementation of {@link ChoiceListFactoryInterface}.
  23. *
  24. * @author Bernhard Schussek <bschussek@gmail.com>
  25. */
  26. class DefaultChoiceListFactory implements ChoiceListFactoryInterface
  27. {
  28. /**
  29. * {@inheritdoc}
  30. */
  31. public function createListFromChoices($choices, $value = null)
  32. {
  33. return new ArrayChoiceList($choices, $value);
  34. }
  35. /**
  36. * {@inheritdoc}
  37. *
  38. * @deprecated Added for backwards compatibility in Symfony 2.7, to be
  39. * removed in Symfony 3.0.
  40. */
  41. public function createListFromFlippedChoices($choices, $value = null, $triggerDeprecationNotice = true)
  42. {
  43. if ($triggerDeprecationNotice) {
  44. @trigger_error('The '.__METHOD__.' is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
  45. }
  46. return new ArrayKeyChoiceList($choices, $value);
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public function createListFromLoader(ChoiceLoaderInterface $loader, $value = null)
  52. {
  53. return new LazyChoiceList($loader, $value);
  54. }
  55. /**
  56. * {@inheritdoc}
  57. */
  58. public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
  59. {
  60. // Backwards compatibility
  61. if ($list instanceof LegacyChoiceListAdapter && empty($preferredChoices)
  62. && null === $label && null === $index && null === $groupBy && null === $attr) {
  63. $mapToNonLegacyChoiceView = function (LegacyChoiceView &$choiceView) {
  64. $choiceView = new ChoiceView($choiceView->data, $choiceView->value, $choiceView->label);
  65. };
  66. $adaptedList = $list->getAdaptedList();
  67. $remainingViews = $adaptedList->getRemainingViews();
  68. $preferredViews = $adaptedList->getPreferredViews();
  69. array_walk_recursive($remainingViews, $mapToNonLegacyChoiceView);
  70. array_walk_recursive($preferredViews, $mapToNonLegacyChoiceView);
  71. return new ChoiceListView($remainingViews, $preferredViews);
  72. }
  73. $preferredViews = array();
  74. $otherViews = array();
  75. $choices = $list->getChoices();
  76. $keys = $list->getOriginalKeys();
  77. if (!is_callable($preferredChoices) && !empty($preferredChoices)) {
  78. $preferredChoices = function ($choice) use ($preferredChoices) {
  79. return false !== array_search($choice, $preferredChoices, true);
  80. };
  81. }
  82. // The names are generated from an incrementing integer by default
  83. if (null === $index) {
  84. $index = 0;
  85. }
  86. // If $groupBy is a callable, choices are added to the group with the
  87. // name returned by the callable. If the callable returns null, the
  88. // choice is not added to any group
  89. if (is_callable($groupBy)) {
  90. foreach ($choices as $value => $choice) {
  91. self::addChoiceViewGroupedBy(
  92. $groupBy,
  93. $choice,
  94. (string) $value,
  95. $label,
  96. $keys,
  97. $index,
  98. $attr,
  99. $preferredChoices,
  100. $preferredViews,
  101. $otherViews
  102. );
  103. }
  104. } else {
  105. // Otherwise use the original structure of the choices
  106. self::addChoiceViewsGroupedBy(
  107. $list->getStructuredValues(),
  108. $label,
  109. $choices,
  110. $keys,
  111. $index,
  112. $attr,
  113. $preferredChoices,
  114. $preferredViews,
  115. $otherViews
  116. );
  117. }
  118. // Remove any empty group view that may have been created by
  119. // addChoiceViewGroupedBy()
  120. foreach ($preferredViews as $key => $view) {
  121. if ($view instanceof ChoiceGroupView && 0 === count($view->choices)) {
  122. unset($preferredViews[$key]);
  123. }
  124. }
  125. foreach ($otherViews as $key => $view) {
  126. if ($view instanceof ChoiceGroupView && 0 === count($view->choices)) {
  127. unset($otherViews[$key]);
  128. }
  129. }
  130. return new ChoiceListView($otherViews, $preferredViews);
  131. }
  132. private static function addChoiceView($choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
  133. {
  134. // $value may be an integer or a string, since it's stored in the array
  135. // keys. We want to guarantee it's a string though.
  136. $key = $keys[$value];
  137. $nextIndex = is_int($index) ? $index++ : call_user_func($index, $choice, $key, $value);
  138. $view = new ChoiceView(
  139. $choice,
  140. $value,
  141. // If the labels are null, use the original choice key by default
  142. null === $label ? (string) $key : (string) call_user_func($label, $choice, $key, $value),
  143. // The attributes may be a callable or a mapping from choice indices
  144. // to nested arrays
  145. is_callable($attr) ? call_user_func($attr, $choice, $key, $value) : (isset($attr[$key]) ? $attr[$key] : array())
  146. );
  147. // $isPreferred may be null if no choices are preferred
  148. if ($isPreferred && call_user_func($isPreferred, $choice, $key, $value)) {
  149. $preferredViews[$nextIndex] = $view;
  150. } else {
  151. $otherViews[$nextIndex] = $view;
  152. }
  153. }
  154. private static function addChoiceViewsGroupedBy($groupBy, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
  155. {
  156. foreach ($groupBy as $key => $value) {
  157. if (null === $value) {
  158. continue;
  159. }
  160. // Add the contents of groups to new ChoiceGroupView instances
  161. if (is_array($value)) {
  162. $preferredViewsForGroup = array();
  163. $otherViewsForGroup = array();
  164. self::addChoiceViewsGroupedBy(
  165. $value,
  166. $label,
  167. $choices,
  168. $keys,
  169. $index,
  170. $attr,
  171. $isPreferred,
  172. $preferredViewsForGroup,
  173. $otherViewsForGroup
  174. );
  175. if (count($preferredViewsForGroup) > 0) {
  176. $preferredViews[$key] = new ChoiceGroupView($key, $preferredViewsForGroup);
  177. }
  178. if (count($otherViewsForGroup) > 0) {
  179. $otherViews[$key] = new ChoiceGroupView($key, $otherViewsForGroup);
  180. }
  181. continue;
  182. }
  183. // Add ungrouped items directly
  184. self::addChoiceView(
  185. $choices[$value],
  186. $value,
  187. $label,
  188. $keys,
  189. $index,
  190. $attr,
  191. $isPreferred,
  192. $preferredViews,
  193. $otherViews
  194. );
  195. }
  196. }
  197. private static function addChoiceViewGroupedBy($groupBy, $choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
  198. {
  199. $groupLabel = call_user_func($groupBy, $choice, $keys[$value], $value);
  200. if (null === $groupLabel) {
  201. // If the callable returns null, don't group the choice
  202. self::addChoiceView(
  203. $choice,
  204. $value,
  205. $label,
  206. $keys,
  207. $index,
  208. $attr,
  209. $isPreferred,
  210. $preferredViews,
  211. $otherViews
  212. );
  213. return;
  214. }
  215. $groupLabel = (string) $groupLabel;
  216. // Initialize the group views if necessary. Unnnecessarily built group
  217. // views will be cleaned up at the end of createView()
  218. if (!isset($preferredViews[$groupLabel])) {
  219. $preferredViews[$groupLabel] = new ChoiceGroupView($groupLabel);
  220. $otherViews[$groupLabel] = new ChoiceGroupView($groupLabel);
  221. }
  222. self::addChoiceView(
  223. $choice,
  224. $value,
  225. $label,
  226. $keys,
  227. $index,
  228. $attr,
  229. $isPreferred,
  230. $preferredViews[$groupLabel]->choices,
  231. $otherViews[$groupLabel]->choices
  232. );
  233. }
  234. }