Completed
Push — master ( e47441...eaeba7 )
by Nekrasov
01:50
created

Helpers::buildBuckets()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.5546
c 0
b 0
f 0
cc 7
nc 8
nop 3
1
<?php
2
3
namespace Arrilot\BitrixModels;
4
5
use Arrilot\BitrixModels\Models\BaseBitrixModel;
6
use Illuminate\Support\Collection;
7
8
class Helpers
9
{
10
    /**
11
     * Does the $haystack starts with $needle
12
     *
13
     * @param $haystack
14
     * @param $needle
15
     * @return bool
16
     */
17
    public static function startsWith($haystack, $needle)
18
    {
19
        return strncmp($haystack, $needle, strlen($needle)) === 0;
20
    }
21
    
22
    /**
23
     * @param Collection|BaseBitrixModel[] $primaryModels первичные модели
24
     * @param Collection|BaseBitrixModel[] $relationModels подгруженные связанные модели
25
     * @param string $primaryKey ключ связи в первичной модели
26
     * @param string $relationKey ключ связи в связанной модели
27
     * @param string $relationName название связи в первичной модели
28
     * @param bool $multiple множественная ли это свзязь
29
     */
30
    public static function assocModels($primaryModels, $relationModels, $primaryKey, $relationKey, $relationName, $multiple)
31
    {
32
        $buckets = static::buildBuckets($relationModels, $relationKey, $multiple);
0 ignored issues
show
Bug introduced by
It seems like $relationModels defined by parameter $relationModels on line 30 can also be of type object<Illuminate\Support\Collection>; however, Arrilot\BitrixModels\Helpers::buildBuckets() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
33
        
34
        foreach ($primaryModels as $i => $primaryModel) {
35
            if ($multiple && is_array($keys = $primaryModel[$primaryKey])) {
36
                $value = [];
37
                foreach ($keys as $key) {
38
                    $key = static::normalizeModelKey($key);
39
                    if (isset($buckets[$key])) {
40
                        $value = array_merge($value, $buckets[$key]);
41
                    }
42
                }
43
            } else {
44
                $key = static::normalizeModelKey($primaryModel[$primaryKey]);
45
                $value = isset($buckets[$key]) ? $buckets[$key] : ($multiple ? [] : null);
46
            }
47
            
48
            $primaryModel->populateRelation($relationName, is_array($value) ? (new Collection($value))->keyBy(function ($item) {return $item->id;}) : $value);
49
        }
50
    }
51
    
52
    /**
53
     * Сгруппировать найденные модели
54
     * @param array $models
55
     * @param string $linkKey
56
     * @param bool $multiple
57
     * @return array
58
     */
59
    protected static function buildBuckets($models, $linkKey, $multiple)
60
    {
61
        $buckets = [];
62
        
63
        foreach ($models as $model) {
64
            $key = $model[$linkKey];
65
            if (is_scalar($key)) {
66
                $buckets[$key][] = $model;
67
            } elseif (is_array($key)){
68
                foreach ($key as $k) {
69
                    $k = static::normalizeModelKey($k);
70
                    $buckets[$k][] = $model;
71
                }
72
            } else {
73
                $key = static::normalizeModelKey($key);
74
                $buckets[$key][] = $model;
75
            }
76
        }
77
        
78
        if (!$multiple) {
79
            foreach ($buckets as $i => $bucket) {
80
                $buckets[$i] = reset($bucket);
81
            }
82
        }
83
        
84
        return $buckets;
85
    }
86
    
87
    /**
88
     * @param mixed $value raw key value.
89
     * @return string normalized key value.
90
     */
91
    protected static function normalizeModelKey($value)
92
    {
93
        if (is_object($value) && method_exists($value, '__toString')) {
94
            // ensure matching to special objects, which are convertable to string, for cross-DBMS relations, for example: `|MongoId`
95
            $value = $value->__toString();
96
        }
97
        
98
        return $value;
99
    }
100
}
101