1<?php 2namespace GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler; 3 4use JMS\Serializer\Context; 5use JMS\Serializer\GraphNavigator; 6use JMS\Serializer\Handler\SubscribingHandlerInterface; 7use JMS\Serializer\XmlDeserializationVisitor; 8use JMS\Serializer\XmlSerializationVisitor; 9use RuntimeException; 10 11class XmlSchemaDateHandler implements SubscribingHandlerInterface 12{ 13 14 protected $defaultTimezone; 15 16 public static function getSubscribingMethods() 17 { 18 return array( 19 array( 20 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION, 21 'format' => 'xml', 22 'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Date', 23 'method' => 'deserializeDate' 24 ), 25 array( 26 'direction' => GraphNavigator::DIRECTION_SERIALIZATION, 27 'format' => 'xml', 28 'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Date', 29 'method' => 'serializeDate' 30 ), 31 array( 32 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION, 33 'format' => 'xml', 34 'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\DateTime', 35 'method' => 'deserializeDateTime' 36 ), 37 array( 38 'direction' => GraphNavigator::DIRECTION_SERIALIZATION, 39 'format' => 'xml', 40 'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\DateTime', 41 'method' => 'serializeDateTime' 42 ), 43 array( 44 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION, 45 'format' => 'xml', 46 'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Time', 47 'method' => 'deserializeTime' 48 ), 49 array( 50 'direction' => GraphNavigator::DIRECTION_SERIALIZATION, 51 'format' => 'xml', 52 'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Time', 53 'method' => 'serializeTime' 54 ), 55 array( 56 'type' => 'DateInterval', 57 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION, 58 'format' => 'xml', 59 'method' => 'deserializeDateIntervalXml', 60 ), 61 ); 62 } 63 64 public function __construct($defaultTimezone = 'UTC') 65 { 66 $this->defaultTimezone = new \DateTimeZone($defaultTimezone); 67 68 } 69 70 public function deserializeDateIntervalXml(XmlDeserializationVisitor $visitor, $data, array $type){ 71 $attributes = $data->attributes('xsi', true); 72 if (isset($attributes['nil'][0]) && (string) $attributes['nil'][0] === 'true') { 73 return null; 74 } 75 return new \DateInterval((string)$data); 76 } 77 78 public function serializeDate(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context) 79 { 80 81 $v = $date->format('Y-m-d'); 82 83 return $visitor->visitSimpleString($v, $type, $context); 84 } 85 86 public function deserializeDate(XmlDeserializationVisitor $visitor, $data, array $type) 87 { 88 $attributes = $data->attributes('xsi', true); 89 if (isset($attributes['nil'][0]) && (string)$attributes['nil'][0] === 'true') { 90 return null; 91 } 92 if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})(Z|([+-]\d{2}:\d{2}))?$/', $data)) { 93 throw new RuntimeException(sprintf('Invalid date "%s", expected valid XML Schema date string.', $data)); 94 } 95 96 return $this->parseDateTime($data, $type); 97 } 98 99 public function serializeDateTime(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context) 100 { 101 102 $v = $date->format(\DateTime::W3C); 103 104 return $visitor->visitSimpleString($v, $type, $context); 105 } 106 107 public function deserializeDateTime(XmlDeserializationVisitor $visitor, $data, array $type) 108 { 109 $attributes = $data->attributes('xsi', true); 110 if (isset($attributes['nil'][0]) && (string)$attributes['nil'][0] === 'true') { 111 return null; 112 } 113 114 return $this->parseDateTime($data, $type); 115 116 } 117 118 public function serializeTime(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context) 119 { 120 $v = $date->format('H:i:s'); 121 if ($date->getTimezone()->getOffset($date) !== $this->defaultTimezone->getOffset($date)) { 122 $v .= $date->format('P'); 123 } 124 return $visitor->visitSimpleString($v, $type, $context); 125 } 126 127 public function deserializeTime(XmlDeserializationVisitor $visitor, $data, array $type) 128 { 129 $attributes = $data->attributes('xsi', true); 130 if (isset($attributes['nil'][0]) && (string)$attributes['nil'][0] === 'true') { 131 return null; 132 } 133 134 $data = (string)$data; 135 136 return new \DateTime($data, $this->defaultTimezone); 137 } 138 139 private function parseDateTime($data, array $type) 140 { 141 $timezone = isset($type['params'][1]) ? new \DateTimeZone($type['params'][1]) : $this->defaultTimezone; 142 $datetime = new \DateTime((string)$data, $timezone); 143 if (false === $datetime) { 144 throw new RuntimeException(sprintf('Invalid datetime "%s", expected valid XML Schema dateTime string.', $data)); 145 } 146 147 return $datetime; 148 } 149} 150 151