1 | <?php |
||||||
2 | /** |
||||||
3 | * Created by PhpStorm. |
||||||
4 | * User: execut |
||||||
5 | * Date: 10/4/16 |
||||||
6 | * Time: 4:14 PM |
||||||
7 | */ |
||||||
8 | |||||||
9 | namespace execut\import\components\parser; |
||||||
10 | |||||||
11 | |||||||
12 | use execut\import\components\parser\exception\MoreThanOne; |
||||||
13 | use execut\import\components\parser\exception\NotFoundRecord; |
||||||
14 | use execut\import\Query; |
||||||
15 | use yii\base\Component; |
||||||
16 | use yii\helpers\Json; |
||||||
17 | |||||||
18 | class ModelsFinder extends Component |
||||||
19 | { |
||||||
20 | public $isCreateAlways = false; |
||||||
21 | public $isUpdateAlways = false; |
||||||
22 | public $isCreateNotExisted = false; |
||||||
23 | public $attributes = null; |
||||||
24 | static $cache = []; |
||||||
25 | public $query = null; |
||||||
26 | public $prepareQuery = null; |
||||||
27 | public $advancedSearch = null; |
||||||
28 | public $asArray = false; |
||||||
29 | /** |
||||||
30 | * @var Stack |
||||||
31 | */ |
||||||
32 | public $stack = null; |
||||||
33 | |||||||
34 | protected function findModelFromCache() { |
||||||
35 | if ($model = $this->getCache()) { |
||||||
36 | return $model; |
||||||
37 | } else { |
||||||
38 | $model = new $this->query->modelClass; |
||||||
39 | $this->setCache($model); |
||||||
40 | } |
||||||
41 | |||||||
42 | return $model; |
||||||
43 | } |
||||||
44 | |||||||
45 | public function getCache() { |
||||||
46 | $key = $this->getCacheKey(false); |
||||||
47 | $subKey = $this->getCacheKey(); |
||||||
48 | if (isset(self::$cache[$key]) && isset(self::$cache[$key][$subKey])) { |
||||||
49 | return self::$cache[$key][$subKey]; |
||||||
50 | } |
||||||
51 | } |
||||||
52 | |||||||
53 | public function setCache($model, $subKey = null) { |
||||||
54 | $key = $this->getCacheKey(false); |
||||||
55 | if ($subKey === null) { |
||||||
56 | $subKey = $this->getCacheKey(); |
||||||
57 | } |
||||||
58 | |||||||
59 | if (!isset(self::$cache[$key])) { |
||||||
60 | self::$cache[$key] = []; |
||||||
61 | } |
||||||
62 | |||||||
63 | self::$cache[$key][$subKey] = $model; |
||||||
64 | } |
||||||
65 | |||||||
66 | public function findModelNew() { |
||||||
67 | if (!isset(self::$cache[$this->getCacheKey(false)])) { |
||||||
68 | $this->initCache(); |
||||||
69 | } |
||||||
70 | |||||||
71 | $result = new Result(); |
||||||
72 | $model = $this->findModelFromCache(); |
||||||
73 | $model->attributes = $this->getAttributesValues(); |
||||||
74 | $result->addModel($model); |
||||||
75 | |||||||
76 | return $result; |
||||||
77 | } |
||||||
78 | |||||||
79 | 6 | public function findModel() { |
|||||
80 | 6 | $cacheKey = $this->getCacheKey(); |
|||||
81 | 6 | if (isset(self::$cache[$cacheKey])) { |
|||||
82 | return self::$cache[$cacheKey]; |
||||||
83 | } |
||||||
84 | |||||||
85 | 6 | if (count(self::$cache) > 10000) { |
|||||
86 | echo 'clean(' . count(self::$cache) . ')'; |
||||||
87 | self::$cache = array_splice(self::$cache, -3000); |
||||||
88 | } |
||||||
89 | |||||||
90 | 6 | $q = $this->query; |
|||||
91 | 6 | $q = clone $q; |
|||||
92 | 6 | $modelClass = $q->modelClass; |
|||||
93 | 6 | $result = new Result(); |
|||||
94 | 6 | $attributesValues = $this->getAttributesValues(); |
|||||
95 | 6 | if ($this->isCreateAlways) { |
|||||
96 | 2 | $model = new $modelClass; |
|||||
97 | 2 | $result->addModel($model); |
|||||
98 | } else { |
||||||
99 | 4 | $attributeForSearch = $this->getAttributesForSearch(); |
|||||
100 | 4 | if ($q instanceof Query) { |
|||||
101 | 4 | $q->byImportAttributes($attributeForSearch); |
|||||
102 | } else { |
||||||
103 | $q->andWhere($attributeForSearch); |
||||||
104 | } |
||||||
105 | |||||||
106 | 4 | if ($this->prepareQuery !== null) { |
|||||
107 | 1 | $callback = $this->prepareQuery; |
|||||
108 | 1 | $q = $callback($q, $result, $this->stack); |
|||||
109 | } |
||||||
110 | |||||||
111 | 4 | if ($this->advancedSearch !== null) { |
|||||
112 | $callback = $this->advancedSearch; |
||||||
113 | $models = $callback($q, $result, $this->stack); |
||||||
114 | } else { |
||||||
115 | 4 | $models = $q->all(); |
|||||
116 | } |
||||||
117 | |||||||
118 | 4 | if (count($models) > 1) { |
|||||
119 | 1 | $exception = new MoreThanOne(); |
|||||
120 | 1 | $exception->modelClass = $modelClass; |
|||||
121 | 1 | $exception->attributes = $attributesValues; |
|||||
122 | |||||||
123 | 1 | throw $exception; |
|||||
124 | } |
||||||
125 | |||||||
126 | 3 | if (count($models) == 1) { |
|||||
127 | 2 | $model = current($models); |
|||||
128 | 2 | if ($this->isUpdateAlways) { |
|||||
129 | $model->attributes = $attributesValues; |
||||||
130 | } |
||||||
131 | |||||||
132 | 2 | $result->addModel($model); |
|||||
133 | |||||||
134 | 2 | return self::$cache[$cacheKey] = $result; |
|||||
135 | 1 | } else if ($this->isCreateNotExisted) { |
|||||
136 | $model = new $modelClass; |
||||||
137 | $result->addModel($model); |
||||||
138 | } else { |
||||||
139 | 1 | $exception = new NotFoundRecord(); |
|||||
140 | 1 | $exception->modelClass = $modelClass; |
|||||
141 | 1 | $exception->attributes = $attributesValues; |
|||||
142 | |||||||
143 | 1 | throw $exception; |
|||||
144 | } |
||||||
145 | } |
||||||
146 | |||||||
147 | 2 | $model->attributes = $attributesValues; |
|||||
148 | |||||||
149 | 2 | return self::$cache[$cacheKey] = $result; |
|||||
150 | } |
||||||
151 | |||||||
152 | /** |
||||||
153 | * @return array |
||||||
154 | */ |
||||||
155 | 6 | protected function getAttributesForSearch(): array |
|||||
156 | { |
||||||
157 | 6 | $attributes = $this->getAttributes(); |
|||||
158 | 6 | $attributeForSearch = []; |
|||||
159 | 6 | foreach ($attributes as $attribute) { |
|||||
160 | 6 | if ($attribute->isForSearchQuery) { |
|||||
161 | 6 | $attributeForSearch[$attribute->key] = $attribute->value; |
|||||
162 | } |
||||||
163 | } |
||||||
164 | 6 | return $attributeForSearch; |
|||||
165 | } |
||||||
166 | |||||||
167 | /** |
||||||
168 | * @return array |
||||||
169 | */ |
||||||
170 | 6 | protected function getAttributesValues(): array |
|||||
171 | { |
||||||
172 | 6 | $attributesValues = []; |
|||||
173 | 6 | $attributes = $this->getAttributes(); |
|||||
174 | 6 | foreach ($attributes as $attribute) { |
|||||
175 | 6 | $attributesValues[$attribute->key] = $attribute->value; |
|||||
176 | } |
||||||
177 | 6 | return $attributesValues; |
|||||
178 | } |
||||||
179 | |||||||
180 | /** |
||||||
181 | * @param $row |
||||||
182 | * @return array |
||||||
183 | */ |
||||||
184 | 6 | protected function getAttributes(): array |
|||||
185 | { |
||||||
186 | 6 | return $this->attributes; |
|||||
187 | } |
||||||
188 | |||||||
189 | protected function initCache(): void |
||||||
190 | { |
||||||
191 | $attributesNames = $this->getSearchAttributesNames(); |
||||||
192 | |||||||
193 | $stack = $this->stack; |
||||||
194 | $rows = $stack->rows; |
||||||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||||
195 | $findPairs = []; |
||||||
196 | foreach ($rows as $rowNbr => $row) { |
||||||
197 | $attributes = $this->getAttributesFromRow($rowNbr); |
||||||
0 ignored issues
–
show
The method
getAttributesFromRow() does not exist on execut\import\components\parser\ModelsFinder . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
198 | $attributesValues = []; |
||||||
199 | foreach ($attributes as $attribute) { |
||||||
200 | if (!$attribute->isValid()) { |
||||||
201 | continue 2; |
||||||
202 | } |
||||||
203 | |||||||
204 | if (!$attribute->isForSearchQuery) { |
||||||
205 | continue; |
||||||
206 | } |
||||||
207 | |||||||
208 | $attributesValues[$attribute->key] = $attribute->value; |
||||||
209 | } |
||||||
210 | $findPairs[] = $attributesValues; |
||||||
211 | } |
||||||
212 | |||||||
213 | $q = clone $this->query; |
||||||
214 | $q->andWhere([ |
||||||
215 | 'IN', |
||||||
216 | $attributesNames, |
||||||
217 | $findPairs |
||||||
218 | ]); |
||||||
219 | |||||||
220 | $models = $q->all(); |
||||||
221 | foreach ($models as $model) { |
||||||
222 | $attributeForSearch = []; |
||||||
223 | foreach ($attributesNames as $attributesName) { |
||||||
224 | $attributeForSearch[$attributesName] = $model->$attributesName; |
||||||
225 | } |
||||||
226 | |||||||
227 | $cacheKey = $q->modelClass . ' ' . Json::encode($attributeForSearch); |
||||||
228 | $this->setCache($model, $cacheKey); |
||||||
229 | } |
||||||
230 | } |
||||||
231 | |||||||
232 | /** |
||||||
233 | * @return string |
||||||
234 | */ |
||||||
235 | 6 | protected function getCacheKey($isWithAttributes = true): string |
|||||
236 | { |
||||||
237 | 6 | $attributeForSearch = $this->getAttributesForSearch(); |
|||||
238 | 6 | $cacheKey = $this->query->modelClass; |
|||||
239 | 6 | if ($isWithAttributes) { |
|||||
240 | 6 | $cacheKey .= ' ' . Json::encode($attributeForSearch); |
|||||
241 | } |
||||||
242 | |||||||
243 | 6 | return $cacheKey; |
|||||
244 | } |
||||||
245 | |||||||
246 | /** |
||||||
247 | * @return array |
||||||
248 | */ |
||||||
249 | protected function getSearchAttributesNames(): array |
||||||
250 | { |
||||||
251 | $attributesNames = []; |
||||||
252 | $attributes = $this->getAttributesFromRow(); |
||||||
253 | foreach ($attributes as $attribute) { |
||||||
254 | if (!$attribute->isForSearchQuery) { |
||||||
255 | continue; |
||||||
256 | } |
||||||
257 | |||||||
258 | $attributesNames[] = $attribute->key; |
||||||
259 | } |
||||||
260 | return $attributesNames; |
||||||
261 | } |
||||||
262 | } |