Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
Manager.php
1<?php
2
4
10
12{
13 public static function add(array $fields, array $products = []): Main\Result
14 {
15 $result = new Main\Result();
16
17 if (empty($fields['TITLE']))
18 {
19 $fields['TITLE'] = '';
20 }
21
22 if (empty($fields['CREATED_BY']))
23 {
24 $fields['CREATED_BY'] = Main\Engine\CurrentUser::get()->getId();
25 }
26
27 $files = isset($fields['FILES']) && is_array($fields['FILES']) ? $fields['FILES'] : [];
28 unset($fields['FILES']);
29
30 $addResult = Catalog\AgentContractTable::add($fields);
31 if ($addResult->isSuccess())
32 {
33 $id = $addResult->getId();
34 $result->setData(['ID' => $id]);
35
36 if ($products)
37 {
38 $addProductsResult = self::addProducts($id, $products);
39 if (!$addProductsResult->isSuccess())
40 {
41 $result->addErrors($addProductsResult->getErrors());
42 }
43 }
44
45 if ($files)
46 {
47 self::saveFiles($id, $files);
48 }
49 }
50 else
51 {
52 $result->addErrors($addResult->getErrors());
53 }
54
55 return $result;
56 }
57
58 public static function update(int $id, array $fields, ?array $products = null): Main\Result
59 {
60 $result = new Main\Result();
61
62 if (empty($fields['MODIFIED_BY']))
63 {
64 $fields['MODIFIED_BY'] = Main\Engine\CurrentUser::get()->getId();
65 }
66
67 $fields['DATE_MODIFY'] = new Main\Type\DateTime();
68
69 $files['FILES'] = $fields['FILES'];
70 $files['FILES_del'] = $fields['FILES_del'] ?? [];
71 unset($fields['FILES'], $fields['FILES_del']);
72
73 $files = self::prepareFilesToUpdate($files);
74
75 $updateResult = Catalog\AgentContractTable::update($id, $fields);
76 if ($updateResult->isSuccess())
77 {
78 if (!is_null($products))
79 {
80 $deleteProductsResult = self::deleteProductsByContractId($id);
81 if (!$deleteProductsResult->isSuccess())
82 {
83 $result->addErrors($deleteProductsResult->getErrors());
84 }
85
86 if ($products)
87 {
88 $addProductsResult = self::addProducts($id, $products);
89 if (!$addProductsResult->isSuccess())
90 {
91 $result->addErrors($addProductsResult->getErrors());
92 }
93 }
94 }
95
96 if ($files)
97 {
98 self::saveFiles($id, $files);
99 }
100 }
101 else
102 {
103 $result->addErrors($updateResult->getErrors());
104 }
105
106 return $result;
107 }
108
109 public static function delete(int $id): Main\Result
110 {
111 $result = new Main\Result();
112
113 $deleteProductsResult = self::deleteProductsByContractId($id);
114 if (!$deleteProductsResult->isSuccess())
115 {
116 $result->addErrors($deleteProductsResult->getErrors());
117 }
118
119 if ($result->isSuccess())
120 {
121 $deleteResult = Catalog\AgentContractTable::delete($id);
122 if (!$deleteResult->isSuccess())
123 {
124 $result->addErrors($deleteResult->getErrors());
125 }
126 }
127
128 return $result;
129 }
130
131 private static function addProducts(int $id, array $products): Main\Result
132 {
133 $result = new Main\Result();
134
135 $products = array_map(
136 static function ($product) use ($id)
137 {
138 $product['CONTRACT_ID'] = $id;
139 return $product;
140 },
141 $products
142 );
143
144 $addProductResult = Catalog\AgentProductTable::addMulti($products, true);
145 if (!$addProductResult->isSuccess())
146 {
147 $result->addErrors($addProductResult->getErrors());
148 }
149
150 return $result;
151 }
152
153 private static function deleteProductsByContractId(int $id): Main\Result
154 {
155 $result = new Main\Result();
156
157 $agentProductIterator = Catalog\AgentProductTable::getList([
158 'select' => ['ID'],
159 'filter' => ['=CONTRACT_ID' => $id],
160 ]);
161 while ($agentProduct = $agentProductIterator->fetch())
162 {
163 $deleteProductResult = Catalog\AgentProductTable::delete($agentProduct['ID']);
164 if (!$deleteProductResult->isSuccess())
165 {
166 $result->addErrors($deleteProductResult->getErrors());
167 }
168 }
169
170 return $result;
171 }
172
173 public static function get(int $id): Main\Result
174 {
175 $result = new Main\Result();
176
177 $agentContract = Catalog\AgentContractTable::getList([
178 'select' => [
179 'ID',
180 'TITLE',
181 'CONTRACTOR_ID',
182 'DATE_MODIFY',
183 'DATE_CREATE',
184 'MODIFIED_BY',
185 'CREATED_BY',
186 ],
187 'filter' => ['=ID' => $id],
188 'limit' => 1
189 ])->fetch();
190
191 if ($agentContract)
192 {
193 $products = [];
194 $productsIds = [];
195 $sectionIds = [];
196
197 $agentProductIterator = Catalog\AgentProductTable::getList([
198 'select' => [
199 'ID',
200 'PRODUCT_ID',
201 'PRODUCT_TYPE',
202 ],
203 'filter' => [
204 '=CONTRACT_ID' => $id,
205 ],
206 ]);
207 while ($agentProduct = $agentProductIterator->fetch())
208 {
209 if ($agentProduct['PRODUCT_TYPE'] === Catalog\AgentProductTable::PRODUCT_TYPE_SECTION)
210 {
211 $sectionIds[] = $agentProduct['PRODUCT_ID'];
212 }
213
214 if ($agentProduct['PRODUCT_TYPE'] === Catalog\AgentProductTable::PRODUCT_TYPE_PRODUCT)
215 {
216 $productsIds[] = $agentProduct['PRODUCT_ID'];
217 }
218
219 $agentProduct['PRODUCT_NAME'] = '';
220 $products[] = $agentProduct;
221 }
222
223 if ($products)
224 {
225 $sectionNames = [];
226 $productNames = [];
227
228 $sectionImages = [];
229 if ($sectionIds)
230 {
231 $sectionIterator = Iblock\SectionTable::getList([
232 'select' => ['ID', 'NAME', 'PICTURE'],
233 'filter' => ['=ID' => array_unique($sectionIds)],
234 ]);
235 while ($sectionData = $sectionIterator->fetch())
236 {
237 $sectionNames[$sectionData['ID']] = $sectionData['NAME'];
238 if (!empty($sectionData['PICTURE']))
239 {
240 $sectionImages[$sectionData['ID']] = self::getImageSource((int)$sectionData['PICTURE']);
241 }
242 }
243 }
244
245 $productImages = [];
246 $iblockProductMorePhotoMap = [];
247 if ($productsIds)
248 {
249 $elementIterator = Iblock\ElementTable::getList([
250 'select' => ['ID', 'NAME', 'IBLOCK_ID', 'PREVIEW_PICTURE', 'DETAIL_PICTURE'],
251 'filter' => ['=ID' => array_unique($productsIds)],
252 ]);
253 while ($elementData = $elementIterator->fetch())
254 {
255 $elementId = $elementData['ID'];
256 $productNames[$elementId] = $elementData['NAME'];
257 if (!empty($elementData['PREVIEW_PICTURE']))
258 {
259 $productImages[$elementId] = self::getImageSource((int)$elementData['PREVIEW_PICTURE']);
260 }
261
262 if (empty($element['IMAGE']) && !empty($elementData['DETAIL_PICTURE']))
263 {
264 $productImages[$elementId] = self::getImageSource((int)$elementData['DETAIL_PICTURE']);
265 }
266
267 if (empty($element['IMAGE']))
268 {
269 $iblockProductMorePhotoMap[$elementData['IBLOCK_ID']] ??= [];
270 $iblockProductMorePhotoMap[$elementData['IBLOCK_ID']][] = $elementId;
271 }
272 }
273
274 if (!empty($iblockProductMorePhotoMap))
275 {
276 $morePhotoIds = [];
277 $iterator = PropertyTable::getList([
278 'select' => ['ID', 'IBLOCK_ID'],
279 'filter' => [
280 '=IBLOCK_ID' => array_keys($iblockProductMorePhotoMap),
281 '=CODE' => \CIBlockPropertyTools::CODE_MORE_PHOTO,
282 '=ACTIVE' => 'Y',
283 ],
284 ]);
285
286 if ($row = $iterator->fetch())
287 {
288 $morePhotoIds[$row['IBLOCK_ID']] = $row['ID'];
289 }
290
291 foreach ($morePhotoIds as $iblockId => $propertyId)
292 {
293 $elementIds = $iblockProductMorePhotoMap[$iblockId];
294 $elementPropertyValues = array_fill_keys($elementIds, []);
295 $offersFilter = [
296 'IBLOCK_ID' => $iblockId,
297 'ID' => $elementIds,
298 ];
299 $propertyFilter = [
300 'ID' => $propertyId,
301 ];
302 \CIBlockElement::GetPropertyValuesArray($elementPropertyValues, $iblockId, $offersFilter, $propertyFilter);
303 foreach ($elementPropertyValues as $productId => $properties)
304 {
305 if (empty($properties))
306 {
307 continue;
308 }
309
310 $morePhotoProperty = reset($properties);
311 $value = $morePhotoProperty['VALUE'] ?? null;
312 if (empty($value))
313 {
314 continue;
315 }
316
317 $propertyValue = is_array($value) ? reset($value) : $value['VALUE'];
318 if ((int)$propertyValue > 0)
319 {
320 $productImages[$productId] = self::getImageSource((int)$propertyValue);
321 }
322 }
323 }
324
325 }
326 }
327
328 $products = array_map(
329 static function ($product) use ($sectionNames, $productNames, $productImages, $sectionImages)
330 {
331 if ($product['PRODUCT_TYPE'] === Catalog\AgentProductTable::PRODUCT_TYPE_SECTION)
332 {
333 $product['PRODUCT_NAME'] = $sectionNames[$product['PRODUCT_ID']];
334 $product['IMAGE'] = $sectionImages[$product['PRODUCT_ID']] ?? null;
335 }
336
337 if ($product['PRODUCT_TYPE'] === Catalog\AgentProductTable::PRODUCT_TYPE_PRODUCT)
338 {
339 $product['PRODUCT_NAME'] = $productNames[$product['PRODUCT_ID']];
340 $product['IMAGE'] = $productImages[$product['PRODUCT_ID']] ?? null;
341 }
342
343 return $product;
344 },
345 $products
346 );
347 }
348
349 $files = self::getFiles($id);
350
351 $result->setData(
352 array_merge(
353 $agentContract,
354 [
355 'PRODUCTS' => $products,
356 'FILES' => $files,
357 ]
358 )
359 );
360 }
361
362 return $result;
363 }
364
365 private static function saveFiles(int $contractId, array $files): void
366 {
367 if (empty($files))
368 {
369 return;
370 }
371
372 // load current file list
373 $existingFiles = [];
374 $fileMap = [];
375 $agentContractFileIterator = Catalog\AgentContractFileTable::getList([
376 'select' => ['ID', 'FILE_ID'],
377 'filter' => ['=CONTRACT_ID' => $contractId],
378 ]);
379 while ($agentContractFile = $agentContractFileIterator->fetch())
380 {
381 $id = (int)$agentContractFile['ID'];
382 $fileId = (int)$agentContractFile['FILE_ID'];
383 $existingFiles[$id] = [
384 'ID' => $id,
385 'FILE_ID' => $fileId,
386 ];
387 $fileMap[$fileId] = $id;
388 }
389
390 // convert the new list of files to array format for each line if needed
391 $files = static::convertFileList($fileMap, $files);
392 if (empty($files))
393 {
394 return;
395 }
396
397 // checking that the passed set of document files is full
398 foreach (array_keys($existingFiles) as $rowId)
399 {
400 if (!isset($files[$rowId]))
401 {
402 $files[$rowId] = $existingFiles[$rowId];
403 }
404 }
405
406 // process file list
407 $parsed = [];
408 foreach ($files as $rowId => $row)
409 {
410 // replace or delete existing file
411 if (
412 is_int($rowId)
413 && is_array($row)
414 && isset($existingFiles[$rowId])
415 )
416 {
417 // delete file
418 if (
419 isset($row['DEL'])
420 && $row['DEL'] === 'Y'
421 )
422 {
423 $resultInternal = Catalog\AgentContractFileTable::delete($rowId);
424 if ($resultInternal->isSuccess())
425 {
426 \CFile::Delete($existingFiles[$rowId]['FILE_ID']);
427 }
428 }
429 // replace file
430 elseif (
431 isset($row['FILE_ID'])
432 )
433 {
434 if ($row['FILE_ID'] !== $existingFiles[$rowId]['FILE_ID'])
435 {
436 $resultInternal = Catalog\AgentContractFileTable::update(
437 $rowId,
438 [
439 'FILE_ID' => $row['FILE_ID'],
440 ]
441 );
442 if ($resultInternal->isSuccess())
443 {
444 \CFile::Delete($existingFiles[$rowId]['FILE_ID']);
445 }
446 }
447 }
448 }
449 // save new file
450 elseif (
451 preg_match('/^n[0-9]+$/', $rowId, $parsed)
452 && is_array($row)
453 )
454 {
455 // file already saved from external code
456 if (isset($row['FILE_ID']))
457 {
458 $resultInternal = Catalog\AgentContractFileTable::add([
459 'CONTRACT_ID' => $contractId,
460 'FILE_ID' => $row['FILE_ID'],
461 ]);
462 if ($resultInternal->isSuccess())
463 {
464 $id = (int)$resultInternal->getId();
465 $fileMap[$row['FILE_ID']] = $id;
466 $existingFiles[$id] = [
467 'ID' => $id,
468 'FILE_ID' => $row['FILE_ID'],
469 ];
470 }
471 }
472 // save uploaded file
473 elseif (
474 isset($row['FILE_UPLOAD'])
475 && is_array($row['FILE_UPLOAD'])
476 )
477 {
478 $row['FILE_UPLOAD']['MODULE_ID'] = 'catalog';
479 $fileId = (int)\CFile::SaveFile(
480 $row['FILE_UPLOAD'],
481 'catalog',
482 false,
483 true
484 );
485 if ($fileId > 0)
486 {
487 $resultInternal = Catalog\AgentContractFileTable::add([
488 'CONTRACT_ID' => $contractId,
489 'FILE_ID' => $fileId,
490 ]);
491 if ($resultInternal->isSuccess())
492 {
493 $id = (int)$resultInternal->getId();
494 $fileMap[$fileId] = $id;
495 $existingFiles[$id] = [
496 'ID' => $id,
497 'FILE_ID' => $fileId,
498 ];
499 }
500 }
501 }
502 }
503 }
504 }
505
506 private static function convertFileList(array $fileMap, array $files): array
507 {
508 $formatArray = false;
509 $formatOther = false;
510 foreach ($files as $value)
511 {
512 if (is_array($value))
513 {
514 $formatArray = true;
515 }
516 else
517 {
518 $formatOther = true;
519 }
520 }
521
522 if ($formatArray && $formatOther)
523 {
524 return [];
525 }
526
527 if ($formatArray)
528 {
529 return $files;
530 }
531
532 $counter = 0;
533 $list = array_values(array_unique($files));
534 $files = [];
535 $parsed = [];
536 foreach ($list as $value)
537 {
538 if (!is_string($value))
539 {
540 continue;
541 }
542 if (preg_match('/^delete([0-9]+)$/', $value, $parsed))
543 {
544 $value = (int)$parsed[1];
545 if (isset($fileMap[$value]))
546 {
547 $id = $fileMap[$value];
548 $files[$id] = [
549 'DEL' => 'Y',
550 ];
551 }
552 }
553 elseif (preg_match('/^[0-9]+$/', $value, $parsed))
554 {
555 $value = (int)$value;
556 if (isset($fileMap[$value]))
557 {
558 $id = $fileMap[$value];
559 $files[$id] = [
560 'ID' => $id,
561 'FILE_ID' => $value,
562 ];
563 }
564 else
565 {
566 $id = 'n' . $counter;
567 $counter++;
568 $files[$id] = [
569 'ID' => null,
570 'FILE_ID' => $value,
571 ];
572 }
573 }
574 }
575
576 return $files;
577 }
578
579 private static function getFiles(int $contractId): array
580 {
581 $files = Catalog\AgentContractFileTable::getList([
582 'select' => ['FILE_ID'],
583 'filter' => ['=CONTRACT_ID' => $contractId]
584 ])->fetchAll();
585
586 return array_column($files, 'FILE_ID');
587 }
588
589 private static function prepareFilesToUpdate(array $fields): array
590 {
591 $filesExists = isset($fields['FILES']) && is_array($fields['FILES']);
592 $filesDelete = isset($fields['FILES_del']) && is_array($fields['FILES_del']);
593 if ($filesExists || $filesDelete)
594 {
595 $result = [];
596 if ($filesExists)
597 {
598 $fileList = $fields['FILES'];
599 Main\Type\Collection::normalizeArrayValuesByInt($fileList, false);
600 $fileList = Main\UI\FileInputUtility::instance()->checkFiles(
601 'files_uploader',
602 $fileList
603 );
604 foreach ($fileList as $id)
605 {
606 $result[$id] = (string)$id;
607 }
608 }
609
610 if ($filesDelete)
611 {
612 $deleteList = $fields['FILES_del'];
613 Main\Type\Collection::normalizeArrayValuesByInt($deleteList, false);
614 foreach ($deleteList as $id)
615 {
616 $result[$id] = 'delete' . $id;
617 }
618 }
619
620 $fields['FILES'] = array_values($result);
621 unset($result);
622 }
623
624 return $fields['FILES'];
625 }
626
627 private static function getImageSource(int $id): ?string
628 {
629 if ($id <= 0)
630 {
631 return null;
632 }
633
634 $file = \CFile::GetFileArray($id);
635 if (!$file)
636 {
637 return null;
638 }
639
640 return Tools::getImageSrc($file, false) ?: null;
641 }
642}
static update(int $id, array $fields, ?array $products=null)
Definition Manager.php:58
static add(array $fields, array $products=[])
Definition Manager.php:13