DataNavigator   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Test Coverage

Coverage 90.74%

Importance

Changes 0
Metric Value
wmc 27
eloc 49
dl 0
loc 141
ccs 49
cts 54
cp 0.9074
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A navigate() 0 9 2
A suggestedConfig() 0 19 5
C applyVisitorToData() 0 37 16
A isTimeFormat() 0 3 1
A getMetadataForClass() 0 11 2
A __construct() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace CCT\Component\ODMElasticsearch\Transformer;
6
7
use CCT\Component\ODMElasticsearch\Transformer\Exception\NoMetadataException;
8
use CCT\Component\ODMElasticsearch\Transformer\Visitor\VisitorInterface;
9
use Metadata\MetadataFactory;
10
use Metadata\MetadataFactoryInterface;
11
12
class DataNavigator implements DataNavigatorInterface
13
{
14
    /**
15
     * @var MetadataFactoryInterface|MetadataFactory
16
     */
17
    protected $metadataFactory;
18
19
    /**
20
     * DataNavigator constructor.
21
     *
22
     * @param MetadataFactoryInterface $metadataFactory
23
     */
24 14
    public function __construct(MetadataFactoryInterface $metadataFactory)
25
    {
26 14
        $this->metadataFactory = $metadataFactory;
27 14
    }
28
29
    /**
30
     * @param mixed $data
31
     * @param VisitorInterface $visitor
32
     * @param array|null $config format of array is ['type' => ]
33
     *
34
     * @return mixed
35
     */
36 14
    public function navigate($data, VisitorInterface $visitor, array $config = null)
37
    {
38
        // If the type was not given, we infer the most specific type from the
39
        // input data in serialization mode.
40 14
        if (null === $config) {
41 13
            $config = $this->suggestedConfig($data);
42
        }
43
44 14
        return $this->applyVisitorToData($data, $visitor, $config);
45
    }
46
47
    /**
48
     * Applies the visitor pattern to the data
49
     *
50
     * @param mixed $data
51
     * @param VisitorInterface $visitor
52
     * @param array|null $config
53
     *
54
     * @return array|mixed|null
55
     */
56 14
    protected function applyVisitorToData($data, VisitorInterface $visitor, array $config = null)
57
    {
58 14
        if (!isset($config['type'])) {
59
            throw new \RuntimeException('Config type not set for data navigator');
60
        }
61 14
        switch ($config['type']) {
62 14
            case 'NULL':
63 1
                return $visitor->visitNull($data, $config);
64
65 13
            case 'string':
66 6
                return $visitor->visitString($data, $config);
67
68 11
            case 'int':
69 11
            case 'integer':
70 1
                return $visitor->visitInteger($data, $config);
71
72 10
            case 'bool':
73 10
            case 'boolean':
74 5
                return $visitor->visitBoolean($data, $config);
75
76 8
            case 'double':
77 7
            case 'float':
78 1
                return $visitor->visitDouble($data, $config);
79 7
            case 'date':
80
                return $visitor->visitDate($data, $config);
81 7
            case 'dateTime':
82 7
            case 'datetime':
83 1
                return $visitor->visitDateTime($data, $config);
84 6
            case 'time':
85 1
                return $visitor->visitTime($data, $config);
86 5
            case 'array':
87 5
                return $visitor->visitArray((array)$data, $config);
88 4
            case 'object':
89 4
                return $visitor->visitObject($data, $config);
90
        }
91
92
        return null;
93
    }
94
95
    /**
96
     * Tries to guess the configuration based on VALUE type
97
     *
98
     * @param $data
99
     *
100
     * @return array
101
     */
102 13
    protected function suggestedConfig($data): array
103
    {
104 13
        $typeName = \gettype($data);
105
106 13
        if ($data instanceof \DateTimeInterface) {
107 1
            return ['type' => 'datetime', 'params' => []];
108
        }
109
110 12
        if ('string' === $typeName && $this->isTimeFormat($data)) {
111 1
            return ['type' => 'time', 'params' => []];
112
        }
113
114 11
        if ('object' === $typeName) {
115 3
            $className = \get_class($data);
116
117 3
            return ['type' => $typeName, 'class' => $className, 'params' => []];
118
        }
119
120 8
        return ['type' => $typeName, 'params' => []];
121
    }
122
123
    /**
124
     * @param $className
125
     *
126
     * @return \Metadata\ClassHierarchyMetadata|\Metadata\MergeableClassMetadata
127
     *
128
     * @throws NoMetadataException
129
     */
130 4
    public function getMetadataForClass($className)
131
    {
132 4
        $metadata = $this->metadataFactory->getMetadataForClass($className);
133
134 4
        if (null === $metadata) {
135
            throw new NoMetadataException(
136
                sprintf('No metadata was found for class "%s". Please check configuration', $className)
137
            );
138
        }
139
140 4
        return $metadata;
141
    }
142
143
    /**
144
     * Checks if a string is in a time format
145
     *
146
     * @param $string
147
     *
148
     * @return bool
149
     */
150 3
    protected function isTimeFormat($string): bool
151
    {
152 3
        return (bool)preg_match('/^(?:2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]$/', $string);
153
    }
154
}
155