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); |
|
|
|
|
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
|
|
|
|
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.