Completed
Pull Request — master (#875)
by Asmir
26:09 queued 11:12
created

PropertyMetadata   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Test Coverage

Coverage 97.85%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 27
c 2
b 0
f 0
lcom 2
cbo 3
dl 0
loc 182
ccs 91
cts 93
cp 0.9785
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
C setAccessor() 0 29 13
A getValue() 0 13 3
A setValue() 0 9 2
A setType() 0 8 2
B serialize() 0 30 1
B unserialize() 0 46 5
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 JMS\Serializer\TypeParser;
23
use Metadata\PropertyMetadata as BasePropertyMetadata;
24
25
class PropertyMetadata extends BasePropertyMetadata
26
{
27
    const ACCESS_TYPE_PROPERTY = 'property';
28
    const ACCESS_TYPE_PUBLIC_METHOD = 'public_method';
29
30
    public $sinceVersion;
31
    public $untilVersion;
32
    public $groups;
33
    public $serializedName;
34
    public $type;
35
    public $xmlCollection = false;
36
    public $xmlCollectionInline = false;
37
    public $xmlCollectionSkipWhenEmpty = true;
38
    public $xmlEntryName;
39
    public $xmlEntryNamespace;
40
    public $xmlKeyAttribute;
41
    public $xmlAttribute = false;
42
    public $xmlValue = false;
43
    public $xmlNamespace;
44
    public $xmlKeyValuePairs = false;
45
    public $xmlElementCData = true;
46
    public $getter;
47
    public $setter;
48
    public $inline = false;
49
    public $skipWhenEmpty = false;
50
    public $readOnly = false;
51
    public $xmlAttributeMap = false;
52
    public $maxDepth = null;
53
    public $excludeIf = null;
54
55
    private $closureAccessor;
56
57 291
    private static $typeParser;
58
59 291
    public function __construct($class, $name)
60 15
    {
61
        parent::__construct($class, $name);
62 15
        $this->closureAccessor = \Closure::bind(function ($o, $name) {
63 11
            return $o->$name;
64 7
        }, null, $class);
65 4
    }
66 1
    public function setAccessor($type, $getter = null, $setter = null)
67 3
    {
68 1
        if (self::ACCESS_TYPE_PUBLIC_METHOD === $type) {
69
            $class = $this->reflection->getDeclaringClass();
70 2
71
            if (empty($getter)) {
72
                if ($class->hasMethod('get' . $this->name) && $class->getMethod('get' . $this->name)->isPublic()) {
73
                    $getter = 'get' . $this->name;
74 13
                } elseif ($class->hasMethod('is' . $this->name) && $class->getMethod('is' . $this->name)->isPublic()) {
75 7
                    $getter = 'is' . $this->name;
76 6
                } elseif ($class->hasMethod('has' . $this->name) && $class->getMethod('has' . $this->name)->isPublic()) {
77
                    $getter = 'has' . $this->name;
78 1
                } else {
79
                    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 288
            if (empty($setter) && !$this->readOnly) {
84 288
                if ($class->hasMethod('set' . $this->name) && $class->getMethod('set' . $this->name)->isPublic()) {
85 288
                    $setter = 'set' . $this->name;
86
                } else {
87 202
                    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 202
            }
90 191
        }
91
92
        $this->getter = $getter;
93 38
        $this->setter = $setter;
94
    }
95
96 62
    public function getValue($obj)
97
    {
98 62
        if (null === $this->getter) {
99 57
            if (null !== $this->closureAccessor) {
100 57
                $accessor = $this->closureAccessor;
101
                return $accessor($obj, $this->name);
102
            }
103 7
104 7
            return parent::getValue($obj);
105
        }
106 249
107
        return $obj->{$this->getter}();
108 249
    }
109 1
110
    public function setValue($obj, $value)
111
    {
112 249
        if (null === $this->setter) {
113 249
            parent::setValue($obj, $value);
114
            return;
115 1
        }
116
117 1
        $obj->{$this->setter}($value);
118 1
    }
119 1
120 1
    public function setType($type)
121 1
    {
122 1
        if (null === self::$typeParser) {
123 1
            self::$typeParser = new TypeParser();
124 1
        }
125 1
126 1
        $this->type = self::$typeParser->parse($type);
127 1
    }
128 1
129 1
    public function serialize()
130 1
    {
131 1
        return serialize(array(
132 1
            $this->sinceVersion,
133 1
            $this->untilVersion,
134 1
            $this->groups,
135 1
            $this->serializedName,
136 1
            $this->type,
137 1
            $this->xmlCollection,
138 1
            $this->xmlCollectionInline,
139 1
            $this->xmlEntryName,
140 1
            $this->xmlKeyAttribute,
141 1
            $this->xmlAttribute,
142 1
            $this->xmlValue,
143
            $this->xmlNamespace,
144
            $this->xmlKeyValuePairs,
145
            $this->xmlElementCData,
146 1
            $this->getter,
147
            $this->setter,
148 1
            $this->inline,
149
            $this->readOnly,
150 1
            $this->xmlAttributeMap,
151 1
            $this->maxDepth,
152 1
            parent::serialize(),
153 1
            'xmlEntryNamespace' => $this->xmlEntryNamespace,
154 1
            'xmlCollectionSkipWhenEmpty' => $this->xmlCollectionSkipWhenEmpty,
155 1
            'excludeIf' => $this->excludeIf,
156 1
            'skipWhenEmpty' => $this->skipWhenEmpty,
157 1
        ));
158 1
    }
159 1
160 1
    public function unserialize($str)
161 1
    {
162 1
        $unserialized = unserialize($str);
163 1
        list(
164 1
            $this->sinceVersion,
165 1
            $this->untilVersion,
166 1
            $this->groups,
167 1
            $this->serializedName,
168 1
            $this->type,
169 1
            $this->xmlCollection,
170
            $this->xmlCollectionInline,
171 1
            $this->xmlEntryName,
172
            $this->xmlKeyAttribute,
173 1
            $this->xmlAttribute,
174
            $this->xmlValue,
175
            $this->xmlNamespace,
176 1
            $this->xmlKeyValuePairs,
177 1
            $this->xmlElementCData,
178
            $this->getter,
179 1
            $this->setter,
180
            $this->inline,
181
            $this->readOnly,
182 1
            $this->xmlAttributeMap,
183 1
            $this->maxDepth,
184
            $parentStr
185
            ) = $unserialized;
186 1
187 1
        if (isset($unserialized['xmlEntryNamespace'])) {
188
            $this->xmlEntryNamespace = $unserialized['xmlEntryNamespace'];
189
        }
190
        if (isset($unserialized['xmlCollectionSkipWhenEmpty'])) {
191
            $this->xmlCollectionSkipWhenEmpty = $unserialized['xmlCollectionSkipWhenEmpty'];
192
        }
193
        if (isset($unserialized['excludeIf'])) {
194
            $this->excludeIf = $unserialized['excludeIf'];
195
        }
196
        if (isset($unserialized['skipWhenEmpty'])) {
197
            $this->skipWhenEmpty = $unserialized['skipWhenEmpty'];
198
        }
199
200
        parent::unserialize($parentStr);
201
202
        $this->closureAccessor = \Closure::bind(function ($o, $name) {
203
            return $o->$name;
204
        }, null, $this->class);
205
    }
206
}
207