Passed
Branch master (bf85d9)
by Johannes
05:40
created

PropertyMetadata   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Test Coverage

Coverage 96.08%

Importance

Changes 0
Metric Value
dl 0
loc 174
ccs 98
cts 102
cp 0.9608
rs 10
c 0
b 0
f 0
wmc 26

7 Methods

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