2namespace Bitrix\Landing;
4use Bitrix\Landing\Hook\Page;
5use \Bitrix\Landing\Internals\HookDataTable as HookData;
7use \Bitrix\Main\EventResult;
57 'BACKGROUND_POSITION',
69 'THEMEFONTS_LINE_HEIGHT',
70 'THEMEFONTS_FONT_WEIGHT',
71 'THEMEFONTS_FONT_WEIGHT_H',
74 private const CACHE_TIME = 2592000;
75 private const CACHE_DIR =
'/landing/hook/';
89 while ((($entry = readdir(
$handle)) !==
false))
91 if ($entry !=
'.' && $entry !=
'..')
93 $classes[] = mb_strtoupper(pathinfo($entry, PATHINFO_FILENAME));
113 if (!is_string(
$type))
118 $isEditMode = self::$editMode ?
'N' :
'Y';
120 $cacheId = self::getCacheId($id,
$type, $isEditMode, $asIs);
121 $data = self::getDataFromCache($cacheId);
125 $data = self::getDataFromDatabase($id,
$type, $isEditMode, $asIs);
126 self::saveDataToCache($cacheId,
$data);
139 private static function getDataFromCache(
string $cacheId):
array
143 $cache =
new CPHPCache();
144 if ($cache->InitCache(self::CACHE_TIME, $cacheId, self::CACHE_DIR))
146 $vars = $cache->GetVars();
166 private static function getDataFromDatabase(
int $id,
string $type,
string $isEditMode,
bool $asIs):
array
170 $res = HookData::getList([
172 'ID',
'HOOK',
'CODE',
'VALUE'
176 '=ENTITY_TYPE' =>
$type,
177 '=PUBLIC' => $isEditMode,
184 foreach (
$res->fetchAll() as $row)
186 if (!isset(
$data[$row[
'HOOK']]))
188 $data[$row[
'HOOK']] = [];
190 if (mb_strpos($row[
'VALUE'],
'serialized#') === 0)
192 $row[
'VALUE'] = unserialize(mb_substr($row[
'VALUE'], 11), [
'allowed_classes' =>
false]);
194 $data[$row[
'HOOK']][$row[
'CODE']] = $asIs ? $row : $row[
'VALUE'];
206 private static function saveDataToCache(
string $cacheId,
array $data): void
208 $cache =
new CPHPCache();
209 if (!$cache->InitCache(self::CACHE_TIME, $cacheId, self::CACHE_DIR))
211 $cache->StartDataCache();
212 $cache->EndDataCache([
$data]);
226 $classDir = self::HOOKS_PAGE_DIR;
227 $classNamespace = self::HOOKS_NAMESPACE;
231 foreach (self::getClassesFromDir($classDir) as $class)
233 if (in_array($class, $excludedHooks))
237 $classFull = __NAMESPACE__ . $classNamespace . $class;
238 if (class_exists($classFull))
240 $hooks[$class] =
new $classFull(
242 !(
$type == self::ENTITY_TYPE_SITE)
248 uasort($hooks,
function(
$a, $b)
250 if (
$a->getSort() == $b->getSort())
254 return (
$a->getSort() < $b->getSort()) ? -1 : 1;
262 if (
$result->getType() != EventResult::ERROR)
264 if ($customExec =
$result->getModified())
266 foreach ((
array)$customExec as
$code => $itemExec)
269 if (isset($hooks[
$code]) && is_callable($itemExec))
271 $hooks[
$code]->setCustomExec($itemExec);
274 unset(
$code, $itemExec);
282 if (!empty($hooks) && $id > 0)
288 foreach ($hooks as
$code => $hook)
307 self::$editMode = $mode;
316 return self::$editMode;
326 if (!Landing::getEditMode())
335 if (!array_key_exists($id, $hooks))
337 $hooks[$id] = self::getList($id, self::ENTITY_TYPE_SITE);
350 if (!Landing::getEditMode())
359 if (!array_key_exists($id, $hooks))
361 $hooks[$id] = self::getList($id, self::ENTITY_TYPE_LANDING);
374 return self::getData($id, self::ENTITY_TYPE_LANDING);
385 protected static function copy($from, $to,
$type, $publication =
false)
392 $classDir = self::HOOKS_PAGE_DIR;
393 $classNamespace = self::HOOKS_NAMESPACE;
397 foreach (self::getClassesFromDir($classDir) as $class)
399 if (in_array($class, $excludedHooks,
true))
403 $classFull = __NAMESPACE__ . $classNamespace . $class;
406 && method_exists($classFull, self::HOOKS_ON_COPY_HANDLER)
409 $handler = self::HOOKS_ON_COPY_HANDLER;
410 if ($preparedData = $classFull::$handler(
$data[$class], $from,
$type, $publication))
412 $data[$class] = $preparedData;
420 $res = HookData::getList([
426 '=ENTITY_TYPE' =>
$type,
427 '=PUBLIC' => $publication ?
'Y' :
'N'
430 while ($row =
$res->fetch())
432 $existData[$row[
'HOOK'] .
'_' . $row[
'CODE']] = $row[
'ID'];
441 $existKey = $hookCode .
'_' .
$code;
442 if (is_array($value))
444 $value =
'serialized#' . serialize($value);
446 if (array_key_exists($existKey, $existData))
448 HookData::update($existData[$existKey], [
451 unset($existData[$existKey]);
457 'ENTITY_TYPE' =>
$type,
461 'PUBLIC' => $publication ?
'Y' :
'N'
470 foreach ($existData as $delId)
472 HookData::delete($delId);
487 $originalEditMode = self::$editMode;
488 if (!self::$editMode)
490 self::$editMode =
true;
492 self::copy($from, $to, self::ENTITY_TYPE_SITE);
493 self::$editMode = $originalEditMode;
504 $originalEditMode = self::$editMode;
505 if (!self::$editMode)
507 self::$editMode =
true;
509 self::copy($from, $to, self::ENTITY_TYPE_LANDING);
510 self::$editMode = $originalEditMode;
530 self::copy($lid, $lid, self::ENTITY_TYPE_LANDING,
true);
540 self::publicationWithSkipNeededPublication(
$siteId, self::ENTITY_TYPE_SITE);
550 self::publicationWithSkipNeededPublication($landingId, self::ENTITY_TYPE_LANDING);
555 $editModeBack = self::$editMode;
556 self::$editMode =
false;
557 $publicData = self::getData($id,
$type,
true);
558 self::$editMode = $editModeBack;
560 if (
$type === self::ENTITY_TYPE_SITE)
562 self::publicationSite($id);
564 if (
$type === self::ENTITY_TYPE_LANDING)
566 self::publicationLanding($id);
571 $needClearCache =
false;
572 foreach (self::getList($id,
$type) as $hook)
574 if ($hook->isNeedPublication())
576 $fieldsToDelete = [];
577 if (isset($publicData[$hook->getCode()]))
579 foreach (
$data[$hook->getCode()] as $fieldCode => $field)
581 if (!isset($publicData[$hook->getCode()][$fieldCode]))
583 $fieldsToDelete[$fieldCode] = $field;
585 elseif ($publicData[$hook->getCode()][$fieldCode][
'VALUE'] !== $field[
'VALUE'])
587 $needClearCache =
true;
588 HookData::update($field[
'ID'],
590 'VALUE' => $field[
'VALUE'],
598 $fieldsToDelete =
$data[$hook->getCode()] ?? [];
602 if (!empty($fieldsToDelete))
604 $needClearCache =
true;
605 foreach ($fieldsToDelete as $fieldCode => $field)
607 $res = HookData::getList([
611 '=ENTITY_TYPE' =>
$type,
612 '=HOOK' => $hook->getCode(),
613 '=CODE' => $fieldCode,
617 if ($row =
$res->fetch())
619 HookData::delete($row[
'ID']);
629 if (
$type === self::ENTITY_TYPE_SITE)
639 while ($landing = $landings->fetch())
644 if (
$type === self::ENTITY_TYPE_LANDING)
664 if (mb_strpos(
$code,
'_') !==
false)
666 $codeHook = mb_substr(
$code, 0, mb_strpos(
$code,
'_'));
667 $codeVal = mb_substr(
$code, mb_strpos(
$code,
'_') + 1);
668 if (!isset($newData[$codeHook]))
670 $newData[$codeHook] =
array();
672 $newData[$codeHook][$codeVal] =
$val;
690 $dataSave = self::getData($id,
$type,
true);
693 foreach ($hooks as $hook)
695 $hookLocked = $hook->isLocked();
696 $codeHook = $hook->getCode();
698 foreach ($hook->getFields() as $field)
700 $codeVal = $field->getCode();
701 if ($hookLocked && !$field->isEmptyValue())
705 if (!isset(
$data[$codeHook][$codeVal]))
710 if (isset($dataSave[$codeHook][$codeVal]))
712 $dataSave[$codeHook][$codeVal][
'CHANGED'] =
true;
713 $dataSave[$codeHook][$codeVal][
'VALUE'] = $field->getValue();
718 if (!isset($dataSave[$codeHook]))
720 $dataSave[$codeHook] =
array();
722 $dataSave[$codeHook][$codeVal] =
array(
725 'VALUE' => $field->getValue()
728 if (is_array($dataSave[$codeHook][$codeVal][
'VALUE']))
730 $dataSave[$codeHook][$codeVal][
'VALUE'] =
'serialized#' . serialize(
731 $dataSave[$codeHook][$codeVal][
'VALUE']
738 foreach ($dataSave as $codeHook => $dataHook)
740 foreach ($dataHook as
$code => $row)
743 is_array($row[
'VALUE']) && empty($row[
'VALUE'])
745 !is_array($row[
'VALUE']) && trim($row[
'VALUE']) ==
''
748 if (isset($row[
'ID']))
750 HookData::delete($row[
'ID']);
755 if (!isset($row[
'ID']))
757 $row[
'ENTITY_ID'] = $id;
758 $row[
'ENTITY_TYPE'] =
$type;
761 elseif (isset($row[
'CHANGED']) && $row[
'CHANGED'])
764 unset($row[
'ID'], $row[
'CHANGED']);
765 HookData::update($updId, $row);
784 if (
$type == self::ENTITY_TYPE_LANDING)
786 $class =
'\Bitrix\Landing\Landing';
795 $searchContent = $class::getList([
797 'TITLE',
'DESCRIPTION'
801 '=DELETED' => [
'Y',
'N'],
802 '=SITE.DELETED' => [
'Y',
'N']
810 $searchContent = array_values($searchContent);
813 foreach (self::getList($id,
$type) as $hook)
815 foreach ($hook->getFields() as $field)
817 if ($field->isSearchable())
819 $searchContent[] = $field->getValue();
824 $searchContent = array_unique($searchContent);
825 $searchContent = $searchContent ? implode(
' ', $searchContent) :
'';
826 $searchContent = trim($searchContent);
830 $res = $class::update($id, [
831 'SEARCH_CONTENT' => $searchContent
845 $check = Site::getList([
855 $editModeBack = self::$editMode;
856 self::$editMode =
true;
857 self::saveData($id, self::ENTITY_TYPE_SITE,
$data);
860 self::publicationSiteWithSkipNeededPublication($id);
862 self::$editMode = $editModeBack;
884 $editModeBack = self::$editMode;
885 self::$editMode =
true;
886 self::saveData($id, self::ENTITY_TYPE_LANDING,
$data);
887 self::indexContent($id, self::ENTITY_TYPE_LANDING);
890 self::publicationLandingWithSkipNeededPublication($id);
892 self::$editMode = $editModeBack;
903 self::indexContent($id, self::ENTITY_TYPE_LANDING);
922 '=ENTITY_TYPE' =>
$type
925 while ($row =
$res->fetch())
927 HookData::delete($row[
'ID']);
940 self::deleteData($id, self::ENTITY_TYPE_SITE);
950 self::deleteData($id, self::ENTITY_TYPE_LANDING);
953 private static function clearCache(): void
955 (
new CPHPCache())->CleanDir(self::CACHE_DIR);
958 private static function getCacheId(
int $entityId,
string $entityType,
string $isPublic,
bool $asIs): string
960 return "hook_data_{$entityId}_{$entityType}_{$isPublic}_" . (int)$asIs;
static copySite($from, $to)
static publicationSite($siteId)
static saveData($id, $type, array $data)
static getClassesFromDir($dir)
static getForLanding($id)
const HOOKS_ON_COPY_HANDLER
static deleteForSite($id)
static publicationLanding($lid)
static copyLanding($from, $to)
static getList($id, $type, array $data=array())
static indexContent($id, $type)
static getData($id, $type, $asIs=false)
static getForLandingRow($id)
static publicationWithSkipNeededPublication($id, $type)
static publicationLandingWithSkipNeededPublication($landingId)
static setEditMode(bool $mode=true)
static saveForSite(int $id, array $data)
static saveForLanding(int $id, array $data)
static deleteData($id, $type)
const ENTITY_TYPE_LANDING
static prepareData(array $data)
static publicationSiteWithSkipNeededPublication($siteId)
static copy($from, $to, $type, $publication=false)
static deleteForLanding($id)
static getOption($code, $default=null)
static getExcludedHooks()
static update($primary, array $data)
static getList(array $parameters=array())
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)