1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
BaseIblockElementRepository.php
См. документацию.
1<?php
2
3namespace Bitrix\Catalog\v2;
4
5use Bitrix\Catalog\Model\Product;
6use Bitrix\Catalog\ProductTable;
7use Bitrix\Catalog\v2\Iblock\IblockInfo;
8use Bitrix\Catalog\v2\Internal\ProductInternalService;
9use Bitrix\Main\Error;
10use Bitrix\Main\Result;
11
21{
23 protected $factory;
25 protected $iblockInfo;
26
27 private ?string $detailUrlTemplate = null;
28
29 private bool $allowedDetailUrl;
30
38 {
39 $this->factory = $factory;
40 $this->iblockInfo = $iblockInfo;
41 $this->setAutoloadDetailUrl(false);
42 }
43
44 public function getEntityById(int $id): ?BaseIblockElementEntity
45 {
46 if ($id <= 0)
47 {
48 throw new \OutOfRangeException($id);
49 }
50
51 $entities = $this->getEntitiesBy([
52 'filter' => [
53 '=ID' => $id,
54 ],
55 ]);
56
57 return reset($entities) ?: null;
58 }
59
60 public function getEntitiesBy($params): array
61 {
62 $entities = [];
63
64 foreach ($this->getList((array)$params) as $item)
65 {
66 $entities[] = $this->createEntity($item);
67 }
68
69 return $entities;
70 }
71
72 public function save(BaseEntity ...$entities): Result
73 {
74 $result = new Result();
75
76 $savedIds = [];
77
78 foreach ($entities as $entity)
79 {
80 $entityId = $entity->getId();
81 if ($entityId !== null)
82 {
83 $res = $this->updateInternal($entityId, $entity->getChangedFields());
84
85 if ($res->isSuccess())
86 {
87 $savedIds[] = $entityId;
88 }
89 else
90 {
91 $result->addErrors($res->getErrors());
92 }
93 }
94 else
95 {
96 $res = $this->addInternal($entity->getFields());
97
98 if ($res->isSuccess())
99 {
100 $id = $res->getData()['ID'];
101 $entity->setId($id);
102 $savedIds[] = $id;
103 }
104 else
105 {
106 $result->addErrors($res->getErrors());
107 }
108 }
109 }
110
111 // re-initialize original fields from database after save (DETAIL_PICTURE, etc)
112 if (!empty($savedIds))
113 {
114 $fields = $this->getList([
115 'filter' => [
116 'ID' => $savedIds,
117 ],
118 ]);
119
120 foreach ($entities as $entity)
121 {
122 $entityFields = $fields[$entity->getId()] ?? null;
123 if (!is_array($entityFields))
124 {
125 continue;
126 }
127 $entityFields = array_diff_key($entityFields, ['TYPE' => true]);
128
129 if ($entityFields)
130 {
131 $entity->initFields($entityFields);
132 }
133 }
134 }
135
136 return $result;
137 }
138
139 public function delete(BaseEntity ...$entities): Result
140 {
141 $result = new Result();
142
143 foreach ($entities as $entity)
144 {
145 if ($entityId = $entity->getId())
146 {
147 $res = $this->deleteInternal($entityId);
148
149 if (!$res->isSuccess())
150 {
151 $result->addErrors($res->getErrors());
152 }
153 }
154 }
155
156 return $result;
157 }
158
159 public function setAutoloadDetailUrl(bool $state): self
160 {
161 $this->allowedDetailUrl = $state;
162
163 return $this;
164 }
165
166 public function checkAutoloadDetailUrl(): bool
167 {
168 return $this->allowedDetailUrl;
169 }
170
171 public function setDetailUrlTemplate(?string $template): self
172 {
173 $this->detailUrlTemplate = $template;
174
175 $this->setAutoloadDetailUrl($template !== null);
176
177 return $this;
178 }
179
180 public function getDetailUrlTemplate(): ?string
181 {
182 return $this->detailUrlTemplate;
183 }
184
185 protected function getDefaultElementSelect(): array
186 {
187 $result = [
188 'ID',
189 'TIMESTAMP_X',
190 'MODIFIED_BY',
191 'DATE_CREATE',
192 'CREATED_BY',
193 'IBLOCK_ID',
194 'IBLOCK_SECTION_ID',
195 'ACTIVE',
196 'ACTIVE_FROM',
197 'ACTIVE_TO',
198 'SORT',
199 'NAME',
200 'PREVIEW_PICTURE',
201 'PREVIEW_TEXT',
202 'PREVIEW_TEXT_TYPE',
203 'DETAIL_PICTURE',
204 'DETAIL_TEXT',
205 'DETAIL_TEXT_TYPE',
206 'WF_STATUS_ID',
207 'WF_PARENT_ELEMENT_ID',
208 'WF_NEW',
209 'IN_SECTIONS',
210 'SHOW_COUNTER',
211 'SHOW_COUNTER_START',
212 'CODE',
213 'TAGS',
214 'XML_ID',
215 'TMP_ID',
216 ];
217 if ($this->checkAutoloadDetailUrl())
218 {
219 $result[] = 'DETAIL_PAGE_URL';
220 }
221
222 return $result;
223 }
224
225 protected function getList(array $params): array
226 {
227 $filter = $params['filter'] ?? [];
228 $order = $params['order'] ?? [];
229 $nav = $params['nav'] ?? false;
230
231 $iblockElements = [];
232 $listIds = [];
233
234 $iterator = \CIBlockElement::GetList(
235 $order,
236 array_merge(
237 $filter,
238 $this->getAdditionalFilter(),
240 ),
241 false,
242 $nav,
243 [
244 'ID',
245 'IBLOCK_ID',
246 ],
247 );
248 while ($row = $iterator->fetch())
249 {
250 $id = (int)$row['ID'];
251 $iblockElements[$id] = $row;
252 $listIds[] = $id;
253 }
254 unset($iterator);
255
256 if (empty($iblockElements))
257 {
258 return [];
259 }
260
261 $elementSelect = $this->getDefaultElementSelect();
262 $detailUrlTemplate = $this->checkAutoloadDetailUrl() ? $this->getDetailUrlTemplate() : null;
263 $specificFields = [
264 'QUANTITY_TRACE' => 'QUANTITY_TRACE_ORIG',
265 'CAN_BUY_ZERO' => 'CAN_BUY_ZERO_ORIG',
266 'SUBSCRIBE' => 'SUBSCRIBE_ORIG',
267 ];
268 $productSelect = array_merge(['*', 'UF_*'], array_values($specificFields));
269
270 foreach (array_chunk($listIds, CATALOG_PAGE_SIZE) as $pageIds)
271 {
272 $elementsIterator = \CIBlockElement::GetList(
273 [],
274 [
275 'ID' => $pageIds,
276 'CHECK_PERMISSIONS' => 'N',
277 'SHOW_NEW' => 'Y',
278 ],
279 false,
280 false,
281 $elementSelect,
282 );
283 if ($detailUrlTemplate)
284 {
285 $elementsIterator->SetUrlTemplates($detailUrlTemplate);
286 }
287 while ($element = $elementsIterator->getNext())
288 {
289 $id = (int)$element['ID'];
290 $iblockElements[$id] += $this->replaceRawFromTilda($element);
291 }
292 unset($elementsIterator);
293
294 $productIterator = ProductTable::getList([
295 'select' => $productSelect,
296 'filter' => [
297 '@ID' => $pageIds,
298 ],
299 ]);
300 while ($product = $productIterator->fetch())
301 {
302 $id = (int)$product['ID'];
303 unset($product['ID']);
304 foreach ($specificFields as $field => $originalField)
305 {
306 $product[$field] = $product[$originalField];
307 unset($product[$originalField]);
308 }
309 $iblockElements[$id] += $product;
310 }
311 unset($productIterator);
312 }
313
314 return $iblockElements;
315 }
316
317 protected function getAdditionalFilter(): array
318 {
319 return [
320 'CHECK_PERMISSIONS' => 'N',
321 'MIN_PERMISSION' => 'R',
322 ];
323 }
324
325 protected function getAdditionalProductFilter(): array
326 {
327 return [];
328 }
329
331 {
332 $entity = $this->makeEntity($fields);
333
334 $entity->initFields($fields);
335
336 return $entity;
337 }
338
339 abstract protected function makeEntity(array $fields = []): BaseIblockElementEntity;
340
341 protected function addInternal(array $fields): Result
342 {
343 $productService = new ProductInternalService();
344
345 return $productService->add($fields);
346 }
347
348 protected function updateInternal(int $id, array $fields): Result
349 {
350 $productService = new ProductInternalService();
351
352 return $productService->update($id, $fields);
353 }
354
355 protected function deleteInternal(int $id): Result
356 {
357 $result = new Result();
358
359 $res = \CIBlockElement::delete($id);
360
361 if ($res)
362 {
363 $res = Product::delete($id);
364
365 if (!$res->isSuccess())
366 {
367 $result->addErrors($res->getErrors());
368 }
369 }
370 else
371 {
372 global $APPLICATION;
373 $exception = $APPLICATION->GetException();
374
375 if ($exception && $exception->GetString())
376 {
377 $errorMessage = $exception->GetString();
378 }
379 else
380 {
381 $errorMessage = "Delete operation for entity with id {$id} failed.";
382 }
383
384 $result->addError(new Error($errorMessage));
385 }
386
387 return $result;
388 }
389
390 private function replaceRawFromTilda(array $element): array
391 {
392 $newElement = [];
393
394 foreach ($element as $key => $value)
395 {
396 $tildaKey = "~{$key}";
397 if (isset($element[$tildaKey]))
398 {
399 $newElement[$key] = $element[$tildaKey];
400 }
401 }
402
403 return $newElement;
404 }
405}
const CATALOG_PAGE_SIZE
Определения include.php:111
global $APPLICATION
Определения include.php:80
__construct(BaseIblockElementFactory $factory, IblockInfo $iblockInfo)
Определения BaseIblockElementRepository.php:37
Определения error.php:15
static getList(array $parameters=array())
Определения datamanager.php:431
$template
Определения file_edit.php:49
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$entity
$filter
Определения iblock_catalog_list.php:54
while($arParentIBlockProperty=$dbParentIBlockProperty->Fetch()) $errorMessage
$order
Определения payment.php:8
$entityId
Определения payment.php:4
if(empty($signedUserToken)) $key
Определения quickway.php:257
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$iterator
Определения yandex_run.php:610
$fields
Определения yandex_run.php:501