Completed
Push — master ( 7bfeaf...efad7d )
by Andreas
09:38
created

ClassMetadata::__sleep()   F

Complexity

Conditions 15
Paths 8192

Size

Total Lines 86
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 15.8857

Importance

Changes 0
Metric Value
dl 0
loc 86
ccs 32
cts 38
cp 0.8421
rs 2
c 0
b 0
f 0
cc 15
eloc 54
nc 8192
nop 0
crap 15.8857

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ODM\MongoDB\Mapping;
21
22
use Doctrine\Instantiator\Instantiator;
23
24
/**
25
 * A <tt>ClassMetadata</tt> instance holds all the object-document mapping metadata
26
 * of a document and it's references.
27
 *
28
 * Once populated, ClassMetadata instances are usually cached in a serialized form.
29
 *
30
 * <b>IMPORTANT NOTE:</b>
31
 *
32
 * The fields of this class are only public for 2 reasons:
33
 * 1) To allow fast READ access.
34
 * 2) To drastically reduce the size of a serialized instance (private/protected members
35
 *    get the whole class name, namespace inclusive, prepended to every property in
36
 *    the serialized representation).
37
 *
38
 * @since       1.0
39
 */
40
class ClassMetadata extends ClassMetadataInfo
41
{
42
    /**
43
     * The ReflectionProperty instances of the mapped class.
44
     *
45
     * @var \ReflectionProperty[]
46
     */
47
    public $reflFields = array();
48
49
    /**
50
     * @var \Doctrine\Instantiator\InstantiatorInterface|null
51
     */
52
    private $instantiator;
53
54
    /**
55
     * Initializes a new ClassMetadata instance that will hold the object-document mapping
56
     * metadata of the class with the given name.
57
     *
58
     * @param string $documentName The name of the document class the new instance is used for.
59
     */
60 980
    public function __construct($documentName)
61
    {
62 980
        parent::__construct($documentName);
63 980
        $this->reflClass = new \ReflectionClass($documentName);
64 980
        $this->namespace = $this->reflClass->getNamespaceName();
65 980
        $this->setCollection($this->reflClass->getShortName());
66 980
        $this->instantiator = new Instantiator();
67 980
    }
68
69
    /**
70
     * Map a field.
71
     *
72
     * @param array $mapping The mapping information.
73
     * @return void
74
     */
75 970
    public function mapField(array $mapping)
76
    {
77 970
        $mapping = parent::mapField($mapping);
78
79 969
        $reflProp = $this->reflClass->getProperty($mapping['fieldName']);
80 968
        $reflProp->setAccessible(true);
81 968
        $this->reflFields[$mapping['fieldName']] = $reflProp;
82 968
    }
83
84
    /**
85
     * Determines which fields get serialized.
86
     *
87
     * It is only serialized what is necessary for best unserialization performance.
88
     * That means any metadata properties that are not set or empty or simply have
89
     * their default value are NOT serialized.
90
     *
91
     * Parts that are also NOT serialized because they can not be properly unserialized:
92
     *      - reflClass (ReflectionClass)
93
     *      - reflFields (ReflectionProperty array)
94
     *
95
     * @return array The names of all the fields that should be serialized.
96
     */
97 6
    public function __sleep()
98
    {
99
        // This metadata is always serialized/cached.
100
        $serialized = array(
101 6
            'fieldMappings',
102
            'associationMappings',
103
            'identifier',
104
            'name',
105
            'namespace', // TODO: REMOVE
106
            'db',
107
            'collection',
108
            'readPreference',
109
            'readPreferenceTags',
110
            'writeConcern',
111
            'rootDocumentName',
112
            'generatorType',
113
            'generatorOptions',
114
            'idGenerator',
115
            'indexes',
116
            'shardKey',
117
        );
118
119
        // The rest of the metadata is only serialized if necessary.
120 6
        if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) {
121
            $serialized[] = 'changeTrackingPolicy';
122
        }
123
124 6
        if ($this->customRepositoryClassName) {
125 1
            $serialized[] = 'customRepositoryClassName';
126
        }
127
128 6
        if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE || $this->discriminatorField !== null) {
129 4
            $serialized[] = 'inheritanceType';
130 4
            $serialized[] = 'discriminatorField';
131 4
            $serialized[] = 'discriminatorValue';
132 4
            $serialized[] = 'discriminatorMap';
133 4
            $serialized[] = 'defaultDiscriminatorValue';
134 4
            $serialized[] = 'parentClasses';
135 4
            $serialized[] = 'subClasses';
136
        }
137
138 6
        if ($this->isMappedSuperclass) {
139 1
            $serialized[] = 'isMappedSuperclass';
140
        }
141
142 6
        if ($this->isEmbeddedDocument) {
143 1
            $serialized[] = 'isEmbeddedDocument';
144
        }
145
146 6
        if ($this->isQueryResultDocument) {
147
            $serialized[] = 'isQueryResultDocument';
148
        }
149
150 6
        if ($this->isVersioned) {
151
            $serialized[] = 'isVersioned';
152
            $serialized[] = 'versionField';
153
        }
154
155 6
        if ($this->lifecycleCallbacks) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->lifecycleCallbacks of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
156
            $serialized[] = 'lifecycleCallbacks';
157
        }
158
159 6
        if ($this->file) {
160 1
            $serialized[] = 'file';
161
        }
162
163 6
        if ($this->slaveOkay) {
0 ignored issues
show
Deprecated Code introduced by
The property Doctrine\ODM\MongoDB\Map...etadataInfo::$slaveOkay has been deprecated with message: in version 1.2 and will be removed in 2.0.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
164 1
            $serialized[] = 'slaveOkay';
165
        }
166
167 6
        if ($this->distance) {
168 1
            $serialized[] = 'distance';
169
        }
170
171 6
        if ($this->collectionCapped) {
172 1
            $serialized[] = 'collectionCapped';
173 1
            $serialized[] = 'collectionSize';
174 1
            $serialized[] = 'collectionMax';
175
        }
176
177 6
        if ($this->isReadOnly) {
178
            $serialized[] = 'isReadOnly';
179
        }
180
181 6
        return $serialized;
182
    }
183
184
    /**
185
     * Restores some state that can not be serialized/unserialized.
186
     *
187
     * @return void
188
     */
189 6
    public function __wakeup()
190
    {
191
        // Restore ReflectionClass and properties
192 6
        $this->reflClass = new \ReflectionClass($this->name);
193 6
        $this->instantiator = $this->instantiator ?: new Instantiator();
194
195 6
        foreach ($this->fieldMappings as $field => $mapping) {
196 3
            if (isset($mapping['declared'])) {
197 1
                $reflField = new \ReflectionProperty($mapping['declared'], $field);
198
            } else {
199 3
                $reflField = $this->reflClass->getProperty($field);
200
            }
201 3
            $reflField->setAccessible(true);
202 3
            $this->reflFields[$field] = $reflField;
203
        }
204 6
    }
205
206
    /**
207
     * Creates a new instance of the mapped class, without invoking the constructor.
208
     *
209
     * @return object
210
     */
211 400
    public function newInstance()
212
    {
213 400
        return $this->instantiator->instantiate($this->name);
214
    }
215
}
216