PageRenderTime 52ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

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

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