Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
ElementProvider.php
1<?php
2
4
12
14{
15 public const ENTITY_ID = 'highloadblock-element';
16
17 public const QUERY_SEARCH = 'S';
18 public const QUERY_SUBSTRING = 'L';
19 public const QUERY_BEGIN = 'B';
20
21 protected const ELEMENTS_LIMIT = 100;
22
23 private int $highloadblockId;
24
25 private ORM\Entity $highloadblock;
26
27 private array $fields;
28
40 public function __construct(array $options = [])
41 {
42 parent::__construct();
43
44 $this->options = array_filter(
46 function ($row)
47 {
48 return $row !== null;
49 }
50 );
51 }
52
53 public function isAvailable(): bool
54 {
55 global $USER;
56
57 if (!(isset($USER) && $USER instanceof \CUser))
58 {
59 return false;
60 }
61 if (!$USER->isAuthorized())
62 {
63 return false;
64 }
65
66 if (!$this->isHighloadblockExists())
67 {
68 return false;
69 }
70
71 if ($USER->IsAdmin())
72 {
73 return true;
74 }
75
76 if (!$this->canReadHighloadblock())
77 {
78 return false;
79 }
80
81 return true;
82 }
83
84 public function getItems(array $ids): array
85 {
86 if (!$this->isHighloadblockExists())
87 {
88 return [];
89 }
90
91 $items = [];
92
93 $elementList = $this->getElements([
94 'filter' => $this->getFilterByIds($ids),
95 ]);
96 foreach ($elementList as $element)
97 {
98 $items[] = $this->makeItem($element);
99 }
100
101 return $items;
102 }
103
104 public function getPreselectedItems(array $ids): array
105 {
106 return $this->getItems($ids);
107 }
108
109 public function fillDialog(Dialog $dialog): void
110 {
111 $dialog->loadPreselectedItems();
112
113 if ($dialog->getItemCollection()->count() > 0)
114 {
115 foreach ($dialog->getItemCollection() as $item)
116 {
117 $dialog->addRecentItem($item);
118 }
119 }
120
121 $recentItems = $dialog->getRecentItems()->getEntityItems(self::ENTITY_ID);
122 $recentItemsCount = count($recentItems);
123
124 if ($recentItemsCount < self::ELEMENTS_LIMIT)
125 {
126 $elementList = $this->getElements([
127 'filter' => [],
128 'limit' => self::ELEMENTS_LIMIT,
129 ]);
130 foreach ($elementList as $element)
131 {
132 $dialog->addRecentItem($this->makeItem($element));
133 }
134 }
135 }
136
137 public function doSearch(SearchQuery $searchQuery, Dialog $dialog): void
138 {
139 $filter = $this->getQueryFilter($searchQuery);
140 if ($filter === null)
141 {
142 return;
143 }
144
145 $elementList = $this->getElements([
146 'filter' => $filter,
147 'limit' => self::ELEMENTS_LIMIT,
148 ]);
149 if (count($elementList) === self::ELEMENTS_LIMIT)
150 {
151 $searchQuery->setCacheable(false);
152 }
153 foreach ($elementList as $element)
154 {
155 $dialog->addItem(
156 $this->makeItem($element)
157 );
158 }
159 }
160
161 protected function getHighloadblockId(): ?int
162 {
163 if (!isset($this->highloadblockId))
164 {
165 $this->initHighloadblock();
166 }
167
168 return $this->highloadblockId > 0 ? $this->highloadblockId : null;
169 }
170
171 protected function initHighloadblock(): void
172 {
173 if (isset($this->highloadblockId))
174 {
175 return;
176 }
177
178 $this->highloadblockId = (int)$this->getOption('highloadblockId');
179 if ($this->highloadblockId > 0)
180 {
181 $hlblock = HighloadBlockTable::getRow([
182 'select' => [
183 'ID',
184 ],
185 'filter' => [
186 '=ID' => $this->highloadblockId,
187 ],
188 ]);
189 if ($hlblock === null)
190 {
191 $this->highloadblockId = 0;
192 }
193 }
194 if ($this->highloadblockId > 0)
195 {
196 $this->highloadblock = HighloadBlockTable::compileEntity($this->highloadblockId);
197 $this->fields = $this->highloadblock->getScalarFields();
198 }
199 }
200
201 protected function isHighloadblockExists(): bool
202 {
203 return $this->getHighloadblockId() !== null;
204 }
205
206 protected function canReadHighloadblock(): bool
207 {
208 $hlblockId = $this->getHighloadblockId();
209 if ($hlblockId === null)
210 {
211 return false;
212 }
213
214 return true;
215 }
216
217 protected function getDefaultValueField(): string
218 {
219 return 'UF_XML_ID';
220 }
221
222 protected function getDefaultTitleField(): string
223 {
224 return 'UF_NAME';
225 }
226
227 protected function getDefaultOrderField(): string
228 {
229 return 'UF_SORT';
230 }
231
232 protected function getDefaultQueryMethod(): string
233 {
234 return self::QUERY_BEGIN;
235 }
236
237 protected function getValueField(): ?string
238 {
239 $field = trim((string)$this->getOption('valueField', $this->getDefaultValueField()));
240
241 return $this->checkFieldName($field) ? $field: null;
242 }
243
244 protected function getTitleField(): ?string
245 {
246 $field = trim((string)$this->getOption('titleField', $this->getDefaultTitleField()));
247
248 return $this->checkFieldName($field) ? $field: null;
249 }
250
251 protected function getOrderField(): ?string
252 {
253 $field = trim((string)$this->getOption('orderField', $this->getDefaultOrderField()));
254
255 return $this->checkFieldName($field) ? $field: null;
256 }
257
258 protected function checkFieldName(string $fieldName): bool
259 {
260 if ($fieldName === '')
261 {
262 return false;
263 }
264
265 return isset($this->fields[$fieldName]);
266 }
267
268 protected function getDirection(): string
269 {
270 $result = mb_strtoupper(trim((string)$this->getOption('direction')));
271
272 return $result === 'DESC' ? 'DESC' : 'ASC';
273 }
274
275 protected function getQueryMethod(): string
276 {
277 return trim((string)$this->getOption('queryMethod', $this->getDefaultQueryMethod()));
278 }
279
280 protected function prepareGetElementsParams(array $settings = []): ?array
281 {
282 $fields = [
283 'VALUE' => $this->getValueField(),
284 'TITLE' => $this->getTitleField(),
285 'ORDER' => $this->getOrderField(),
286 ];
287 if (in_array(null, $fields, true))
288 {
289 return null;
290 }
291
292 $select = [
293 'ID',
294 'VALUE' => $fields['VALUE'],
295 'TITLE' => $fields['TITLE'],
296 ];
297 if ($fields['ORDER'] !== 'ID')
298 {
299 $select[] = $fields['ORDER'];
300 }
301
302 $result = [
303 'select' => $select,
304 'filter' => $settings['filter'] ?? [],
305 'order' => [
306 $fields['ORDER'] => $this->getDirection(),
307 'ID' => 'ASC',
308 ],
309 ];
310
311 if (isset($settings['limit']))
312 {
313 $result['limit'] = $settings['limit'];
314 }
315
316 return $result;
317 }
318
319 protected function getQueryFilter(SearchQuery $searchQuery): ?array
320 {
321 $query = $searchQuery->getQuery();
322 if (mb_strlen($query) < 2)
323 {
324 return [];
325 }
326 $titleField = $this->getTitleField();
327 if ($titleField === null)
328 {
329 return null;
330 }
331
332 return match ($this->getQueryMethod())
333 {
334 self::QUERY_SEARCH => [
335 '*'.$titleField => $query,
336 ],
337 self::QUERY_SUBSTRING => [
338 '%'.$titleField => $query,
339 ],
340 default => [
341 $titleField => $query.'%',
342 ],
343 };
344 }
345
346 protected function getFilterByIds(array $ids): array
347 {
348 if (empty($ids))
349 {
350 return [];
351 }
352 $valueField = $this->getValueField();
353 if ($valueField === null)
354 {
355 return [];
356 }
357
358 return [
359 '@' . $valueField => $ids,
360 ];
361 }
362
363 protected function getElements(array $settings = []): array
364 {
365 $params = $this->prepareGetElementsParams($settings);
366 if ($params === null)
367 {
368 return [];
369 }
370
371 $result = [];
372 $ormClass = $this->highloadblock->getDataClass();
373 $iterator = $ormClass::getList($params);
374 while ($row = $iterator->fetch())
375 {
376 $result[] = $row;
377 }
378 unset ($row, $iterator);
379
380 return $result;
381 }
382
383 protected function makeItem(array $row): Item
384 {
385 $item = [
386 'id' => $row['VALUE'],
387 'entityId' => self::ENTITY_ID,
388 'title' => $row['TITLE'],
389 ];
390
391 return new Item($item);
392 }
393}
getOption(string $option, $defaultValue=null)
loadPreselectedItems($preselectedMode=true)
Definition dialog.php:389