DateTimeToArrayTransformer.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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\DataTransformer;
  11. use Symfony\Component\Form\Exception\UnexpectedTypeException;
  12. /**
  13. * Transforms between a normalized time and a localized time string/array.
  14. *
  15. * Options:
  16. *
  17. * * "input": The type of the normalized format ("time" or "timestamp"). Default: "datetime"
  18. * * "output": The type of the transformed format ("string" or "array"). Default: "string"
  19. * * "format": The format of the time string ("short", "medium", "long" or "full"). Default: "short"
  20. *
  21. * @author Bernhard Schussek <bernhard.schussek@symfony.com>
  22. * @author Florian Eckerstorfer <florian@eckerstorfer.org>
  23. */
  24. class DateTimeToArrayTransformer extends BaseDateTimeTransformer
  25. {
  26. private $pad;
  27. private $fields;
  28. public function __construct($inputTimezone = null, $outputTimezone = null, $fields = null, $pad = false)
  29. {
  30. parent::__construct($inputTimezone, $outputTimezone);
  31. if (is_null($fields)) {
  32. $fields = array('year', 'month', 'day', 'hour', 'minute', 'second');
  33. }
  34. $this->fields = $fields;
  35. $this->pad =$pad;
  36. }
  37. /**
  38. * Transforms a normalized date into a localized date string/array.
  39. *
  40. * @param DateTime $dateTime Normalized date.
  41. * @return string|array Localized date array.
  42. */
  43. public function transform($dateTime)
  44. {
  45. if (null === $dateTime) {
  46. return array_intersect_key(array(
  47. 'year' => '',
  48. 'month' => '',
  49. 'day' => '',
  50. 'hour' => '',
  51. 'minute' => '',
  52. 'second' => '',
  53. ), array_flip($this->fields));
  54. }
  55. if (!$dateTime instanceof \DateTime) {
  56. throw new UnexpectedTypeException($dateTime, '\DateTime');
  57. }
  58. $inputTimezone = $this->inputTimezone;
  59. $outputTimezone = $this->outputTimezone;
  60. if ($inputTimezone != $outputTimezone) {
  61. $dateTime->setTimezone(new \DateTimeZone($outputTimezone));
  62. }
  63. $result = array_intersect_key(array(
  64. 'year' => $dateTime->format('Y'),
  65. 'month' => $dateTime->format('m'),
  66. 'day' => $dateTime->format('d'),
  67. 'hour' => $dateTime->format('H'),
  68. 'minute' => $dateTime->format('i'),
  69. 'second' => $dateTime->format('s'),
  70. ), array_flip($this->fields));
  71. if (!$this->pad) {
  72. foreach ($result as &$entry) {
  73. // remove leading zeros
  74. $entry = (string)(int)$entry;
  75. }
  76. }
  77. return $result;
  78. }
  79. /**
  80. * Transforms a localized date string/array into a normalized date.
  81. *
  82. * @param array $value Localized date string/array
  83. * @return DateTime Normalized date
  84. */
  85. public function reverseTransform($value)
  86. {
  87. if (null === $value) {
  88. return null;
  89. }
  90. $inputTimezone = $this->inputTimezone;
  91. $outputTimezone = $this->outputTimezone;
  92. if (!is_array($value)) {
  93. throw new UnexpectedTypeException($value, 'array');
  94. }
  95. if (implode('', $value) === '') {
  96. return null;
  97. }
  98. $emptyFields = array();
  99. foreach ($this->fields as $field) {
  100. if (empty($value[$field])) {
  101. $emptyFields[] = $field;
  102. }
  103. }
  104. if (count($emptyFields) > 0) {
  105. throw new TransformationFailedException(sprintf(
  106. 'The fields "%s" should not be empty', implode('", "', $emptyFields)));
  107. }
  108. try {
  109. $dateTime = new \DateTime(sprintf(
  110. '%s-%s-%s %s:%s:%s %s',
  111. empty($value['year']) ? '1970' : $value['year'],
  112. empty($value['month']) ? '1' : $value['month'],
  113. empty($value['day']) ? '1' : $value['day'],
  114. empty($value['hour']) ? '0' : $value['hour'],
  115. empty($value['minute']) ? '0' : $value['minute'],
  116. empty($value['second']) ? '0' : $value['second'],
  117. $outputTimezone
  118. ));
  119. } catch (\Exception $e) {
  120. throw new TransformationFailedException($e->getMessage(), null, $e);
  121. }
  122. if ($inputTimezone != $outputTimezone) {
  123. $dateTime->setTimezone(new \DateTimeZone($inputTimezone));
  124. }
  125. return $dateTime;
  126. }
  127. }