1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
form.php
См. документацию.
1<?php
2
3namespace Bitrix\Landing\Subtype;
4
5use Bitrix\Crm\Integration\UserConsent;
6use Bitrix\Crm\Settings\LeadSettings;
7use Bitrix\Crm\UI\Webpack;
8use Bitrix\Crm\WebForm;
9use Bitrix\Landing\History;
10use Bitrix\Landing\Landing;
11use Bitrix\Landing\Block;
12use Bitrix\Landing\Internals\BlockTable;
13use Bitrix\Landing\Manager;
14use Bitrix\Landing\Site;
15use Bitrix\Main\Loader;
16use Bitrix\Main\Localization\Loc;
17use Bitrix\Socialservices\ApClient;
18
19Loc::loadMessages(__FILE__);
20
25class Form
26{
27 protected const ATTR_FORM_PARAMS = 'data-b24form';
28 protected const ATTR_FORM_EMBED = 'data-b24form-embed';
29 protected const ATTR_FORM_STYLE = 'data-b24form-design';
30 protected const ATTR_FORM_USE_STYLE = 'data-b24form-use-style';
31 protected const ATTR_FORM_FROM_CONNECTOR = 'data-b24form-connector';
32 protected const ATTR_FORM_OLD_DOMAIN = 'data-b24form-original-domain';
33 protected const ATTR_FORM_OLD_HEADER = 'data-b24form-show-header';
34 protected const SELECTOR_FORM_NODE = '.bitrix24forms';
35 protected const SELECTOR_OLD_STYLE_NODE = '.landing-block-form-styles';
36 protected const STYLE_SETTING = 'crm-form';
37 protected const REGEXP_FORM_STYLE = '/data-b24form-design *= *[\'"](\{.+\})[\'"]/i';
38 protected const REGEXP_FORM_ID_INLINE = '/data-b24form=["\']#crmFormInline(?<id>[\d]+)["\']/i';
39
40 public const INLINE_MARKER_PREFIX = '#crmFormInline';
41 public const POPUP_MARKER_PREFIX = '#crmFormPopup';
42
43 protected const AVAILABLE_FORM_FIELDS = [
44 'ID',
45 'NAME',
46 'SECURITY_CODE',
47 'IS_CALLBACK_FORM',
48 'ACTIVE',
49 'XML_ID',
50 ];
51
52 private static array $errors = [];
53
54 // region replaces for view and public
55
61 public static function prepareFormsToPublication(string $content): string
62 {
63 // change - replace markers always, not only if connector
64 return self::replaceFormMarkers($content);
65 }
66
72 public static function prepareFormsToView(string $content): string
73 {
74 if (self::isCrm())
75 {
76 $content = self::replaceFormMarkers($content);
77 }
78 return $content;
79 }
80
87 protected static function replaceFormMarkers(string $content): string
88 {
89 $replace = preg_replace_callback(
90 '/(?<pre><a[^>]+href=|data-b24form=)["\'](form:)?#crmForm(?<type>Inline|Popup)(?<id>[\d]+)["\']/i',
91 static function ($matches)
92 {
93 $id = (int)$matches['id'];
94 if (!$id)
95 {
96 return $matches[0];
97 }
98
99 $form = self::getFormById($id, true);
100 if (!$form || !$form['URL'])
101 {
102 return $matches[0];
103 }
104
105 if (strtolower($matches['type']) === 'inline')
106 {
107 $param = "{$form['ID']}|{$form['SECURITY_CODE']}|{$form['URL']}";
108
109 return $matches['pre'] . "\"{$param}\"";
110 }
111
112 if (strtolower($matches['type']) === 'popup')
113 {
114 $script = "<script data-b24-form=\"click/{$id}/{$form['SECURITY_CODE']}\" data-skip-moving=\"true\">
115 (function(w,d,u){
116 var s=d.createElement('script');s.async=true;s.src=u+'?'+(Date.now()/180000|0);
117 var h=d.getElementsByTagName('script')[0];h.parentNode.insertBefore(s,h);
118 })(window,document,'{$form['URL']}');
119 </script>";
120
121 return $script . $matches['pre'] . "\"#\" onclick=\"BX.PreventDefault();\"";
122 }
123
124 return $matches[0];
125 },
127 );
128
129 $replace = $replace ?? $content;
130
131 //replace link to form in data-pseudo-url
132 $replace = preg_replace_callback(
133 '/(?<pre><img|<i.*)data-pseudo-url="{.*(form:)?#crmForm(?<type>Inline|Popup)(?<id>[\d]+).*}"(?<pre2>.*>)/i',
134 static function ($matches)
135 {
136 if (
137 !(int)$matches['id']
138 || !($form = self::getFormById((int)$matches['id'], true))
139 )
140 {
141 return $matches[0];
142 }
143
144 if (strtolower($matches['type']) === 'popup')
145 {
146 $script = "<script data-b24-form=\"click/{$matches['id']}/{$form['SECURITY_CODE']}\" data-skip-moving=\"true\">
147 (function(w,d,u){
148 var s=d.createElement('script');s.async=true;s.src=u+'?'+(Date.now()/180000|0);
149 var h=d.getElementsByTagName('script')[0];h.parentNode.insertBefore(s,h);
150 })(window,document,'{$form['URL']}');
151 </script>";
152
153 //add class g-cursor-pointer
154 preg_match_all('/(class="[^"]*)/i', $matches['pre'], $matchesPre);
155 $matches['pre'] = str_replace($matchesPre[1][0], $matchesPre[1][0]. ' g-cursor-pointer', $matches['pre']);
156
157 return $script . $matches['pre'] . ' '. $matches['pre2'];
158 }
159
160 return $matches[0];
161 },
162 $replace
163 );
164
165 return $replace ?? $content;
166 }
167
172 public static function clearCache(): void
173 {
174 $sites = [];
175 $res = BlockTable::getList(
176 [
177 'select' => [
178 'SITE_ID' => 'LANDING.SITE_ID',
179 ],
180 'filter' => [
181 '=LANDING.ACTIVE' => 'Y',
182 '=LANDING.SITE.ACTIVE' => 'Y',
183 '=PUBLIC' => 'Y',
184 '=DELETED' => 'N',
185 'CONTENT' => '%bitrix24forms%',
186 ],
187 'group' => [
188 'LANDING.SITE_ID',
189 ],
190 ]
191 );
192 while ($row = $res->fetch())
193 {
194 if (!in_array($row['SITE_ID'], $sites))
195 {
196 $sites[] = $row['SITE_ID'];
197 }
198 }
199
200 foreach ($sites as $site)
201 {
202 Site::update($site, [
203 'DATE_MODIFY' => false
204 ]);
205 }
206 }
207 // endregion
208
209 // region get forms
215 public static function getForms(bool $force = false): array
216 {
217 static $forms = [];
218 if ($forms && !$force)
219 {
220 return $forms;
221 }
222
223 if (self::isCrm())
224 {
225 $forms = self::getFormsForPortal();
226 }
228 {
229 $forms = self::getFormsViaConnector();
230 }
231
232 return $forms;
233 }
234
239 protected static function isCrm(): bool
240 {
241 return Loader::includeModule('crm');
242 }
243
244 protected static function getFormsForPortal(array $filter = []): array
245 {
246 $res = Webform\Internals\FormTable::getDefaultTypeList(
247 [
248 'select' => self::AVAILABLE_FORM_FIELDS,
249 'filter' => $filter,
250 'order' => [
251 'ID' => 'ASC',
252 ],
253 'cache' => ['ttl' => 86400],
254 ]
255 );
256
257 $forms = [];
258 while ($form = $res->fetch())
259 {
260 $form['ID'] = (int)$form['ID'];
261 $forms[$form['ID']] = $form;
262 }
263
264 return $forms;
265 }
266
267 protected static function getFormsViaConnector(): array
268 {
269 $forms = [];
270 $client = ApClient::init();
271 if ($client)
272 {
273 $res = $client->call('crm.webform.list', ['GET_INACTIVE' => 'Y']);
274 if (isset($res['result']) && is_array($res['result']))
275 {
276 foreach ($res['result'] as $form)
277 {
278 $form['ID'] = (int)$form['ID'];
279 $forms[$form['ID']] = $form;
280 }
281 }
282 else if (isset($res['error']))
283 {
284 self::$errors[] = [
285 'code' => $res['error'],
286 'message' => $res['error_description'] ?? $res['error'],
287 ];
288 }
289 }
290
291 return $forms;
292 }
293
298 public static function getFormById(int $id, bool $full = false): array
299 {
300 $forms = self::getFormsByFilter(['=ID' => $id]);
301 $form = !empty($forms) ? array_shift($forms) : null;
302 if (!$form)
303 {
304 return [];
305 }
306
307 if ($full)
308 {
309 if (self::isCrm())
310 {
311 $webpack = Webpack\Form::instance($form['ID']);
312 if (!$webpack->isBuilt())
313 {
314 $webpack->build();
315 $webpack = Webpack\Form::instance($form['ID']);
316 }
317 $form['URL'] = $webpack->getEmbeddedFileUrl();
318 }
319 }
320
321 return $form;
322 }
323
328 public static function getCallbackForms(): array
329 {
330 return self::getFormsByFilter(['=IS_CALLBACK_FORM' => 'Y', '=ACTIVE' => 'Y']);
331 }
332
333 protected static function getFormsByFilter(array $filter): array
334 {
335 static $cache = [];
336 $cacheKey = serialize($filter);
337 if (array_key_exists($cacheKey, $cache))
338 {
339 return $cache[$cacheKey];
340 }
341
342 $filter = array_filter(
343 $filter,
344 static function ($key)
345 {
346 $key = trim($key);
347 $equalKey = ltrim($key, '=');
348 return
349 in_array($key, self::AVAILABLE_FORM_FIELDS, true)
350 || in_array($equalKey, self::AVAILABLE_FORM_FIELDS, true)
351 ;
352 },
353 ARRAY_FILTER_USE_KEY
354 );
355 $forms = [];
356
357 if (self::isCrm())
358 {
359 $forms = self::getFormsForPortal($filter);
360 }
362 {
363 foreach (self::getFormsViaConnector() as $form)
364 {
365 $filtred = true;
366 foreach ($filter as $key => $value)
367 {
368 if (!$form[$key] || $form[$key] !== $value)
369 {
370 $filtred = false;
371 break;
372 }
373 }
374 if ($filtred)
375 {
376 $forms[$form['ID']] = $form;
377 }
378 }
379 }
380
381 $cache[$cacheKey] = $forms;
382
383 return $forms;
384 }
385
386 // endregion
387
388 // region prepare manifest
396 public static function prepareManifest(array $manifest, Block $block = null, array $params = []): array
397 {
398 // add extension
399 if (!isset($manifest['assets']) || !is_array($manifest['assets']))
400 {
401 $manifest['assets'] = [];
402 }
403 if (!isset($manifest['assets']['ext']))
404 {
405 $manifest['assets']['ext'] = [];
406 }
407 if (!is_array($manifest['assets']['ext']))
408 {
409 $manifest['assets']['ext'] = [$manifest['assets']['ext']];
410 }
411 if (!in_array('landing_form', $manifest['assets']['ext'], true))
412 {
413 $manifest['assets']['ext'][] = 'landing_form';
414 }
415
416 // style setting
417 if (
418 !isset($manifest['style']['block']) && !isset($manifest['style']['nodes'])
419 )
420 {
421 $manifest['style'] = [
422 'block' => ['type' => Block::DEFAULT_WRAPPER_STYLE],
423 'nodes' => $manifest['style'] ?? [],
424 ];
425 }
426 $manifest['style']['nodes'][self::SELECTOR_FORM_NODE] = [
427 'type' => self::STYLE_SETTING,
428 ];
429
430 if (Manager::isB24())
431 {
432 $link = '/crm/webform/';
433 }
434 else if (Manager::isB24Connector())
435 {
436 $link = '/bitrix/admin/b24connector_crm_forms.php?lang=' . LANGUAGE_ID;
437 }
438 if (isset($link))
439 {
440 $manifest['block']['attrsFormDescription'] = '<a href="' . $link . '" target="_blank">' .
441 Loc::getMessage('LANDING_BLOCK_FORM_CONFIG') .
442 '</a>';
443 }
444
445 // add callbacks
446 $manifest['callbacks'] = [
447 'afterAdd' => function (Block &$block)
448 {
449 $historyActivity = History::isActive();
450 History::deactivate();
451
452 $dom = $block->getDom();
453 if (!($node = $dom->querySelector(self::SELECTOR_FORM_NODE)))
454 {
455 return;
456 }
457
458 $attrsToSet = [self::ATTR_FORM_EMBED => ''];
459 if (!self::isCrm())
460 {
461 $attrsToSet[self::ATTR_FORM_FROM_CONNECTOR] = 'Y';
462 }
463
464 // if block copy - not update params
465 if (
466 ($attrsExists = $node->getAttributes())
467 && isset($attrsExists[self::ATTR_FORM_PARAMS])
468 && $attrsExists[self::ATTR_FORM_PARAMS]
469 && $attrsExists[self::ATTR_FORM_PARAMS]->getValue()
470 )
471 {
472 $attrsToSet[self::ATTR_FORM_PARAMS] = $attrsExists[self::ATTR_FORM_PARAMS]->getValue();
473 }
474 else
475 {
476 // try to get 1) default callback form 2) last added form 3) create new form
477 $forms = self::getFormsByFilter([
478 '=XML_ID' => 'crm_preset_fb'
479 ]);
480 $forms = self::prepareFormsToAttrs($forms);
481 if (empty($forms))
482 {
483 $forms = self::getForms(true); // force to preserve cycle when create form landing block
484 $forms = self::prepareFormsToAttrs($forms);
485 if (empty($forms))
486 {
487 $forms = self::createDefaultForm();
488 $forms = self::prepareFormsToAttrs($forms);
489 }
490 }
491
492 if (!empty($forms))
493 {
494 self::setFormIdParam(
495 $block,
496 str_replace(self::INLINE_MARKER_PREFIX, '', $forms[0]['value'])
497 );
498 }
499 }
500
501 // preload alert
502 $node->setInnerHTML(
503 '<div class="g-landing-alert">'
504 . Loc::getMessage('LANDING_BLOCK_WEBFORM_PRELOADER')
505 . '</div>'
506 );
507 $block->saveContent($dom->saveHTML());
508
509 // save
510 $block->setAttributes([self::SELECTOR_FORM_NODE => $attrsToSet]);
511 $block->save();
512
513 $historyActivity ? History::activate() : History::deactivate();
514 },
515 ];
516
517 // add attrs
518 if (
519 !array_key_exists('attrs', $manifest)
520 || !is_array($manifest['attrs'])
521 )
522 {
523 $manifest['attrs'] = [];
524 }
525
526 // hard operation getAttrs is only FOR EDITOR, in public set fake array for saveAttributes later
527 $manifest['attrs'][self::SELECTOR_FORM_NODE] =
528 Landing::getEditMode()
529 ? self::getAttrs()
530 : [['attribute' => self::ATTR_FORM_PARAMS]];
531
532 return $manifest;
533 }
534
539 protected static function getAttrs(): array
540 {
541 static $attrs = [];
542 if ($attrs)
543 {
544 return $attrs;
545 }
546
547 // get from CRM or via connector
548 $forms = self::getForms();
549 $forms = self::prepareFormsToAttrs($forms);
550
551 $attrs = [
552 $attrs[] = [
553 'name' => 'Embed form flag',
554 'attribute' => self::ATTR_FORM_EMBED,
555 'type' => 'string',
556 'hidden' => true,
557 ],
558 [
559 'name' => 'Form design',
560 'attribute' => self::ATTR_FORM_STYLE,
561 'type' => 'string',
562 'hidden' => true,
563 ],
564 [
565 'name' => 'Form from connector flag',
566 'attribute' => self::ATTR_FORM_FROM_CONNECTOR,
567 'type' => 'string',
568 'hidden' => true,
569 ],
570 ];
571
572 if (!empty($forms))
573 {
574 // get forms list
575 $attrs[] = [
576 'name' => Loc::getMessage('LANDING_BLOCK_WEBFORM'),
577 'attribute' => self::ATTR_FORM_PARAMS,
578 'items' => $forms,
579 'type' => 'list',
580 ];
581 // show header
582 // use custom design
583 $attrs[] = [
584 'name' => Loc::getMessage('LANDING_BLOCK_WEBFORM_USE_STYLE'),
585 'attribute' => self::ATTR_FORM_USE_STYLE,
586 'type' => 'list',
587 'items' => [
588 [
589 'name' => Loc::getMessage('LANDING_BLOCK_WEBFORM_USE_STYLE_Y'),
590 'value' => 'Y',
591 ],
592 [
593 'name' => Loc::getMessage('LANDING_BLOCK_WEBFORM_USE_STYLE_N'),
594 'value' => 'N',
595 ],
596 ],
597 ];
598 }
599 // no form - no settings, just message for user
600 else
601 {
602 $attrs[] = [
603 'name' => Loc::getMessage('LANDING_BLOCK_WEBFORM'),
604 'attribute' => self::ATTR_FORM_PARAMS,
605 'type' => 'list',
606 'items' => !empty(self::$errors)
607 ? array_map(fn ($item) => ['name' => $item['message'], 'value' => false], self::$errors)
608 : [[
609 'name' => Loc::getMessage('LANDING_BLOCK_WEBFORM_NO_FORM'),
610 'value' => false,
611 ]],
612 ];
613 }
614
615 return $attrs;
616 }
617
623 protected static function prepareFormsToAttrs(array $forms): array
624 {
625 $sorted = [];
626 foreach ($forms as $form)
627 {
628 if (array_key_exists('ACTIVE', $form) && $form['ACTIVE'] !== 'Y')
629 {
630 continue;
631 }
632
633 $item = [
634 'name' => $form['NAME'],
635 'value' => self::INLINE_MARKER_PREFIX . $form['ID'],
636 ];
637
638 if ($form['IS_CALLBACK_FORM'] === 'Y')
639 {
640 $sorted[] = $item;
641 }
642 else
643 {
644 array_unshift($sorted, $item);
645 }
646 }
647
648 return $sorted;
649 }
650 // endregion
651
652 // region actions with blocks and forms
660 public static function getLandingFormBlocks($landingIds): array
661 {
662 if (empty($landingIds))
663 {
664 return [];
665 }
666
667 if (!is_array($landingIds))
668 {
669 $landingIds = [$landingIds];
670 }
671
672 return BlockTable::getList(
673 [
674 'select' => ['ID', 'LID'],
675 'filter' => [
676 '=LID' => $landingIds,
677 '=DELETED' => 'N',
678 'CONTENT' => '%data-b24form=%',
679 ],
680 ]
681 )->fetchAll()
682 ;
683 }
684
690 public static function getFormByBlock(int $blockId): ?int
691 {
692 $block = new Block($blockId);
693 if (preg_match(self::REGEXP_FORM_ID_INLINE, $block->getContent(), $matches))
694 {
695 return (int)$matches[1];
696 }
697 return null;
698 }
699
706 public static function setFormIdToBlock(int $blockId, int $formId): bool
707 {
708 $block = new Block($blockId);
709 self::setFormIdParam($block, $formId);
710 $block->save();
711
712 return $block->getError()->isEmpty();
713 }
714
720 protected static function setFormIdParam(Block $block, int $formId): void
721 {
722 if (($form = self::getFormById($formId)))
723 {
724 // todo: can add force public flag for replaces, when we know exactly that block is public
725 $newParam = self::INLINE_MARKER_PREFIX . $form['ID'];
726
727 $block->setAttributes([
728 self::SELECTOR_FORM_NODE => [self::ATTR_FORM_PARAMS => $newParam],
729 ]);
730 }
731 }
732
737 protected static function createDefaultForm(): array
738 {
739 if ($formId = self::createForm([]))
740 {
741 return self::getFormsByFilter(['=ID' => $formId]);
742 }
743
744 return [];
745 }
746
751 protected static function createForm(array $formData): ?int
752 {
753 if (self::isCrm())
754 {
755 $form = new WebForm\Form;
756
757 $defaultData = WebForm\Preset::getById('crm_preset_cd');
758
759 $defaultData['XML_ID'] = '';
760 $defaultData['ACTIVE'] = 'Y';
761 $defaultData['IS_SYSTEM'] = 'N';
762 $defaultData['IS_CALLBACK_FORM'] = 'N';
763 $defaultData['BUTTON_CAPTION'] = $form->getButtonCaption();
764
765 $agreementId = UserConsent::getDefaultAgreementId();
766 $defaultData['USE_LICENCE'] = $agreementId ? 'Y' : 'N';
767 if ($agreementId)
768 {
769 $defaultData['LICENCE_BUTTON_IS_CHECKED'] = 'Y';
770 $defaultData['AGREEMENT_ID'] = $agreementId;
771 }
772
773 $isLeadEnabled = LeadSettings::getCurrent()->isEnabled();
774 $defaultData['ENTITY_SCHEME'] = (string)(
775 $isLeadEnabled
776 ? WebForm\Entity::ENUM_ENTITY_SCHEME_LEAD
777 : WebForm\Entity::ENUM_ENTITY_SCHEME_DEAL
778 );
779
780 $currentUserId = is_object($GLOBALS['USER']) ? $GLOBALS['USER']->getId() : null;
781 $defaultData['ACTIVE_CHANGE_BY'] = $currentUserId;
782 $defaultData['ASSIGNED_BY_ID'] = $currentUserId;
783
784 $formData = array_merge($defaultData, $formData);
785 $form->merge($formData);
786 $form->save();
787
788 return !$form->hasErrors() ? $form->getId() : null;
789 }
790
791 return null;
792 }
793
798 public static function setSpecialFormToBlock(Block $block, string $xmlId): void
799 {
800 if (($formData = self::getSpecialFormsData()[$xmlId]))
801 {
802 $formId = null;
803 foreach (self::getForms() as $form)
804 {
805 if (
806 array_key_exists('XML_ID', $form)
807 && $form['XML_ID'] === $xmlId
808 )
809 {
810 $formId = $form['ID'];
811 break;
812 }
813 }
814
815 if (!$formId)
816 {
817 $formId = self::createForm($formData);
818 }
819
820 if ($formId)
821 {
822 self::setFormIdParam($block, $formId);
823 $block->save();
824 }
825 }
826 }
827
828 protected static function getSpecialFormsData(): ?array
829 {
830 if (self::isCrm())
831 {
832 $data = [
833 'crm_preset_store_v3' => [
834 'XML_ID' => 'crm_preset_store_v3',
835 'NAME' => Loc::getMessage('LANDING_FORM_SPECIAL_STOREV3_NAME'),
836 'IS_SYSTEM' => 'N',
837 'ACTIVE' => 'Y',
838 'RESULT_SUCCESS_TEXT' => Loc::getMessage('LANDING_FORM_SPECIAL_STOREV3_RESULT_SUCCESS'),
839 'RESULT_FAILURE_TEXT' => Loc::getMessage('LANDING_FORM_SPECIAL_STOREV3_RESULT_FAILURE'),
840 'COPYRIGHT_REMOVED' => 'N',
841 'IS_PAY' => 'N',
842 'FORM_SETTINGS' => [
843 'DEAL_DC_ENABLED' => 'Y',
844 ],
845 'BUTTON_CAPTION' => '',
846 'FIELDS' => [
847 [
848 'TYPE' => 'string',
849 'CODE' => 'CONTACT_NAME',
850 'CAPTION' => Loc::getMessage('LANDING_FORM_SPECIAL_STOREV3_FIELD_NAME'),
851 'SORT' => 100,
852 'REQUIRED' => 'N',
853 'MULTIPLE' => 'N',
854 'PLACEHOLDER' => '',
855 ],
856 [
857 'TYPE' => 'phone',
858 'CODE' => 'CONTACT_PHONE',
859 'CAPTION' => Loc::getMessage('LANDING_FORM_SPECIAL_STOREV3_FIELD_PHONE'),
860 'SORT' => 200,
861 'REQUIRED' => 'N',
862 'MULTIPLE' => 'N',
863 'PLACEHOLDER' => '',
864 ],
865 [
866 'TYPE' => 'text',
867 'CODE' => 'DEAL_COMMENTS',
868 'CAPTION' => Loc::getMessage('LANDING_FORM_SPECIAL_STOREV3_FIELD_COMMENT'),
869 'SORT' => 300,
870 'REQUIRED' => 'N',
871 'MULTIPLE' => 'N',
872 'PLACEHOLDER' => '',
873 ],
874 ],
875 ],
876 ];
877
878 $isLeadEnabled = LeadSettings::getCurrent()->isEnabled();
879
880 foreach ($data as $id => $form)
881 {
882 if ($isLeadEnabled)
883 {
884 foreach ($data[$id]['FIELDS'] as $key => $field)
885 {
886 $field['CODE'] = str_replace(['CONTACT', 'DEAL'], 'LEAD', $field['CODE']);
887 $data[$id]['FIELDS'][$key] = $field;
888 }
889 }
890 }
891
892 return $data;
893 }
894
895 return null;
896 }
897
898 // endregion
899
900 // region update
905 public static function updateLandingToEmbedForms(int $landingId): void
906 {
907 $res = BlockTable::getList(
908 [
909 'select' => [
910 'ID',
911 ],
912 'filter' => [
913 'LID' => $landingId,
914 '=DELETED' => 'N',
915 ],
916 ]
917 );
918 while ($row = $res->fetch())
919 {
920 $block = new Block($row['ID']);
921 self::updateBlockToEmbed($block);
922 }
923 }
924
929 protected static function updateBlockToEmbed(Block $block): void
930 {
931 // check if update needed
932 $manifest = $block->getManifest();
933 if (
934 !$manifest['block']['subtype']
935 || (!is_array($manifest['block']['subtype']) && $manifest['block']['subtype'] !== 'form')
936 || (is_array($manifest['block']['subtype']) && !in_array('form', $manifest['block']['subtype'], true))
937 )
938 {
939 return;
940 }
941 $dom = $block->getDom();
942 if (
943 !($resultNode = $dom->querySelector(self::SELECTOR_FORM_NODE))
944 || !($attrs = $resultNode->getAttributes())
945 || !array_key_exists(self::ATTR_FORM_PARAMS, $attrs))
946 {
947 return;
948 }
949 $formParams = explode('|', $attrs[self::ATTR_FORM_PARAMS]->getValue());
950 if (count($formParams) !== 2 || !(int)$formParams[0])
951 {
952 return;
953 }
954
955 // update
956 $forms = self::getForms();
957 if (array_key_exists($formParams[0], $forms))
958 {
959 $form = $forms[$formParams[0]];
960 self::setFormIdParam($block, $form['ID']);
961 $resultNode->setAttribute(self::ATTR_FORM_EMBED, '');
962 $resultNode->removeAttribute(self::ATTR_FORM_OLD_DOMAIN);
963 $resultNode->removeAttribute(self::ATTR_FORM_OLD_HEADER);
964
965 if (
966 !array_key_exists(self::ATTR_FORM_STYLE, $attrs)
967 || !$attrs[self::ATTR_FORM_STYLE]->getValue()
968 )
969 {
970 // find new styles
971 $contentFromRepo = Block::getContentFromRepository($block->getCode());
972 if (
973 $contentFromRepo
974 && preg_match(self::REGEXP_FORM_STYLE, $contentFromRepo, $style)
975 )
976 {
977 $resultNode->setAttribute(self::ATTR_FORM_STYLE, $style[1]);
978 }
979 }
980 }
981
982 if (($oldStyleNode = $dom->querySelector(self::SELECTOR_OLD_STYLE_NODE)))
983 {
984 $oldStyleNode->getParentNode()->removeChild($oldStyleNode);
985 }
986
987 $block->saveContent($dom->saveHTML());
988 $block->save();
989 }
990
996 public static function getOriginalFormDomain(): string
997 {
998 trigger_error(
999 "Now using embedded forms, no need domain",
1000 E_USER_WARNING
1001 );
1002
1003 return '';
1004 }
1005 // endregion
1006}
save(array $additionalFields=[])
Определения block.php:2704
setAttributes($data)
Определения block.php:4593
saveContent(string $content, $designed=false)
Определения block.php:2676
getManifest(bool $extended=false, bool $missCache=false, array $params=array())
Определения block.php:1682
getDom($clear=false)
Определения block.php:3530
getCode()
Определения block.php:1403
static isB24()
Определения manager.php:1135
static isB24Connector()
Определения manager.php:1178
static setFormIdToBlock(int $blockId, int $formId)
Определения form.php:706
const ATTR_FORM_STYLE
Определения form.php:29
const ATTR_FORM_PARAMS
Определения form.php:27
const ATTR_FORM_FROM_CONNECTOR
Определения form.php:31
static prepareFormsToAttrs(array $forms)
Определения form.php:623
static getFormById(int $id, bool $full=false)
Определения form.php:298
const ATTR_FORM_EMBED
Определения form.php:28
static prepareFormsToPublication(string $content)
Определения form.php:61
static setSpecialFormToBlock(Block $block, string $xmlId)
Определения form.php:798
static getOriginalFormDomain()
Определения form.php:996
static getAttrs()
Определения form.php:539
static getFormsByFilter(array $filter)
Определения form.php:333
static getSpecialFormsData()
Определения form.php:828
const REGEXP_FORM_STYLE
Определения form.php:37
static createForm(array $formData)
Определения form.php:751
static isCrm()
Определения form.php:239
const SELECTOR_FORM_NODE
Определения form.php:34
static setFormIdParam(Block $block, int $formId)
Определения form.php:720
const SELECTOR_OLD_STYLE_NODE
Определения form.php:35
static prepareManifest(array $manifest, Block $block=null, array $params=[])
Определения form.php:396
static createDefaultForm()
Определения form.php:737
const REGEXP_FORM_ID_INLINE
Определения form.php:38
static getFormsViaConnector()
Определения form.php:267
static prepareFormsToView(string $content)
Определения form.php:72
static updateBlockToEmbed(Block $block)
Определения form.php:929
const AVAILABLE_FORM_FIELDS
Определения form.php:43
static getCallbackForms()
Определения form.php:328
const INLINE_MARKER_PREFIX
Определения form.php:40
static replaceFormMarkers(string $content)
Определения form.php:87
static updateLandingToEmbedForms(int $landingId)
Определения form.php:905
const ATTR_FORM_OLD_HEADER
Определения form.php:33
static getFormByBlock(int $blockId)
Определения form.php:690
static getFormsForPortal(array $filter=[])
Определения form.php:244
const STYLE_SETTING
Определения form.php:36
static clearCache()
Определения form.php:172
static getLandingFormBlocks($landingIds)
Определения form.php:660
const POPUP_MARKER_PREFIX
Определения form.php:41
const ATTR_FORM_OLD_DOMAIN
Определения form.php:32
static getForms(bool $force=false)
Определения form.php:215
const ATTR_FORM_USE_STYLE
Определения form.php:30
$sites
Определения clear_component_cache.php:15
$content
Определения commerceml.php:144
$data['IS_AVAILABLE']
Определения .description.php:13
</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
$filter
Определения iblock_catalog_list.php:54
$GLOBALS['____1690880296']
Определения license.php:1
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
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
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$matches
Определения index.php:22
$site
Определения yandex_run.php:614