PageRenderTime 32ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php

https://gitlab.com/pr0055/symfonypizza
PHP | 264 lines | 188 code | 41 blank | 35 comment | 20 complexity | 8bf6bc5eeb4d0d18ba66b798588a274c 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\Extension\Core\Type;
  11. use Symfony\Component\Form\AbstractType;
  12. use Symfony\Component\Form\FormInterface;
  13. use Symfony\Component\Form\FormBuilderInterface;
  14. use Symfony\Component\Form\ReversedTransformer;
  15. use Symfony\Component\Form\Exception\InvalidConfigurationException;
  16. use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
  17. use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
  18. use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
  19. use Symfony\Component\Form\FormView;
  20. use Symfony\Component\OptionsResolver\Options;
  21. use Symfony\Component\OptionsResolver\OptionsResolver;
  22. class TimeType extends AbstractType
  23. {
  24. private static $widgets = array(
  25. 'text' => 'Symfony\Component\Form\Extension\Core\Type\TextType',
  26. 'choice' => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
  27. );
  28. /**
  29. * {@inheritdoc}
  30. */
  31. public function buildForm(FormBuilderInterface $builder, array $options)
  32. {
  33. $parts = array('hour');
  34. $format = 'H';
  35. if ($options['with_seconds'] && !$options['with_minutes']) {
  36. throw new InvalidConfigurationException('You can not disable minutes if you have enabled seconds.');
  37. }
  38. if ($options['with_minutes']) {
  39. $format .= ':i';
  40. $parts[] = 'minute';
  41. }
  42. if ($options['with_seconds']) {
  43. $format .= ':s';
  44. $parts[] = 'second';
  45. }
  46. if ('single_text' === $options['widget']) {
  47. $builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format));
  48. } else {
  49. $hourOptions = $minuteOptions = $secondOptions = array(
  50. 'error_bubbling' => true,
  51. );
  52. if ('choice' === $options['widget']) {
  53. $hours = $minutes = array();
  54. foreach ($options['hours'] as $hour) {
  55. $hours[str_pad($hour, 2, '0', STR_PAD_LEFT)] = $hour;
  56. }
  57. // Only pass a subset of the options to children
  58. $hourOptions['choices'] = $hours;
  59. $hourOptions['placeholder'] = $options['placeholder']['hour'];
  60. $hourOptions['choice_translation_domain'] = $options['choice_translation_domain']['hour'];
  61. if ($options['with_minutes']) {
  62. foreach ($options['minutes'] as $minute) {
  63. $minutes[str_pad($minute, 2, '0', STR_PAD_LEFT)] = $minute;
  64. }
  65. $minuteOptions['choices'] = $minutes;
  66. $minuteOptions['placeholder'] = $options['placeholder']['minute'];
  67. $minuteOptions['choice_translation_domain'] = $options['choice_translation_domain']['minute'];
  68. }
  69. if ($options['with_seconds']) {
  70. $seconds = array();
  71. foreach ($options['seconds'] as $second) {
  72. $seconds[str_pad($second, 2, '0', STR_PAD_LEFT)] = $second;
  73. }
  74. $secondOptions['choices'] = $seconds;
  75. $secondOptions['placeholder'] = $options['placeholder']['second'];
  76. $secondOptions['choice_translation_domain'] = $options['choice_translation_domain']['second'];
  77. }
  78. // Append generic carry-along options
  79. foreach (array('required', 'translation_domain') as $passOpt) {
  80. $hourOptions[$passOpt] = $options[$passOpt];
  81. if ($options['with_minutes']) {
  82. $minuteOptions[$passOpt] = $options[$passOpt];
  83. }
  84. if ($options['with_seconds']) {
  85. $secondOptions[$passOpt] = $options[$passOpt];
  86. }
  87. }
  88. }
  89. $builder->add('hour', self::$widgets[$options['widget']], $hourOptions);
  90. if ($options['with_minutes']) {
  91. $builder->add('minute', self::$widgets[$options['widget']], $minuteOptions);
  92. }
  93. if ($options['with_seconds']) {
  94. $builder->add('second', self::$widgets[$options['widget']], $secondOptions);
  95. }
  96. $builder->addViewTransformer(new DateTimeToArrayTransformer($options['model_timezone'], $options['view_timezone'], $parts, 'text' === $options['widget']));
  97. }
  98. if ('string' === $options['input']) {
  99. $builder->addModelTransformer(new ReversedTransformer(
  100. new DateTimeToStringTransformer($options['model_timezone'], $options['model_timezone'], 'H:i:s')
  101. ));
  102. } elseif ('timestamp' === $options['input']) {
  103. $builder->addModelTransformer(new ReversedTransformer(
  104. new DateTimeToTimestampTransformer($options['model_timezone'], $options['model_timezone'])
  105. ));
  106. } elseif ('array' === $options['input']) {
  107. $builder->addModelTransformer(new ReversedTransformer(
  108. new DateTimeToArrayTransformer($options['model_timezone'], $options['model_timezone'], $parts)
  109. ));
  110. }
  111. }
  112. /**
  113. * {@inheritdoc}
  114. */
  115. public function buildView(FormView $view, FormInterface $form, array $options)
  116. {
  117. $view->vars = array_replace($view->vars, array(
  118. 'widget' => $options['widget'],
  119. 'with_minutes' => $options['with_minutes'],
  120. 'with_seconds' => $options['with_seconds'],
  121. ));
  122. // Change the input to a HTML5 time input if
  123. // * the widget is set to "single_text"
  124. // * the html5 is set to true
  125. if ($options['html5'] && 'single_text' === $options['widget']) {
  126. $view->vars['type'] = 'time';
  127. // we need to force the browser to display the seconds by
  128. // adding the HTML attribute step if not already defined.
  129. // Otherwise the browser will not display and so not send the seconds
  130. // therefore the value will always be considered as invalid.
  131. if ($options['with_seconds'] && !isset($view->vars['attr']['step'])) {
  132. $view->vars['attr']['step'] = 1;
  133. }
  134. }
  135. }
  136. /**
  137. * {@inheritdoc}
  138. */
  139. public function configureOptions(OptionsResolver $resolver)
  140. {
  141. $compound = function (Options $options) {
  142. return 'single_text' !== $options['widget'];
  143. };
  144. $placeholderDefault = function (Options $options) {
  145. return $options['required'] ? null : '';
  146. };
  147. $placeholderNormalizer = function (Options $options, $placeholder) use ($placeholderDefault) {
  148. if (is_array($placeholder)) {
  149. $default = $placeholderDefault($options);
  150. return array_merge(
  151. array('hour' => $default, 'minute' => $default, 'second' => $default),
  152. $placeholder
  153. );
  154. }
  155. return array(
  156. 'hour' => $placeholder,
  157. 'minute' => $placeholder,
  158. 'second' => $placeholder,
  159. );
  160. };
  161. $choiceTranslationDomainNormalizer = function (Options $options, $choiceTranslationDomain) {
  162. if (is_array($choiceTranslationDomain)) {
  163. $default = false;
  164. return array_replace(
  165. array('hour' => $default, 'minute' => $default, 'second' => $default),
  166. $choiceTranslationDomain
  167. );
  168. };
  169. return array(
  170. 'hour' => $choiceTranslationDomain,
  171. 'minute' => $choiceTranslationDomain,
  172. 'second' => $choiceTranslationDomain,
  173. );
  174. };
  175. $resolver->setDefaults(array(
  176. 'hours' => range(0, 23),
  177. 'minutes' => range(0, 59),
  178. 'seconds' => range(0, 59),
  179. 'widget' => 'choice',
  180. 'input' => 'datetime',
  181. 'with_minutes' => true,
  182. 'with_seconds' => false,
  183. 'model_timezone' => null,
  184. 'view_timezone' => null,
  185. 'placeholder' => $placeholderDefault,
  186. 'html5' => true,
  187. // Don't modify \DateTime classes by reference, we treat
  188. // them like immutable value objects
  189. 'by_reference' => false,
  190. 'error_bubbling' => false,
  191. // If initialized with a \DateTime object, FormType initializes
  192. // this option to "\DateTime". Since the internal, normalized
  193. // representation is not \DateTime, but an array, we need to unset
  194. // this option.
  195. 'data_class' => null,
  196. 'compound' => $compound,
  197. 'choice_translation_domain' => false,
  198. ));
  199. $resolver->setNormalizer('placeholder', $placeholderNormalizer);
  200. $resolver->setNormalizer('choice_translation_domain', $choiceTranslationDomainNormalizer);
  201. $resolver->setAllowedValues('input', array(
  202. 'datetime',
  203. 'string',
  204. 'timestamp',
  205. 'array',
  206. ));
  207. $resolver->setAllowedValues('widget', array(
  208. 'single_text',
  209. 'text',
  210. 'choice',
  211. ));
  212. $resolver->setAllowedTypes('hours', 'array');
  213. $resolver->setAllowedTypes('minutes', 'array');
  214. $resolver->setAllowedTypes('seconds', 'array');
  215. }
  216. /**
  217. * {@inheritdoc}
  218. */
  219. public function getBlockPrefix()
  220. {
  221. return 'time';
  222. }
  223. }