Completed
Pull Request — master (#26)
by
unknown
06:22
created

Helpers::normalizeModelKey()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 3
nc 2
nop 1
1
<?php
2
3
namespace Arrilot\BitrixModels;
4
5
class Helpers
6
{
7
    /**
8
     * Does the $haystack starts with $needle
9
     *
10
     * @param $haystack
11
     * @param $needle
12
     * @return bool
13
     */
14
    public static function startsWith($haystack, $needle)
15
    {
16
        return strncmp($haystack, $needle, strlen($needle)) === 0;
17
    }
18
    
19
    /**
20
     * @param Collection|BaseBitrixModel[] $primaryModels первичные модели
21
     * @param Collection|BaseBitrixModel[] $relationModels подгруженные связанные модели
22
     * @param string $primaryKey ключ связи в первичной модели
23
     * @param string $relationKey ключ связи в связанной модели
24
     * @param string $relationName название связи в первичной модели
25
     * @param bool $multiple множественная ли это свзязь
26
     */
27
    public static function assocModels($primaryModels, $relationModels, $primaryKey, $relationKey, $relationName, $multiple)
28
    {
29
        $buckets = static::buildBuckets($relationModels, $relationKey, $multiple);
30
    
31
        foreach ($primaryModels as $i => $primaryModel) {
32
            if ($multiple && is_array($keys = $primaryModel[$primaryKey])) {
33
                $value = [];
34
                foreach ($keys as $key) {
35
                    $key = static::normalizeModelKey($key);
36
                    if (isset($buckets[$key])) {
37
                        $value = array_merge($value, $buckets[$key]);
38
                    }
39
                }
40
            } else {
41
                $key = static::normalizeModelKey($primaryModel[$primaryKey]);
42
                $value = isset($buckets[$key]) ? $buckets[$key] : ($multiple ? [] : null);
43
            }
44
        
45
            $primaryModel->populateRelation($relationName, is_array($value) ? (new Collection($value))->keyBy(function ($item) {return $item->id;}) : $value);
46
        }
47
    }
48
    
49
    /**
50
     * Сгруппировать найденные модели
51
     * @param array $models
52
     * @param string $linkKey
53
     * @param bool $multiple
54
     * @return array
55
     */
56
    protected static function buildBuckets($models, $linkKey, $multiple)
57
    {
58
        $buckets = [];
59
        
60
        foreach ($models as $model) {
61
            $key = $model[$linkKey];
62
            if (is_scalar($key)) {
63
                $buckets[$key][] = $model;
64
            } elseif (is_array($key)){
65
                foreach ($key as $k) {
66
                    $k = static::normalizeModelKey($k);
67
                    $buckets[$k][] = $model;
68
                }
69
            } else {
70
                $key = static::normalizeModelKey($key);
71
                $buckets[$key][] = $model;
72
            }
73
        }
74
        
75
        if (!$multiple) {
76
            foreach ($buckets as $i => $bucket) {
77
                $buckets[$i] = reset($bucket);
78
            }
79
        }
80
        
81
        return $buckets;
82
    }
83
    
84
    /**
85
     * @param mixed $value raw key value.
86
     * @return string normalized key value.
87
     */
88
    protected static function normalizeModelKey($value)
89
    {
90
        if (is_object($value) && method_exists($value, '__toString')) {
91
            // ensure matching to special objects, which are convertable to string, for cross-DBMS relations, for example: `|MongoId`
92
            $value = $value->__toString();
93
        }
94
        
95
        return $value;
96
    }
97
}
98