Completed
Push — master ( f2e43e...df01cf )
by Maciej
14:18
created

lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Doctrine\ODM\MongoDB\Mapping;
4
5
use Doctrine\Instantiator\Instantiator;
6
7
/**
8
 * A <tt>ClassMetadata</tt> instance holds all the object-document mapping metadata
9
 * of a document and it's references.
10
 *
11
 * Once populated, ClassMetadata instances are usually cached in a serialized form.
12
 *
13
 * <b>IMPORTANT NOTE:</b>
14
 *
15
 * The fields of this class are only public for 2 reasons:
16
 * 1) To allow fast READ access.
17
 * 2) To drastically reduce the size of a serialized instance (private/protected members
18
 *    get the whole class name, namespace inclusive, prepended to every property in
19
 *    the serialized representation).
20
 *
21
 * @since       1.0
22
 */
23
class ClassMetadata extends ClassMetadataInfo
24
{
25
    /**
26
     * The ReflectionProperty instances of the mapped class.
27
     *
28
     * @var \ReflectionProperty[]
29
     */
30
    public $reflFields = array();
31
32
    /**
33
     * @var \Doctrine\Instantiator\InstantiatorInterface|null
34
     */
35
    private $instantiator;
36
37
    /**
38
     * Initializes a new ClassMetadata instance that will hold the object-document mapping
39
     * metadata of the class with the given name.
40
     *
41
     * @param string $documentName The name of the document class the new instance is used for.
42
     */
43 1464
    public function __construct($documentName)
44
    {
45 1464
        parent::__construct($documentName);
46 1464
        $this->reflClass = new \ReflectionClass($documentName);
47 1464
        $this->namespace = $this->reflClass->getNamespaceName();
48 1464
        $this->setCollection($this->reflClass->getShortName());
49 1464
        $this->instantiator = new Instantiator();
50 1464
    }
51
52
    /**
53
     * Map a field.
54
     *
55
     * @param array $mapping The mapping information.
56
     * @return void
57
     */
58 1392
    public function mapField(array $mapping)
59
    {
60 1392
        $mapping = parent::mapField($mapping);
61
62 1391
        $reflProp = $this->reflClass->getProperty($mapping['fieldName']);
63 1390
        $reflProp->setAccessible(true);
64 1390
        $this->reflFields[$mapping['fieldName']] = $reflProp;
65 1390
    }
66
67
    /**
68
     * Determines which fields get serialized.
69
     *
70
     * It is only serialized what is necessary for best unserialization performance.
71
     * That means any metadata properties that are not set or empty or simply have
72
     * their default value are NOT serialized.
73
     *
74
     * Parts that are also NOT serialized because they can not be properly unserialized:
75
     *      - reflClass (ReflectionClass)
76
     *      - reflFields (ReflectionProperty array)
77
     *
78
     * @return array The names of all the fields that should be serialized.
79
     */
80 6
    public function __sleep()
81
    {
82
        // This metadata is always serialized/cached.
83
        $serialized = array(
84 6
            'fieldMappings',
85
            'associationMappings',
86
            'identifier',
87
            'name',
88
            'namespace', // TODO: REMOVE
89
            'db',
90
            'collection',
91
            'readPreference',
92
            'readPreferenceTags',
93
            'writeConcern',
94
            'rootDocumentName',
95
            'generatorType',
96
            'generatorOptions',
97
            'idGenerator',
98
            'indexes',
99
            'shardKey',
100
        );
101
102
        // The rest of the metadata is only serialized if necessary.
103 6
        if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) {
104
            $serialized[] = 'changeTrackingPolicy';
105
        }
106
107 6
        if ($this->customRepositoryClassName) {
108 1
            $serialized[] = 'customRepositoryClassName';
109
        }
110
111 6
        if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE || $this->discriminatorField !== null) {
112 4
            $serialized[] = 'inheritanceType';
113 4
            $serialized[] = 'discriminatorField';
114 4
            $serialized[] = 'discriminatorValue';
115 4
            $serialized[] = 'discriminatorMap';
116 4
            $serialized[] = 'defaultDiscriminatorValue';
117 4
            $serialized[] = 'parentClasses';
118 4
            $serialized[] = 'subClasses';
119
        }
120
121 6
        if ($this->isMappedSuperclass) {
122 1
            $serialized[] = 'isMappedSuperclass';
123
        }
124
125 6
        if ($this->isEmbeddedDocument) {
126 1
            $serialized[] = 'isEmbeddedDocument';
127
        }
128
129 6
        if ($this->isQueryResultDocument) {
130
            $serialized[] = 'isQueryResultDocument';
131
        }
132
133 6
        if ($this->isVersioned) {
134
            $serialized[] = 'isVersioned';
135
            $serialized[] = 'versionField';
136
        }
137
138 6
        if ($this->lifecycleCallbacks) {
139
            $serialized[] = 'lifecycleCallbacks';
140
        }
141
142 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...
143 1
            $serialized[] = 'slaveOkay';
144
        }
145
146 6
        if ($this->collectionCapped) {
147 1
            $serialized[] = 'collectionCapped';
148 1
            $serialized[] = 'collectionSize';
149 1
            $serialized[] = 'collectionMax';
150
        }
151
152 6
        if ($this->isReadOnly) {
153
            $serialized[] = 'isReadOnly';
154
        }
155
156 6
        return $serialized;
157
    }
158
159
    /**
160
     * Restores some state that can not be serialized/unserialized.
161
     *
162
     * @return void
163
     */
164 6
    public function __wakeup()
165
    {
166
        // Restore ReflectionClass and properties
167 6
        $this->reflClass = new \ReflectionClass($this->name);
168 6
        $this->instantiator = $this->instantiator ?: new Instantiator();
169
170 6
        foreach ($this->fieldMappings as $field => $mapping) {
171 3
            if (isset($mapping['declared'])) {
172 1
                $reflField = new \ReflectionProperty($mapping['declared'], $field);
173
            } else {
174 3
                $reflField = $this->reflClass->getProperty($field);
175
            }
176 3
            $reflField->setAccessible(true);
177 3
            $this->reflFields[$field] = $reflField;
178
        }
179 6
    }
180
181
    /**
182
     * Creates a new instance of the mapped class, without invoking the constructor.
183
     *
184
     * @return object
185
     */
186 354
    public function newInstance()
187
    {
188 354
        return $this->instantiator->instantiate($this->name);
189
    }
190
}
191