Completed
Push — master ( a2eaba...a27a4d )
by Simonas
14:46 queued 08:23
created

Converter::addClassMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\ElasticsearchBundle\Mapping;
13
14
use ONGR\ElasticsearchBundle\Result\ObjectIterator;
15
16
/**
17
 * This class converts array to document object.
18
 */
19
class Converter
20
{
21
    private $propertyMetadata = [];
22
23
    public function addClassMetadata(string $class, array $metadata): void
24
    {
25
        $this->propertyMetadata[$class] = $metadata;
26
    }
27
28
    public function convertArrayToDocument(string $namespace, array $raw)
29
    {
30
        if (!isset($this->propertyMetadata[$namespace])) {
31
            throw new \Exception("Cannot convert array to object of class `$class`.");
32
        }
33
34
        return $this->denormalize($raw, $namespace);
35
    }
36
37
    public function convertDocumentToArray($document): array
38
    {
39
        $class = get_class($document);
40
41
        if (!isset($this->propertyMetadata[$class])) {
42
            throw new \Exception("Cannot convert object of class `$class` to array.");
43
        }
44
45
        return $this->normalize($document);
46
    }
47
48
    protected function normalize($document, $metadata = null)
49
    {
50
        $metadata = $metadata ?? $this->propertyMetadata[get_class($document)];
51
        $result = [];
52
53
        foreach ($metadata as $field => $fieldMeta) {
54
            $getter = $fieldMeta['getter'];
55
            $value = $fieldMeta['public'] ? $document->{$fieldMeta['name']} : $document->$getter();
56
57
            if ($fieldMeta['embeded']) {
58
                if (is_iterable($value)) {
59
                    foreach ($value as $item) {
60
                        $result[$field][] = $this->normalize($item, $fieldMeta['sub_properties']);
61
                    }
62
                } else {
63
                    $result[$field] = $this->normalize($value, $fieldMeta['sub_properties']);
64
                }
65
            } else {
66
                if ($value instanceof \DateTime) {
67
                    $value = $value->format(\DateTime::ISO8601);
68
                }
69
                $result[$field] = $value;
70
            }
71
        }
72
73
        return $result;
74
    }
75
76
    protected function denormalize(array $raw, string $namespace)
77
    {
78
        $metadata = $this->propertyMetadata[$namespace];
79
        $object = new $namespace();
80
81
        foreach ($raw as $field => $value) {
82
            $fieldMeta = $metadata[$field];
83
            $setter = $fieldMeta['setter'];
84
85
            if ($fieldMeta['embeded']) {
86
                $this->addClassMetadata($fieldMeta['class'], $fieldMeta['sub_properties']);
87
                $iterator = new ObjectIterator($fieldMeta['class'], $value, $this);
88
89
                if ($fieldMeta['public']) {
90
                    $object->{$fieldMeta['name']} = $iterator;
91
                } else {
92
                    $object->$setter($iterator);
93
                }
94
            } else {
95
                if ($fieldMeta['type'] == 'date') {
96
                    $value = \DateTime::createFromFormat(\DateTime::ISO8601, $value) ?: null;
97
                }
98
                if ($fieldMeta['public']) {
99
                    $object->{$fieldMeta['name']} = $value;
100
                } else {
101
                    if ($fieldMeta['identifier']) {
102
                        $setter = function ($field, $value) {
103
                            $this->$field = $value;
104
                        };
105
106
                        $setter = \Closure::bind($setter, $object, $object);
107
                        $setter($fieldMeta['name'], $value);
108
                    } else {
109
                        $object->$setter($value);
110
                    }
111
                }
112
            }
113
        }
114
115
        return $object;
116
    }
117
}
118