Completed
Pull Request — master (#1661)
by Andreas
08:41 queued 03:51
created

ClassMetadataFactory::completeIdGeneratorMapping()   C

Complexity

Conditions 18
Paths 24

Size

Total Lines 66
Code Lines 50

Duplication

Lines 26
Ratio 39.39 %

Code Coverage

Tests 30
CRAP Score 38.736

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 26
loc 66
ccs 30
cts 50
cp 0.6
rs 5.8227
cc 18
eloc 50
nc 24
nop 1
crap 38.736

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\Common\Persistence\Mapping\AbstractClassMetadataFactory;
23
use Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
24
use Doctrine\Common\Persistence\Mapping\ReflectionService;
25
use Doctrine\ODM\MongoDB\Configuration;
26
use Doctrine\ODM\MongoDB\DocumentManager;
27
use Doctrine\ODM\MongoDB\Event\LoadClassMetadataEventArgs;
28
use Doctrine\ODM\MongoDB\Events;
29
use Doctrine\ODM\MongoDB\Id\AbstractIdGenerator;
30
use Doctrine\ODM\MongoDB\Id\AlnumGenerator;
31
use Doctrine\ODM\MongoDB\Id\AutoGenerator;
32
use Doctrine\ODM\MongoDB\Id\IncrementGenerator;
33
use Doctrine\ODM\MongoDB\Id\UuidGenerator;
34
35
/**
36
 * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
37
 * metadata mapping informations of a class which describes how a class should be mapped
38
 * to a document database.
39
 *
40
 * @since       1.0
41
 */
42
class ClassMetadataFactory extends AbstractClassMetadataFactory
43
{
44
    protected $cacheSalt = "\$MONGODBODMCLASSMETADATA";
45
46
    /** @var DocumentManager The DocumentManager instance */
47
    private $dm;
48
49
    /** @var Configuration The Configuration instance */
50
    private $config;
51
52
    /** @var \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver The used metadata driver. */
53
    private $driver;
54
55
    /** @var \Doctrine\Common\EventManager The event manager instance */
56
    private $evm;
57
58
    /**
59
     * Sets the DocumentManager instance for this class.
60
     *
61
     * @param DocumentManager $dm The DocumentManager instance
62
     */
63 1182
    public function setDocumentManager(DocumentManager $dm)
64
    {
65 1182
        $this->dm = $dm;
66 1182
    }
67
68
    /**
69
     * Sets the Configuration instance
70
     *
71
     * @param Configuration $config
72
     */
73 1182
    public function setConfiguration(Configuration $config)
74
    {
75 1182
        $this->config = $config;
76 1182
    }
77
78
    /**
79
     * Lazy initialization of this stuff, especially the metadata driver,
80
     * since these are not needed at all when a metadata cache is active.
81
     */
82 936
    protected function initialize()
83
    {
84 936
        $this->driver = $this->config->getMetadataDriverImpl();
85 936
        $this->evm = $this->dm->getEventManager();
86 936
        $this->initialized = true;
87 936
    }
88
89
    /**
90
     * {@inheritDoc}
91
     */
92
    protected function getFqcnFromAlias($namespaceAlias, $simpleClassName)
93
    {
94
        return $this->config->getDocumentNamespace($namespaceAlias) . '\\' . $simpleClassName;
95
    }
96
97
    /**
98
     * {@inheritDoc}
99
     */
100 381
    protected function getDriver()
101
    {
102 381
        return $this->driver;
103
    }
104
105
    /**
106
     * {@inheritDoc}
107
     */
108 932
    protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService)
109
    {
110 932
    }
111
112
    /**
113
     * {@inheritDoc}
114
     */
115 936
    protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService)
116
    {
117 936
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122 932
    protected function isEntity(ClassMetadataInterface $class)
123
    {
124 932
        return ! $class->isMappedSuperclass && ! $class->isEmbeddedDocument && ! $class->isQueryResultDocument;
0 ignored issues
show
Bug introduced by
Accessing isMappedSuperclass on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
Accessing isEmbeddedDocument on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
Accessing isQueryResultDocument on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     */
130 936
    protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents = array())
131
    {
132
        /** @var $class ClassMetadata */
133
        /** @var $parent ClassMetadata */
134 936
        if ($parent) {
135 379
            $class->setInheritanceType($parent->inheritanceType);
136 379
            $class->setDiscriminatorField($parent->discriminatorField);
137 379
            $class->setDiscriminatorMap($parent->discriminatorMap);
138 379
            $class->setDefaultDiscriminatorValue($parent->defaultDiscriminatorValue);
139 379
            $class->setIdGeneratorType($parent->generatorType);
140 379
            $this->addInheritedFields($class, $parent);
0 ignored issues
show
Compatibility introduced by
$class of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ODM\Mong...\Mapping\ClassMetadata>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
141 379
            $this->addInheritedRelations($class, $parent);
0 ignored issues
show
Compatibility introduced by
$class of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ODM\Mong...\Mapping\ClassMetadata>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
142 379
            $this->addInheritedIndexes($class, $parent);
0 ignored issues
show
Compatibility introduced by
$class of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ODM\Mong...\Mapping\ClassMetadata>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
143 379
            $this->setInheritedShardKey($class, $parent);
0 ignored issues
show
Compatibility introduced by
$class of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ODM\Mong...\Mapping\ClassMetadata>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
144 379
            $class->setIdentifier($parent->identifier);
145 379
            $class->setVersioned($parent->isVersioned);
146 379
            $class->setVersionField($parent->versionField);
147 379
            $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
148 379
            $class->setAlsoLoadMethods($parent->alsoLoadMethods);
149 379
            $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
150 379
            $class->setReadPreference($parent->readPreference, $parent->readPreferenceTags);
151 379
            $class->setWriteConcern($parent->writeConcern);
152 379
            $class->setFile($parent->getFile());
153 379
            if ($parent->isMappedSuperclass) {
154 313
                $class->setCustomRepositoryClass($parent->customRepositoryClassName);
155
            }
156
        }
157
158
        // Invoke driver
159
        try {
160 936
            $this->driver->loadMetadataForClass($class->getName(), $class);
161 6
        } catch (\ReflectionException $e) {
162
            throw MappingException::reflectionFailure($class->getName(), $e);
163
        }
164
165 932
        $this->validateIdentifier($class);
0 ignored issues
show
Compatibility introduced by
$class of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ODM\Mong...\Mapping\ClassMetadata>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
166
167 932
        if ($parent && $rootEntityFound && $parent->generatorType === $class->generatorType) {
0 ignored issues
show
Bug introduced by
Accessing generatorType on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
168 111
            if ($parent->generatorType) {
169 111
                $class->setIdGeneratorType($parent->generatorType);
170
            }
171 111
            if ($parent->generatorOptions) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parent->generatorOptions 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...
172
                $class->setIdGeneratorOptions($parent->generatorOptions);
173
            }
174 111
            if ($parent->idGenerator) {
175 111
                $class->setIdGenerator($parent->idGenerator);
176
            }
177
        } else {
178 932
            $this->completeIdGeneratorMapping($class);
0 ignored issues
show
Compatibility introduced by
$class of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ODM\Mong...ping\ClassMetadataInfo>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
179
        }
180
181 932
        if ($parent && $parent->isInheritanceTypeSingleCollection()) {
182 96
            $class->setDatabase($parent->getDatabase());
183 96
            $class->setCollection($parent->getCollection());
184
        }
185
186 932
        $class->setParentClasses($nonSuperclassParents);
187
188 932 View Code Duplication
        if ($this->evm->hasListeners(Events::loadClassMetadata)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
189 2
            $eventArgs = new LoadClassMetadataEventArgs($class, $this->dm);
190 2
            $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
191
        }
192 932
    }
193
194
    /**
195
     * Validates the identifier mapping.
196
     *
197
     * @param ClassMetadata $class
198
     * @throws MappingException
199
     */
200 932
    protected function validateIdentifier($class)
201
    {
202 932
        if ( ! $class->identifier && ! $class->isMappedSuperclass && ! $class->isEmbeddedDocument && ! $class->isQueryResultDocument) {
203
            throw MappingException::identifierRequired($class->name);
204
        }
205 932
    }
206
207
    /**
208
     * Creates a new ClassMetadata instance for the given class name.
209
     *
210
     * @param string $className
211
     * @return \Doctrine\ODM\MongoDB\Mapping\ClassMetadata
212
     */
213 936
    protected function newClassMetadataInstance($className)
214
    {
215 936
        return new ClassMetadata($className);
216
    }
217
218 932
    private function completeIdGeneratorMapping(ClassMetadataInfo $class)
219
    {
220 932
        $idGenOptions = $class->generatorOptions;
221 932
        switch ($class->generatorType) {
222 932
            case ClassMetadata::GENERATOR_TYPE_AUTO:
223 861
                $class->setIdGenerator(new AutoGenerator());
224 861
                break;
225 155 View Code Duplication
            case ClassMetadata::GENERATOR_TYPE_INCREMENT:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
226 9
                $incrementGenerator = new IncrementGenerator();
227 9
                if (isset($idGenOptions['key'])) {
228
                    $incrementGenerator->setKey($idGenOptions['key']);
229
                }
230 9
                if (isset($idGenOptions['collection'])) {
231
                    $incrementGenerator->setCollection($idGenOptions['collection']);
232
                }
233 9
                if (isset($idGenOptions['startingId'])) {
234 1
                    $incrementGenerator->setStartingId((int) $idGenOptions['startingId']);
235
                }
236 9
                $class->setIdGenerator($incrementGenerator);
237 9
                break;
238 146
            case ClassMetadata::GENERATOR_TYPE_UUID:
239 4
                $uuidGenerator = new UuidGenerator();
240 4
                isset($idGenOptions['salt']) && $uuidGenerator->setSalt($idGenOptions['salt']);
241 4
                $class->setIdGenerator($uuidGenerator);
242 4
                break;
243 142 View Code Duplication
            case ClassMetadata::GENERATOR_TYPE_ALNUM:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
244 1
                $alnumGenerator = new AlnumGenerator();
245 1
                if (isset($idGenOptions['pad'])) {
246
                    $alnumGenerator->setPad($idGenOptions['pad']);
247
                }
248 1
                if (isset($idGenOptions['chars'])) {
249 1
                    $alnumGenerator->setChars($idGenOptions['chars']);
250
                } elseif (isset($idGenOptions['awkwardSafe'])) {
251
                    $alnumGenerator->setAwkwardSafeMode($idGenOptions['awkwardSafe']);
252
                }
253
254 1
                $class->setIdGenerator($alnumGenerator);
255 1
                break;
256 141
            case ClassMetadata::GENERATOR_TYPE_CUSTOM:
257
                if (empty($idGenOptions['class'])) {
258
                    throw MappingException::missingIdGeneratorClass($class->name);
259
                }
260
261
                $customGenerator = new $idGenOptions['class'];
262
                unset($idGenOptions['class']);
263
                if ( ! $customGenerator instanceof AbstractIdGenerator) {
264
                    throw MappingException::classIsNotAValidGenerator(get_class($customGenerator));
265
                }
266
267
                $methods = get_class_methods($customGenerator);
268
                foreach ($idGenOptions as $name => $value) {
269
                    $method = 'set' . ucfirst($name);
270
                    if ( ! in_array($method, $methods)) {
271
                        throw MappingException::missingGeneratorSetter(get_class($customGenerator), $name);
272
                    }
273
274
                    $customGenerator->$method($value);
275
                }
276
                $class->setIdGenerator($customGenerator);
277
                break;
278 141
            case ClassMetadata::GENERATOR_TYPE_NONE;
279 141
                break;
280
            default:
281
                throw new MappingException('Unknown generator type: ' . $class->generatorType);
282
        }
283 932
    }
284
285
    /**
286
     * Adds inherited fields to the subclass mapping.
287
     *
288
     * @param ClassMetadata $subClass
289
     * @param ClassMetadata $parentClass
290
     */
291 379
    private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass)
292
    {
293 379
        foreach ($parentClass->fieldMappings as $fieldName => $mapping) {
294 130 View Code Duplication
            if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
295 123
                $mapping['inherited'] = $parentClass->name;
296
            }
297 130
            if ( ! isset($mapping['declared'])) {
298 130
                $mapping['declared'] = $parentClass->name;
299
            }
300 130
            $subClass->addInheritedFieldMapping($mapping);
301
        }
302 379
        foreach ($parentClass->reflFields as $name => $field) {
303 130
            $subClass->reflFields[$name] = $field;
304
        }
305 379
    }
306
307
308
    /**
309
     * Adds inherited association mappings to the subclass mapping.
310
     *
311
     * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $subClass
312
     * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $parentClass
313
     *
314
     * @return void
315
     *
316
     * @throws MappingException
317
     */
318 379
    private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass)
319
    {
320 379
        foreach ($parentClass->associationMappings as $field => $mapping) {
321 78
            if ($parentClass->isMappedSuperclass) {
322 4
                $mapping['sourceDocument'] = $subClass->name;
323
            }
324
325 78 View Code Duplication
            if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
326 74
                $mapping['inherited'] = $parentClass->name;
327
            }
328 78
            if ( ! isset($mapping['declared'])) {
329 78
                $mapping['declared'] = $parentClass->name;
330
            }
331 78
            $subClass->addInheritedAssociationMapping($mapping);
332
        }
333 379
    }
334
335
    /**
336
     * Adds inherited indexes to the subclass mapping.
337
     *
338
     * @param ClassMetadata $subClass
339
     * @param ClassMetadata $parentClass
340
     */
341 379
    private function addInheritedIndexes(ClassMetadata $subClass, ClassMetadata $parentClass)
342
    {
343 379
        foreach ($parentClass->indexes as $index) {
344 53
            $subClass->addIndex($index['keys'], $index['options']);
345
        }
346 379
    }
347
348
    /**
349
     * Adds inherited shard key to the subclass mapping.
350
     *
351
     * @param ClassMetadata $subClass
352
     * @param ClassMetadata $parentClass
353
     */
354 379
    private function setInheritedShardKey(ClassMetadata $subClass, ClassMetadata $parentClass)
355
    {
356 379
        if ($parentClass->isSharded()) {
357 5
            $subClass->setShardKey(
358 5
                $parentClass->shardKey['keys'],
359 5
                $parentClass->shardKey['options']
360
            );
361
        }
362 379
    }
363
}
364