1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
RequestImages.php
См. документацию.
1<?php
2declare(strict_types=1);
3
4namespace Bitrix\Landing\Copilot\Generation\Step;
5
6use Bitrix\Landing\Copilot\Connector\AI;
7use Bitrix\Landing\Copilot\Connector\AI\Prompt;
8use Bitrix\Landing\Copilot\Data\Site;
9use Bitrix\Landing\Copilot\Data\Node\Img;
10use Bitrix\Landing\Copilot\Data\Node\Node;
11use Bitrix\Landing\Copilot\Data\Type\NodeType;
12use Bitrix\Landing\Copilot\Generation\Request;
13use Bitrix\Landing\Copilot\Generation\Type\RequestEntityDto;
14use Bitrix\Landing\Copilot\Generation\Type\RequestQuotaDto;
15use Bitrix\Landing\Copilot\Generation\Type\RequestEntities;
16use Bitrix\Landing\Copilot\Model\RequestToEntitiesTable;
17use Bitrix\Main\ORM\Query\Query;
18
20{
21 public function __construct()
22 {
23 parent::__construct();
24 if (class_exists(self::getConnectorClass()))
25 {
26 $this->connector = new (self::getConnectorClass())();
27 }
28 }
29
33 public static function getConnectorClass(): string
34 {
35 return AI\Image::class;
36 }
37
38 protected const EVENT_NAME = 'onCopilotImageCreate';
39
44 {
45 return new RequestQuotaDto(
46 self::getConnectorClass(),
47 self::getImagesQuota($siteData)
48 );
49 }
50
58 private static function getImagesQuota(Site $siteData): int
59 {
60 $imageCount = 0;
61
62 foreach ($siteData->getBlocks() as $block)
63 {
64 if ($block->isMenu())
65 {
66 continue;
67 }
68 foreach ($block->getNodes() as $node)
69 {
70 if (
71 $node->getType() === NodeType::Img
72 && !$node->isAvatarNode()
73 )
74 {
75 $placeholders = $node->getPlaceholders();
76 $imageCount += count($placeholders);
77 }
78 }
79 }
80
81 return $imageCount;
82 }
83
87 protected function getEntitiesToRequest(): array
88 {
89 if (!isset($this->siteData))
90 {
91 return [];
92 }
93
94 if (!empty($this->entities))
95 {
96 return $this->entities;
97 }
98
99 $filter = Query::filter()->logic('or');
100 $landingId = $this->siteData->getLandingId();
101
102 foreach ($this->siteData->getBlocks() as $block)
103 {
104 foreach ($block->getNodes() as $node)
105 {
106 if (
107 $node->getType() === NodeType::Img
108 && !empty($node->getPromptTexts())
109 )
110 {
111 if (
112 !$landingId
113 || !$block->getId()
114 || !$node->getCode()
115 )
116 {
117 continue;
118 }
119
120 foreach ($node->getPromptTexts() as $position => $prompt)
121 {
122 if (empty($prompt))
123 {
124 continue;
125 }
126
127 $key = self::createEntityKey($landingId, $block->getId(), $node->getCode(), $position);
129 $landingId,
130 $block->getId(),
131 $node->getCode(),
132 $position,
133 $prompt,
134 );
135 $this->entities[$key] = $entity;
136 $filter->where(
137 Query::filter()
138 ->where('LANDING_ID', '=', $landingId)
139 ->where('BLOCK_ID', '=', $block->getId())
140 ->where('NODE_CODE', '=', $node->getCode())
141 ->where('POSITION', '=', $position)
142 );
143 }
144 }
145 }
146 }
147
148 // mark sended requests
149 if (!empty($this->entities))
150 {
151 $generationId = $this->generation->getId();
152 $res = RequestToEntitiesTable::query()
153 ->setSelect([
154 'REQUEST_ID',
155 'LANDING_ID',
156 'BLOCK_ID',
157 'NODE_CODE',
158 'POSITION',
159 ])
160 ->where($filter)
161 ->where('STEP_REF.GENERATION_ID', '=', $generationId)
162 ->where('REQUEST_REF.DELETED', '=', 'N')
163 //todo: exist request in step RequestPreviewImage
164 // ->where('STEP_REF.STEP', '=', $this->stepId)
165 ->exec()
166 ;
167 $rows = $res->fetchAll();
168
169 foreach ($rows as $row)
170 {
172 (int)$row['LANDING_ID'],
173 (int)$row['BLOCK_ID'],
174 $row['NODE_CODE'],
175 (int)$row['POSITION'],
176 );
177 if (isset($this->entities[$key]))
178 {
179 $this->entities[$key]->requestId = (int)$row['REQUEST_ID'];
180 }
181 }
182 }
183
184 return $this->entities;
185 }
186
187 protected static function createEntityKey(
188 int $landingId,
189 int $blockId,
190 string $nodeCode,
191 int $position,
192 ): string
193 {
194 return "l{$landingId}_b{$blockId}_n{$nodeCode}_p{$position}";
195 }
196
197 protected function sendRequests(): bool
198 {
199 if (!isset($this->siteData, $this->stepId))
200 {
201 return false;
202 }
203
204 foreach ($this->getEntitiesToRequest() as $entity)
205 {
206 if (
207 !isset($entity->landingId)
208 || !isset($entity->blockId)
209 || !isset($entity->nodeCode)
210 || !isset($entity->position)
211 || !isset($entity->prompt)
212 )
213 {
214 continue;
215 }
216
217 if (isset($entity->requestId))
218 {
219 continue;
220 }
221
222 $timer = $this->generation->getTimer();
223 if (!$timer->check())
224 {
225 throw new \RuntimeException("The maximum execution time has been reached, step {$this->stepId} was aborted");
226 }
227
228 $prompt = new Prompt($entity->prompt);
229 // todo: add size and ratio
230 $prompt->setMarkers(['format' => 'square']);
231
232 $request = new Request($this->generation->getId(), $this->stepId);
233 if ($request->send($prompt, $this->connector))
234 {
235 $this->requests[$request->getId()] = $request;
236 $entity->requestId = $request->getId();
237
238 RequestToEntitiesTable::add([
239 'REQUEST_ID' => $request->getId(),
240 'ENTITY_TYPE' => RequestEntities::Image->value,
241 'LANDING_ID' => $entity->landingId,
242 'BLOCK_ID' => $entity->blockId,
243 'NODE_CODE' => $entity->nodeCode,
244 'POSITION' => $entity->position,
245 ]);
246 }
247 }
248
249 return true;
250 }
251
252 protected function applyResponses(): bool
253 {
254 $changed = false;
255
256 $landingId = $this->siteData->getLandingId();
257 foreach ($this->requests as $request)
258 {
259 if (
260 !$request->isReceived()
261 || $request->isApplied()
262 )
263 {
264 continue;
265 }
266
267 $timer = $this->generation->getTimer();
268 if (!$timer->check())
269 {
270 throw new \RuntimeException("The maximum execution time has been reached, step {$this->stepId} was aborted");
271 }
272
273 // todo: collect filter in foreaech and get all relations in one query
274 $relation = RequestToEntitiesTable::query()
275 ->setSelect(['*'])
276 ->where('REQUEST_ID', '=', $request->getId())
277 ->where('LANDING_ID', '=', $landingId)
278 ->where('ENTITY_TYPE', '=', RequestEntities::Image->value)
279 ->exec()
280 ->fetch()
281 ;
282 if (!$relation)
283 {
284 continue;
285 }
286
287 $blockId = (int)$relation['BLOCK_ID'];
288 $nodeCode = $relation['NODE_CODE'];
289 $position = (int)($relation['POSITION'] ?? 0);
290
291 foreach ($this->siteData->getBlocks([$blockId]) as $blockData)
292 {
293 foreach ($blockData->getNodes([$nodeCode]) as $nodeData)
294 {
295 if (empty($request->getError()))
296 {
297 if ($this->applyNode($nodeData, $position, $request))
298 {
299 $request->setApplied();
300 $changed = true;
301 }
302 }
303 else
304 {
305 if ($this->fixNode($nodeData, $position))
306 {
307 $request->setApplied();
308 }
309 }
310 }
311 }
312 }
313
314 return $changed;
315 }
316
317 private function applyNode(Node $nodeData, int $position, Request $request): bool
318 {
319 if (
320 $nodeData->getType() === NodeType::Img
321 && empty($nodeData->getGenderData())
322 )
323 {
327 $result = $request->getResult();
328 $url = is_array($result) ? array_shift($result) : $result;
329
330 if (
331 $nodeData
332 ->setImageFromPath((string)$url, $position)
333 ->toLanding($position)
334 )
335 {
336 $values = $nodeData->getValues($position);
337 $this->getEvent()->send(
338 self::EVENT_NAME,
339 [
340 'blockId' => (string)$nodeData->getParentBlock()?->getId(),
341 'selector' => $nodeData->getCode(),
342 'position' => $position,
343 'value' => !empty($values) ? array_shift($values) : [],
344 'isEditInStyle' => $nodeData->isEditInStyle(),
345 ],
346 );
347
348 return true;
349 }
350 }
351
352 return false;
353 }
354
361 private function fixNode(Node $node, int $position): bool
362 {
363 if (
364 $node->getType() !== NodeType::Img
365 || !empty($node->getGenderData())
366 )
367 {
368 return false;
369 }
370
371 $findInNode = function (Node $node): ?array
372 {
373 if (
374 $node->getType() !== NodeType::Img
375 || !empty($node->getGenderData())
376 )
377 {
378 return null;
379 }
380
381 foreach ($node->getValues() as $value)
382 {
383 if (isset($value['id'], $value['id2x'], $value['src'], $value['src2x']))
384 {
385 return $value;
386 }
387 }
388
389 return null;
390 };
391
395
396 $selectedValue = $findInNode($node);
397
398 // find value in other blocks in site
399 if (
400 !$selectedValue
401 && $node->getParentBlock()->getParentSite()
402 )
403 {
404 foreach ($node->getParentBlock()->getParentSite()->getBlocks() as $block)
405 {
406 foreach ($block->getNodes() as $otherNode)
407 {
408 $selectedValue = $findInNode($otherNode);
409 if ($selectedValue)
410 {
411 break 2;
412 }
413 }
414 }
415 }
416
417 if (!$selectedValue)
418 {
419 return false;
420 }
421
422 if (
423 $node
424 ->setValue($selectedValue, $position)
425 ->toLanding($position)
426 )
427 {
428 $this->getEvent()->send(
429 self::EVENT_NAME,
430 [
431 'blockId' => (string)$node->getParentBlock()?->getId(),
432 'selector' => $node->getCode(),
433 'position' => $position,
434 'value' => !empty($selectedValue) ? $selectedValue : [],
435 'isEditInStyle' => $node->isEditInStyle(),
436 ],
437 );
438
439 return true;
440 }
441
442 return false;
443 }
444}
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
getBlocks(?array $ids=null)
Определения Site.php:298
static getRequestQuota(Site $siteData)
Определения RequestImages.php:43
static createEntityKey(int $landingId, int $blockId, string $nodeCode, int $position,)
Определения RequestImages.php:187
Определения request.php:10
</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
setValue($value)
Определения Param.php:163
Определения cookies.php:2
if(empty($signedUserToken)) $key
Определения quickway.php:257
</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
$rows
Определения options.php:264
$url
Определения iframe.php:7