These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace exchange\classes; |
||
4 | |||
5 | use CMSFactory\ModuleSettings; |
||
6 | use core\models\Route; |
||
7 | use core\models\RouteQuery; |
||
8 | use Propel\Runtime\Exception\PropelException; |
||
9 | |||
10 | /** |
||
11 | * |
||
12 | * |
||
13 | * |
||
14 | * @author kolia |
||
15 | */ |
||
16 | final class Categories extends ExchangeBase |
||
17 | { |
||
18 | |||
19 | /** |
||
20 | * |
||
21 | * @var array |
||
22 | */ |
||
23 | private $categoriesNames = []; |
||
24 | |||
25 | /** |
||
26 | * Parsed categories from XML to one-dimension array |
||
27 | * @var array |
||
28 | */ |
||
29 | private $categoriesXml = []; |
||
30 | |||
31 | /** |
||
32 | * |
||
33 | * @var array |
||
34 | */ |
||
35 | private $existing = []; |
||
36 | |||
37 | /** |
||
38 | * |
||
39 | */ |
||
40 | private $externalIds; |
||
41 | |||
42 | /** |
||
43 | * |
||
44 | * @var array |
||
45 | */ |
||
46 | private $new = []; |
||
47 | |||
48 | /** |
||
49 | * Check if category exists (by external id) (helper) |
||
50 | * @param string $externalId |
||
51 | * @param boolean $returnCategoryId if TRUE, then method will return id of category |
||
52 | * @return boolean|int FALSE if category is new, TRUE otherwise |
||
53 | */ |
||
54 | public function categoryExists2($externalId, $returnCategoryId = FALSE) { |
||
55 | |||
56 | if (null === $this->externalIds) { |
||
57 | $this->externalIds = []; |
||
58 | foreach ($this->categories as $categoryId => $categoryData) { |
||
59 | if (!empty($categoryData['external_id'])) { |
||
60 | $this->externalIds[$categoryData['external_id']] = $categoryId; |
||
61 | } |
||
62 | } |
||
63 | } |
||
64 | $exists = isset($this->externalIds[$externalId]); |
||
65 | if ($exists == TRUE) { |
||
66 | return $returnCategoryId !== TRUE ? TRUE : $this->externalIds[$externalId]; |
||
67 | } |
||
68 | return FALSE; |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Starting import of the categories |
||
73 | * @return boolean|array FALSE|array(count of inserted, count of deleted) |
||
74 | * @throws \Exception |
||
75 | */ |
||
76 | protected function import_() { |
||
77 | |||
78 | // getting categories names for checking fr unique names |
||
79 | $categoriesI18n = $this->db |
||
80 | ->where('locale', \MY_Controller::getCurrentLocale()) |
||
81 | ->get('shop_category_i18n') |
||
82 | ->result_array(); |
||
83 | |||
84 | /** @var array $categoriesI18n */ |
||
85 | foreach ($categoriesI18n as $category) { |
||
86 | array_push($this->categoriesNames, $category['name']); |
||
87 | } |
||
88 | // creating one-dimention array of categories |
||
89 | $this->processCategories($this->importData); |
||
90 | |||
91 | // inserting |
||
92 | $insertCount = count($this->new); |
||
93 | if ($insertCount > 0) { |
||
94 | $dbArray = $this->getPreparedData($this->new); |
||
95 | $this->insertBatch('shop_category', $dbArray); |
||
96 | $this->dataLoad->getNewData('categories'); |
||
97 | $i18nData = $this->getI18nData($this->new); |
||
98 | $this->insertBatch('shop_category_i18n', $i18nData); |
||
99 | } |
||
100 | |||
101 | $ignoreExisting = ModuleSettings::ofModule('exchange')->get('ignore_existing'); |
||
102 | // updating |
||
103 | $updateCount = count($this->existing); |
||
104 | if ($updateCount > 0 && !isset($ignoreExisting['categories'])) { |
||
105 | $dbArray = $this->getPreparedData($this->existing); |
||
106 | $this->updateBatch('shop_category', $dbArray, 'external_id'); |
||
107 | $this->dataLoad->getNewData('categories'); |
||
108 | $i18nData = $this->getI18nData($this->existing); |
||
109 | $this->updateBatch('shop_category_i18n', $i18nData, 'id'); |
||
110 | } |
||
111 | |||
112 | $pathsAndParents = $this->getPathsAndParents(); |
||
113 | $this->updateBatch('shop_category', $pathsAndParents, 'id'); |
||
114 | |||
115 | $this->dataLoad->getNewData('categories'); |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Creates one-dimension array with categories from XML-file |
||
120 | * (method is filling $categories, $new and $existing arrays of class instance) |
||
121 | * @param \SimpleXMLElement $categories |
||
122 | * @param string $parent (default null) external id of parent if there is |
||
123 | */ |
||
124 | private function processCategories(\SimpleXMLElement $categories, $parent = NULL) { |
||
125 | foreach ($categories as $category) { |
||
126 | $externalId = (string) $category->Ид; |
||
127 | |||
128 | // splitting on those which need to be updated and new (by external id) |
||
129 | if (FALSE == $this->categoryExists($externalId)) { |
||
130 | $this->new[] = $externalId; |
||
131 | $name = $this->getCategoryName((string) $category->Наименование); |
||
132 | } else { |
||
133 | $this->existing[] = $externalId; |
||
134 | $name = (string) $category->Наименование; |
||
135 | } |
||
136 | |||
137 | $this->categoriesXml[$externalId] = [ |
||
138 | 'name' => $name, |
||
139 | 'active' => (string) $category->Статус === 'Удален' ? 0 : 1, |
||
140 | 'external_id' => $externalId, |
||
141 | 'parent_external_id' => $parent === null ? 0 : $parent, |
||
142 | ]; |
||
143 | |||
144 | if (isset($category->Группы)) { |
||
145 | $this->processCategories($category->Группы->Группа, $externalId); |
||
146 | } |
||
147 | } |
||
148 | |||
149 | } |
||
150 | |||
151 | /** |
||
152 | * Check if category exists (by external id) (helper) |
||
153 | * @param string $externalId |
||
154 | * @return boolean FALSE if category is new, FALSE otherwise |
||
155 | */ |
||
156 | public function categoryExists($externalId) { |
||
157 | |||
158 | foreach ($this->categories as $categoryId => $categoryData) { |
||
159 | if ($externalId == $categoryData['external_id']) { |
||
160 | return TRUE; |
||
161 | } |
||
162 | } |
||
163 | return FALSE; |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * @param string $name |
||
168 | * @return string |
||
169 | */ |
||
170 | private function getCategoryName($name) { |
||
171 | |||
172 | $nameTemp = $name; |
||
173 | $i = 1; |
||
174 | while (in_array($nameTemp, $this->categoriesNames, true)) { |
||
175 | $nameTemp = $name . ' ' . $i++; |
||
176 | } |
||
177 | array_push($this->categoriesNames, $nameTemp); |
||
178 | return $nameTemp; |
||
179 | } |
||
180 | |||
181 | /** |
||
182 | * Prepare array for DB insert/update query |
||
183 | * (returns array ready to inserting in database) |
||
184 | * @param array $categoriesExternalIds |
||
185 | * @return array |
||
186 | */ |
||
187 | private function getPreparedData(array $categoriesExternalIds) { |
||
188 | |||
189 | $dbArray = []; |
||
190 | foreach ($categoriesExternalIds as $externalId) { |
||
191 | // fitment of category url (might be busy) |
||
192 | // preparing array for insert |
||
193 | $dbArray[] = [ |
||
194 | 'external_id' => $externalId, |
||
195 | 'active' => $this->categoriesXml[$externalId]['active'], |
||
196 | ]; |
||
197 | } |
||
198 | return $dbArray; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * @param array $categoriesExternalIds |
||
203 | * @return array |
||
204 | */ |
||
205 | private function getI18nData($categoriesExternalIds) { |
||
206 | |||
207 | $i18n = []; |
||
208 | foreach ($this->categories as $categoryId => $categoryData) { |
||
209 | if (in_array($categoryData['external_id'], $categoriesExternalIds, true)) { |
||
210 | $i18n[] = [ |
||
211 | 'id' => $categoryData['id'], |
||
212 | 'locale' => $this->locale, |
||
213 | 'name' => $this->categoriesXml[$categoryData['external_id']]['name'], |
||
214 | ]; |
||
215 | } |
||
216 | } |
||
217 | return $i18n; |
||
218 | } |
||
219 | |||
220 | /** |
||
221 | * Filling parent ids of |
||
222 | * @return array |
||
223 | */ |
||
224 | private function getPathsAndParents() { |
||
225 | $categoriesExternalIds = array_merge($this->new, $this->existing); |
||
226 | // UPDATING INSERTED CATEGORIES (add parent ids & full path) |
||
227 | $this->dataLoad->getNewData('categories'); // getting categories form db again |
||
228 | // getting only categories which was inserted |
||
229 | $categories = []; |
||
230 | // "parent data" is in $this->categories (db), |
||
231 | foreach ($this->categories as $categoryId => $categoryData) { |
||
232 | if (in_array($categoryData['external_id'], $categoriesExternalIds, true)) { |
||
233 | $categories[$categoryData['id']] = [ |
||
234 | 'id' => $categoryData['id'], |
||
235 | 'parent_id' => $this->getParentIdDb($categoryData['external_id']), |
||
236 | 'external_id' => $categoryData['external_id'], |
||
237 | ]; |
||
238 | } |
||
239 | } |
||
240 | |||
241 | // creating id-paths and url-paths of each category |
||
242 | foreach ($categories as $categoryId => $categoryData) { |
||
243 | $currentPathIds = []; |
||
244 | |||
245 | $neededCid = $categoryData['parent_id']; |
||
246 | |||
247 | while ($neededCid != 0) { |
||
248 | $currentPathIds[] = $neededCid; |
||
249 | $neededCid = $categories[$neededCid]['parent_id']; |
||
250 | } |
||
251 | |||
252 | $parentUrl = RouteQuery::create()->filterByEntityId($categoryData['parent_id'])->filterByType(Route::TYPE_SHOP_CATEGORY)->findOne(); |
||
253 | try{ |
||
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||
254 | |||
255 | $route = new RouteQuery(); |
||
256 | $route->filterByParentUrl($parentUrl ? $parentUrl->getFullUrl() : ''); |
||
257 | $route->filterByUrl(translit_url($this->categoriesXml[$categoryData['external_id']]['name'])); |
||
258 | $route->findByType(Route::TYPE_SHOP_CATEGORY); |
||
259 | $route->filterByEntityId($categoryData['id']); |
||
260 | $route->findOneOrCreate()->save(); |
||
261 | |||
262 | }catch (PropelException $exp){ |
||
263 | dd($exp); |
||
0 ignored issues
–
show
|
|||
264 | } |
||
265 | $categories[$categoryId]['route_id'] = $route->findOne()->getId(); |
||
266 | $categories[$categoryId]['full_path_ids'] = serialize(array_reverse($currentPathIds)); |
||
267 | } |
||
268 | |||
269 | return $categories; |
||
270 | } |
||
271 | |||
272 | /** |
||
273 | * Returning DB id of category by external_id (helper) |
||
274 | * @param string $externalId |
||
275 | * @return int|boolean id (DB primary key) of category|FALSE |
||
276 | */ |
||
277 | private function getParentIdDb($externalId) { |
||
278 | |||
279 | $parentExternalId = $this->categoriesXml[$externalId]['parent_external_id']; |
||
280 | if ((string) $parentExternalId == '0') { |
||
281 | return 0; |
||
282 | } |
||
283 | foreach ($this->categories as $categoryData) { |
||
284 | if ($parentExternalId == $categoryData['external_id']) { |
||
285 | return $categoryData['id']; |
||
286 | } |
||
287 | } |
||
288 | return 0; |
||
289 | } |
||
290 | |||
291 | } |