protected function setDynamic($edit)
{
static $sourceList = null;
static $isDetailDynamic = null;
static $dynamicElementId = null;
static $dynamicFilter = null;
$data = $this->dynamicParams;
$caching = false;
$cache = null;
// check if is true dynamic
if (!$this->active || !$this->content)
{
return;
}
if (!is_array($data) || empty($data))
{
return;
}
// check feature
$availableFeature = RestrictionManager::isAllowed(
'limit_sites_dynamic_blocks',
['targetBlockId' => $this->id]
);
if (!$availableFeature)
{
$hackContent = preg_replace(
'/^<([a-z]+)s/',
'<$1 style="display: none;" ',
$this->content
);
$this->saveContent(
$hackContent .
$this::getMessageBlock([
'HEADER' => Loc::getMessage('LANDING_BLOCK_MESSAGE_ERROR_DYNAMIC_LIMIT_TITLE'),
'MESSAGE' => RestrictionManager::getSystemErrorMessage('limit_sites_dynamic_blocks'),
'BUTTON' => Loc::getMessage('LANDING_BLOCK_MESSAGE_ERROR_LIMIT_BUTTON'),
'LINK' => Manager::BUY_LICENSE_PATH
], 'locked')
);
return;
}
// if is detail page
if ($isDetailDynamic === null)
{
$isDetailDynamic = Landing::isDynamicDetailPage();
}
if ($dynamicElementId === null)
{
$dynamicElementId = Landing::getDynamicElementId();
}
if ($dynamicFilter === null)
{
$dynamicFilter = Landing::getDynamicFilter();
}
if (!$edit && Cache::isCaching())
{
$cache = new CPHPCache();
$cacheTime = 3600;
$cacheId = 'block_' . $this->id . '_' . $dynamicElementId . '_';
$cacheId .= md5(serialize($dynamicFilter));
$cachePath = '/landing/dynamic/' . $this->id;
if ($cache->initCache($cacheTime, $cacheId, $cachePath))
{
$result = $cache->getVars();
if ($result['title'])
{
Manager::setPageTitle($result['title'], true);
LandingSeo::changeValue('title', $result['title']);
}
$rememberAccess = $this->access;
$this->access = $this::ACCESS_W;
$this->saveContent($result['content']);
$this->access = $rememberAccess;
header('X-Bitrix24-Page: dynamic');
return;
}
else
{
$caching = true;
$cache->startDataCache($cacheTime, $cacheId, $cachePath);
Manager::getCacheManager()->startTagCache($cachePath);
Cache::register($this->id);
}
}
$updated = false;
// @todo: remove after refactoring
$manifest = $this->getManifest();
// build sources list
if ($sourceList === null)
{
$sourceList = new SourceSelector();
}
// @todo: remove after refactoring
$getDetailPage = function(array $detailPage, $filterId = 0, $elemId = 0)
{
$filterId = intval($filterId);
$elemId = intval($elemId);
$query = [];
if (isset($detailPage['query']))
{
$query = (array) $detailPage['query'];
unset($detailPage['query']);
}
// normalize the array
$detailPage = array_merge(
array_fill_keys(['text', 'href', 'target'], ''),
$detailPage
);
trimArr($detailPage, true);
if ($filterId && $elemId && $detailPage['href'])
{
$detailPage['href'] = str_replace(
'#landing',
'#dynamic',
$detailPage['href']
);
$detailPage['href'] .= '_' . $filterId;
$detailPage['href'] .= '_' . $elemId;
}
else if ($filterId && $elemId)
{
$detailPage['href'] = '#';
}
if ($detailPage['href'] && $query)
{
$detailPage['query'] = http_build_query($query);
}
return $detailPage;
};
// apply for each selector dynamic data from source
$disableUpdate = false;
$pageTitle = '';
foreach ($data as $cardSelector => $item)
{
$update = [];
$itemDetail = $cardSelector == 'wrapper';
if (
!isset($item['source']) ||
!isset($item['settings']) ||
!isset($item['references'])
)
{
continue;
}
// build start params
$sourceId = $item['source'];
$settings = $item['settings'];
$references = (array)$item['references'];
$filterId = isset($item['filterId'])
? intval($item['filterId'])
: 0;
$detailPage = isset($settings['detailPage'])
? (array)$settings['detailPage']
: [];
$pagesCount = (
isset($settings['pagesCount']) &&
$settings['pagesCount'] > 0
)
? (int)$settings['pagesCount']
: 10;
$filter = isset($settings['source']['filter'])
? (array)$settings['source']['filter']
: [];
$order = isset($settings['source']['sort'])
? (array)$settings['source']['sort']
: [];
$additional = isset($settings['source']['additional'])
? (array)$settings['source']['additional']
: [];
$stubs = isset($item['stubs'])
? (array)$item['stubs']
: [];
// load external filter, if we on detail
if (
$isDetailDynamic && $itemDetail &&
$dynamicFilter['SOURCE_ID'] == $sourceId
)
{
$filter = $dynamicFilter['FILTER'];
}
$sourceParameters = [
'select' => array_values($references),
'filter' => $filter,
'order' => $order,
'limit' => $pagesCount,
'additional' => $additional
];
// gets list or singleton data
$sourceData = [];
$source = $sourceList->getDataLoader(
$sourceId,
$sourceParameters,
[
'context_filter' => [
'SITE_ID' => $this->siteId,
'LANDING_ID' => $this->lid,
'LANDING_ACTIVE' => $this->landingActive ? 'Y' : ['Y', 'N']
],
'cache' => $cache,
'block' => $this
]
);
if (is_object($source))
{
// detail page
if ($isDetailDynamic && $itemDetail)
{
$sourceData = $source->getElementData($dynamicElementId);
if (!$sourceData)
{
$disableUpdate = true;
continue;
}
$pageTitle = $source->getSeoTitle();
Manager::setPageTitle($pageTitle, true);
LandingSeo::changeValue('title', $pageTitle);
}
// element list
else
{
$sourceData = $source->getElementListData();
$pagesCount = max(1, count($sourceData));
}
}
// apply getting data in block
if (!empty($sourceData) && is_array($sourceData))
{
// collect array for update html
foreach ($references as $selector => $field)
{
if (empty($field) || !is_array($field))
{
continue;
}
if (empty($field['id']))
{
continue;
}
if (mb_strpos($selector, '@') !== false)
{
[$selector,] = explode('@', $selector);
}
if (!isset($update[$selector]))
{
$update[$selector] = [];
}
$fieldCode = $field['id'];
$fieldType = isset($manifest['nodes'][$selector]['type'])
? $manifest['nodes'][$selector]['type']
: NodeType::TEXT;
// fill ever selector with data, if data exist
$detailPageData = [];
foreach ($sourceData as $dataItem)
{
// set link to the card
// @todo: need refactoring
if (
$fieldType == NodeType::LINK &&
isset($field['action'])
)
{
switch ($field['action'])
{
case 'detail':
{
$detailPage['text'] = isset($field['text'])
? $field['text']
: '';
$update[$selector][] = $detailPageData[$selector][] = $getDetailPage(
$detailPage,
$filterId,
$dataItem['ID']
);
break;
}
case 'link':
{
if (isset($field['link']))
{
$field['link'] = (array) $field['link'];
if (isset($field['text']))
{
$field['link']['text'] = $field['text'];
}
$update[$selector][] = $getDetailPage(
$field['link']
);
}
break;
}
case 'landing':
{
if (isset($dataItem['LINK']))
{
$update[$selector][] = $detailPageData[$selector][] = $getDetailPage([
'text' => isset($field['text'])
? $field['text']
: '',
'href' => $dataItem['LINK'],
'target' => '_self',
'query' => isset($dataItem['_GET']) ? $dataItem['_GET'] : []
]);
}
}
}
}
else// if ($fieldType != NodeType::LINK)
{
$value = isset($dataItem[$fieldCode])
? $dataItem[$fieldCode]
: '';
$update[$selector][] = $value;
if ($detailPage)
{
$detailPageData[$selector][] = $getDetailPage(
$detailPage,
$filterId,
$dataItem['ID']
);;
}
else if (isset($dataItem['LINK']))
{
$detailPageData[$selector][] = $getDetailPage([
'text' => isset($field['text'])
? $field['text']
: '',
'href' => $dataItem['LINK'],
'target' => '_self',
'query' => isset($dataItem['_GET']) ? $dataItem['_GET'] : []
]);
}
}
}
// not touch the selector, if there is no data
if (!$update[$selector])
{
unset($update[$selector]);
}
// set detail url for nodes
// @todo: refactor
else if (
isset($field['link']) &&
(
$fieldType == NodeType::IMAGE ||
$fieldType == NodeType::TEXT
)
)
{
if (!isset($detailPageData[$selector]))
{
continue;
}
foreach ($update[$selector] as $i => &$value)
{
if ($fieldType == NodeType::IMAGE)
{
$value = (array) $value;
}
else
{
$value = [
'text' => (string) $value
];
}
if (
$detailPageData[$selector][$i] &&
UtilsAction::isTrue($field['link'])
)
{
$detailPageData[$selector][$i]['enabled'] = true;
}
else
{
$detailPageData[$selector][$i]['enabled'] = false;
}
if ($detailPageData[$selector][$i]['enabled'])
{
$value['url'] = $detailPageData[$selector][$i];
}
}
unset($value);
}
}
if (!$itemDetail)
{
$rememberAccess = $this->access;
$this->access = $this::ACCESS_W;
$this->adjustCards(
$cardSelector,
$pagesCount
);
$this->access = $rememberAccess;
}
}
// stubs (common content)
if ($stubs)
{
foreach ($stubs as $selector => $stub)
{
if (mb_strpos($selector, '@') !== false)
{
[$selector,] = explode('@', $selector);
}
$update[$selector] = array_fill(0, $pagesCount, $stub);
}
}
// update dynamic
if ($update)
{
$updated = true;
$rememberAccess = $this->access;
$this->access = $this::ACCESS_W;
$this->updateNodes(
$update,
[
'sanitize' => false,
'skipCheckAffected' => true
]
);
if(!$edit)
{
AssetsPreProcessing::blockSetDynamicProcessing($this);
}
$this->access = $rememberAccess;
header('X-Bitrix24-Page: dynamic');
if ($caching)
{
$cache->endDataCache([
'title' => $pageTitle,
'content' => $this->content
]);
Manager::getCacheManager()->endTagCache();
}
}
else if (false)
{
$this->runtimeRequiredUserAction = [
'header' => Loc::getMessage('LANDING_BLOCK_MESSAGE_ERROR_NO_DATA_TITLE'),
'description' => Loc::getMessage('LANDING_BLOCK_MESSAGE_ERROR_NO_DATA_TEXT')
];
}
}
if (
$disableUpdate ||
(!$updated && !Landing::getEditMode())
)
{
if ($cache)
{
$cache->abortDataCache();
}
$this->deleted = true;
}
}