Недавно писал расширение с использованием eID scripts и теперь хочу поделиться некоторыми мыслями.
1. Кратко о том, что это такое и зачем оно нужно.
Часто не требуется грузить весь фронтенд TYPO3, а достаточно небольшой его части. Например, нужно показать картинку или вернуть ответ на ajax-запрос. В этом случаем можно прописать в файле ext_localconf.php своего расширения нечто такое:
PHP код:
if(TYPO3_MODE == 'FE'){
$TYPO3_CONF_VARS['FE']['eID_include']['something_cool'] = 'EXT:mycoolext/ajax.php';
}
(Разумеется, стоит создать в нашем расширении этот самый ajax.php)
Мы только что определили eID скрипт с ключевым словом 'something_cool'. Это ключевое слово должно быть уникальным в пределах инсталляции, поэтому лучше использовать название своего расширения (возможно с префиксами или постфиксами).
2. Как это работает
Вся инициализация TYPO3 начинается с выполнения файла index_ts.php, который лежит в typo3/sysext/cms/tslib/. (Кстати, рекомендую просмотреть его тем, кто желает таки узнать, как работает
схема рендеринга фронтэнда).
Сразу после совсем базовой инициализации и различных проверок, но до создания глобального объекта TSFE можно увидеть вот такой кусок кода:
PHP код:
// *********************
// Look for extension ID which will launch alternative output engine
// *********************
if ($temp_extId = t3lib_div::_GP('eID')) {
if ($classPath = t3lib_div::getFileAbsFileName($TYPO3_CONF_VARS['FE']['eID_include'][$temp_extId])) {
require_once(PATH_tslib.'class.tslib_eidtools.php');
require($classPath);
}
exit;
}
Как видим, если через GET или POST передано значение eID, то TYPO3 выдаёт нам в руки класс tslib_eidtools (из файла class.tslib_eidtools.php), говорит "а контент будете генерировать сами" и делает exit;
Для проверки напишем в нашем ajax.php что-то вроде
PHP код:
<?php
echo 'eID output';
?>
Теперь при обращении
http://oursite.ru/index.php?eID=something_cool мы должны увидеть надпись 'eID output'. Разберемся с классом tslib_eidtools. У него есть всего два простых метода класса: connectDB() и initFeUser(). Первый, соответственно, соединяется с базой данных, а второй инициализирует fe-пользователя. Иногда в различных ajax-ответах нужно достать данные из сессии пользователя (кстати, нужно помнить о том, что fe user тут может быть и анонимным - сессия у него есть всё равно).
3. Про сессии
Итак, получить данные из сессии анонимного пользователя можно примерно так:
PHP код:
<?php
if (!defined ('PATH_typo3conf')) die ('Could not access this script directly!');
class ajax{
public $fe_user;
public function __construct(){
$this->fe_user = tslib_eidtools::initFeUser();
}
public function process(){
$data = $this->fe_user->getKey('ses','ourdata');
}
}
$ajax = new ajax();
echo $ajax->process();
?>
Здесь всё будет хорошо работать. Правда, иногда из сессии нужно не только читать данные, но и писать их в неё. И вот в этом случае обычный $this->fe_user->setKey() работать не будет.
После получаса бегания по исходникам тайпы, я нашел решение. Примерно вот такое:
PHP код:
<?php
if (!defined ('PATH_typo3conf')) die ('Could not access this script directly!');
class ajax{
public $fe_user;
public function __construct(){
$this->fe_user = tslib_eidtools::initFeUser();
}
public function process(){
$data = $this->fe_user->getKey('ses','ourdata');
$data++;
$this->fe_user->setKey('ses','ourdata',$data);
}
public function __destruct(){
$this->fe_user->storeSessionData();
}
}
$ajax = new ajax();
echo $ajax->process();
?>
Важно не забыть вызвать fe_user->storeSessionData(), иначе сессия не будет записана в БД.
P.S. Стоит ли писать иногда такие вот посты о хитростях программирования расширений? Я бы попросил всех, кому такие вещи интересны, написать об этом в комментариях =)