Completed
Pull Request — 6.1-dev (#889)
by
unknown
01:22
created

Converter::convertArrayToDocument()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
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($item, $fieldMeta['sub_properties']);
0 ignored issues
show
Bug introduced by
The variable $item seems to be defined by a foreach iteration on line 59. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
64
                }
65
            } else {
66
                $result[$field] = $value;
67
            }
68
        }
69
70
        return $result;
71
    }
72
73
    protected function denormalize(array $raw, string $namespace)
74
    {
75
        $metadata = $this->propertyMetadata[$namespace];
76
        $object = new $namespace();
77
78
        foreach ($raw as $field => $value) {
79
            $fieldMeta = $metadata[$field];
80
            $setter = $fieldMeta['setter'];
81
82
            if ($fieldMeta['embeded']) {
83
                $this->addClassMetadata($fieldMeta['class'], $fieldMeta['sub_properties']);
84
                $iterator = new ObjectIterator($fieldMeta['class'], $value, $this);
85
86
                if ($fieldMeta['public']) {
87
                    $object->{$fieldMeta['name']} = $iterator;
88
                } else {
89
                    $object->$setter($iterator);
90
                }
91
            } else {
92
                if ($fieldMeta['public']) {
93
                    $object->{$fieldMeta['name']} = $value;
94
                } else {
95
                    if ($fieldMeta['identifier']) {
96
                        $setter = function ($field, $value) {
97
                            $this->$field = $value;
98
                        };
99
100
                        $setter = \Closure::bind($setter, $object, $object);
101
                        $setter($fieldMeta['name'], $value);
102
                    } else {
103
                        $object->$setter($value);
104
                    }
105
                }
106
            }
107
        }
108
109
        return $object;
110
    }
111
}
112