Всем привет!
Чтож в данной статье вернемся к теме RSS Агрегатора. Однако, рассмотрим не саму его работу, а процесс создания мини приложения начиная с Мастера, заканчивая Гаджетом.
[spoiler]
すたると!:
Как-то возникла задача написания RSS Агрегатора, который бы собирал новости с других сайтов и сохранял бы в инфоблоке для последующего вывода и поиска по ним. Ну, а для большей наглядности желательно было наличие Гаджета, который бы позволял выводить группу источников, либо какие-то конкретные для отображения.
Process:
1. Написание Мастера:
Для этого нам потребуется описать файл .description
Где очень важным является параметр STEPS названия которых в последствии будут названиями классов в самом мастере.
Далее приступим к созданию самого мастере. Рассмотрим файл wizard.php, который является так сказать самой базой мастера — выполняемым кодом. Взглянем поближе на создание шагов, ранее мы описали шаг Start, соответственно класс нашего шага должен называться Start и расширять базовый класс CwizardStep. В моем примере используется CWRSSAggregator, т.к. класс был расширен своими дополнительными методами для упрощения последующей работы мастера
InitStep() — метод который инициализирует основные параметры шага
$this->SetTitle() — устанавливает заголовок окна
$this->SetNextStep() — устанавлиает название шага, на который будет произведен по клику по кнопке «Далее\Вперед»
$this->SetStepID('start'); — устанавлиает название текущего шага
$this->SetCancelStep(); — устанавлиает название шага, на который будет произведен по клику по кнопке «Назад\Отмена»
ShowStep() — метод внутри которого формируется тело мастера. Содержимое тела хранится в свойстве класса $this->content
OnPostForm() — метод внутри которого производится обработка шага, т.е. Получение и обработка входных параметров с последующем переходом на другой шаг, либо выводом сообщения об ошибке. Если ошибок не будет то произойдет переход к следующему шагу, в нашем примере это $this->SetNextStep('step1');
Подобным образом формируются все необходимые шаги мастера для достижения нашей цели. В нашей реализации получилось 16 шагов из которых более половины автоматические, За автоматическую отправку формы отвечает $this->SetAutoSubmit(); в Init() методе. Это Довольно удобный инструмент, когда наше решение довольно громоздкое и мы не уверены, что все корректно выполнитеся, запишется итд за 1 шаг.
Более детальную информацию о мастерах Вы можете найти в нашей документации:
http://dev.1c-bitrix.ru/api_help/main...common.php
В процессе работы данного мастера производится копирование
компонента в /bitrix/components/samiko/
гаджета в /bitrix/gadgets/samiko/
основного класса RSS Агрегатора в /bitrix/php_interface/samiko/rss_aggregator/
Der Aggregator!:
Сам агрегатор по себе довольно простой, содержит 4 файла
rss_aggregator.php — основной класс
rss_exception.php — класс исключений\ошибок
rss_install.php — класс установки\удаления мастера
rss_model.php — класс логики агрегатора
Что же происходит в целом: когда мы устанавливаем решение через мастер, дополнительно создается информационный блок с настройками (RSS фидам) и устанавливается связь агрегатора и инфоблока.
Далее при работе мастера, компонента, гаджета связь будет проверяться. Это позволяет нам избавится от запоминания не нужных настроек и параметров, что очень удобно для конечных пользователей.
Работа агрегатора это отдельная история, если кого-то заинтересуют, то сообщите, обязательно напишу развернутое описание работы с описанием внутреннего API.
Пока что необходимо знать о 2х основных методах:
CRSSAggregator::RunRSS($amount = false) — ручной запуск работы агрегатора, который производит сбор новостей, статей с других сайтов
CRSSAggregator::runAgentRSS($amount = false) — запуск работы агрегатора для агента, который производит сбор новостей, статей с других сайтов
Оба метода имеют один единственный входной параметр — $amount, это число запрашиваемых feed'ов, за 1 проход, лично я бы не рекомендовал устанавливать данное значение более чем в 3. Пустой параметр, означает запросить все.
Гаджет~
Наступила очередь и гаджета, у него 3 основных файла, так называемый минимум:
.description.php — общее описание
.parameters.php — описание параметров
index.php — код, шаблон гаджета
Сам код довольно простой, в нем мы только проверяем 1 из входных параметров и подключаем компонент.
В целом мы украдкой посмотрели как реализовать свое решение на примере RSS Агрегатора.
Исходники решенияздесь
Updated:
Добавлены события:
1) "rssaggregator", "OnBeforeRSSAggregatorElementAdd"
2) "rssaggregator", "OnAfterRSSAggregatorRequest"
3) "rssaggregator", "OnRSSAggregatorElementPrepare"
4) "rssaggregator", "OnBeforeRSSAggregatorElementAdd"
Чтож в данной статье вернемся к теме RSS Агрегатора. Однако, рассмотрим не саму его работу, а процесс создания мини приложения начиная с Мастера, заканчивая Гаджетом.
[spoiler]
すたると!:
Как-то возникла задача написания RSS Агрегатора, который бы собирал новости с других сайтов и сохранял бы в инфоблоке для последующего вывода и поиска по ним. Ну, а для большей наглядности желательно было наличие Гаджета, который бы позволял выводить группу источников, либо какие-то конкретные для отображения.
Process:
1. Написание Мастера:
Для этого нам потребуется описать файл .description
<? if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); $arWizardDescription = Array( "NAME" => GetMessage('WZ_DESCRIPTION_TITLE'), "DESCRIPTION" => GetMessage('WZ_DESCRIPTION_DESCRIPTION'), "ICON" => "", "COPYRIGHT" => GetMessage('WZ_DESCRIPTION_COPY'), "VERSION" => "0.3.3b", "STEPS" => Array( "Start", "Step1", "Step2", "Step3", "Step4", "Step5", "Step6", "Step7", "Step8", "Step9", "Step10", "CancelStep", "ErrorStep", "RollBack", "FinalStep", "ExistsStep" ), ); ?> |
Далее приступим к созданию самого мастере. Рассмотрим файл wizard.php, который является так сказать самой базой мастера — выполняемым кодом. Взглянем поближе на создание шагов, ранее мы описали шаг Start, соответственно класс нашего шага должен называться Start и расширять базовый класс CwizardStep. В моем примере используется CWRSSAggregator, т.к. класс был расширен своими дополнительными методами для упрощения последующей работы мастера
//start wizard class Start extends CWRSSAggregator { function InitStep() { $this->SetTitle(GetMessage('WZ_RSSAGRREGATOR_START_TITLE')); $this->SetNextStep('step1'); $this->SetStepID('start'); $this->SetCancelStep('cancel'); } function OnPostForm() { $Settings = $this->GetSettings(); $wizard = &$this->GetWizard(); if(isset($Settings["RSS_INSTALL"]) && $Settings["RSS_INSTALL"] =='Y' && $wizard->IsNextButtonClick())//already installed $wizard->SetCurrentStep("existsstep"); } function ShowStep() { $Settings = $this->GetSettings(); $this->content .= ' <style type="text/css"> ul {list-style: none} small {color:red} </style> '; $this->content .= GetMessage('WZ_RSSAGRREGATOR_START_CONTENT_1'); if(isset($Settings["RSS_INSTALL"]) && $Settings["RSS_INSTALL"] =='Y')//already installed $this->content .= '<br/>
} } |
InitStep() — метод который инициализирует основные параметры шага
$this->SetTitle() — устанавливает заголовок окна
$this->SetNextStep() — устанавлиает название шага, на который будет произведен по клику по кнопке «Далее\Вперед»
$this->SetStepID('start'); — устанавлиает название текущего шага
$this->SetCancelStep(); — устанавлиает название шага, на который будет произведен по клику по кнопке «Назад\Отмена»
ShowStep() — метод внутри которого формируется тело мастера. Содержимое тела хранится в свойстве класса $this->content
OnPostForm() — метод внутри которого производится обработка шага, т.е. Получение и обработка входных параметров с последующем переходом на другой шаг, либо выводом сообщения об ошибке. Если ошибок не будет то произойдет переход к следующему шагу, в нашем примере это $this->SetNextStep('step1');
Подобным образом формируются все необходимые шаги мастера для достижения нашей цели. В нашей реализации получилось 16 шагов из которых более половины автоматические, За автоматическую отправку формы отвечает $this->SetAutoSubmit(); в Init() методе. Это Довольно удобный инструмент, когда наше решение довольно громоздкое и мы не уверены, что все корректно выполнитеся, запишется итд за 1 шаг.
Более детальную информацию о мастерах Вы можете найти в нашей документации:
В процессе работы данного мастера производится копирование
компонента в /bitrix/components/samiko/
гаджета в /bitrix/gadgets/samiko/
основного класса RSS Агрегатора в /bitrix/php_interface/samiko/rss_aggregator/
Der Aggregator!:
Сам агрегатор по себе довольно простой, содержит 4 файла
rss_aggregator.php — основной класс
rss_exception.php — класс исключений\ошибок
rss_install.php — класс установки\удаления мастера
rss_model.php — класс логики агрегатора
Что же происходит в целом: когда мы устанавливаем решение через мастер, дополнительно создается информационный блок с настройками (RSS фидам) и устанавливается связь агрегатора и инфоблока.
Далее при работе мастера, компонента, гаджета связь будет проверяться. Это позволяет нам избавится от запоминания не нужных настроек и параметров, что очень удобно для конечных пользователей.
Работа агрегатора это отдельная история, если кого-то заинтересуют, то сообщите, обязательно напишу развернутое описание работы с описанием внутреннего API.
Пока что необходимо знать о 2х основных методах:
CRSSAggregator::RunRSS($amount = false) — ручной запуск работы агрегатора, который производит сбор новостей, статей с других сайтов
CRSSAggregator::runAgentRSS($amount = false) — запуск работы агрегатора для агента, который производит сбор новостей, статей с других сайтов
Оба метода имеют один единственный входной параметр — $amount, это число запрашиваемых feed'ов, за 1 проход, лично я бы не рекомендовал устанавливать данное значение более чем в 3. Пустой параметр, означает запросить все.
Гаджет~
Наступила очередь и гаджета, у него 3 основных файла, так называемый минимум:
.description.php — общее описание
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); $arDescription = Array( "NAME"=>GetMessage("GD_RSS_AGG_READER_NAME"), "DESCRIPTION"=>GetMessage("GD_RSS_AGG_READER_DESC"), "ICON"=>"", "GROUP"=> Array("ID"=>"services"), ); ?> |
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); $arRssOptions = unserialize(COption::GetOptionString('iblock', 'rssagrregator_settings')); if(!CModule::IncludeModule("iblock") || !($arRssOptions["RSS_INSTALL"]=="Y") || (intval($arRssOptions["RSS_IB_ID"])<=0) || (intval($arRssOptions["RSS_IB_RESULT_ID"])<=0)) return; $arRSSSourcesAllowedType = array( "NONE" => '-', "SECTION" => GetMessage('GD_RSS_AGG_READER_ALLOWED_BY_GROUP'), "ID" => GetMessage('GD_RSS_AGG_READER_ALLOWED_BY_SOURCE') ); $arParameters = Array( "PARAMETERS"=> Array( "CACHE_TIME" => array( "NAME" => GetMessage("GD_RSS_AGG_READER_CACHE_TIME"), "TYPE" => "STRING", "DEFAULT" => "3600" ), "ALLOWED_SOURCE_TYPE" => Array( "NAME" => GetMessage("GD_RSS_AGG_READER_ALLOWED_SOURCE_TYPE"), "TYPE" => "LIST", "VALUES" => $arRSSSourcesAllowedType, "MULTIPLE" => "N", "REFRESH" => "Y" ), ), "USER_PARAMETERS" => Array( "CNT" => Array( "NAME" => GetMessage("GD_RSS_AGG_READER_CNT"), "TYPE" => "STRING", "MULTIPLE" => "N", "DEFAULT" => "10", ), ), ); if(is_array($arCurrentValues)) { if(in_array($arCurrentValues["ALLOWED_SOURCE_TYPE"], array_keys($arRSSSourcesAllowedType)) && $arCurrentValues["ALLOWED_SOURCE_TYPE"]!='NONE') { $arRSSSources = array(); $SelectType = false; if($arCurrentValues["ALLOWED_SOURCE_TYPE"] == "ID") { $obRSSSources = CIblockElement::GetList( array(), array( "ACVITE" => "Y", "GLOBAL_ACTIVE" => "Y", "IBLOCK_ID" => $arRssOptions["RSS_IB_ID"], ), false, false, array("NAME", "ID") ); while($arrRSSSources = $obRSSSources->Fetch()) $arRSSSources[$arrRSSSources["ID"]] = $arrRSSSources["NAME"]; } elseif($arCurrentValues["ALLOWED_SOURCE_TYPE"] == "SECTION") { $obRSSSources = CIblockSection::GetList( array(), array( "ACVITE" => "Y", "GLOBAL_ACTIVE" => "Y", "IBLOCK_ID" => $arRssOptions["RSS_IB_ID"], ), false, false, array("NAME", "ID") ); while($arrRSSSources = $obRSSSources->Fetch()) $arRSSSources[$arrRSSSources["ID"]] = $arrRSSSources["NAME"]; $SelectType = ''; } $arParameters["PARAMETERS"]["ALLOWED_SOURCE_LIST"] = Array( "NAME" => GetMessage("GD_RSS_AGG_READER_ALLOWED_SOURCE_LIST"), "TYPE" => "LIST", "VALUES" => $arRSSSources, "MULTIPLE" => "Y", "REFRESH" => "Y" ); $arRSSSourcesAllowed = $arRSSSources; if(count($arCurrentValues["ALLOWED_SOURCE_LIST"])>0) { if(!isset($arCurrentValues["ALLOWED_SOURCE_LIST"][0]) ||(intval($arCurrentValues["ALLOWED_SOURCE_LIST"][0])>0) ) foreach ($arRSSSourcesAllowed as $key=>$value) if(!in_array($key, $arCurrentValues["ALLOWED_SOURCE_LIST"])) unset($arRSSSourcesAllowed[$key]); } $arParameters["USER_PARAMETERS"]["SOURCE_LIST"] = array( "NAME" => GetMessage("GD_RSS_AGG_READER_SOURCE_LIST"), "TYPE" => "LIST", "VALUES" => $arRSSSourcesAllowed, "MULTIPLE" => $arCurrentValues["ALLOWED_SOURCE_TYPE"] == "SECTION"?"N":"Y", ); } } ?> |
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); $arRssOptions = unserialize(COption::GetOptionString('iblock', 'rssagrregator_settings')); if(!CModule::IncludeModule("iblock") || !($arRssOptions["RSS_INSTALL"]=="Y") || (intval($arRssOptions["RSS_IB_ID"])<=0) || (intval($arRssOptions["RSS_IB_RESULT_ID"])<=0)) return; $arGadgetParams["CNT"] = IntVal($arGadgetParams["CNT"]); if($arGadgetParams["CNT"]>25) $arGadgetParams["CNT"] = 25; $APPLICATION->IncludeComponent("samiko:rssaggregator.elements.list", ".default", array( "RSS_SOURCES" => (array)$arGadgetParams["SOURCE_LIST"], "NEWS_COUNT" => $arGadgetParams["CNT"], "CACHE_TYPE" => "A", "CACHE_TIME" => "3600", "ACTIVE_DATE_FORMAT" => "", "DISPLAY_TOP_PAGER" => "N", "DISPLAY_BOTTOM_PAGER" => "N", "PAGER_TITLE" => "", "PAGER_SHOW_ALWAYS" => "N", "PAGER_TEMPLATE" => "", "PAGER_DESC_NUMBERING" => "N", "PAGER_DESC_NUMBERING_CACHE_TIME" => "36000", "PAGER_SHOW_ALL" => "N", "ALLOWED_SOURCE_TYPE" => $arGadgetParams["ALLOWED_SOURCE_TYPE"], ), false, array("HIDE_ICONS"=>"Y") );?> |
В целом мы украдкой посмотрели как реализовать свое решение на примере RSS Агрегатора.
Исходники решения
Updated:
Добавлены события:
1) "rssaggregator", "OnBeforeRSSAggregatorElementAdd"
2) "rssaggregator", "OnAfterRSSAggregatorRequest"
3) "rssaggregator", "OnRSSAggregatorElementPrepare"
4) "rssaggregator", "OnBeforeRSSAggregatorElementAdd"