ЗАДАЧА: Создать решение, при установке добавляющее в Менеджер Сайта спецблок
«Кто сейчас на сайте».
Спецблок должен выводить загружаемую в асинхронном режиме с сервера информацию
о зарегистрированных пользователях, которые в данный момент находятся на сайте.
Суть решения
Задача будет реализована следующим образом:
- С помощью «Генератора
решений» создадим модуль, имеющий только публичную часть и спецблок.
- Добавим метод обработки запросов к вебсервису
REST.API, который будет возвращать информацию о пользователях с активными
сессиями.
- Спецблок будет содержать JavaScript функционал
получения и отображения информации от вебсервиса.
Далее - подробная пошаговая инструкция по реализации решения.
Реализация
Создание
кода дистрибутива
Используя решение «Генератор
решений» создадим дистрибутив базового класса.

Вебсервис
REST.API Amiro.CMS
Для того, чтобы модуль мог отвечать на запросы к REST.API необходимо
добавить обработчик этого запроса и разрешить публичный доступ к нему.
Внесем следующие изменения в файл
_local/modules/data/{genModId}/amiro.whos_online/code/AmiClean_WhosOnline_Service.php
public function addWebserviceHandlers(array &$aEvent){
parent::addWebserviceHandlers($aEvent);
// Разрешаем доступ к действию 'whos_online.get'
$this->oWebService->setPublicAccess('whos_online.get', TRUE);
// Добавляем обработчик действия 'whos_online.get'
AMI_Event::addHandler('on_webservice_{whos_online.get}_action', array($this, 'handleGetAction'), AMI_Event::MOD_ANY);
return $aEvent;
}
Реализуем код обработчика. Обработчик должен выполнить следующие действия:
- Получить список данных активных пользователей
(основываясь на сроке истечения из сессии и времени жизни сессии)
- Заполнить массив данных в формате, который ожидается
на клиенте
- Отдать полученные результаты запрашивающему скрипту
в формате JSON
public function handleGetAction($name, array &$aEvent){
// Получение списка данных пользователей через модели сессий и пользователей
$oSessionTable = AMI::getResourceModel('env/session/table');
$oSessionTable->setDependence('users', 'u', 'i.id_member = u.id', 'JOIN');
$oSessionTable->setActiveDependence('u');
$oList =
$oSessionTable
->getList()
// Добавляем в запрос поля из связанной таблицы пользователей
->addColumns(array('id', 'login', 'nickname'), 'u')
// Добавляем срезку по активности пользователя, активными будем считать тех пользователей,
// у которых время истечения сессии минус время жизни сессии отличается от текущего времени
// не более чем на пять минут
->addWhereDef(
DB_Query::getSnippet('AND DATE_SUB(expired, INTERVAL %s MINUTE) > DATE_SUB(NOW(), INTERVAL 5 MINUTE)')
->plain(AMI::getOption('session', 'timeout'))
)
->load();
// Массив с результатами выборки
$aEvent['online'] = array();
$aAddedIds = array();
foreach($oList as $oItem){
if(!in_array($oItem->u_id, $aAddedIds)){
$aEvent['online'][] =
array(
'id' => $oItem->u_id,
'login' => $oItem->u_login,
'nickname' => $oItem->u_nickname
);
$aAddedIds[] = $oItem->u_id;
}
}
// Отправка результата в формате JSON
$this->oWebService->ok($aEvent);
return $aEvent;
}
Спецблок
Для того, чтобы модуль мог отвечать на запросы к REST.API, необходимо
добавить обработчик этого запроса и разрешить публичный доступ к нему.
Модифицируем
_local/modules/data/{genModId}/amiro.whos_online/code/AmiClean_WhosOnline_Frn.php
- Укажем в контроллере модуля на наличие спецблока.
class AmiClean_WhosOnline_Frn extends Hyper_AmiClean_Frn{
public function __construct(AMI_Request $oRequest, AMI_Response $oResponse){
parent::__construct($oRequest, $oResponse);
if($this->isSpecblock()){
// Если модуль инициализирован в режиме спецблока, то
// для отображения будет использована компонента типа 'specblock'
$this->addComponents(array('specblock'));
}
}
}
2. Укажем в контроллере компоненты спецблока, что спецблок не использует
модель данных.
class AmiClean_WhosOnline_SpecblockFrn extends AMI_ModSpecblock{
protected $useModel = FALSE;
}
3. В методе отображении спецблока выполним обработку сета specblock шаблона
модуля с передачей в него необходимых данных.
class AmiClean_WhosOnline_SpecblockViewFrn extends Hyper_AmiClean_ComponentViewFrn{
public function get(){
// Данные необходимые спецблоку на клиенте
$aScope = array(
// ID текущей инстанции модуля
'modId' => $this->getModId(),
// Страница профиля пользователя
'membersLink' => AMI_PageManager::getModLink('members', AMI_Registry::get('lang'))
);
return $this->parse('specblock', $aScope);
}
}
4. В шаблоне модуля пропишем сет спецблока.
_local/modules/data/{genModId}/amiro.whos_online/distrib/configs/ami_clean/whos_online/templates_frn/--modId--.tpl
##--system info: module_owner="##section##" module="##modId##" system="1"--##
%%include_language "templates/lang/modules/##modId##.lng"%%
<!--#set var="specblock" value="
##-- Контейнер для отображения данных --##
<h2>%%users_online%%</h2>
<div id="whos_online"></div>
<script>
var membersLink = '##membersLink##';
##-- Параметры запроса к вебсервису --##
var aParams = {
service: 'ami_webservice',
action: 'whos_online.get',
appToken: 'app_token_public',
version: '1.1',
modId : '##modId##',
fullEnv: 1
};
##-- Запрос к вебсервису --##
$.getJSON(frontBaseHref + 'ami_service.php', aParams, function(data){
##-- Получение результатов запроса и заполнение данных спецблока --##
var aData = (typeof(data.data) != 'undefined') ? data.data : {};
if((typeof(aData.errorCode) == 'undefined') || (aData.errorCode != 'OK')){
$('#whos_online').html('%%error_message%%');
return;
}
// Ссылка на профиль пользователя
var profileLink= frontBaseHref + '/' + membersLink + '?action=view&id=';
for(var i=0; i<aData.online.length; i++){
var aMember = aData.online[i];
var username = (aMember.nickname != '') ? aMember.nickname : aMember.login;
var memberHTML = '<a href="' + profileLink + aMember.id + '">' + aMember.login + '</a> ';
$('#whos_online').append(memberHTML);
}
});
</script>
"-->
5. В файл локализаций модуля добавим необходимые языковые переменные.
_local/modules/data/{genModId}/amiro.whos_online/distrib/configs/ami_clean/whos_online/locales_frn/--modId--.lng
%%users_online%en%%
Users online
%%users_online%ru%%
Сейчас на сайте
%%error_message%en%%
Data error!
%%error_message%ru%%
Ошибка получения данных!
6. Добавим в Meta-файл модуля заголовки и описание спецблока.
_local/modules/data/{genModId}/amiro.whos_online/code/AmiClean_WhosOnline_Meta.php
protected $aCaptions = array(
'' => array(
'specblock' => array(
'obligatory' => TRUE,
'type' => self::CAPTION_TYPE_STRING,
'locales' => array(
'en' => array(
'name' => 'Specblock caption for Site Manager',
'caption' => 'Who is online now',
),
'ru' => array(
'name' => 'Название спецблока для менеджера сайта',
'caption' => 'Кто сейчас на сайте',
),
),
),
),
);
6. Поскольку, спецблок не имеет настроек, удалим файлы:
_local/modules/data/{genModId}/amiro.whos_online/distrib/configs/ami_clean/whos_online/declaration/options.php
_local/modules/data/{genModId}/amiro.whos_online/distrib/configs/ami_clean/whos_online/declaration/rules.php
7. В файле свойств модуля оставим следующие
строки
_local/modules/datа/{genModId}/amiro.whos_online/distrib/configs/ami_clean/whos_online/declaration/properties.php
<?php
// {{}}
if($oDeclarator->isRegistered('##modId##')){
$oMod = $oDeclarator->getModule('##modId##');
$oMod->setProperty('front_request_types', array('plain'));
$oMod->setProperty('dont_show_in_pm', true);
$oMod->setProperty('spec_blocks', array('spec_small_##modId##'));
}
На этом основная часть разработки решения завершена. Остается поправить
содержимое файла manifest.xml и собрать архив дистрибутива в модуле "«Генератор
решений».