HasManyFromStr.php
4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/**
+-----------------------------------------------------------------------------------------------------------------------
* 模型层基类:业务模型的基类,提供对数据库基本的增删改查类操作,不包含业务逻辑
+-----------------------------------------------------------------------------------------------------------------------
*
* PHP version 7
*
* @category App\Restructure\Relations
* @package App\Restructure\Relations
* @author Richer <yangzi1028@163.com>
* @date 2022年7月6日16:17:44
* @copyright 2022-2022 Richer (http://www.Richer.com/)
* @license http://www.Richer.com/ License
* @link http://www.Richer.com/
*/
namespace App\Restructure\Relations;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
/**
* Class HasManyFromStr
*
* @category App\Restructure\Relations
* @package App\Restructure\Relations
* @author Richer <yangzi1028@163.com>
* @date 2022年7月6日16:17:44
* @copyright 2022-2022 Richer (http://www.Richer.com/)
* @license http://www.Richer.com/ License
* @link http://www.Richer.com/
*/
class HasManyFromStr extends HasMany
{
protected $separator = ','; //分隔符
protected $strict;
public function __construct(Builder $query, Model $parent, string $foreignKey, string $localKey, $separator, $strict = false)
{
$this->separator = $separator;
$this->strict = $strict; //元素执行函数 true 代表转为int
parent::__construct($query, $parent, $foreignKey, $localKey);
}
/**
* 重写获取单个模型建方法
*/
public function addConstraints()
{
if (static::$constraints) {
$this->query->whereIn($this->foreignKey, $this->handleIn($this->separator, $this->getParentKey()));
$this->query->whereNotNull($this->foreignKey);
}
}
/**
* 重写获取所有主键方法.
*
* @param array $models
* @param string $key
* @return array
*/
protected function getKeys(array $models, $key = null)
{
$keysArr = [];
collect($models)->map(function ($value) use ($key, &$keysArr) {
$result = $key ? $value->getAttribute($key) : $value->getKey();
$keysArr = array_merge($keysArr, $this->handleIn($this->separator, $result));
});
return collect($keysArr)->values()->unique()->sort()->all();
}
/**
* 重写匹配方法
* @param array $models
* @param Collection $results
* @param string $relation
* @return array
*/
public function match(array $models, Collection $results, $relation)
{
$dictionary = $this->buildDictionary($results);
// Once we have the dictionary we can simply spin through the parent models to
// link them up with their children using the keyed dictionary to make the
// matching very convenient and easy work. Then we'll just return them.
foreach ($models as $model) {
$keys = $model->getAttribute($this->localKey);
$keys = $this->handleIn($this->separator, $keys);
$keys = array_unique(array_filter($keys));
$type = 'one';
$relationResults = [];
foreach ($keys as $key) {
if (isset($dictionary[$key])) {
$temp = $this->getRelationValue($dictionary, $key, $type);
$relationResults[] = $temp;
}
}
$model->setRelation(
$relation,
collect($relationResults)
);
}
return $models;
}
/**
* 自定义转换方法
* @param $separator
* @param $keyString
* @return array
*/
private function handleIn($separator, $keyString)
{
$keys = is_array($keyString)?$keyString : explode($separator, $keyString);
$keys = array_unique($keys);
if ($this->strict === false) {
return $keys;
}
array_walk($keys, function (&$value) {
$fun = $this->strict === true ? 'intval' : $this->strict;
$value = $fun($value);
});
return $keys;
}
}