Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
database.php
1<?php
2
4
20
26final class Database
27 implements
32 IDelete,
33 IScope
34{
36 protected $locationTable = Model\LocationTable::class;
38 protected $hierarchyTable = Model\HierarchyTable::class;
40 protected $locationNameTable = Model\LocationNameTable::class;
42 protected $addressTable = Model\AddressTable::class;
44 protected $fieldTable = Model\LocationFieldTable::class;
45
49 public function isScopeSatisfy(int $scope): bool
50 {
51 return $scope === LOCATION_SEARCH_SCOPE_ALL || $scope === LOCATION_SEARCH_SCOPE_INTERNAL;
52 }
53
55 public function findByExternalId(string $externalId, string $sourceCode, string $languageId)
56 {
57 if($externalId == '')
58 {
59 return null;
60 }
61
62 $result = $this->createQuery($languageId)
63 ->addFilter('=EXTERNAL_ID', $externalId)
64 ->addFilter('=SOURCE_CODE', $sourceCode)
65 ->fetchObject();
66
67 if($result)
68 {
69 $result = \Bitrix\Location\Entity\Location\Converter\OrmConverter::createLocation($result, $languageId);
70 }
71
72 return $result;
73
74 }
75
77 public function findById(int $id, string $languageId)
78 {
79 if($id <= 0)
80 {
81 return null;
82 }
83
84 $result = null;
85 $res = $this->createQuery($languageId)
86 ->addFilter('=ID', $id)
87 ->fetchObject();
88
89 if($res)
90 {
91 $result = \Bitrix\Location\Entity\Location\Converter\OrmConverter::createLocation($res, $languageId);
92 }
93
94 return $result;
95 }
96
100 public function findByText(string $text, string $languageId)
101 {
102 if($text == '')
103 {
104 return null;
105 }
106
107 $text = Builder::build($languageId)->normalize($text);
108
109 $result = $this->createQuery($languageId)
110 ->addFilter('%NAME.NAME_NORMALIZE', $text)
111 ->fetchCollection();
112
113 return \Bitrix\Location\Entity\Location\Converter\OrmConverter::createCollection($result, $languageId);
114 }
115
117 public function findParents(Location $location, string $languageId)
118 {
119 if($location->getId() <= 0)
120 {
121 return null;
122 }
123
124 $ormCollection = $this->hierarchyTable::getList([
125 'filter' => [
126 '=DESCENDANT_ID' => $location->getId(),
127 '=ANCESTOR.NAME.LANGUAGE_ID' => $languageId, //todo: if not found required language
128 ],
129 'order' => ['LEVEL' => 'ASC'],
130 'select' => [
131 '*',
132 'ANCESTOR',
133 'ANCESTOR.NAME'
134 ]
135 ])->fetchCollection();
136
137 $result = \Bitrix\Location\Entity\Location\Converter\OrmConverter::createParentCollection($ormCollection, $languageId);
138 $result->setDescendant($location);
139 return $result;
140 }
141
142 protected function obtainLocationKeys(Location $location): array
143 {
144 $result = [0, ''];
145
146 $query = $this->locationTable::query()
147 ->where('EXTERNAL_ID', $location->getExternalId())
148 ->where('SOURCE_CODE', $location->getSourceCode())
149 ->addSelect('ID')
150 ->addSelect('CODE');
151
152 if($res = $query->fetch())
153 {
154 $result = [(int)$res['ID'], (string)$res['CODE']];
155 }
156
157 return $result;
158 }
159
160 protected function generateLocationCode()
161 {
162 return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
163 mt_rand(0, 0xffff), mt_rand(0, 0xffff),
164 mt_rand(0, 0xffff),
165 mt_rand(0, 0x0fff) | 0x4000,
166 mt_rand(0, 0x3fff) | 0x8000,
167 mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
168 );
169 }
170
174 public function save(Location $location): Result
175 {
176 $isNewLocation = false;
177
178 // We can have already saved location with the same externalId and source code.
179 if($location->getId() <= 0)
180 {
181 [$locationId, $locationCode] = $this->obtainLocationKeys($location);
182
183 if($locationId > 0)
184 {
185 $location->setId($locationId);
186 $location->setCode($locationCode);
187 }
188 else
189 {
190 $location->setCode($this->generateLocationCode());
191 }
192 }
193
194 $fields = Location\Converter\DbFieldConverter::convertToDbFields($location);
195
196 if($location->getId() > 0)
197 {
198 $result = $this->locationTable::update($location->getId(), $fields);
199 }
200 else
201 {
202 $result = $this->locationTable::add($fields);
203 $isNewLocation = true;
204
205 if($result->isSuccess())
206 {
207 $location->setId($result->getId());
208 }
209 }
210
211 if($result->isSuccess())
212 {
213 $res = $this->saveName($location, $isNewLocation);
214
215 if(!$res->isSuccess())
216 {
217 $result->addErrors($res->getErrors());
218 }
219
220 $res = $this->saveFields($location);
221
222 if(!$res->isSuccess())
223 {
224 $result->addErrors($res->getErrors());
225 }
226 }
227
228 return $result;
229 }
230
231 private function saveFields(Location $location)
232 {
233 if($location->getId() <= 0)
234 {
235 throw new ArgumentNullException('Location Id');
236 }
237
238 $fieldsCollection = Location\Converter\OrmConverter::convertFieldsToOrm($location);
239
240 $this->fieldTable::deleteByLocationId($location->getId());
241 return $fieldsCollection->save();
242 }
243
244 private function saveName(Location $location, bool $isLocationNew)
245 {
246 $fields = Location\Converter\DbFieldConverter::convertNameToDbFields($location);
247 $itemExist = false;
248
249 if(!$isLocationNew)
250 {
251 $itemExist = $this->locationNameTable::getById([
252 'LOCATION_ID' => $fields['LOCATION_ID'],
253 'LANGUAGE_ID' => $fields['LANGUAGE_ID']]
254 )->fetch();
255 }
256
257 if($itemExist)
258 {
259 $result = $this->locationNameTable::update([
260 'LOCATION_ID' => $fields['LOCATION_ID'],
261 'LANGUAGE_ID' => $fields['LANGUAGE_ID']
262 ], $fields);
263 }
264 else
265 {
266 $result = $this->locationNameTable::add($fields);
267 }
268
269 return $result;
270 }
271
273 public function delete(Location $location): Result
274 {
275 $id = $location->getId();
276
277 if($id <= 0)
278 {
279 return new Result();
280 }
281
282 $res = $this->addressTable::getList([
283 'filter' => ['LOCATION_ID' => (int)$id]
284 ]);
285
286 if($row = $res->fetch())
287 {
288 return (new Result())
289 ->addError(
290 new Error(
291 Loc::getMessage('LOCATION_REPO_DB_EXIST_LINKED_ADDRESS')
292 )
293 );
294 }
295
296 $result = $this->locationTable::delete($id);
297
298 if($result->isSuccess())
299 {
300 $this->locationNameTable::deleteByLocationId($id);
301 $this->hierarchyTable::deleteByLocationId($id);
302 $this->fieldTable::deleteByLocationId($id);
303 }
304
305 return $result;
306 }
307
314 public function saveParents(Parents $parents): Result
315 {
316 $result = new Result();
317
318 if($parents->count() <= 0)
319 {
320 return new Result();
321 }
322
323 if($parents->getDescendant()->getId() <= 0)
324 {
325 throw new ArgumentNullException('descendant has not saved yet');
326 }
327
328 $data = [];
329 $items = $parents->getItems();
330 krsort($items);
331
336 foreach($items as $level => $parentLocation)
337 {
338 if($parentLocation->getId() <= 0)
339 {
340 $res = $parentLocation->save();
341
342 if(!$res->isSuccess())
343 {
344 $result->addErrors($res->getErrors());
345 continue;
346 }
347 }
348
349 $data[] = [
350 'DESCENDANT_ID' => (int)$parents->getDescendant()->getId(),
351 'ANCESTOR_ID' => (int)$parentLocation->getId(),
352 'LEVEL' => (int)$level,
353 ];
354 }
355
356 if(!empty($data))
357 {
358 $this->hierarchyTable::insertBatch($data);
359 }
360
361 return $result;
362 }
363
364 private function createQuery(string $languageId)
365 {
366 return $this->locationTable::query()
367 ->addFilter('=NAME.LANGUAGE_ID', $languageId)
368 ->addSelect('*')
369 ->addSelect('NAME')
370 ->addSelect('FIELDS');
371 }
372}
findParents(Location $location, string $languageId)
Definition database.php:117
findByExternalId(string $externalId, string $sourceCode, string $languageId)
Definition database.php:55
findByText(string $text, string $languageId)
Definition database.php:100
findById(int $id, string $languageId)
Definition database.php:77
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29