1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace app\modules\shop\models; |
4
|
|
|
|
5
|
|
|
use app\behaviors\CleanRelations; |
6
|
|
|
use app\behaviors\Tree; |
7
|
|
|
use app\components\Helper; |
8
|
|
|
use app\models\BaseObject; |
9
|
|
|
use app\modules\data\components\ImportableInterface; |
10
|
|
|
use app\modules\shop\models\FilterSets; |
11
|
|
|
use app\properties\HasProperties; |
12
|
|
|
use app\traits\GetImages; |
13
|
|
|
use devgroup\TagDependencyHelper\ActiveRecordHelper; |
14
|
|
|
use Yii; |
15
|
|
|
use yii\behaviors\TimestampBehavior; |
16
|
|
|
use yii\caching\TagDependency; |
17
|
|
|
use yii\data\ActiveDataProvider; |
18
|
|
|
use yii\db\ActiveRecord; |
19
|
|
|
use yii\db\Expression; |
20
|
|
|
use yii\helpers\ArrayHelper; |
21
|
|
|
use yii\helpers\Url; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* This is the model class for table "category". |
25
|
|
|
* |
26
|
|
|
* @property integer $id |
27
|
|
|
* @property integer $category_group_id |
28
|
|
|
* @property integer $parent_id |
29
|
|
|
* @property string $name |
30
|
|
|
* @property string $title |
31
|
|
|
* @property string $h1 |
32
|
|
|
* @property string $meta_description |
33
|
|
|
* @property string $breadcrumbs_label |
34
|
|
|
* @property string $slug |
35
|
|
|
* @property string $slug_compiled |
36
|
|
|
* @property integer $slug_absolute |
37
|
|
|
* @property string $content |
38
|
|
|
* @property string $announce |
39
|
|
|
* @property integer $sort_order |
40
|
|
|
* @property boolean $active |
41
|
|
|
* @property string $date_added |
42
|
|
|
* @property string $date_modified |
43
|
|
|
* @property Category[] $children |
44
|
|
|
* @property Category $parent |
45
|
|
|
*/ |
46
|
|
|
class Category extends ActiveRecord implements \JsonSerializable, ImportableInterface |
47
|
|
|
{ |
48
|
|
|
use GetImages; |
49
|
|
|
|
50
|
|
|
const DELETE_MODE_SINGLE_CATEGORY = 1; |
51
|
|
|
const DELETE_MODE_ALL = 2; |
52
|
|
|
const DELETE_MODE_MAIN_CATEGORY = 3; |
53
|
|
|
const CATEGORY_PARENT = 0; |
54
|
|
|
const CATEGORY_ACTIVE = 1; |
55
|
|
|
const CATEGORY_INACTIVE = 0; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Category identity map |
59
|
|
|
* [ |
60
|
|
|
* 'category_id' => $category_model_instance, |
61
|
|
|
* ] |
62
|
|
|
* |
63
|
|
|
* Used by findById |
64
|
|
|
* @var array |
65
|
|
|
*/ |
66
|
|
|
public static $identity_map = []; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Special caching for findBySlug |
70
|
|
|
* Stores category->id for pair slug:category_group_id:parent_id |
71
|
|
|
* @var array |
72
|
|
|
*/ |
73
|
|
|
private static $id_by_slug_group_parent = []; |
74
|
|
|
private static $id_by_name_group_parent = []; |
75
|
|
|
|
76
|
|
|
public $deleteMode = 1; |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @var null|string Url path caching variable |
80
|
|
|
*/ |
81
|
|
|
private $urlPath = null; |
82
|
|
|
|
83
|
|
|
/** @var null|array Array of parent categories ids including root category */ |
84
|
|
|
private $parentIds = null; |
85
|
|
|
|
86
|
|
|
/** @var FilterSets[] */ |
87
|
|
|
private $filterSets = null; |
88
|
|
|
|
89
|
|
View Code Duplication |
public function behaviors() |
90
|
|
|
{ |
91
|
|
|
return [ |
92
|
|
|
[ |
93
|
|
|
'class' => HasProperties::className(), |
|
|
|
|
94
|
|
|
], |
95
|
|
|
[ |
96
|
|
|
'class' => \devgroup\TagDependencyHelper\ActiveRecordHelper::className(), |
|
|
|
|
97
|
|
|
], |
98
|
|
|
[ |
99
|
|
|
'class' => CleanRelations::className(), |
|
|
|
|
100
|
|
|
], |
101
|
|
|
[ |
102
|
|
|
'class' => Tree::className(), |
|
|
|
|
103
|
|
|
'activeAttribute' => 'active', |
104
|
|
|
'sortOrder' => [ |
105
|
|
|
'sort_order' => SORT_ASC, |
106
|
|
|
'id' => SORT_ASC |
107
|
|
|
], |
108
|
|
|
], |
109
|
|
|
[ |
110
|
|
|
'class' => TimestampBehavior::className(), |
|
|
|
|
111
|
|
|
'createdAtAttribute' => 'date_added', |
112
|
|
|
'updatedAtAttribute' => 'date_modified', |
113
|
|
|
'value' => new Expression('NOW()'), |
114
|
|
|
'attributes' => [ |
115
|
|
|
ActiveRecord::EVENT_BEFORE_INSERT => ['date_added'], |
116
|
|
|
ActiveRecord::EVENT_BEFORE_UPDATE => ['date_modified'], |
117
|
|
|
], |
118
|
|
|
], |
119
|
|
|
]; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Return delete modes list |
124
|
|
|
* @return array |
|
|
|
|
125
|
|
|
*/ |
126
|
|
View Code Duplication |
public static function deleteModesList() |
127
|
|
|
{ |
128
|
|
|
return [ |
129
|
|
|
self::DELETE_MODE_MAIN_CATEGORY => Yii::t('app', 'Delete all products that relate to this category as main'), |
130
|
|
|
self::DELETE_MODE_SINGLE_CATEGORY => Yii::t('app', 'Delete only that products that exists ONLY in that category'), |
131
|
|
|
self::DELETE_MODE_ALL => Yii::t('app', 'Delete along with it no matter what'), |
132
|
|
|
]; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @inheritdoc |
137
|
|
|
*/ |
138
|
|
|
public static function tableName() |
139
|
|
|
{ |
140
|
|
|
return '{{%category}}'; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @inheritdoc |
145
|
|
|
*/ |
146
|
|
View Code Duplication |
public function rules() |
147
|
|
|
{ |
148
|
|
|
return [ |
149
|
|
|
[['category_group_id', 'parent_id', 'name', 'slug'], 'required'], |
150
|
|
|
[['category_group_id', 'parent_id', 'slug_absolute', 'sort_order', 'active'], 'integer'], |
151
|
|
|
[['name', 'title', 'h1', 'meta_description', 'breadcrumbs_label', 'content', 'announce'], 'string'], |
152
|
|
|
[['slug'], 'string', 'max' => 80], |
153
|
|
|
[['slug_compiled'], 'string', 'max' => 180], |
154
|
|
|
[['title_append'], 'string'], |
155
|
|
|
[['active'], 'default', 'value' => 1], |
156
|
|
|
[['date_added', 'date_modified'], 'safe'], |
157
|
|
|
['sort_order', 'default', 'value' => 0], |
158
|
|
|
]; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @inheritdoc |
163
|
|
|
*/ |
164
|
|
|
public function beforeValidate() |
165
|
|
|
{ |
166
|
|
|
if (empty($this->slug) && !empty($this->name)) { |
167
|
|
|
$this->slug = Helper::createSlug($this->name); |
168
|
|
|
} |
169
|
|
|
if (empty($this->title) && !empty($this->name)) { |
170
|
|
|
$this->title = $this->name; |
171
|
|
|
} |
172
|
|
|
if (empty($this->h1) && !empty($this->title)) { |
173
|
|
|
$this->h1 = $this->title; |
174
|
|
|
} |
175
|
|
|
if (empty($this->breadcrumbs_label) && !empty($this->name)) { |
176
|
|
|
$this->breadcrumbs_label = $this->name; |
177
|
|
|
} |
178
|
|
|
return parent::beforeValidate(); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* @inheritdoc |
183
|
|
|
*/ |
184
|
|
|
public function attributeLabels() |
185
|
|
|
{ |
186
|
|
|
return [ |
187
|
|
|
'id' => Yii::t('app', 'ID'), |
188
|
|
|
'category_group_id' => Yii::t('app', 'Category Group ID'), |
189
|
|
|
'parent_id' => Yii::t('app', 'Parent ID'), |
190
|
|
|
'name' => Yii::t('app', 'Name'), |
191
|
|
|
'title' => Yii::t('app', 'Title'), |
192
|
|
|
'h1' => Yii::t('app', 'H1'), |
193
|
|
|
'meta_description' => Yii::t('app', 'Meta Description'), |
194
|
|
|
'breadcrumbs_label' => Yii::t('app', 'Breadcrumbs Label'), |
195
|
|
|
'slug' => Yii::t('app', 'Slug'), |
196
|
|
|
'slug_compiled' => Yii::t('app', 'Slug Compiled'), |
197
|
|
|
'slug_absolute' => Yii::t('app', 'Slug Absolute'), |
198
|
|
|
'content' => Yii::t('app', 'Content'), |
199
|
|
|
'announce' => Yii::t('app', 'Announce'), |
200
|
|
|
'sort_order' => Yii::t('app', 'Sort Order'), |
201
|
|
|
'active' => Yii::t('app', 'Active'), |
202
|
|
|
'title_append' => Yii::t('app', 'Title Append'), |
203
|
|
|
'date_added' => Yii::t('app', 'Date Added'), |
204
|
|
|
'date_modified' => Yii::t('app', 'Date Modified'), |
205
|
|
|
]; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Search tasks |
210
|
|
|
* @param $params |
211
|
|
|
* @return ActiveDataProvider |
212
|
|
|
*/ |
213
|
|
|
public function search($params) |
214
|
|
|
{ |
215
|
|
|
/* @var $query \yii\db\ActiveQuery */ |
216
|
|
|
$query = self::find()->where(['parent_id' => $this->parent_id])->with('images'); |
217
|
|
|
$dataProvider = new ActiveDataProvider( |
218
|
|
|
[ |
219
|
|
|
'query' => $query, |
220
|
|
|
'pagination' => [ |
221
|
|
|
'pageSize' => 10, |
222
|
|
|
], |
223
|
|
|
] |
224
|
|
|
); |
225
|
|
|
if (!($this->load($params))) { |
226
|
|
|
return $dataProvider; |
227
|
|
|
} |
228
|
|
|
$query->andFilterWhere(['id' => $this->id]); |
229
|
|
|
$query->andFilterWhere(['like', 'name', $this->name]); |
230
|
|
|
$query->andFilterWhere(['like', 'slug', $this->slug]); |
231
|
|
|
$query->andFilterWhere(['like', 'slug_compiled', $this->slug_compiled]); |
232
|
|
|
$query->andFilterWhere(['like', 'slug_absolute', $this->slug_absolute]); |
233
|
|
|
$query->andFilterWhere(['like', 'title', $this->title]); |
234
|
|
|
$query->andFilterWhere(['like', 'h1', $this->h1]); |
235
|
|
|
$query->andFilterWhere(['like', 'meta_description', $this->meta_description]); |
236
|
|
|
$query->andFilterWhere(['like', 'breadcrumbs_label', $this->breadcrumbs_label]); |
237
|
|
|
$query->andFilterWhere(['active' => $this->active]); |
238
|
|
|
return $dataProvider; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Returns model using indentity map and cache |
243
|
|
|
* @param int $id |
244
|
|
|
* @param int|null $isActive |
|
|
|
|
245
|
|
|
* @return Category|null |
246
|
|
|
*/ |
247
|
|
View Code Duplication |
public static function findById($id, $isActive = 1) |
248
|
|
|
{ |
249
|
|
|
if (!is_numeric($id)) { |
250
|
|
|
return null; |
251
|
|
|
} |
252
|
|
|
if (!isset(static::$identity_map[$id])) { |
253
|
|
|
$cacheKey = static::tableName() . ":$id:$isActive"; |
254
|
|
|
if (false === $model = Yii::$app->cache->get($cacheKey)) { |
255
|
|
|
$model = static::find()->where(['id' => $id])->with('images'); |
256
|
|
|
if (null !== $isActive) { |
257
|
|
|
$model->andWhere(['active' => $isActive]); |
258
|
|
|
} |
259
|
|
|
if (null !== $model = $model->one()) { |
260
|
|
|
Yii::$app->cache->set( |
261
|
|
|
$cacheKey, |
262
|
|
|
$model, |
263
|
|
|
86400, |
264
|
|
|
new TagDependency( |
265
|
|
|
[ |
266
|
|
|
'tags' => [ |
267
|
|
|
ActiveRecordHelper::getObjectTag($model, $model->id) |
|
|
|
|
268
|
|
|
] |
269
|
|
|
] |
270
|
|
|
) |
271
|
|
|
); |
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
static::$identity_map[$id] = $model; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
return static::$identity_map[$id]; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Finds category by slug inside category_group_id |
282
|
|
|
* Uses cache and identity_map |
283
|
|
|
*/ |
284
|
|
|
public static function findBySlug($slug, $category_group_id, $parent_id = 0) |
285
|
|
|
{ |
286
|
|
|
$params = [ |
287
|
|
|
'slug' => $slug, |
288
|
|
|
'category_group_id' => $category_group_id, |
289
|
|
|
]; |
290
|
|
|
if ($parent_id >= 0) { |
291
|
|
|
$params['parent_id'] = $parent_id; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
$identity_key = $slug . ':' . $category_group_id . ':' . $parent_id; |
295
|
|
|
if (isset(static::$id_by_slug_group_parent[$identity_key]) === true) { |
296
|
|
|
return static::findById(static::$id_by_slug_group_parent[$identity_key], null); |
297
|
|
|
} |
298
|
|
|
$category = Yii::$app->cache->get("Category:bySlug:" . $identity_key); |
299
|
|
|
if ($category === false) { |
300
|
|
|
$category = Category::find()->where($params)->one(); |
301
|
|
|
if (is_object($category) === true) { |
302
|
|
|
static::$identity_map[$category->id] = $category; |
303
|
|
|
static::$id_by_slug_group_parent[$identity_key] = $category->id; |
304
|
|
|
Yii::$app->cache->set( |
305
|
|
|
"Category:bySlug:" . $identity_key, |
306
|
|
|
$category, |
307
|
|
|
86400, |
308
|
|
|
new TagDependency( |
309
|
|
|
[ |
310
|
|
|
'tags' => ActiveRecordHelper::getObjectTag($category, $category->id) |
311
|
|
|
] |
312
|
|
|
) |
313
|
|
|
); |
314
|
|
|
return $category; |
315
|
|
View Code Duplication |
} else { |
316
|
|
|
Yii::$app->cache->set( |
317
|
|
|
"Category:bySlug:" . $identity_key, |
318
|
|
|
$category, |
319
|
|
|
86400, |
320
|
|
|
new TagDependency( |
321
|
|
|
[ |
322
|
|
|
'tags' => ActiveRecordHelper::getCommonTag(Category::className()) |
|
|
|
|
323
|
|
|
] |
324
|
|
|
) |
325
|
|
|
); |
326
|
|
|
return null; |
327
|
|
|
} |
328
|
|
|
} else { |
329
|
|
|
return $category; |
330
|
|
|
} |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* Ищет по name в рамках category_group_id |
335
|
|
|
* Заносит в identity_map |
336
|
|
|
*/ |
337
|
|
|
public static function findByName($name, $category_group_id, $parent_id = 0) |
338
|
|
|
{ |
339
|
|
|
$params = [ |
340
|
|
|
'name' => $name, |
341
|
|
|
'category_group_id' => $category_group_id, |
342
|
|
|
]; |
343
|
|
|
if ($parent_id >= 0) { |
344
|
|
|
$params['parent_id'] = $parent_id; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
$identity_key = $name . ':' . $category_group_id . ':' . $parent_id; |
348
|
|
|
if (isset(static::$id_by_name_group_parent[$identity_key])) { |
349
|
|
|
return static::findById(static::$id_by_name_group_parent[$identity_key], null); |
350
|
|
|
} |
351
|
|
|
$category = Yii::$app->cache->get("Category:byName:" . $identity_key); |
352
|
|
|
if (!is_object($category)) { |
353
|
|
|
$category = Category::find()->where($params)->one(); |
354
|
|
|
if (is_object($category)) { |
355
|
|
|
static::$identity_map[$category->id] = $category; |
356
|
|
|
static::$id_by_name_group_parent[$identity_key] = $category->id; |
357
|
|
|
Yii::$app->cache->set( |
358
|
|
|
"Category:byName:" . $identity_key, |
359
|
|
|
$category, |
360
|
|
|
86400, |
361
|
|
|
new TagDependency( |
362
|
|
|
[ |
363
|
|
|
'tags' => ActiveRecordHelper::getObjectTag($category, $category->id) |
364
|
|
|
] |
365
|
|
|
) |
366
|
|
|
); |
367
|
|
|
return $category; |
368
|
|
|
} else { |
369
|
|
|
return null; |
370
|
|
|
} |
371
|
|
|
} else { |
372
|
|
|
return $category; |
373
|
|
|
} |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
public function getUrlPath($include_parent_category = true) |
377
|
|
|
{ |
378
|
|
|
if ($this->urlPath === null) { |
379
|
|
|
if ($this->parent_id == 0) { |
380
|
|
|
if ($include_parent_category) { |
381
|
|
|
return $this->slug; |
382
|
|
|
} else { |
383
|
|
|
return ''; |
384
|
|
|
} |
385
|
|
|
} |
386
|
|
|
$slugs = [$this->slug]; |
387
|
|
|
|
388
|
|
|
$this->parentIds = []; |
389
|
|
|
|
390
|
|
|
$parent_category = $this->parent_id > 0 ? $this->parent : 0; |
391
|
|
View Code Duplication |
while ($parent_category !== null) { |
392
|
|
|
$this->parentIds[] = intval($parent_category->id); |
393
|
|
|
$slugs[] = $parent_category->slug; |
394
|
|
|
$parent_category = $parent_category->parent; |
395
|
|
|
} |
396
|
|
|
if ($include_parent_category === false) { |
397
|
|
|
array_pop($slugs); |
398
|
|
|
} |
399
|
|
|
$this->urlPath = implode("/", array_reverse($slugs)); |
400
|
|
|
} |
401
|
|
|
return $this->urlPath; |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* @return array Returns array of ids of parent categories(breadcrumbs ids) |
406
|
|
|
*/ |
407
|
|
|
public function getParentIds() |
408
|
|
|
{ |
409
|
|
|
if ($this->parentIds === null) { |
410
|
|
|
$this->parentIds = []; |
411
|
|
|
$parent_category = $this->parent_id > 0 ? $this->parent : null; |
412
|
|
View Code Duplication |
while ($parent_category !== null) { |
413
|
|
|
$this->parentIds[] = intval($parent_category->id); |
414
|
|
|
$parent_category = $parent_category->parent; |
415
|
|
|
} |
416
|
|
|
} |
417
|
|
|
return $this->parentIds; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* Ищет root для группы категорий |
422
|
|
|
* Использует identity_map |
423
|
|
|
* @return Category|null |
|
|
|
|
424
|
|
|
*/ |
425
|
|
|
public static function findRootForCategoryGroup($id = null) |
426
|
|
|
{ |
427
|
|
|
if (null === $id) { |
428
|
|
|
return null; |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
return static::find() |
432
|
|
|
->where([ |
433
|
|
|
'category_group_id' => $id, |
434
|
|
|
'parent_id' => static::CATEGORY_PARENT, |
435
|
|
|
'active' => static::CATEGORY_ACTIVE, |
436
|
|
|
]) |
437
|
|
|
->orderBy(['sort_order' => SORT_ASC, 'id' => SORT_ASC]) |
438
|
|
|
->one(); |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* @deprecated |
443
|
|
|
* @param $category_group_id |
444
|
|
|
* @param int $level |
445
|
|
|
* @param int $is_active |
446
|
|
|
* @return Category[] |
447
|
|
|
*/ |
448
|
|
|
public static function getByLevel($category_group_id, $level = 0, $is_active = 1) |
449
|
|
|
{ |
450
|
|
|
$cacheKey = "CategoriesByLevel:$category_group_id:$level"; |
451
|
|
|
if (false === $models = Yii::$app->cache->get($cacheKey)) { |
452
|
|
|
$models = Category::find()->where( |
453
|
|
|
['category_group_id' => $category_group_id, 'parent_id' => $level, 'active' => $is_active] |
454
|
|
|
)->orderBy('sort_order')->with('images')->all(); |
455
|
|
|
|
456
|
|
|
if (null !== $models) { |
457
|
|
|
|
458
|
|
|
$cache_tags = []; |
459
|
|
|
foreach ($models as $model) { |
460
|
|
|
$cache_tags [] = ActiveRecordHelper::getObjectTag($model, $model->id); |
461
|
|
|
} |
462
|
|
|
$cache_tags [] = ActiveRecordHelper::getObjectTag(static::className(), $level); |
|
|
|
|
463
|
|
|
|
464
|
|
|
|
465
|
|
|
Yii::$app->cache->set( |
466
|
|
|
$cacheKey, |
467
|
|
|
$models, |
468
|
|
|
86400, |
469
|
|
|
new TagDependency( |
470
|
|
|
[ |
471
|
|
|
'tags' => $cache_tags |
472
|
|
|
] |
473
|
|
|
) |
474
|
|
|
); |
475
|
|
|
} |
476
|
|
|
} |
477
|
|
|
foreach ($models as $model) { |
478
|
|
|
static::$identity_map[$model->id] = $model; |
479
|
|
|
} |
480
|
|
|
return $models; |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
/** |
484
|
|
|
* @param int $parentId |
|
|
|
|
485
|
|
|
* @param int|null $isActive |
|
|
|
|
486
|
|
|
* @return Category[]|array |
487
|
|
|
*/ |
488
|
|
|
public static function getByParentId($parentId = null, $isActive = 1) |
489
|
|
|
{ |
490
|
|
|
if (null === $parentId) { |
491
|
|
|
return []; |
492
|
|
|
} |
493
|
|
|
$parentId = intval($parentId); |
494
|
|
|
$cacheKey = "CategoriesByParentId:$parentId" . ':' . (null === $isActive ? 'null' : $isActive); |
495
|
|
|
if (false !== $models = Yii::$app->cache->get($cacheKey)) { |
496
|
|
|
return $models; |
497
|
|
|
} |
498
|
|
|
$query = static::find() |
499
|
|
|
->where(['parent_id' => $parentId]); |
500
|
|
|
if (null !== $isActive) { |
501
|
|
|
$query->andWhere(['active' => $isActive]); |
502
|
|
|
} |
503
|
|
|
$models = $query->orderBy(['sort_order' => SORT_ASC, 'id' => SORT_ASC]) |
504
|
|
|
->with('images') |
505
|
|
|
->all(); |
506
|
|
|
|
507
|
|
|
if (empty($models)) { |
508
|
|
|
return []; |
509
|
|
|
} |
510
|
|
|
Yii::$app->cache->set( |
511
|
|
|
$cacheKey, |
512
|
|
|
$models, |
513
|
|
|
0, |
514
|
|
|
new TagDependency([ |
515
|
|
|
'tags' => array_reduce($models, |
516
|
|
|
function ($result, $item) |
517
|
|
|
{ |
518
|
|
|
/** @var Category $item */ |
519
|
|
|
$result[] = ActiveRecordHelper::getObjectTag(static::className(), $item->id); |
|
|
|
|
520
|
|
|
return $result; |
521
|
|
|
}, |
522
|
|
|
[ActiveRecordHelper::getObjectTag(static::className(), $parentId)] |
|
|
|
|
523
|
|
|
) |
524
|
|
|
]) |
525
|
|
|
); |
526
|
|
|
return $models; |
527
|
|
|
} |
528
|
|
|
|
529
|
|
|
public function afterSave($insert, $changedAttributes) |
530
|
|
|
{ |
531
|
|
|
parent::afterSave($insert, $changedAttributes); |
532
|
|
|
|
533
|
|
|
static::$identity_map[$this->id] = $this; |
534
|
|
|
|
535
|
|
|
if (isset($changedAttributes['category_group_id'])) { |
536
|
|
|
foreach ($this->children as $child) { |
537
|
|
|
$child->category_group_id = $this->category_group_id; |
538
|
|
|
$child->save(true, ['category_group_id']); |
539
|
|
|
} |
540
|
|
|
} |
541
|
|
|
|
542
|
|
|
if (isset($changedAttributes['parent_id'])) { |
543
|
|
|
if (is_null($this->parent) === false) { |
544
|
|
|
$this->category_group_id = $this->parent->category_group_id; |
545
|
|
|
$this->save(true, ['category_group_id']); |
546
|
|
|
} |
547
|
|
|
} |
548
|
|
|
} |
549
|
|
|
|
550
|
|
|
/** |
551
|
|
|
* Preparation to delete category. |
552
|
|
|
* Deleting related products and inserted categories. |
553
|
|
|
* @return bool |
554
|
|
|
*/ |
555
|
|
|
public function beforeDelete() |
556
|
|
|
{ |
557
|
|
|
if (!parent::beforeDelete()) { |
558
|
|
|
return false; |
559
|
|
|
} |
560
|
|
|
$product = Yii::$container->get(Product::class); |
561
|
|
|
$productObject = BaseObject::getForClass(get_class($product)); |
562
|
|
|
switch ($this->deleteMode) { |
563
|
|
|
case self::DELETE_MODE_ALL: |
564
|
|
|
$products = |
565
|
|
|
!is_null($productObject) |
566
|
|
|
? $product::find() |
567
|
|
|
->join( |
568
|
|
|
'INNER JOIN', |
569
|
|
|
$productObject->categories_table_name . ' pc', |
570
|
|
|
'pc.object_model_id = product.id' |
571
|
|
|
) |
572
|
|
|
->where('pc.category_id = :id', [':id' => $this->id]) |
573
|
|
|
->all() |
574
|
|
|
: []; |
575
|
|
|
break; |
576
|
|
|
case self::DELETE_MODE_MAIN_CATEGORY: |
577
|
|
|
$products = $product::findAll(['main_category_id' => $this->id]); |
578
|
|
|
break; |
579
|
|
|
default: |
580
|
|
|
$products = |
581
|
|
|
!is_null($productObject) |
582
|
|
|
? $product::find() |
583
|
|
|
->join( |
584
|
|
|
'INNER JOIN', |
585
|
|
|
$productObject->categories_table_name . ' pc', |
586
|
|
|
'pc.object_model_id = product.id' |
587
|
|
|
) |
588
|
|
|
->join( |
589
|
|
|
'INNER JOIN', |
590
|
|
|
$productObject->categories_table_name . ' pc2', |
591
|
|
|
'pc2.object_model_id = product.id' |
592
|
|
|
) |
593
|
|
|
->where('pc.category_id = :id', [':id' => $this->id]) |
594
|
|
|
->groupBy('pc2.object_model_id') |
595
|
|
|
->having('COUNT(*) = 1') |
596
|
|
|
->all() |
597
|
|
|
: []; |
598
|
|
|
break; |
599
|
|
|
} |
600
|
|
|
foreach ($products as $product) { |
601
|
|
|
$product->delete(); |
602
|
|
|
} |
603
|
|
|
foreach ($this->children as $child) { |
604
|
|
|
$child->deleteMode = $this->deleteMode; |
605
|
|
|
$child->delete(); |
606
|
|
|
} |
607
|
|
|
if (!is_null($productObject)) { |
608
|
|
|
Yii::$app->db |
609
|
|
|
->createCommand() |
610
|
|
|
->delete($productObject->categories_table_name, ['category_id' => $this->id]) |
611
|
|
|
->execute(); |
612
|
|
|
} |
613
|
|
|
return true; |
614
|
|
|
} |
615
|
|
|
|
616
|
|
|
public function afterDelete() |
617
|
|
|
{ |
618
|
|
|
FilterSets::deleteAll(['category_id' => $this->id]); |
619
|
|
|
parent::afterDelete(); |
620
|
|
|
} |
621
|
|
|
|
622
|
|
|
|
623
|
|
|
/** |
624
|
|
|
* Get children menu items with selected depth |
625
|
|
|
* @param int $parentId |
626
|
|
|
* @param null|integer $depth |
627
|
|
|
* @return array |
628
|
|
|
*/ |
629
|
|
|
public static function getMenuItems($parentId = 0, $depth = null, $fetchModels = false) |
630
|
|
|
{ |
631
|
|
|
if ($depth === 0) { |
632
|
|
|
return []; |
633
|
|
|
} |
634
|
|
|
$cacheKey = 'CategoryMenuItems:' . implode(':', [ |
635
|
|
|
$parentId, |
636
|
|
|
null === $depth ? 'null' : intval($depth), |
637
|
|
|
intval($fetchModels) |
638
|
|
|
]) ; |
639
|
|
|
$items = Yii::$app->cache->get($cacheKey); |
640
|
|
|
if ($items !== false) { |
641
|
|
|
return $items; |
642
|
|
|
} |
643
|
|
|
$items = []; |
644
|
|
|
$categories = static::find()->select(['id', 'name', 'category_group_id'])->where( |
645
|
|
|
['parent_id' => $parentId, 'active' => 1] |
646
|
|
|
)->orderBy(['sort_order' => SORT_ASC, 'id' => SORT_ASC])->with('images')->all(); |
647
|
|
|
$cache_tags = [ |
648
|
|
|
ActiveRecordHelper::getCommonTag(static::className()), |
|
|
|
|
649
|
|
|
]; |
650
|
|
|
|
651
|
|
|
/** @var Category $category */ |
652
|
|
|
foreach ($categories as $category) { |
653
|
|
|
$items[] = [ |
654
|
|
|
'label' => $category->name, |
655
|
|
|
'url' => Url::toRoute( |
656
|
|
|
[ |
657
|
|
|
'@category', |
658
|
|
|
'category_group_id' => $category->category_group_id, |
659
|
|
|
'last_category_id' => $category->id, |
660
|
|
|
] |
661
|
|
|
), |
662
|
|
|
'id' => $category->id, |
663
|
|
|
'model' => $fetchModels ? $category : null, |
664
|
|
|
'items' => static::getMenuItems($category->id, null === $depth ? null : $depth - 1), |
665
|
|
|
]; |
666
|
|
|
$cache_tags[] = ActiveRecordHelper::getObjectTag(static::className(), $category->id); |
|
|
|
|
667
|
|
|
} |
668
|
|
|
$cache_tags [] = ActiveRecordHelper::getObjectTag(static::className(), $parentId); |
|
|
|
|
669
|
|
|
Yii::$app->cache->set( |
670
|
|
|
$cacheKey, |
671
|
|
|
$items, |
672
|
|
|
86400, |
673
|
|
|
new TagDependency( |
674
|
|
|
[ |
675
|
|
|
'tags' => $cache_tags, |
676
|
|
|
] |
677
|
|
|
) |
678
|
|
|
); |
679
|
|
|
return $items; |
680
|
|
|
} |
681
|
|
|
|
682
|
|
|
/** |
683
|
|
|
* @return FilterSets[] |
684
|
|
|
*/ |
685
|
|
|
public function filterSets() |
686
|
|
|
{ |
687
|
|
|
if ($this->filterSets === null) { |
688
|
|
|
$this->filterSets = FilterSets::getForCategoryId($this->id); |
689
|
|
|
} |
690
|
|
|
return $this->filterSets; |
691
|
|
|
} |
692
|
|
|
|
693
|
|
|
/** |
694
|
|
|
* @param int $parentId |
695
|
|
|
* @param int|null $categoryGroupId |
696
|
|
|
* @param string $name |
697
|
|
|
* @param bool $dummyObject |
698
|
|
|
* @return Category|null |
699
|
|
|
*/ |
700
|
|
|
public static function createEmptyCategory($parentId = 0, $categoryGroupId = null, $name = 'Catalog', $dummyObject = false) |
701
|
|
|
{ |
702
|
|
|
$categoryGroupId = null === $categoryGroupId ? CategoryGroup::getFirstModel()->id : intval($categoryGroupId); |
703
|
|
|
|
704
|
|
|
$model = new static(); |
705
|
|
|
$model->loadDefaultValues(); |
706
|
|
|
$model->parent_id = $parentId; |
707
|
|
|
$model->category_group_id = $categoryGroupId; |
708
|
|
|
$model->h1 = $model->title = $model->name = $name; |
709
|
|
|
$model->slug = Helper::createSlug($model->name); |
710
|
|
|
|
711
|
|
|
if (!$dummyObject) { |
712
|
|
|
if (!$model->save()) { |
713
|
|
|
return null; |
714
|
|
|
} |
715
|
|
|
$model->refresh(); |
716
|
|
|
} |
717
|
|
|
|
718
|
|
|
return $model; |
719
|
|
|
} |
720
|
|
|
|
721
|
|
|
/** |
722
|
|
|
* @param int|Product|null $productModel |
723
|
|
|
* @param bool $asMainCategory |
724
|
|
|
* @return bool |
725
|
|
|
*/ |
726
|
|
|
public function linkProduct($productModel = null, $asMainCategory = false) |
727
|
|
|
{ |
728
|
|
|
if ($productModel instanceof Product) { |
729
|
|
|
return $productModel->linkToCategory($this->id, $asMainCategory); |
730
|
|
|
} elseif (is_int($productModel) || is_string($productModel)) { |
731
|
|
|
$productModel = intval($productModel); |
732
|
|
|
$product = Yii::$container->get(Product::class); |
733
|
|
|
if (null !== $productModel = $product::findById($productModel, null)) { |
734
|
|
|
return $productModel->linkToCategory($this->id, $asMainCategory); |
735
|
|
|
} |
736
|
|
|
} |
737
|
|
|
|
738
|
|
|
return false; |
739
|
|
|
} |
740
|
|
|
|
741
|
|
|
/** |
742
|
|
|
* @return string |
743
|
|
|
*/ |
744
|
|
|
public function __toString() |
745
|
|
|
{ |
746
|
|
|
return ($this->className() . ':' . $this->id); |
|
|
|
|
747
|
|
|
} |
748
|
|
|
|
749
|
|
|
/** |
750
|
|
|
* @return string |
751
|
|
|
*/ |
752
|
|
|
public function jsonSerialize() |
753
|
|
|
{ |
754
|
|
|
return ($this->className() . ':' . $this->id); |
|
|
|
|
755
|
|
|
} |
756
|
|
|
|
757
|
|
|
/** |
758
|
|
|
* Process fields before the actual model is saved(inserted or updated) |
759
|
|
|
* @param array $fields |
760
|
|
|
* @param $multipleValuesDelimiter |
761
|
|
|
* @param array $additionalFields |
762
|
|
|
*/ |
763
|
|
|
public function processImportBeforeSave(array $fields, $multipleValuesDelimiter, array $additionalFields) |
764
|
|
|
{ |
765
|
|
|
$_attributes = $this->attributes(); |
766
|
|
|
foreach ($fields as $key => $value) { |
767
|
|
|
if (in_array($key, $_attributes)) { |
768
|
|
|
$this->$key = $value; |
769
|
|
|
} |
770
|
|
|
} |
771
|
|
|
|
772
|
|
View Code Duplication |
if (empty($this->slug)) { |
773
|
|
|
$this->slug = Helper::createSlug($this->name); |
774
|
|
|
} elseif (mb_strlen($this->slug) > 80) { |
775
|
|
|
$this->slug = mb_substr($this->slug, 0, 80); |
776
|
|
|
} |
777
|
|
|
|
778
|
|
|
if (empty($this->name)) { |
779
|
|
|
$this->name = 'unnamed-category'; |
780
|
|
|
} |
781
|
|
|
} |
782
|
|
|
|
783
|
|
|
/** |
784
|
|
|
* Process fields after the actual model is saved(inserted or updated) |
785
|
|
|
* @param array $fields |
786
|
|
|
* @param $multipleValuesDelimiter |
787
|
|
|
* @param array $additionalFields |
788
|
|
|
*/ |
789
|
|
|
public function processImportAfterSave(array $fields, $multipleValuesDelimiter, array $additionalFields) |
790
|
|
|
{ |
791
|
|
|
} |
792
|
|
|
} |
793
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.