Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
element.php
1<?php
2
4
12use CCatalogStoreDocsElement;
18
19class Element extends Controller
20{
21 private const DOCUMENT_STATUS_ALLOWED = 0;
22 private const DOCUMENT_STATUS_CONDUCT = -1;
23 private const DOCUMENT_STATUS_ABSENT = -2;
24
25 //region Actions
29 public function getFieldsAction(): array
30 {
31 return ['DOCUMENT_ELEMENT' => $this->getViewFields()];
32 }
33
38 public function addAction(array $fields): ?array
39 {
40 $documentId = (int)($fields['DOC_ID'] ?? 0);
41 if (!$documentId)
42 {
43 $this->setDocumentNotFoundError();
44
45 return null;
46 }
47
48 $documentFields = $this->getDocumentFields($documentId);
49 if (!$documentFields)
50 {
51 $this->setDocumentNotFoundError();
52
53 return null;
54 }
55 elseif (!$this->checkDocumentAccess(ActionDictionary::ACTION_STORE_DOCUMENT_MODIFY, $documentFields))
56 {
57 return null;
58 }
59 elseif (!$this->checkStoresAccess(0, $fields))
60 {
61 return null;
62 }
63
64 switch ($this->getDocumentStatusById($documentId))
65 {
66 case self::DOCUMENT_STATUS_ALLOWED:
67 $addResult = CCatalogStoreDocsElement::add($fields);
68 if ($addResult)
69 {
70 return ['DOCUMENT_ELEMENT' => $this->get($addResult)];
71 }
72
73 $this->addError(new Error('Error of adding new document element'));
74 break;
75
76 case self::DOCUMENT_STATUS_CONDUCT:
77 $this->setDocumentConductError();
78 break;
79
80 default:
81 $this->setDocumentNotFoundError();
82 break;
83 }
84
85 return null;
86 }
87
93 public function updateAction(int $id, array $fields): ?array
94 {
95 $documentFields = $this->getDocumentFieldsByElementId($id);
96 if (!$documentFields)
97 {
98 $this->setDocumentNotFoundError();
99
100 return null;
101 }
102 elseif (!$this->checkDocumentAccess(ActionDictionary::ACTION_STORE_DOCUMENT_MODIFY, $documentFields))
103 {
104 return null;
105 }
106 elseif (!$this->checkStoresAccess($id, $fields))
107 {
108 return null;
109 }
110
111 switch ($this->getDocumentStatusByElementId($id))
112 {
113 case self::DOCUMENT_STATUS_ALLOWED:
114 $result = CCatalogStoreDocsElement::update($id, $fields);
115
116 if ($result)
117 {
118 return ['DOCUMENT_ELEMENT' => $this->get($id)];
119 }
120
121 $this->addError(new Error('Error of modifying new document'));
122 break;
123
124 case self::DOCUMENT_STATUS_CONDUCT:
125 $this->setDocumentConductError();
126 break;
127
128 default:
129 $this->setDocumentNotFoundError();
130 break;
131 }
132
133 return null;
134 }
135
140 public function deleteAction(int $id): ?bool
141 {
142 $documentFields = $this->getDocumentFieldsByElementId($id);
143 if (!$documentFields)
144 {
145 $this->setDocumentNotFoundError();
146
147 return null;
148 }
149 elseif (!$this->checkDocumentAccess(ActionDictionary::ACTION_STORE_DOCUMENT_MODIFY, $documentFields))
150 {
151 return null;
152 }
153 elseif (!$this->checkStoresAccess($id))
154 {
155 return null;
156 }
157
158 switch ($this->getDocumentStatusByElementId($id))
159 {
160 case self::DOCUMENT_STATUS_ALLOWED:
161 $result = CCatalogStoreDocsElement::delete($id);
162 if ($result)
163 {
164 return true;
165 }
166
167 $this->addError(new Error('Error of deleting document'));
168 break;
169
170 case self::DOCUMENT_STATUS_CONDUCT:
171 $this->setDocumentConductError();
172 break;
173
174 default:
175 $this->setDocumentNotFoundError();
176 break;
177 }
178
179 return null;
180 }
181
189 public function listAction(
190 PageNavigation $pageNavigation,
191 array $order = [],
192 array $filter = [],
193 array $select = []
194 ): Page
195 {
196 $filter['@DOCUMENT.DOC_TYPE'] = array_keys(Catalog\Controller\Document::getAvailableRestDocumentTypes());
197
198 $accessFilter = AccessController::getCurrent()->getEntityFilter(
199 ActionDictionary::ACTION_STORE_DOCUMENT_VIEW,
200 get_class($this->getEntityTable())
201 );
202 if ($accessFilter)
203 {
204 // combines through a new array so that the `OR` condition does not bypass the access filter.
205 $filter = [
206 $accessFilter,
207 $filter,
208 ];
209 }
210
211 return new Page(
212 'DOCUMENT_ELEMENTS',
213 $this->getList($select, $filter, $order, $pageNavigation),
214 $this->count($filter)
215 );
216 }
217
223 public function fieldsAction(): ?array
224 {
225 return [$this->getViewFields()];
226 }
227
228 protected function getDefaultPreFilters(): array
229 {
230 return array_merge(
231 parent::getDefaultPreFilters(),
232 [
233 new ActionFilter\Scope(ActionFilter\Scope::REST),
234 ]
235 );
236 }
237
241 protected function getEntityTable()
242 {
243 return new \Bitrix\Catalog\StoreDocumentElementTable();
244 }
245
249 protected function checkModifyPermissionEntity()
250 {
251 $r = new Result();
252
253 if (!AccessController::getCurrent()->check(Controller::CATALOG_STORE))
254 {
255 $r->addError(new Error(
256 Controller::ERROR_ACCESS_DENIED,
257 'ERROR_DOCUMENT_RIGHTS'
258 ));
259 }
260
261 return $r;
262 }
263
264 protected function checkReadPermissionEntity()
265 {
266 $r = new Result();
267
268 if (
269 !AccessController::getCurrent()->check(Controller::CATALOG_STORE)
270 && !AccessController::getCurrent()->check(Controller::CATALOG_READ)
271 )
272 {
273 $r->addError(new Error(
274 Controller::ERROR_ACCESS_DENIED,
275 'ERROR_DOCUMENT_RIGHTS'
276 ));
277 }
278
279 return $r;
280 }
281
288 protected function checkPermissionEntity($name, $arguments=[])
289 {
290 if ($name === 'fields')
291 {
292 return $this->checkGetFieldsPermissionEntity();
293 }
294
295 return parent::checkPermissionEntity($name, $arguments);
296 }
297
298 private function getDocumentStatusById(int $documentId): int
299 {
300 return $this->getDocumentStatus(
301 $this->getDocumentFields($documentId)
302 );
303 }
304
305 private function getDocumentFields(int $documentId): ?array
306 {
307 return Catalog\StoreDocumentTable::getRow([
308 'select' => [
309 'ID',
310 'STATUS',
311 'DOC_TYPE',
312 ],
313 'filter' => [
314 '=ID' => $documentId,
315 ],
316 ]);
317 }
318
319 private function getDocumentStatusByElementId(int $elementId): int
320 {
321 return $this->getDocumentStatus(
322 $this->getDocumentFieldsByElementId($elementId)
323 );
324 }
325
326 public function getDocumentFieldsByElementId(int $elementId): ?array
327 {
328 $row = Catalog\StoreDocumentElementTable::getRow([
329 'select' => [
330 'STORE_DOCUMENT_ID' => 'DOC_ID',
331 'STATUS' => 'DOCUMENT.STATUS',
332 'DOC_TYPE' => 'DOCUMENT.DOC_TYPE',
333 ],
334 'filter' => [
335 '=ID' => $elementId,
336 ],
337 ]);
338 if ($row)
339 {
340 $row['ID'] = $row['STORE_DOCUMENT_ID'];
341 unset($row['STORE_DOCUMENT_ID']);
342 }
343
344 return $row;
345 }
346
347 private function getDocumentStatus($row): int
348 {
349 if (empty($row) || !is_array($row))
350 {
351 return self::DOCUMENT_STATUS_ABSENT;
352 }
353
354 $documentTypes = Catalog\Controller\Document::getAvailableRestDocumentTypes();
355 if (!isset($documentTypes[$row['DOC_TYPE']]))
356 {
357 return self::DOCUMENT_STATUS_ABSENT;
358 }
359
360 return ($row['STATUS'] === 'N'
361 ? self::DOCUMENT_STATUS_ALLOWED
362 : self::DOCUMENT_STATUS_CONDUCT
363 );
364 }
365
366 private function setDocumentRightsError(): void
367 {
368 $this->addError(new \Bitrix\Main\Error(
369 Controller::ERROR_ACCESS_DENIED,
370 'ERROR_DOCUMENT_RIGHTS'
371 ));
372 }
373
374 private function setDocumentNotFoundError(): void
375 {
376 $this->addError(new \Bitrix\Main\Error(
377 'Document not found',
378 'ERROR_DOCUMENT_STATUS'
379 ));
380 }
381
382 private function setDocumentConductError(): void
383 {
384 $this->addError(new \Bitrix\Main\Error(
385 'Conducted document',
386 'ERROR_DOCUMENT_STATUS'
387 ));
388 }
389
398 private function checkDocumentAccess(string $action, array $documentFields): bool
399 {
400 $can = AccessController::getCurrent()->check(
401 $action,
402 StoreDocument::createFromArray($documentFields)
403 );
404 if (!$can)
405 {
406 $this->setDocumentRightsError();
407
408 return false;
409 }
410
411 return true;
412 }
413
422 private function checkStoresAccess(int $id, array $fields = []): bool
423 {
424 $fields['ID'] = $id;
425
426 $can = AccessController::getCurrent()->check(
427 ActionDictionary::ACTION_STORE_VIEW,
428 StoreDocumentElement::createFromArray($fields)
429 );
430 if (!$can)
431 {
432 $this->setDocumentRightsError();
433
434 return false;
435 }
436
437 return true;
438 }
439}
updateAction(int $id, array $fields)
Definition element.php:93
checkPermissionEntity($name, $arguments=[])
Definition element.php:288
listAction(PageNavigation $pageNavigation, array $order=[], array $filter=[], array $select=[])
Definition element.php:189
addError(Main\Error $error)
Definition error.php:22