The last notes
All English-language materials have been translated fully automatically using the Google service
Clearing the Bitrix modules cache
Quite often, during development in Bitrix24, fragments of code remain deleted, but saved using the cache. For example, recent conversations or a list of recent groups. In this case, it is enough to simply get rid of them by running the command:
BXClearCache( true, "/bx/imc/recent/");
or
BXClearCache( true, "/bx/group/");
Clearing the component cache
If during development you need to programmatically clear the cache of a component, then you can use the OnBeforeIBlockElementUpdate
function in init.php
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", Array("updateCacheClass", "OnBeforeIBlockElementUpdateHandler"));
class updateCacheClass{
function OnBeforeIBlockElementUpdateHandler(&$arFields) {
if ($arFields['IBLOCK_ID'] == 3) {
CBitrixComponent::clearComponentCache('simplecomp:simplecomp.exam4');
}
}
}
Cache infoblock output
Make light cached output of infoblock elements
CModule::IncludeModule("iblock");
$cntIBLOCK_List = 19;
$cache = new CPHPCache();
$cache_time = 3600*12; //кеш на сутки
$cache_id = 'arIBlockListID'.$cntIBLOCK_List;
$cache_path = 'arIBlockListID';
if ($cache_time > 0 && $cache->InitCache($cache_time, $cache_id, $cache_path))
{
$res = $cache->GetVars();
if (is_array($res["arIBlockListID"]) && (count($res["arIBlockListID"]) > 0)){
$arIBlockListID = $res["arIBlockListID"];
}
$arIBlockListID['CACHE']='true';
}
if (!is_array($arIBlockListID))
{
$arIBlockListID['CACHE']='false';
$arIBlockListID['NAME']=CIBlock::GetArrayByID($cntIBLOCK_List, "NAME");
$arIBlockListID['DESCRIPTION']=CIBlock::GetArrayByID($cntIBLOCK_List, "DESCRIPTION");
$arIBlockListID['PICTURE']=CFile::GetPath(CIBlock::GetArrayByID($cntIBLOCK_List, "PICTURE"));
$arSelect = array("ID", "NAME", "CODE",'PREVIEW_TEXT','PREVIEW_PICTURE','PROPERTY_MORE_PHOTOS');
$arFilter = array("IBLOCK_ID" => intval($cntIBLOCK_List),"IBLOCK_TYPE" => 'content', "ACTIVE_DATE" => "Y", "ACTIVE" => "Y");
$rsImplementation = CIBlockElement::GetList(Array(), $arFilter, false, array(), $arSelect);
while ($arImplementation = $rsImplementation->GetNextElement()) {
$arItem = $arImplementation->GetFields();
$arIBlockListID[$arItem['ID']]=$arItem;
}
//////////// end cache /////////
if ($cache_time > 0)
{
$cache->StartDataCache($cache_time, $cache_id, $cache_path);
$cache->EndDataCache(array("arIBlockListID"=>$arIBlockListID));
}
}
Updating the value of a cached variable
A quick and not entirely elegant solution to update a variable in a cached component / template is to add code to component_epilog.php
<? global $CITY; ?>
<script type="text/javascript">
$(document).ready(function() {
$('#TOWN').val('<?=$CITY['NAME']?>');
});
</script>
Two different types of component caching
In most of the standard Bitrix components, caching of the $ arResult array and the html code is used simultaneously. However, when writing your own components, this is not always convenient, it often happens that you need to execute some code in the template on each hit, so it's better to cache only the data in $ arResult. Below I gave 2 examples of caching (for component.php) - with and without html code caching. Please note that in the second option, the template is connected after the caching block, and $ this-> EndResultCache () takes its place.
Caching $ arResult and template html-code:
if($this->startResultCache(false, array(($arParams["CACHE_GROUPS"]==="N"? false: $USER->GetGroups())))){
if(!Loader::includeModule("iblock")) {
$this->abortResultCache();
ShowError("Iblock module not installed");
return;
}
$this->includeComponentTemplate();
}
Caching $arResult only:
if($this->startResultCache(false, array(($arParams["CACHE_GROUPS"]==="N"? false: $USER->GetGroups())))){
if(!Loader::includeModule("iblock")){
$this->abortResultCache();
ShowError("Iblock module not installed");
return;
}
$this->EndResultCache();
}
$this->includeComponentTemplate();
Add data to the cache from a template for use in component_epilog.php
Component_epilog.php is a file that runs after the template is rendered and is not cached, i.e. it runs regardless of whether the newly generated html code was shown from the template or output from the cache. Accordingly, we can use this file to perform some actions on each hit, even, for example, display the html code above on the page using deferred functions. But the data available in component_epilog.php tends to be quite limited in components that use html caching. In this example, I will show how to expand the list of this data, for this we will insert the following code into the result_modifier.php file in the component template (For example, the key "ITEMS" in the $ arResult array is used, containing the main component in the "bitrix: news.list" data array):
if (is_object($this->__component)){
$this->__component->SetResultCacheKeys(array('ITEMS'));
if (!isset($arResult['ITEMS']))
$arResult['ITEMS'] = $this->__component->arResult['ITEMS'];
}
Writing $ arResult of the parent complex component from the template
Sometimes in the template files of a complex component (which do not have their own cache) it is convenient to have some data from the usual (non-complex) components used in them. Example: after connecting the catalog.section.list component, in accordance with the structure of the html-code provided by the layout designer, we need access to some section fields in the template of the complex component. To avoid additional queries to the database and the associated inevitable caching, or reconnecting the catalog.section.list component, let's do this:
Let's add all the necessary data to the component cache, for example, use the result_modifier.php file to add the $ arResult ["SECTION"] array
if (is_object($this->__component)){
$this->__component->SetResultCacheKeys(array('SECTION'));
if (!isset($arResult['SECTION']))
$arResult['SECTION'] = $this->__component->arResult['SECTION'];
}
In the component_epilog.php file, get the parent component object, if available, and use its arResult property to write the value
if(is_object($this->__parent))
if($this->__parent->arResult)
$this->__parent->arResult["SECTION_DEPTH_LEVEL"] = $arResult["SECTION"]["DEPTH_LEVEL"];
In a complex component template, the value will be available in the $ arResult variable
$arResult["SECTION_DEPTH_LEVEL"]
We cache data in $ arResult instead of html-code in regular components (from the template)
If you need to perform some manipulations with the data after creating the cache (for example, sorting the list of offices by distance from the current location), then the usual caching of the html code in the news.list component will not work. To cache the data in $ arResult, and not the generated html code, you can do the following:
Use the result_modifier.php file to add the $ arResult ["ITEMS"] array
if (is_object($this->__component)){
$this->__component->SetResultCacheKeys(array('ITEMS'));
if (!isset($arResult['ITEMS']))
$arResult['ITEMS'] = $this->__component->arResult['ITEMS'];
}
The template output itself will be placed not in template.php, but in component_epilog.php (in this case, even after creating the cache, we will have access to the $ arResult ["ITEMS"] array).
Getting rid of the message "Cannot find '' template with page ''"
This cryptic message is generated if the specified template was not found when connecting the component. However, there are times (although quite exotic) when this message may be inappropriate. So that in the absence of a template, the component does not display this message, but returns false, we include the template inside the component instead of the standard "$ this-> IncludeComponentTemplate ();" as follows
if (!$this->__bInited)
return false;
if ($this->InitComponentTemplate("", $this->siteTemplateId, "")) {
$this->showComponentTemplate();
if($this->__component_epilog)
$this->includeComponentEpilog($this->__component_epilog);
return true;
}else{
return false;
}
Disable the ability to edit component parameters
A very common case. It is by no means useful for all components to allow editing their parameters, especially if the call of the component is in the files header.php, footer.php, etc. To prohibit editing the parameters of a component in edit mode, in the fifth parameter of the $ APPLICATION-> IncludeComponent function, insert next array:
Array("HIDE_ICONS"=>"Y")
Script for automatic cache clearing
if (empty($_SERVER['DOCUMENT_ROOT'])) {
$_SERVER['DOCUMENT_ROOT'] = realpath(__DIR__).'/../../../';
}
define('BX_BUFFER_USED', true);
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('NO_AGENT_STATISTIC', true);
define('STOP_STATISTICS', true);
define('SITE_ID', 's1');
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
BXClearCache(true);
if (class_exists('\Bitrix\Main\Data\ManagedCache')) {
(new \Bitrix\Main\Data\ManagedCache())->cleanAll();
}
if (class_exists('\CStackCacheManager')) {
(new \CStackCacheManager())->CleanAll();
}
if (class_exists('\Bitrix\Main\Data\StaticHtmlCache')) {
\Bitrix\Main\Data\StaticHtmlCache::getInstance()->deleteAll();
}
Original here
Another option here
Material used:
Comments