AbstractReverseVisitor   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Test Coverage

Coverage 75%

Importance

Changes 0
Metric Value
wmc 14
eloc 43
dl 0
loc 110
ccs 33
cts 44
cp 0.75
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A navigateObjectHydrate() 0 38 6
A setDataNavigator() 0 3 1
B getConfigFromPropertyMetadata() 0 37 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace CCT\Component\ODMElasticsearch\Transformer\Visitor;
6
7
use CCT\Component\ODMElasticsearch\Metadata\Exception\InvalidArgumentException;
8
use CCT\Component\ODMElasticsearch\Metadata\PropertyMetadata;
9
use CCT\Component\ODMElasticsearch\Metadata\PropertyMetadataInterface;
10
use CCT\Component\ODMElasticsearch\Metadata\VirtualPropertyMetadata;
11
use CCT\Component\ODMElasticsearch\Repository\Exception\NoMetadataConfigException;
12
use CCT\Component\ODMElasticsearch\Transformer\DataNavigatorInterface;
13
use CCT\Component\ODMElasticsearch\Transformer\Exception\RuntimeException;
14
15
abstract class AbstractReverseVisitor implements ReverseVisitorInterface
16
{
17
    /**
18
     * @var DataNavigatorInterface
19
     */
20
    protected $dataNavigator;
21
22
    /**
23
     * Set data navigator for visitor
24
     *
25
     * @param DataNavigatorInterface $dataNavigator
26
     */
27 1
    public function setDataNavigator(DataNavigatorInterface $dataNavigator): void
28
    {
29 1
        $this->dataNavigator = $dataNavigator;
30 1
    }
31
32
    /**
33
     * Navigate object populating it with data from an array
34
     *
35
     * @param array $data
36
     * @param array $config
37
     *
38
     * @return mixed
39
     */
40 1
    protected function navigateObjectHydrate(array $data, array $config)
41
    {
42 1
        if (false === array_key_exists('class', $config)) {
43
            throw new InvalidArgumentException(
44
                'Reverse visitors must have the config opinion "class" set for object types'
45
            );
46
        }
47
48 1
        if (null === $this->dataNavigator) {
49
            throw new RuntimeException(
50
                'Data Navigator has not been set. Make sure to call setDataNavigator on visitor before transforming'
51
            );
52
        }
53
54 1
        $className = $config['class'];
55 1
        $metadata = $this->dataNavigator->getMetadataForClass($className);
56
57 1
        $object = $config['params']['populate_object'] ?? new $className;
58
59
        /** @var PropertyMetadata|VirtualPropertyMetadata $propertyMetadata */
60 1
        foreach ($metadata->getRootClassMetadata()->propertyMetadata as $propertyMetadata) {
0 ignored issues
show
Bug introduced by
The method getRootClassMetadata() does not exist on Metadata\MergeableClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

60
        foreach ($metadata->/** @scrutinizer ignore-call */ getRootClassMetadata()->propertyMetadata as $propertyMetadata) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
61 1
            if (!($propertyMetadata instanceof PropertyMetadataInterface)) {
62
                continue;
63
            }
64
65 1
            $index = $propertyMetadata->getFieldName() ?? $propertyMetadata->name;
0 ignored issues
show
Bug introduced by
Accessing name on the interface CCT\Component\ODMElastic...opertyMetadataInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
66
67 1
            if (false === array_key_exists($index, $data)) {
68 1
                continue;
69
            }
70
71 1
            $newConfig = $this->getConfigFromPropertyMetadata($propertyMetadata, $object);
72
73 1
            $value = $this->dataNavigator->navigate($data[$index], $this, $newConfig);
74 1
            $propertyMetadata->setValue($object, $value);
75
        }
76
77 1
        return $object;
78
    }
79
80
    /**
81
     * Get configuration from property metadata
82
     *
83
     * @param PropertyMetadataInterface $propertyMetadata
84
     * @param mixed $object
85
     *
86
     * @return array
87
     */
88 1
    protected function getConfigFromPropertyMetadata(PropertyMetadataInterface $propertyMetadata, $object = null): array
89
    {
90 1
        if (null === $propertyMetadata->getType()) {
91
            throw new InvalidArgumentException(
92
                'All properties must have a type set for reverse visit, ' . $propertyMetadata->getName()
93
            );
94
        }
95
96 1
        if ('object' === $propertyMetadata->getType()) {
97 1
            $className = $propertyMetadata->getTypeClass();
98 1
            if (null === $className) {
99
                throw new NoMetadataConfigException(
100
                    sprintf(
101
                        'Property "%s" could not resolve class type. ' .
102
                        'Please add class_type parameter to property config',
103
                        $propertyMetadata->getName()
104
                    )
105
                );
106
            }
107 1
            $params = [];
108
109 1
            if (null !== $object) {
110 1
                $relatedObject = $propertyMetadata->getValue($object);
111 1
                $params['populate_object'] = $relatedObject ?? null;
112
            }
113
114 1
            return array('type' => $propertyMetadata->getType(), 'class' => $className, $params);
115
        }
116
117 1
        if ('array' === $propertyMetadata->getType()) {
118 1
            $className = $propertyMetadata->getTypeClass();
119 1
            if (null !== $className) {
120 1
                return array('type' => $propertyMetadata->getType(), 'class' => $className, 'params' => array());
121
            }
122
        }
123
124 1
        return array('type' => $propertyMetadata->getType(), 'params' => array());
125
    }
126
}
127