1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
Item.php
См. документацию.
1<?php
2namespace Bitrix\UI\Avatar\Mask;
3
4use Bitrix\Main;
5use Bitrix\UI\Avatar;
6use SebastianBergmann\CodeCoverage\Report\PHP;
7
8class Item
9{
10 public const MAX_SIDE_SIZE = 1024; // in Pixels
11 public const MAX_FILE_SIZE = 600000; // in Bites
12 public const FILE_TYPES = ['png', 'gif'];
13 public const ORM_OPERATION_LIMIT_COUNT = 2;
14 private static array $buffer = [];
15 protected int $id;
16 protected array $data;
18
19 public function __construct(int $id)
20 {
21 if ($id > 0 && ($this->data = Avatar\Model\ItemTable::getById($id)->fetch()))
22 {
23 $this->id = $id;
24 if (is_subclass_of($this->data['OWNER_TYPE'], Owner\DefaultOwner::class))
25 {
26 $this->owner = new $this->data['OWNER_TYPE']($this->data['OWNER_ID']);
27 }
28 else
29 {
30 throw new Main\ArgumentTypeException("Mask owner ({$this->data['OWNER_TYPE']}) is unreachable.");
31 }
32 }
33 else
34 {
35 throw new Main\ObjectNotFoundException("Mask id ($id) is not found.");
36 }
37 }
38
39 public function getId(): int
40 {
41 return $this->id;
42 }
43
44 public function isEditableBy(Avatar\Mask\Consumer $consumer): bool
45 {
46 if ($consumer->isAdmin())
47 {
48 return true;
49 }
50 if ($this->getOwner() instanceof Owner\User && $this->getOwner()->getId() === $this->getId())
51 {
52 return true;
53 }
54 return false;
55 }
56
57 public function isReadableBy(Avatar\Mask\Consumer $consumer): bool
58 {
59 if ($consumer->isAdmin())
60 {
61 return true;
62 }
63 if ($this->getOwner() instanceof Owner\User && $this->getOwner()->getId() === $consumer->getId())
64 {
65 return true;
66 }
67 if (Avatar\Model\AccessTable::getList([
68 'select' => ['ID'],
69 'filter' => [
70 '=ITEM_ID' => $this->getId(),
71 '=ACCESS_CODE' => $consumer->getAccessCodes()
72 ]
73 ])->fetch())
74 {
75 return true;
76 }
77 return false;
78 }
79
80 public function update(array $data): Main\Result
81 {
82 $dataToSave = array_intersect_key($data, ['TITLE' => null, 'DESCRIPTION' => null]);
83 if (array_key_exists('FILE', $data)
84 && !empty($data['FILE'])
85 )
86 {
87 $file = $data['FILE'] + [
88 'MODULE_ID' => 'ui',
89 'del' => 'Y',
90 'old_file' => $this->data['FILE_ID'],
91 ];
92
93 if ($fileId = \CFile::SaveFile($file, 'ui/mask'))
94 {
95 $dataToSave['FILE_ID'] = $fileId;
96 }
97 }
98 if (!empty($dataToSave))
99 {
100 Avatar\Model\ItemTable::update($this->getId(), $dataToSave);
101 }
102
103 if (array_key_exists('ACCESS_CODE', $data))
104 {
105 $this->setAccessCode($data['ACCESS_CODE']);
106 }
107
108 return new Main\Result();
109 }
110
111 public function delete(): Main\Result
112 {
113 return static::deleteByFilter(['ID' => $this->getId()]);
114 }
115
116 public function getOwner(): Owner\DefaultOwner
117 {
118 return $this->owner;
119 }
120
121 public function getAccessCode(): array
122 {
123 return array_column(Avatar\Model\AccessTable::getList([
124 'select' => ['ACCESS_CODE'],
125 'filter' => ['ITEM_ID' => $this->getId()]
126 ])->fetchAll(), 'ACCESS_CODE');
127 }
128
129 protected function setAccessCode(array $accessCodes)
130 {
131 Avatar\Model\AccessTable::deleteByFilter(['ITEM_ID' => $this->getId()]);
132 if (!empty($accessCodes))
133 {
134 $itemId = $this->getId();
135 Avatar\Model\AccessTable::addMulti(array_map(function($accessCode) use ($itemId) {
136 return ['ITEM_ID' => $itemId, 'ACCESS_CODE' => $accessCode];
137 }, $accessCodes), true);
138 }
139 }
140
141 public function applyToFileBy(int $originalFileId, int $fileId, Avatar\Mask\Consumer $consumer)
142 {
143
145 'ITEM_ID' => $this->id,
146 'ORIGINAL_FILE_ID' => $originalFileId,
147 'FILE_ID' => $fileId,
148 'USER_ID' => $consumer->getUserId()
149 ]);
150 }
151
152 public static function create(Owner\DefaultOwner $owner, array $file, ?array $descriptionParams = []): Main\Entity\AddResult
153 {
154 $result = new Main\Entity\AddResult();
155 $fileCheckResult = \CFile::CheckImageFile($file,
156 static::MAX_FILE_SIZE,
157 static::MAX_SIDE_SIZE,
158 static::MAX_SIDE_SIZE,
159 ['png', 'svg']
160 );
161 if ($fileCheckResult === null)
162 {
163 $file['MODULE_ID'] = 'ui';
164
165 if ($fileId = \CFile::SaveFile($file, 'ui/mask'))
166 {
168 'OWNER_TYPE' => get_class($owner),
169 'OWNER_ID' => $owner->getId(),
170 'GROUP_ID' => $descriptionParams['GROUP_ID'] ?? null,
171 'TITLE' => $descriptionParams['TITLE'] ?? null,
172 'DESCRIPTION' => $descriptionParams['DESCRIPTION'] ?? null,
173 'SORT' => $descriptionParams['SORT'] ?? 0,
174 'FILE_ID' => $fileId
175 ]);
176
177 if ($result->isSuccess() && ($item = static::getInstance($result->getId())))
178 {
179 $item->setAccessCode($descriptionParams['ACCESS_CODE'] ?? $owner->getDefaultAccess());
180 $result->setData([$item]);
181 return $result;
182 }
183 \CFile::Delete($fileId);
184 }
185 }
186 $result->addError(new Main\Error($fileCheckResult, 'image check'));
187 return $result;
188 }
189
190 public static function getInstance($id): ?Item
191 {
192 try
193 {
194 return new static($id);
195 }
196 catch (Main\ObjectNotFoundException $exception)
197 {
198 return null;
199 }
200 }
201
203 {
204 $result = new Main\Entity\DeleteResult();
205
207 $sqlHelper = $connection->getSqlHelper();
208 $sqlItemTableName = Avatar\Model\ItemTable::getTableName();
209 $where = Main\ORM\Query\Query::buildFilterSql(Avatar\Model\ItemTable::getEntity(), $filter);
210 if (empty($where))
211 {
212 return $result;
213 }
214
216 $sql = [
217 $connection->getSqlHelper()->getInsertIgnore(
218 'b_ui_avatar_mask_file_deleted',
219 ' (ENTITY, ORIGINAL_FILE_ID, FILE_ID, ITEM_ID) ',
220 <<<SQL
221SELECT 'ITEM_TEMP', FILE_ID, FILE_ID, ID
222 FROM {$sqlHelper->quote($sqlItemTableName)}
223 WHERE {$where}
224SQL
225 ),
226 $connection->getType() === 'mysql' ?
227 <<<MYSQL
228DELETE ACCESS1
229 FROM {$sqlHelper->quote(Avatar\Model\AccessTable::getTableName())} AS ACCESS1,
230 b_ui_avatar_mask_file_deleted AS FDTABLE
231 WHERE ACCESS1.ITEM_ID = FDTABLE.ITEM_ID AND FDTABLE.ENTITY = 'ITEM_TEMP'
232MYSQL : ($connection->getType() ==='pgsql' ?
233 <<<PGSQL
234DELETE FROM {$sqlHelper->quote(Avatar\Model\AccessTable::getTableName())} AS ACCESS1
235USING b_ui_avatar_mask_file_deleted AS FDTABLE
236WHERE ACCESS1.ITEM_ID = FDTABLE.ITEM_ID AND FDTABLE.ENTITY = 'ITEM_TEMP'
237PGSQL : ''),
238 $connection->getType() === 'mysql' ?
239 <<<MYSQL
240DELETE RECENTLYUSED1
241 FROM {$sqlHelper->quote(Avatar\Model\RecentlyUsedTable::getTableName())} AS RECENTLYUSED1,
242 b_ui_avatar_mask_file_deleted AS FDTABLE
243 WHERE RECENTLYUSED1.ITEM_ID = FDTABLE.ITEM_ID AND FDTABLE.ENTITY = 'ITEM_TEMP'
244MYSQL : ($connection->getType() ==='pgsql' ?
245 <<<PGSQL
246DELETE FROM {$sqlHelper->quote(Avatar\Model\RecentlyUsedTable::getTableName())} AS RECENTLYUSED1
247USING b_ui_avatar_mask_file_deleted AS FDTABLE WHERE RECENTLYUSED1.ITEM_ID = FDTABLE.ITEM_ID AND FDTABLE.ENTITY = 'ITEM_TEMP'
248PGSQL : ''),
249 $connection->getSqlHelper()->getInsertIgnore(
250 'b_ui_avatar_mask_file_deleted',
251 ' (ENTITY, ORIGINAL_FILE_ID, FILE_ID, ITEM_ID) ',
252 <<<SQL
253SELECT 'LINK', LINK1.ORIGINAL_FILE_ID, LINK1.FILE_ID, LINK1.ITEM_ID
254 FROM {$sqlHelper->quote(Avatar\Model\ItemToFileTable::getTableName())} AS LINK1,
255 b_ui_avatar_mask_file_deleted AS FDTABLE
256 WHERE LINK1.ITEM_ID = FDTABLE.ITEM_ID AND FDTABLE.ENTITY = 'ITEM_TEMP'
257SQL
258 ),
259 $connection->getType() === 'mysql' ?
260 <<<MYSQL
261DELETE LINK1
262 FROM {$sqlHelper->quote(Avatar\Model\ItemToFileTable::getTableName())} AS LINK1,
263 b_ui_avatar_mask_file_deleted AS FDTABLE
264 WHERE LINK1.ITEM_ID = FDTABLE.ITEM_ID AND FDTABLE.ENTITY = 'ITEM_TEMP'
265MYSQL : ($connection->getType() ==='pgsql' ?
266 <<<PGSQL
267DELETE FROM {$sqlHelper->quote(Avatar\Model\ItemToFileTable::getTableName())} AS LINK1
268USING b_ui_avatar_mask_file_deleted AS FDTABLE WHERE LINK1.ITEM_ID = FDTABLE.ITEM_ID AND FDTABLE.ENTITY = 'ITEM_TEMP'
269PGSQL : ''),
270 <<<SQL
271UPDATE b_ui_avatar_mask_file_deleted SET ENTITY = 'ITEM' WHERE ENTITY = 'ITEM_TEMP';
272SQL,
273 ];
274 $sql = implode(';' . PHP_EOL, $sql);
275
276 $connection->executeSqlBatch($sql);
277
278 $cleaningString = static::clearFileTable();
279 if ($cleaningString !== '')
280 {
281 \CAgent::AddAgent($cleaningString, 'ui','Y',0, '',
282 'Y', '', 100, false, false
283 );
284 }
285 return $result;
286 }
287
288 public static function clearFileTable(): string
289 {
291 $limit = self::ORM_OPERATION_LIMIT_COUNT;
292 $dbRes = $connection->query("
293 SELECT *
294 FROM b_ui_avatar_mask_file_deleted
295 WHERE ENTITY IN ('ITEM', 'LINK')
296 ORDER BY ID ASC
297 LIMIT {$limit}
298 "
299 );
300 $items = [];
301 if ($res = $dbRes->fetch())
302 {
303 do
304 {
305 self::$buffer[] = $res['FILE_ID'];
306 $items[] = $res['ITEM_ID'];
307 \CFile::Delete($res['FILE_ID']);
308 } while ($res = $dbRes->fetch());
309 $itemsSql = implode(',', $items);
310 $connection->queryExecute("DELETE FROM b_ui_avatar_mask_file_deleted WHERE ITEM_ID IN ({$itemsSql})");
311 }
312
313 if (count($items) < self::ORM_OPERATION_LIMIT_COUNT)
314 {
315 return '';
316 }
317 return '\\' . __CLASS__ . "::" . __FUNCTION__ . "();";
318 }
319
320 public static function onFileDelete($file)
321 {
322 if (in_array($file['ID'], self::$buffer))
323 {
324 return;
325 }
326 if ($file['MODULE_ID'] === 'ui')
327 {
328 Avatar\Model\ItemToFileTable::deleteByFilter(['=FILE_ID' => $file['ID']]);
329 }
330 else if ($file['MODULE_ID'] === 'main' && Avatar\Model\ItemToFileTable::getList([
331 'select' => ['FILE_ID'],
332 'filter' => ['=ORIGINAL_FILE_ID' => $file['ID']],
333 ])->fetch())
334 {
336 $sqlHelper = $connection->getSqlHelper();
337 $fileId = (int) $file['ID'];
338
339 $sql = [
340 $sqlHelper->getInsertIgnore(
341 'b_ui_avatar_mask_file_deleted',
342 '(ENTITY, ORIGINAL_FILE_ID, FILE_ID, ITEM_ID)',
343 <<<SQL
344SELECT 'LINK', ORIGINAL_FILE_ID, FILE_ID, ITEM_ID
345 FROM {$sqlHelper->quote(Avatar\Model\ItemToFileTable::getTableName())}
346 WHERE ORIGINAL_FILE_ID = {$fileId}
347SQL
348 ),
349 <<<SQL
350DELETE FROM {$sqlHelper->quote(Avatar\Model\ItemToFileTable::getTableName())} WHERE ORIGINAL_FILE_ID = {$fileId}
351SQL,
352 ];
353 $sql = implode(';' . PHP_EOL, $sql);
354
355 $connection->executeSqlBatch($sql);
356
357 $cleaningString = static::clearFileTable();
358 if ($cleaningString !== '')
359 {
360 \CAgent::AddAgent($cleaningString, 'ui','Y',0, '',
361 'Y', '', 100, false, false
362 );
363 }
364 }
365 }
366}
$connection
Определения actionsdefinitions.php:38
static getConnection($name="")
Определения application.php:638
Определения error.php:15
static addMulti($rows, $ignoreEvents=false)
Определения datamanager.php:1041
static add(array $data)
Определения datamanager.php:877
static update($primary, array $data)
Определения datamanager.php:1256
static buildFilterSql(Entity $entity, $filter)
Определения query.php:3913
getId()
Определения Item.php:39
isEditableBy(Avatar\Mask\Consumer $consumer)
Определения Item.php:44
array $data
Определения Item.php:16
const ORM_OPERATION_LIMIT_COUNT
Определения Item.php:13
int $id
Определения Item.php:15
Owner DefaultOwner $owner
Определения Item.php:17
static deleteByFilter(array $filter)
Определения Item.php:202
const MAX_SIDE_SIZE
Определения Item.php:10
const FILE_TYPES
Определения Item.php:12
setAccessCode(array $accessCodes)
Определения Item.php:129
static getInstance($id)
Определения Item.php:190
static clearFileTable()
Определения Item.php:288
__construct(int $id)
Определения Item.php:19
update(array $data)
Определения Item.php:80
applyToFileBy(int $originalFileId, int $fileId, Avatar\Mask\Consumer $consumer)
Определения Item.php:141
getOwner()
Определения Item.php:116
const MAX_FILE_SIZE
Определения Item.php:11
getAccessCode()
Определения Item.php:121
static onFileDelete($file)
Определения Item.php:320
static create(Owner\DefaultOwner $owner, array $file, ?array $descriptionParams=[])
Определения Item.php:152
isReadableBy(Avatar\Mask\Consumer $consumer)
Определения Item.php:57
static getTableName()
Определения ItemTable.php:16
static deleteByFilter(array $filter)
Определения OrmDataManager.php:8
</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
$filter
Определения iblock_catalog_list.php:54
Определения ufield.php:9
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$items
Определения template.php:224
$dbRes
Определения yandex_detail.php:168