Пример создания модуля
57
Попробуем на примере создать очень простой модуль/дополнение для LiveStreet. Сразу стоит оговориться, что под модулем в LiveStreet подразумевается некая библиотека дополнительного функционала, а не какой то законченный блок функционала. Модуль это только его часть. Надеюсь понятно смог объяснить, а теперь приступим!
Создадим функционал сложения двух чисел, введённых пользователем. Причем если пользователь авторизован, то выводим удвоенную сумму.
Разделим этап разработки такого функционала на несколько этапов:
Замечание: на самом деле для такого простого функционала, как суммирование двух чисел, модуль можно и не создавать, а производить сложение прямо в экшене. Но мы пойдем правильным путем с точки зрения архитектуры движка и создадим простой модуль.
Все модули находяться в каталоге /classes/modules/, каждый в своей директории. Если модуль системный, т.е. принадлежит ядру движка(даже не движа, а фреймворку), то он имеет префикс sys_. Все пользовательские модули, т.е. модули которые реализуют уже конкретный функционал сайта, не должны иметь этот префикс.
Итак, создаем в каталоге /classes/modules/ каталог mytest, а в нем файл Mytest.class.php следующего содержания(classes/modules/mytest/Mytest.class.php):
Все модули должны быть унаследованы от базового абстрактного класса Module и должны иметь обязательный метод Init(), в котором происходит какая либо инициализация модуля при его запуске. В нашем случаи ничего инициализировать не нужно, просто оставляем метод пустым. Далее мы определяем метод Summ(), это и будет наш основной метод в модуле, который будет производить сложение чисел.
Теперь создадим экшен, для этого в каталоге /classes/actions/ создаем класс экшена ActionSumm.class.php:
Каждый экшен наследуется от родительского класса Action. Обязательными методами являются Init() и RegisterEvent(), в Init() мы определяем какой евент будет запускаться по умолчанию(он у нас всего один), а в RegisterEvent() регистрируем все используемые евенты, т.е. привязываем к нему метод для обработки.
В SubmitSumm() проверяем на корректность введённые пользователем данные — два числа для сложения. Если числа введены корректно, то суммируем их.
Пришла очередь шаблона. Все шаблоны лежат в каталоге /templates/skin/название_шаблона/, шаблоны привязанные к экшенам лежат в соответствующих каталогах в /templates/skin/название_шаблона/actions/.
В нашем случаи это будет каталог /templates/skin/habra/actions/ActionSumm/, в нём создадим файлик шаблона summ.tpl:
Если название шаблона(Summ) совпадает с название евента в экшене, то этот шаблон автоматически подключится для вывода.
Теперь осталось разрешить наш экшен в файле роутинга config.route.php. Добавим новую строку в секцию «page»:
Этим мы открываем доступ к нашей страничке вида
Всё, новый функционал движка готов к работе!
Надеюсь данный топик будет полезным любителям-копателям :)
Создадим функционал сложения двух чисел, введённых пользователем. Причем если пользователь авторизован, то выводим удвоенную сумму.
Разделим этап разработки такого функционала на несколько этапов:
- создание модуля, где собственно сложение и будет происходить
- создание шаблона странички, где пользователь будет вводить данные и видеть результат
- создание экшена сложения
Замечание: на самом деле для такого простого функционала, как суммирование двух чисел, модуль можно и не создавать, а производить сложение прямо в экшене. Но мы пойдем правильным путем с точки зрения архитектуры движка и создадим простой модуль.
Все модули находяться в каталоге /classes/modules/, каждый в своей директории. Если модуль системный, т.е. принадлежит ядру движка(даже не движа, а фреймворку), то он имеет префикс sys_. Все пользовательские модули, т.е. модули которые реализуют уже конкретный функционал сайта, не должны иметь этот префикс.
Итак, создаем в каталоге /classes/modules/ каталог mytest, а в нем файл Mytest.class.php следующего содержания(classes/modules/mytest/Mytest.class.php):
<?
class LsMytest extends Module {
public function Init() {
}
public function Summ($iFirst,$iSecond) {
$iResult=$iFirst+$iSecond;
// если юзер авторизован то удваиваем сумму
if ($this->User_IsAuthorization()) {
$iResult=$iResult*2;
}
return $iResult;
}
}
?>Все модули должны быть унаследованы от базового абстрактного класса Module и должны иметь обязательный метод Init(), в котором происходит какая либо инициализация модуля при его запуске. В нашем случаи ничего инициализировать не нужно, просто оставляем метод пустым. Далее мы определяем метод Summ(), это и будет наш основной метод в модуле, который будет производить сложение чисел.
Теперь создадим экшен, для этого в каталоге /classes/actions/ создаем класс экшена ActionSumm.class.php:
<?
class ActionSumm extends Action {
public function Init() {
$this->SetDefaultEvent('summ');
}
protected function RegisterEvent() {
$this->AddEvent('summ','EventSumm');
}
protected function EventSumm() {
//обрабатываем отправку формы
$this->SubmitSumm();
}
protected function SubmitSumm() {
// если не было отправки формы то завершаем обработку
if (!getRequest('submit_summ')) {
return;
}
// проверяем корректность ввода чисел
$bOk=true;
if (!func_check(getRequest('summ_a'),'id')) {
$this->Message_AddError('Параметр А не является числом','Ошибка');
$bOk=false;
}
if (!func_check(getRequest('summ_b'),'id')) {
$this->Message_AddError('Параметр B не является числом','Ошибка');
$bOk=false;
}
if ($bOk) {
// вызываем метод модуля для подсчета суммы
$iResult=$this->Mytest_Summ(getRequest('summ_a'),getRequest('summ_b'));
$this->Message_AddNotice('Сумма: '.$iResult);
}
}
}
?>Каждый экшен наследуется от родительского класса Action. Обязательными методами являются Init() и RegisterEvent(), в Init() мы определяем какой евент будет запускаться по умолчанию(он у нас всего один), а в RegisterEvent() регистрируем все используемые евенты, т.е. привязываем к нему метод для обработки.
В SubmitSumm() проверяем на корректность введённые пользователем данные — два числа для сложения. Если числа введены корректно, то суммируем их.
Пришла очередь шаблона. Все шаблоны лежат в каталоге /templates/skin/название_шаблона/, шаблоны привязанные к экшенам лежат в соответствующих каталогах в /templates/skin/название_шаблона/actions/.
В нашем случаи это будет каталог /templates/skin/habra/actions/ActionSumm/, в нём создадим файлик шаблона summ.tpl:
{include file='header.tpl'}
{include file='system_message.tpl'}
<form method="POST">
A: <input type="text" name="summ_a" value="{$_aRequest.summ_a}">
B: <input type="text" name="summ_b" value="{$_aRequest.summ_b}">
<input type="submit" name="submit_summ" value="Посчитать!">
</form>
{include file='footer.tpl'}Если название шаблона(Summ) совпадает с название евента в экшене, то этот шаблон автоматически подключится для вывода.
Теперь осталось разрешить наш экшен в файле роутинга config.route.php. Добавим новую строку в секцию «page»:
'summ' => 'ActionSumm',Этим мы открываем доступ к нашей страничке вида
Всё, новый функционал движка готов к работе!
Надеюсь данный топик будет полезным любителям-копателям :)
- +27
- 21 октября 2008, 11:11
- ort
Буду иметь ввиду. Как раз было желание сделать модуль «Компании» как на хабре… уж очень нужно.

- BisnoyZakat
- 22 октября 2008, 11:15
- ↓
Дело не в том, хорош он или плох… дело в том, что для моего проекта нужен этот модуль… в ливстрите его нет…

- BisnoyZakat
- 22 октября 2008, 11:48
- ↑
- ↓
Проект который я делаю привязан к Казахстану. Я хочу чтобы был блок компании где ведется Рейтинг наших Казахстанских компаний. Одно дело когда вы видите названия компании к которым не имеете никакого отношения… другое дело когда большинство этих компаний находятся в вашем городе и вы быть может в них работали.
Опять же в контексте моего проекта это будет еще и гайдлайн по казахстанским компаниям.
Опять же в контексте моего проекта это будет еще и гайдлайн по казахстанским компаниям.

- BisnoyZakat
- 22 октября 2008, 12:36
- ↑
- ↓
комментарий был удален
комментарий был удален
Попробовал поставить простейший модуль, форма ввода 2-х чисел появляется, кнопка «Посчитать», при нажатии выдает такое:Fatal error: Uncaught exception 'Exception' with message 'Не найден класс модуля — Mytest' in /*******/classes/engine/Engine.class.php:95 Stack trace: #0 /******/classes/engine/Engine.class.php(140): Engine->LoadModule('Mytest', true) #1 /*******/classes/engine/Action.class.php(258): Engine->_CallModule('Mytest_Summ', Array) #2 [internal function]: Action->__call('Mytest_Summ', Array) #3 /******/classes/actions/ActionSumm.class.php(33): ActionSumm->Mytest_Summ('5', '8') #4 /*********/classes/actions/ActionSumm.class.php(13): ActionSumm->SubmitSumm() #5 /*******/classes/engine/Action.class.php(103): eval()'d code(1): ActionSumm->EventSumm() #6 /*******/classes/engine/Action.class.php(103): eval() #7 /******/classes/engine/Router.class.php(140): Action->ExecEv in /*******/classes/engine/Engine.class.php on line 95
Добрый день. Делаю каталог программ.
Подскажите, пожалуйста, каким образом прописать в роутинг такие страницы:
/programm/
/programm/{prog_name}/
/programm/{prog_name}/{prog_version}/
на выходе урлы имеют такой вид:
/programm/
/programm/acemoney/
/programm/acemoney/1.2.3/
В методе
делаю заглушки для эти методы, но третий урл не подхватывается, все время отрабатывает второй урл.
Мне не нужно конкретное решение этой проблемы, хочется понимания того, каким образом работает AddEventPreg.
Я правильно понимаю?
prog_name может быть только латинской буквой, подчеркиванием или тире.
prog_version: число или несколько чисел, разделенных точкой.
Но это не суть важно, главное понять принцип. В коде не смог его «прочесть», каюсь.
Подскажите, пожалуйста, каким образом прописать в роутинг такие страницы:
/programm/
/programm/{prog_name}/
/programm/{prog_name}/{prog_version}/
на выходе урлы имеют такой вид:
/programm/
/programm/acemoney/
/programm/acemoney/1.2.3/
В методе
<code>protected function RegisterEvent() {
$this->AddEvent('programm',
'EventProgrammList');
$this->AddEventPreg('/^([0-9_A-Za-z-]+)$/i',
'EventProgrammItem');
$this->AddEventPreg('/^([0-9_A-Za-z-]+)$/i',
'^(([0-9]+)([0-9\.]+))+$/i',
'EventProgrammItemVersion');
}</code>делаю заглушки для эти методы, но третий урл не подхватывается, все время отрабатывает второй урл.
Мне не нужно конкретное решение этой проблемы, хочется понимания того, каким образом работает AddEventPreg.
<code>protected function RegisterEvent() {
$this->AddEvent('programm',
'EventProgrammList');
$this->AddEventPreg('/^регэксп_для_prog_name$/i',
'EventProgrammItem');
$this->AddEventPreg('/^регэксп_для_prog_name$/i',
'^регэксп_для_prog_version$/i',
'EventProgrammItemVersion');
}</code>Я правильно понимаю?
prog_name может быть только латинской буквой, подчеркиванием или тире.
prog_version: число или несколько чисел, разделенных точкой.
Но это не суть важно, главное понять принцип. В коде не смог его «прочесть», каюсь.
вот так:
но чтоб не плодить разные евенты можно сделать так:
AddEventPreg работает очень просто — первый параметр это шаблон евента, а остальные шаблоны параметров
<code>$this->AddEvent('_list','EventProgrammList');
$this->AddEventPreg('/^[a-z\-\_]+$/i','/^$/','EventProgrammItem');
$this->AddEventPreg('/^[a-z\-\_]+$/i','/^[a-z\-\_\.]+$/i','EventProgrammItemVersion');</code>но чтоб не плодить разные евенты можно сделать так:
<code>$this->AddEvent('_list','EventProgrammList');
$this->AddEventPreg('/^[a-z\-\_]+$/i','/^([a-z\-\_\.]+)?$/i','EventProgrammItem');</code>в таком случаи номер версии можно доставать в EventProgrammItem.AddEventPreg работает очень просто — первый параметр это шаблон евента, а остальные шаблоны параметров
Большое спасибо за обстоятельный ответ!
>>AddEventPreg работает очень просто — первый параметр это шаблон евента,
>>а остальные шаблоны параметров
Максим, в моем случае event — это будет название программы, а параметр это версия программы? Я правильно понял?
причем судя по короткой записи параметр может как использоваться, так и нет.
Т.е. вышеописанное добавление event сработает
и при таком урл
и при таком урл
да?
>>AddEventPreg работает очень просто — первый параметр это шаблон евента,
>>а остальные шаблоны параметров
Максим, в моем случае event — это будет название программы, а параметр это версия программы? Я правильно понял?
<code>$this->AddEventPreg('/^[a-z\-\_]+$/i','/^([a-z\-\_\.]+)?$/i','EventProgrammItem');</code>причем судя по короткой записи параметр может как использоваться, так и нет.
Т.е. вышеописанное добавление event сработает
и при таком урл
<code>/programm/acemoney/</code>
и при таком урл
<code>/programm/acemoney/1.2.3/</code>
да?
Предлагаю идею: роутинг попробовать делать на основе полного урл, т.е.
собирать в роутер все варианты урл, потом на входе смотреть — попадает ли запрашиваемый хотя бы под один шаблон зарегистрированных, далее получать из него название Action и запускаемого в нем EventMethod.
Прозрачность формирования роутинга увеличивается и многое упрощается.
Причем если будет зарегистрирован к примеру такой маршрут:
для показа страницы пользователя, то получается у нас в верхнем уровне две страницы:
'/([0-9_A-Za-z-]+)/' и '/programm/', так вот при запросе урл '/programm/' сперва искать четкое совпадение, а потом по регуляркам сравнивать, и в данном примере выводить страницу со списокм программ, а не персональную карточку участника с ником «programm».
Подумайте на досуге.
<code>
$this->AddRoute('/programm/',
'ActionName1',
'EventMethod1');
$this->AddRoute('/programm/([0-9_A-Za-z-]+)/',
'ActionName2',
'EventMethod2');
$this->AddRoute('/programm/([0-9_A-Za-z-]+)/([0-9][0-9\.]+)',
'ActionName3',
'EventMethod3');</code>собирать в роутер все варианты урл, потом на входе смотреть — попадает ли запрашиваемый хотя бы под один шаблон зарегистрированных, далее получать из него название Action и запускаемого в нем EventMethod.
Прозрачность формирования роутинга увеличивается и многое упрощается.
Причем если будет зарегистрирован к примеру такой маршрут:
<code>$this->AddRoute('/([0-9_A-Za-z-]+)/',
'ActionUser',
'EventShowUserCard');
</code>для показа страницы пользователя, то получается у нас в верхнем уровне две страницы:
'/([0-9_A-Za-z-]+)/' и '/programm/', так вот при запросе урл '/programm/' сперва искать четкое совпадение, а потом по регуляркам сравнивать, и в данном примере выводить страницу со списокм программ, а не персональную карточку участника с ником «programm».
Подумайте на досуге.
роутер не должен знать ни о каких евентах и разных комбинаций экшенов, его задача должна быть максимально проста — запустить нужный экшен, а дальше вся логика в этом экшене.
делать экшен динамический не есть хорошо, этим мы накладываем сами себе ограничения — например, пользователь имеет право иметь логин «programm» и т.п.
Задача стоит в разделении задач, а не делать из них мишанину
делать экшен динамический не есть хорошо, этим мы накладываем сами себе ограничения — например, пользователь имеет право иметь логин «programm» и т.п.
Задача стоит в разделении задач, а не делать из них мишанину
делаю так
на выходе имею
Fatal error: Uncaught exception 'Exception' with message 'Не найден шаблон: actions/ActionEnciclopedy/rty.tpl'
А как явно указать какой шаблон я хочу использовать?
<code>
protected function RegisterEvent()
{
$this -> AddEvent('enciclopedy','CarEnciclopedy');
$this -> AddEventPreg('/.+/','Maker');
}
</code>на выходе имею
Fatal error: Uncaught exception 'Exception' with message 'Не найден шаблон: actions/ActionEnciclopedy/rty.tpl'
А как явно указать какой шаблон я хочу использовать?
Господа, а почему ошибка по Message_AddError вылезает 2 раза? И это касается не только этого, примерного модуля, а вообще.
Простой
Выдает мне 2 предупреждения об ошибке
Простой
if()$this->Message_AddError('Error','Ошиибка');Выдает мне 2 предупреждения об ошибке
сделал все действия но вылетела ошибка при нажатии на кнопку
Fatal error: Class 'LsMytest' not found in C:\apache\localhost\www\classes\engine\Engine.class.php on line 98
была похожая проблема выше «небольшая ошибка: файл класса модуля должен называться не mytest.class.php, а Mytest.class.php»
я исправил с большой буквы но это не помогло…
что может быль не так?
спасибо.
Fatal error: Class 'LsMytest' not found in C:\apache\localhost\www\classes\engine\Engine.class.php on line 98
была похожая проблема выше «небольшая ошибка: файл класса модуля должен называться не mytest.class.php, а Mytest.class.php»
я исправил с большой буквы но это не помогло…
что может быль не так?
спасибо.
Добрый день. Ктонить может подсказать, как сделать чтобы по ссылке, например выводилась php страница?

- MaxSvargal
- 16 июля 2009, 01:35
- ↑
- ↓
Прочитал статью. Мне 15 лет, для меня она немного сложновата. Здесь написано как создать модуль на всю страницу, а можете написать статью как написать модуль в виде блока сбоку на сайте? Просто недавно начал изучать пхп…
Написал отдельный пхп файл выводящий количество строк в таблице, теперь мне как-то нужно это вставить в livestreet
Написал отдельный пхп файл выводящий количество строк в таблице, теперь мне как-то нужно это вставить в livestreet
комментарий был удален
комментарий был удален
комментарий был удален
комментарий был удален
комментарий был удален
Если название шаблона(Summ) совпадает с название евента в экшене, то этот шаблон автоматически подключится для вывода.
А если не совпадёт, как указать какой именно шаблон выводить?
Например, ActionEvent = «a», а шаблон мне нужно вывести «b». Где установить шаблон «b»? В данный момент вижу вот что:
Fatal error: Uncaught exception 'Exception' with message 'Can not find the template: /var/www/site.ru/plugins/my/templates/skin/new/actions/MyAction/b.tpl' in /var/www/site.ru/engine/modules/viewer/Viewer.class.php:272 Stack trace: #0 /var/www/site.ru/engine/classes/Engine.class.php(334): eval()'d code(1): LsViewer->Display('/var/www/site...') #1 /var/www/site.ru/engine/classes/Engine.class.php(334): eval() #2 /var/www/site.ru/engine/classes/Router.class.php(340): Engine->_CallModule('Viewer_Display', Array) #3 [internal function]: Router->__call('Viewer_Display', Array) #4 /var/www/site.ru/engine/classes/Router.class.php(69): Router->Viewer_Display('/var/www/site...') #5 /var/www/site.ru/index.php(36): Router->Exec() #6 {main} thrown in /var/www/site.ru/engine/modules/viewer/Viewer.class.php on line 272
Шаблоны:
"/var/www/мой_сайт/plugins/test/templates/skin/new/actions/ActionTest/test.tpl",
"/var/www/мой_сайт/plugins/test/templates/skin/new/actions/ActionTest/test2.tpl",
Экшен "/var/www/мой_сайт/plugins/test/classes/actions/ActionTest.class.php":
"/var/www/мой_сайт/plugins/test/templates/skin/new/actions/ActionTest/test.tpl",
"/var/www/мой_сайт/plugins/test/templates/skin/new/actions/ActionTest/test2.tpl",
Экшен "/var/www/мой_сайт/plugins/test/classes/actions/ActionTest.class.php":
class PluginTest_ActionTest extends ActionPlugin {
public function Init() {
/*
* Событие по-умолчанию
*/
$this->SetDefaultEvent('test');
}
/*
* Регистрируем все используемые события
*/
protected function RegisterEvent() {
//$this->AddEvent('test','EventTest');
$this->AddEventPreg('/^[a-z\-\_]+$/i','/^([a-z\-\_\.]+)?$/i','EventTest');
}
protected function EventTest() {
$Param1 = Router::GetActionEvent();
$Param2 = $this->GetParam(0);
$Param3 = $this->GetParam(1);
if ($Param1 = 'test') {
$this->SetTemplateAction('test');
} else {
$this->SetTemplateAction('test2');
}
}
/*
* Завершение работы Action`a
*/
public function EventShutdown() {
}
}
Вызываю
Fatal error: Uncaught exception 'Exception' with message 'Can not find the template: /var/www/мой_сайт/plugins/geo/templates/skin/new/actions/ActionTest/test77.tpl' in /var/www/мой_сайт/engine/modules/viewer/Viewer.class.php:272 Stack trace: #0 /var/www/мой_сайт/engine/classes/Engine.class.php(334): eval()'d code(1): LsViewer->Display('/var/www/мой_сайт...') #1 /var/www/мой_сайт/engine/classes/Engine.class.php(334): eval() #2 /var/www/мой_сайт/engine/classes/Router.class.php(340): Engine->_CallModule('Viewer_Display', Array) #3 [internal function]: Router->__call('Viewer_Display', Array) #4 /var/www/мой_сайт/engine/classes/Router.class.php(69): Router->Viewer_Display('/var/www/мой_сайт...') #5 /var/www/мой_сайт/index.php(36): Router->Exec() #6 {main} thrown in /var/www/мой_сайт/engine/modules/viewer/Viewer.class.php on line 272
SetTemplateAction() не работает. Если указываю через SetTemplate(), то получается. Но это неправильно: SetTemplateAction() ведь предназначен для Action, почему он тогда не переопределяет шаблон в экшене плагина?
Оба метода — для установки шаблона. Только файл шаблона в разных местах может лежать — либо в корне скина, либо в подпапке экшена.
SetTemplate() — файл лежит в в общей папке шаблона: templates\skin\название_скина\
SetTemplateAction() — файл лежит в папке с шаблоном экшена: templates\skin\название_скина\actions\MyAction\
SetTemplate() — файл лежит в в общей папке шаблона: templates\skin\название_скина\
SetTemplateAction() — файл лежит в папке с шаблоном экшена: templates\skin\название_скина\actions\MyAction\
Да. Но в случае с экшеном плагина SetTemplateAction, похоже, игнорируется. Прочитайте мой комментарий выше 2randomtoy и попробуйте тоже проделать это, если не трудно. Хочу понять — у меня руки кривые или это баг…
Комментарии (67)
RSS свернуть / развернуть