[spoiler]
1. Защита от прямого вызова
Во всех PHP-файлах (component.php, .description.php, .parameters.php, template.php и др.) компонента первая строка должна быть такой:
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); |
Данная строка гарантирует подключение компонента после подключения
2. Кеширование
Для упрощения разработки компонентов 2.0, использующих кеширование данных и выводимого HTML, был добавлен метод
- учитывает параметры компонента CACHE_TYPE (тип кеширования) и CACHE_TIME (время кеширования);
- кеширует весь выводимый шаблоном HTML, а также массив $arResult.
Пример использования StartResultCache
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); //Module if (!CModule::IncludeModule("learning")) { ShowError(GetMessage("LEARNING_MODULE_NOT_FOUND")); return; } if($this->StartResultCache(false, $USER->GetGroups())) { /*... Выборка данных в массив $arResult*/ //Подключение шаблона $this->IncludeComponentTemplate(); } |
Этот код работает правильно, однако он неоптимален. Подключение модуля происходит всегда, даже если есть валидный кеш, поэтому CModule::IncludeModule следует включить в кешируемую область.
Пример более рационального использования StartResultCache
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); if($this->StartResultCache(false, $USER->GetGroups())) { //Module if (!CModule::IncludeModule("learning")) { $this->AbortResultCache(); ShowError(GetMessage("LEARNING_MODULE_NOT_FOUND")); return; } /*... Выборка данных в массив $arResult*/ //Подключение шаблона $this->IncludeComponentTemplate(); } |
Необходимо также учитывать, что в идентификатор кеша метод StartResultCache "подмешивает" адрес текущей страницы. Если компонент будет использоваться, например, в шаблоне сайта (т.е. будет вызываться на всех страницах веб-ресурса), то количество созданных файлов кеша будет соответствовать количеству страниц на сайте. Для кеширования таких компонентов следует использовать стандартный класс
3. Безопасность данных в массиве $arResult
Для повышения безопасности шаблонов и уменьшения головной боли разработчика шаблонов в массиве $arResult должны содержаться уже обработанные данные (через htmlspecialchars или $cdbresult->GetNext()).
Если необходимы «сырые» данные, следует помещать их в отдельные поля, начинающиеся с тильды ($arResult["~NAME"]). Метод
4. Постраничная навигация
Постраничная навигация реализуется с помощью системного компонента system.pagenavigation. Этот компонент можно вызвать непосредственно с помощью
Входные параметры компонента system.pagenavigation:
string NAV_TITLE - название постраничной навигации;
CDBResult NAV_RESULT - ссылка на объект типа
bool SHOW_ALWAYS - показывать постраничную навигацию, если все записи помещаются на одну страницу.
Метод CDBResult::GetPageNavString подключает компонент system.pagenavigation и возвращает HTML постраничной навигации.
Сигнатура функции:
CDBResult::GetPageNavString( string [I]navigationTitle[/I], string [I]templateName[/I] = "", bool [I]showAlways[/I]=false ) |
navigationTitle – название постраничной навигации;
templateName – шаблон постраничной навигации;
showAlways – показывать постраничную навигацию, если все записи помещаются на одну страницу.
Типичный пример использования CDBResult::GetPageNavString
В логике компонента (component.php):
CPageOption::SetOptionString("main", "nav_page_in_session", "N"); // убирает запоминание страниц $obTicket = CTicket::GetList(Array(), Array()); //Выбираем записи $obTicket->NavStart(20); //Разбиваем по 20 элементов на страницу $arResult["NAV_STRING"] = $obTicket->GetPageNavString("Обращения"); //HTML постраничного вывода $arResult["NAV_RESULT"] = $obTicket; //ссылка на объект |
В шаблоне (template.php):
<?=$arResult["NAV_STRING"]?> |
Ссылка на объект в $arResult["NAV_RESULT"] нужна для того, чтобы в шаблоне компонента была возможность подключить system.pagenavigation.
5. Идентификаторы картинок
API-методы возвращают только идентификатор картинки, которого в шаблоне компонента будет недостаточно. Необходимы все данные: высота, ширина, путь к файлу. Вместо стандартной функции
Метод CFile::GetFileArray($FILE_ID) возвращает массив со всеми данными о файле (см. описание
Компонент:
$arResult["IMAGE"] = CFile::GetFileArray($arElement["IMAGE_ID"]); |
Шаблон:
<?if ($arResult["IMAGE"] !== false):?> <img src="<?=$arResult["IMAGE"]["SRC"]?>" width="<?=$arResult["IMAGE"]["WIDTH"]?>" height="<?=$arResult["IMAGE"]["HEIGHT"]?>" border="0" /> <?endif?> |
6. Защита форм, ссылок "Удалить" и других действий, зависящих от прав доступа текущего пользователя
Представим, что на вашем сайте выводится компонент новостей, в котором есть возможность удалить новость. Ссылка на удаление выглядит таким образом:
www.mysite.ru/news/detail.php?ID=123&delete=Y |
Далее недоброжелатель помещает эту ссылку в форуме, например, в теге <img src="
Для этого в продукте есть ряд функций в помощь:
string bitrix_sessid() - возвращает идентификатор сессии, предварительно обработанный функцией md5.
bool check_bitrix_sessid($varname='sessid') - возвращает true, если верно условие $_REQUEST[$varname] == bitrix_sessid(), иначе false.
string bitrix_sessid_get($varname='sessid') - возвращает строку вида $varname=идентификатор сессии
string bitrix_sessid_post($varname='sessid') - возвращает строку вида <input type="hidden" name="$varname" id="$varname" value="идентификатор сесии" />
Передача идентификатора сессии в форме
<form method="post" action="/news/add.php"> <?=bitrix_sessid_post()?> Title: <input type="text" name="NAME" size="40" maxlength="255" value=""> </form> |
Передача идентификатора в ссылке
<a href="/news/detail.php?ID=123&delete=Y&<?=bitrix_sessid_get()?>">Удалить</a> |
Проверка сессии
if($arResult["Perm"]>=BLOG_PERMS_MODERATE && intval($_GET["delete_comment_id"])>0 && check_bitrix_sessid()) { /*Удаление комментария*/ } |
Это не есть хорошо. Новый метод кеширования очень и очень удобен. И я думаю было бы прекрасно отказаться полностью от старого метода. Но в приведенном примере без него никак. Так почему бы не ввести в методе StartResultCache() дополнительный параметр, который отключал бы включение в ID кеша текущего адреса?