Completed
Pull Request — master (#900)
by Michael
11:10 queued 08:18
created

PropertyMetadata::unserialize()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 45
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 5.0157

Importance

Changes 0
Metric Value
cc 5
eloc 36
nc 16
nop 1
dl 0
loc 45
ccs 32
cts 35
cp 0.9143
crap 5.0157
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright 2016 Johannes M. Schmitt <[email protected]>
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
namespace JMS\Serializer\Metadata;
22
23
use JMS\Serializer\Exception\RuntimeException;
24
use Metadata\PropertyMetadata as BasePropertyMetadata;
25
26
class PropertyMetadata extends BasePropertyMetadata
27
{
28
    const ACCESS_TYPE_PROPERTY = 'property';
29
    const ACCESS_TYPE_PUBLIC_METHOD = 'public_method';
30
31
    public $sinceVersion;
32
    public $untilVersion;
33
    public $groups;
34
    public $serializedName;
35
    public $type;
36
    public $xmlCollection = false;
37
    public $xmlCollectionInline = false;
38
    public $xmlCollectionSkipWhenEmpty = true;
39
    public $xmlEntryName;
40
    public $xmlEntryNamespace;
41
    public $xmlKeyAttribute;
42
    public $xmlAttribute = false;
43
    public $xmlValue = false;
44
    public $xmlNamespace;
45
    public $xmlKeyValuePairs = false;
46
    public $xmlElementCData = true;
47
    public $getter;
48
    public $setter;
49
    public $inline = false;
50
    public $skipWhenEmpty = false;
51
    public $readOnly = false;
52
    public $xmlAttributeMap = false;
53
    public $maxDepth = null;
54
    public $excludeIf = null;
55
56
    private $closureAccessor;
57
58 261
    public function __construct($class, $name)
59
    {
60 261
        parent::__construct($class, $name);
61 261
        $this->closureAccessor = \Closure::bind(function ($o, $name) {
62 148
            return $o->$name;
63 261
        }, null, $class);
64 261
    }
65
66 243
    public function setAccessor($type, $getter = null, $setter = null)
67
    {
68 243
        if (self::ACCESS_TYPE_PUBLIC_METHOD === $type) {
69 14
            $class = $this->reflection->getDeclaringClass();
70
71 14
            if (empty($getter)) {
72 10
                if ($class->hasMethod('get' . $this->name) && $class->getMethod('get' . $this->name)->isPublic()) {
73 6
                    $getter = 'get' . $this->name;
74 4
                } elseif ($class->hasMethod('is' . $this->name) && $class->getMethod('is' . $this->name)->isPublic()) {
75 1
                    $getter = 'is' . $this->name;
76 3
                } elseif ($class->hasMethod('has' . $this->name) && $class->getMethod('has' . $this->name)->isPublic()) {
77 1
                    $getter = 'has' . $this->name;
78
                } else {
79 2
                    throw new RuntimeException(sprintf('There is neither a public %s method, nor a public %s method, nor a public %s method in class %s. Please specify which public method should be used for retrieving the value of the property %s.', 'get' . ucfirst($this->name), 'is' . ucfirst($this->name), 'has' . ucfirst($this->name), $this->class, $this->name));
80
                }
81
            }
82
83 12
            if (empty($setter) && !$this->readOnly) {
84 6
                if ($class->hasMethod('set' . $this->name) && $class->getMethod('set' . $this->name)->isPublic()) {
85 5
                    $setter = 'set' . $this->name;
86
                } else {
87 1
                    throw new RuntimeException(sprintf('There is no public %s method in class %s. Please specify which public method should be used for setting the value of the property %s.', 'set' . ucfirst($this->name), $this->class, $this->name));
88
                }
89
            }
90
        }
91
92 240
        $this->getter = $getter;
93 240
        $this->setter = $setter;
94 240
    }
95
96 158
    public function getValue($obj)
97
    {
98 158
        if (null === $this->getter) {
99 148
            $accessor = $this->closureAccessor;
100 148
            return $accessor($obj, $this->name);
101
        }
102
103 28
        return $obj->{$this->getter}();
104
    }
105
106 63
    public function setValue($obj, $value)
107
    {
108 63
        if (null === $this->setter) {
109 58
            parent::setValue($obj, $value);
110 58
            return;
111
        }
112
113 7
        $obj->{$this->setter}($value);
114 7
    }
115
116 200
    public function setType(array $type)
117
    {
118 200
        $this->type = $type;
119 200
    }
120
121 1
    public function serialize()
122
    {
123 1
        return serialize([
124 1
            $this->sinceVersion,
125 1
            $this->untilVersion,
126 1
            $this->groups,
127 1
            $this->serializedName,
128 1
            $this->type,
129 1
            $this->xmlCollection,
130 1
            $this->xmlCollectionInline,
131 1
            $this->xmlEntryName,
132 1
            $this->xmlKeyAttribute,
133 1
            $this->xmlAttribute,
134 1
            $this->xmlValue,
135 1
            $this->xmlNamespace,
136 1
            $this->xmlKeyValuePairs,
137 1
            $this->xmlElementCData,
138 1
            $this->getter,
139 1
            $this->setter,
140 1
            $this->inline,
141 1
            $this->readOnly,
142 1
            $this->xmlAttributeMap,
143 1
            $this->maxDepth,
144 1
            parent::serialize(),
145 1
            'xmlEntryNamespace' => $this->xmlEntryNamespace,
146 1
            'xmlCollectionSkipWhenEmpty' => $this->xmlCollectionSkipWhenEmpty,
147 1
            'excludeIf' => $this->excludeIf,
148 1
            'skipWhenEmpty' => $this->skipWhenEmpty,
149
        ]);
150
    }
151
152 1
    public function unserialize($str)
153
    {
154 1
        $unserialized = unserialize($str);
155
        list(
156 1
            $this->sinceVersion,
157 1
            $this->untilVersion,
158 1
            $this->groups,
159 1
            $this->serializedName,
160 1
            $this->type,
161 1
            $this->xmlCollection,
162 1
            $this->xmlCollectionInline,
163 1
            $this->xmlEntryName,
164 1
            $this->xmlKeyAttribute,
165 1
            $this->xmlAttribute,
166 1
            $this->xmlValue,
167 1
            $this->xmlNamespace,
168 1
            $this->xmlKeyValuePairs,
169 1
            $this->xmlElementCData,
170 1
            $this->getter,
171 1
            $this->setter,
172 1
            $this->inline,
173 1
            $this->readOnly,
174 1
            $this->xmlAttributeMap,
175 1
            $this->maxDepth,
176
            $parentStr
177 1
            ) = $unserialized;
178
179 1
        if (isset($unserialized['xmlEntryNamespace'])) {
180
            $this->xmlEntryNamespace = $unserialized['xmlEntryNamespace'];
181
        }
182 1
        if (isset($unserialized['xmlCollectionSkipWhenEmpty'])) {
183 1
            $this->xmlCollectionSkipWhenEmpty = $unserialized['xmlCollectionSkipWhenEmpty'];
184
        }
185 1
        if (isset($unserialized['excludeIf'])) {
186
            $this->excludeIf = $unserialized['excludeIf'];
187
        }
188 1
        if (isset($unserialized['skipWhenEmpty'])) {
189 1
            $this->skipWhenEmpty = $unserialized['skipWhenEmpty'];
190
        }
191
192 1
        parent::unserialize($parentStr);
193
194 1
        $this->closureAccessor = \Closure::bind(function ($o, $name) {
195
            return $o->$name;
196 1
        }, null, $this->class);
197 1
    }
198
}
199