1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace NerdsAndCompany\Schematic\Services; |
4
|
|
|
|
5
|
|
|
use Craft\Craft; |
6
|
|
|
use Craft\CategoryGroupModel; |
7
|
|
|
use Craft\CategoryGroupLocaleModel; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Schematic Category Groups Service. |
11
|
|
|
* |
12
|
|
|
* Sync Craft Setups. |
13
|
|
|
* |
14
|
|
|
* @author Nerds & Company |
15
|
|
|
* @copyright Copyright (c) 2015-2016, Nerds & Company |
16
|
|
|
* @license MIT |
17
|
|
|
* |
18
|
|
|
* @link http://www.nerds.company |
19
|
|
|
*/ |
20
|
|
|
class CategoryGroups extends Base |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* Export categoryGroups. |
24
|
|
|
* |
25
|
|
|
* @param CategoryGroupModel[] $categoryGroups |
26
|
|
|
* |
27
|
|
|
* @return array |
28
|
|
|
*/ |
29
|
3 |
|
public function export(array $categoryGroups = []) |
30
|
|
|
{ |
31
|
3 |
|
Craft::log(Craft::t('Exporting Category Groups')); |
32
|
|
|
|
33
|
3 |
|
$categoryGroupDefinitions = []; |
34
|
|
|
|
35
|
3 |
|
foreach ($categoryGroups as $categoryGroup) { |
36
|
2 |
|
$categoryGroupDefinitions[$categoryGroup->handle] = $this->getCategoryGroupDefinition($categoryGroup); |
37
|
3 |
|
} |
38
|
|
|
|
39
|
3 |
|
return $categoryGroupDefinitions; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Get category groups definition. |
44
|
|
|
* |
45
|
|
|
* @param CategoryGroupModel $categoryGroup |
46
|
|
|
* |
47
|
|
|
* @return array |
48
|
|
|
*/ |
49
|
2 |
|
private function getCategoryGroupDefinition(CategoryGroupModel $categoryGroup) |
50
|
|
|
{ |
51
|
2 |
|
$fieldLayout = Craft::app()->fields->getLayoutById($categoryGroup->fieldLayoutId); |
52
|
|
|
return [ |
53
|
2 |
|
'name' => $categoryGroup->name, |
54
|
2 |
|
'hasUrls' => $categoryGroup->hasUrls, |
55
|
2 |
|
'template' => $categoryGroup->template, |
56
|
2 |
|
'maxLevels' => $categoryGroup->maxLevels, |
57
|
2 |
|
'locales' => $this->getLocaleDefinitions($categoryGroup->getLocales()), |
58
|
2 |
|
'fieldLayout' => Craft::app()->schematic_fields->getFieldLayoutDefinition($fieldLayout), |
59
|
2 |
|
]; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Get locale definitions. |
64
|
|
|
* |
65
|
|
|
* @param CategoryGroupLocaleModel[] $locales |
66
|
|
|
* |
67
|
|
|
* @return array |
68
|
|
|
*/ |
69
|
2 |
|
private function getLocaleDefinitions(array $locales) |
70
|
|
|
{ |
71
|
2 |
|
$localeDefinitions = []; |
72
|
|
|
|
73
|
2 |
|
foreach ($locales as $locale) { |
74
|
2 |
|
$localeDefinitions[$locale->locale] = $this->getLocaleDefinition($locale); |
75
|
2 |
|
} |
76
|
|
|
|
77
|
2 |
|
return $localeDefinitions; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Get locale definition. |
82
|
|
|
* |
83
|
|
|
* @param CategoryGroupLocaleModel $locale |
84
|
|
|
* |
85
|
|
|
* @return array |
86
|
|
|
*/ |
87
|
2 |
|
private function getLocaleDefinition(CategoryGroupLocaleModel $locale) |
88
|
|
|
{ |
89
|
|
|
return [ |
90
|
2 |
|
'urlFormat' => $locale->urlFormat, |
91
|
2 |
|
'nestedUrlFormat' => $locale->nestedUrlFormat, |
92
|
2 |
|
]; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Attempt to import category groups. |
97
|
|
|
* |
98
|
|
|
* @param array $categoryGroupDefinitions |
99
|
|
|
* @param bool $force If set to true category groups not included in the import will be deleted |
100
|
|
|
* |
101
|
|
|
* @return Result |
102
|
|
|
*/ |
103
|
4 |
|
public function import(array $categoryGroupDefinitions, $force = false) |
104
|
|
|
{ |
105
|
4 |
|
Craft::log(Craft::t('Importing Category Groups')); |
106
|
|
|
|
107
|
4 |
|
$this->resetCraftCategoriesServiceCache(); |
108
|
|
|
$categoryGroups = Craft::app()->categories->getAllGroups('handle'); |
109
|
|
|
|
110
|
|
|
foreach ($categoryGroupDefinitions as $categoryGroupHandle => $categoryGroupDefinition) { |
111
|
|
|
$categoryGroup = array_key_exists($categoryGroupHandle, $categoryGroups) |
112
|
|
|
? $categoryGroups[$categoryGroupHandle] |
113
|
|
|
: new CategoryGroupModel(); |
114
|
|
|
|
115
|
|
|
unset($categoryGroups[$categoryGroupHandle]); |
116
|
|
|
|
117
|
|
|
$this->populateCategoryGroup($categoryGroup, $categoryGroupDefinition, $categoryGroupHandle); |
118
|
|
|
|
119
|
|
|
if (!Craft::app()->categories->saveGroup($categoryGroup)) { // Save categorygroup via craft |
120
|
|
|
$this->addErrors($categoryGroup->getAllErrors()); |
121
|
|
|
|
122
|
|
|
continue; |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
if ($force) { |
127
|
|
|
foreach ($categoryGroups as $categoryGroup) { |
128
|
|
|
Craft::app()->categories->deleteGroupById($categoryGroup->id); |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
return $this->getResultModel(); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Populate categorygroup. |
137
|
|
|
* |
138
|
|
|
* @param CategoryGroupModel $categoryGroup |
139
|
|
|
* @param array $categoryGroupDefinition |
140
|
|
|
* @param string $categoryGroupHandle |
141
|
|
|
*/ |
142
|
|
|
private function populateCategoryGroup(CategoryGroupModel $categoryGroup, array $categoryGroupDefinition, $categoryGroupHandle) |
143
|
|
|
{ |
144
|
|
|
$categoryGroup->setAttributes([ |
145
|
|
|
'handle' => $categoryGroupHandle, |
146
|
|
|
'name' => $categoryGroupDefinition['name'], |
147
|
|
|
'hasUrls' => $categoryGroupDefinition['hasUrls'], |
148
|
|
|
'template' => $categoryGroupDefinition['template'], |
149
|
|
|
'maxLevels' => $categoryGroupDefinition['maxLevels'], |
150
|
|
|
]); |
151
|
|
|
|
152
|
|
|
$this->populateCategoryGroupLocales($categoryGroup, $categoryGroupDefinition['locales']); |
153
|
|
|
|
154
|
|
|
$fieldLayout = Craft::app()->schematic_fields->getFieldLayout($categoryGroupDefinition['fieldLayout']); |
155
|
|
|
$categoryGroup->setFieldLayout($fieldLayout); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Populate section locales. |
160
|
|
|
* |
161
|
|
|
* @param CategoryGroupModel $categoryGroup |
162
|
|
|
* @param $localeDefinitions |
163
|
|
|
*/ |
164
|
|
|
private function populateCategoryGroupLocales(CategoryGroupModel $categoryGroup, $localeDefinitions) |
165
|
|
|
{ |
166
|
|
|
$locales = $categoryGroup->getLocales(); |
167
|
|
|
|
168
|
|
|
foreach ($localeDefinitions as $localeId => $localeDef) { |
169
|
|
|
$locale = array_key_exists($localeId, $locales) ? $locales[$localeId] : new CategoryGroupLocaleModel(); |
170
|
|
|
|
171
|
|
|
$locale->setAttributes([ |
172
|
|
|
'locale' => $localeId, |
173
|
|
|
'urlFormat' => $localeDef['urlFormat'], |
174
|
|
|
'nestedUrlFormat' => $localeDef['nestedUrlFormat'], |
175
|
|
|
]); |
176
|
|
|
|
177
|
|
|
// Todo: Is this a hack? I don't see another way. |
178
|
|
|
// Todo: Might need a sorting order as well? It's NULL at the moment. |
179
|
|
|
Craft::app()->db->createCommand()->insertOrUpdate('locales', [ |
180
|
|
|
'locale' => $locale->locale, |
181
|
|
|
], []); |
182
|
|
|
|
183
|
|
|
$locales[$localeId] = $locale; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
$categoryGroup->setLocales($locales); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* Reset craft fields service cache using reflection |
191
|
|
|
*/ |
192
|
4 |
|
private function resetCraftCategoriesServiceCache() |
193
|
|
|
{ |
194
|
4 |
|
$obj = Craft::app()->categories; |
195
|
4 |
|
$refObject = new \ReflectionObject($obj); |
196
|
4 |
|
$refProperty = $refObject->getProperty('_fetchedAllCategoryGroups'); |
197
|
|
|
$refProperty->setAccessible(true); |
198
|
|
|
$refProperty->setValue($obj, false); |
199
|
|
|
$refProperty = $refObject->getProperty('_categoryGroupsById'); |
200
|
|
|
$refProperty->setAccessible(true); |
201
|
|
|
$refProperty->setValue($obj, array()); |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|