Test Failed
Push — develop ( 2ad78c...b57f29 )
by Nuno
04:26
created

ObjectsResolver   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 15
eloc 44
dl 0
loc 106
ccs 0
cts 43
cp 0
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A toUpdate() 0 24 5
A shouldBeSplitted() 0 20 4
A splitSearchable() 0 27 6
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of Scout Extended.
7
 *
8
 * (c) Algolia Team <[email protected]>
9
 *
10
 *  For the full copyright and license information, please view the LICENSE
11
 *  file that was distributed with this source code.
12
 */
13
14
namespace Algolia\ScoutExtended\Searchable;
15
16
use function get_class;
17
use Illuminate\Support\Str;
18
use Illuminate\Support\Collection;
19
20
/**
21
 * @internal
22
 */
23
final class ObjectsResolver
24
{
25
    /**
26
     * Contains a list of splittables searchables.
27
     *
28
     * @var [
0 ignored issues
show
Documentation Bug introduced by
The doc comment [ at position 0 could not be parsed: Unknown type name '[' at position 0 in [.
Loading history...
29
     *      '\App\Thread' => true,
30
     *      '\App\User' => false,
31
     * ];
32
     */
33
    private $splittables = [];
34
35
    /**
36
     * Get an collection of objects to update
37
     * from the given searchables.
38
     *
39
     * @param \Illuminate\Support\Collection $searchables
40
     *
41
     * @return \Illuminate\Support\Collection
42
     */
43
    public function toUpdate(Collection $searchables): Collection
44
    {
45
        $result = [];
46
47
        foreach ($searchables as $key => $searchable) {
48
49
            if (empty($array = array_merge($searchable->toSearchableArray(), $searchable->scoutMetadata()))) {
50
                continue;
51
            }
52
53
            if ($this->shouldBeSplitted($searchable)) {
54
                [$pieces, $splittedBy] = $this->splitSearchable($searchable, $array);
55
                foreach ($pieces as $number => $piece) {
56
                    $array['objectID'] = ObjectIdEncrypter::encrypt($searchable, $number);
57
                    $array[$splittedBy] = $piece;
58
                    $result[] = $array;
59
                }
60
            } else {
61
                $array['objectID'] = ObjectIdEncrypter::encrypt($searchable);
62
                $result[] = $array;
63
            }
64
        }
65
66
        return collect($result);
67
    }
68
69
    /**
70
     * @param  object $searchable
71
     *
72
     * @return bool
73
     */
74
    private function shouldBeSplitted($searchable): bool
75
    {
76
        $class = get_class($searchable->getModel());
77
78
        if (array_key_exists($class, $this->splittables)) {
79
            return $this->splittables[$class];
80
        }
81
82
        $this->splittables[$class] = false;
83
84
        foreach ($searchable->toSearchableArray() as $key => $value) {
85
            $method = 'split'.Str::camel($key);
86
            $model = $searchable->getModel();
87
            if (method_exists($model, $method)) {
88
                $this->splittables[$class] = true;
89
                break;
90
            }
91
        }
92
93
        return $this->splittables[$class];
94
    }
95
96
    /**
97
     * @param  object $searchable
98
     * @param  array $array
99
     *
100
     * @return array
101
     */
102
    private function splitSearchable($searchable, array $array): array
103
    {
104
        $splittedBy = null;
105
        $pieces = [];
106
        foreach ($array as $key => $value) {
107
            $method = 'split'.Str::camel($key);
108
            $model = $searchable->getModel();
109
            if (method_exists($model, $method)) {
110
                $result = $model->{$method}($value);
111
112
                if (is_array($result)) {
113
                    $pieces = $result;
114
                } else {
115
                    if (is_string($result)) {
116
                        $pieces = (new $result)($value);
117
                    } else {
118
                        if (is_object($result)) {
119
                            $pieces = $result->__invoke($value);
120
                        }
121
                    }
122
                }
123
                $splittedBy = $key;
124
                break;
125
            }
126
        }
127
128
        return [$pieces, $splittedBy];
129
    }
130
}
131