Completed
Pull Request — master (#9)
by
unknown
14:13
created

XmlSchemaDateHandler::serializeDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 7
Ratio 100 %

Code Coverage

Tests 4
CRAP Score 1.008

Importance

Changes 0
Metric Value
dl 7
loc 7
ccs 4
cts 5
cp 0.8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
crap 1.008
1
<?php
2
namespace GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler;
3
4
use JMS\Serializer\Context;
5
use JMS\Serializer\GraphNavigator;
6
use JMS\Serializer\Handler\SubscribingHandlerInterface;
7
use JMS\Serializer\XmlDeserializationVisitor;
8
use JMS\Serializer\XmlSerializationVisitor;
9
use RuntimeException;
10
11
class XmlSchemaDateHandler implements SubscribingHandlerInterface
12
{
13
14
    protected $defaultTimezone;
15
    protected $serializeTimezone;
16
    protected $deserializeTimezone;
17
18
    public static function getSubscribingMethods()
19
    {
20
        return array(
21
            array(
22
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
23
                'format' => 'xml',
24
                'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Date',
25
                'method' => 'deserializeDate'
26
            ),
27
            array(
28
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
29
                'format' => 'xml',
30
                'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Date',
31
                'method' => 'serializeDate'
32
            ),
33
            array(
34
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
35
                'format' => 'xml',
36
                'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\DateTime',
37
                'method' => 'deserializeDateTime'
38
            ),
39
            array(
40
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
41
                'format' => 'xml',
42
                'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\DateTime',
43
                'method' => 'serializeDateTime'
44
            ),
45
            array(
46
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
47
                'format' => 'xml',
48
                'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Time',
49
                'method' => 'deserializeTime'
50
            ),
51
            array(
52
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
53
                'format' => 'xml',
54
                'type' => 'GoetasWebservices\Xsd\XsdToPhp\XMLSchema\Time',
55
                'method' => 'serializeTime'
56
            ),
57
            array(
58
                'type' => 'DateInterval',
59
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
60
                'format' => 'xml',
61
                'method' => 'deserializeDateIntervalXml',
62
            ),
63
        );
64 17
    }
65
66 17
    /**
67
     * @param string $defaultTimezone default timezone if timezone is absent in deserialized string
68 17
     * @param null $serializeTimezone timezone of serialized date/datetime/time. Works properly since php 7.0
69
     * @param null $deserializeTimezone timezone of deserialized date/datetime/time. Works properly since php 7.0
70
     *                                  note that $defaultTimezone may be applied first
71
     */
72
    public function __construct($defaultTimezone = 'UTC', $serializeTimezone = null, $deserializeTimezone = null)
73
    {
74
        $this->defaultTimezone = new \DateTimeZone($defaultTimezone);
75
        $this->serializeTimezone = $serializeTimezone ? new \DateTimeZone($serializeTimezone) : null;
76
        $this->deserializeTimezone = $deserializeTimezone ? new \DateTimeZone($deserializeTimezone) : null;
77
    }
78 5
79 View Code Duplication
    public function deserializeDateIntervalXml(XmlDeserializationVisitor $visitor, $data, array $type){
0 ignored issues
show
Unused Code introduced by
The parameter $visitor is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
80
        $attributes = $data->attributes('xsi', true);
81 5
        if (isset($attributes['nil'][0]) && (string) $attributes['nil'][0] === 'true') {
82
            return null;
83 5
        }
84
        return new \DateInterval((string)$data);
85
    }
86 5
87 View Code Duplication
    public function serializeDate(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88 5
    {
89 5
        $date = $this->prepareDateTimeBeforeSerialize($date);
90
        $v = $date->format('Y-m-d');
91
92 5
        return $visitor->visitSimpleString($v, $type, $context);
0 ignored issues
show
Unused Code introduced by
The call to XmlSerializationVisitor::visitSimpleString() has too many arguments starting with $context.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
93 1
    }
94
95
    public function deserializeDate(XmlDeserializationVisitor $visitor, $data, array $type)
0 ignored issues
show
Unused Code introduced by
The parameter $visitor is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
96 4
    {
97
        $attributes = $data->attributes('xsi', true);
98
        if (isset($attributes['nil'][0]) && (string)$attributes['nil'][0] === 'true') {
99 7
            return null;
100
        }
101
        if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})(Z|([+-]\d{2}:\d{2}))?$/', $data)) {
102 7
            throw new RuntimeException(sprintf('Invalid date "%s", expected valid XML Schema date string.', $data));
103
        }
104 7
105
        return $this->parseDateTime($data, $type);
106
    }
107
108 View Code Duplication
    public function serializeDateTime(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
109
    {
110
        $date = $this->prepareDateTimeBeforeSerialize($date);
111
        $v = $date->format(\DateTime::W3C);
112
113
        return $visitor->visitSimpleString($v, $type, $context);
0 ignored issues
show
Unused Code introduced by
The call to XmlSerializationVisitor::visitSimpleString() has too many arguments starting with $context.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
114
    }
115
116 View Code Duplication
    public function deserializeDateTime(XmlDeserializationVisitor $visitor, $data, array $type)
0 ignored issues
show
Unused Code introduced by
The parameter $visitor is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118
        $attributes = $data->attributes('xsi', true);
119
        if (isset($attributes['nil'][0]) && (string)$attributes['nil'][0] === 'true') {
120
            return null;
121
        }
122
123
        return $this->parseDateTime($data, $type);
124
125
    }
126
127
    public function serializeTime(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context)
128
    {
129
        $date = $this->prepareDateTimeBeforeSerialize($date);
130
        $v = $date->format('H:i:s');
131
        if ($date->getTimezone()->getOffset($date) !== $this->defaultTimezone->getOffset($date)) {
132
            $v .= $date->format('P');
133
        }
134
        return $visitor->visitSimpleString($v, $type, $context);
0 ignored issues
show
Unused Code introduced by
The call to XmlSerializationVisitor::visitSimpleString() has too many arguments starting with $context.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
135
    }
136
137
    public function deserializeTime(XmlDeserializationVisitor $visitor, $data, array $type)
0 ignored issues
show
Unused Code introduced by
The parameter $visitor is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
138
    {
139 4
        $attributes = $data->attributes('xsi', true);
140
        if (isset($attributes['nil'][0]) && (string)$attributes['nil'][0] === 'true') {
141 4
            return null;
142 4
        }
143 4
144
        if ($this->deserializeTimezone) {
145
            return $this->parseDateTime($data, $type);
146
        }
147 4
148
        $data = (string)$data;
149
150
        return new \DateTime($data, $this->defaultTimezone);
151
    }
152
153
    private function parseDateTime($data, array $type)
154
    {
155
        $timezone = isset($type['params'][1]) ? new \DateTimeZone($type['params'][1]) : $this->defaultTimezone;
156
        $datetime = new \DateTime((string)$data, $timezone);
157
        if (false === $datetime) {
158
            throw new RuntimeException(sprintf('Invalid datetime "%s", expected valid XML Schema dateTime string.', $data));
159
        }
160
161
        if ($this->deserializeTimezone) {
162
            $datetime->setTimezone($this->deserializeTimezone);
163
        }
164
165
        return $datetime;
166
    }
167
168
    private function prepareDateTimeBeforeSerialize(\DateTime $date)
169
    {
170
        if ($this->serializeTimezone) {
171
            $dateCopy = clone $date;
172
            $dateCopy->setTimezone($this->serializeTimezone);
173
            return $dateCopy;
174
        }
175
176
        return $date;
177
    }
178
}
179
180