Делегирование в плагинах

Решил не засорять топик с руководством по созданию плагинов, напишу тут, что нашел в процессе тестирования.

Итак, по порядку, что уже было:
1) (fixed) ошибка с определением названия экшена при делегировании: создал тикет
2) предложение об автоподстановке префиксов делегатов ( livestreet.ru/blog/dev_documentation/3710.html#comment59803, пункт 2 )
3) (fixed) отсутствие поддержки делегирования на основе данных из xml-файла (по-видимому, функция просто ещё в разработке)

И теперь ещё кое-какие мысли (пока все в файле /engine/classes/ActionPlugin.class.php).

— Сейчас, при делегировании экшена (например {plugin_dir}/classes/actions/ActionSettings.class.php) происходит автоматическое делегирование соответствующей директории темплейтов, что не очень хорошо, т.к. это совершенно необязательно по логике и придется тупо копировать всю папку actions/ActionSettings в плагин.
Сейчас там проверяется только наличие в плагине папки с соответствующим шаблоном:
$sTemplateName=in_array(Config::Get('view.skin'),array_map('basename',glob(Config::Get('path.root.server').'/plugins/'.$aMatches[1].'/templates/skin/*',GLOB_ONLYDIR)))
				? Config::Get('view.skin')
				: 'default';

хорошо бы проверять наличие папки с соответствующим экшеном:
$fGetTpl = create_function('$sPath','preg_match("/skin\/([\w]+)\/actions/i",$sPath,$aMatches); return $aMatches[1];');
$sTemplateName=in_array(Config::Get('view.skin'),array_map($fGetTpl,glob(Config::Get('path.root.server').'/plugins/'.$aMatches[1].'/templates/skin/*/actions/Action'.ucfirst($aMatches[2]),GLOB_ONLYDIR)))
				? Config::Get('view.skin')
				: 'default';


— В методе SetTemplateAction() код
$this->getTemplatePathPlugin().'/actions/Action'.ucfirst($aMatches[2]).'/'.$sTemplate.'.tpl'
в случае без делегирования вернет /actions/ActionSettings/profile.tpl, а надо actions/ActionSettings/profile.tpl, поэтому первый слэш переносим отсюда в getTemplatePathPlugin():
$sDir=Config::Get('path.root.server')."/plugins/{$aMatches[1]}/templates/skin/{$sTemplateName}/";


— Дублирование кода в GetTemplate() лучше заменить на
if (is_null($this->sActionTemplate)) {
    $this->SetTemplateAction($this->sCurrentEvent);
}


— В дополнение к первому:
Чаще всего нужно изменить не все шаблоны экшена, а только некоторые, зачем же копировать не измененные? Сделаем проверку, есть ли они в делегирующей папке, и, если нет, вернем стандартные:
protected function SetTemplateAction($sTemplate) {
if($sActionTemplate=preg_match('/^Plugin([\w]+)_Action([\w]+)$/i',$this->GetActionClass(),$aMatches)) {
      $sTplFile = 'actions/Action'.ucfirst($aMatches[2]).'/'.$sTemplate.'.tpl';
      $sActionTemplate = is_file($this->getTemplatePathPlugin().$sTplFile)
        ? $this->getTemplatePathPlugin().$sTplFile
        : $sTplFile;
    }
    $this->sActionTemplate = $sActionTemplate;
	}


Вот такие вот мысли.
Что скажете?

PS — также с нетерпением ждем описания функционала кастомных модулей.

11 комментариев

avatar
Ну что тут сказать? Сама идея с плагинами и делегированием — это весчь. Но ее реализации до идеала еще далеко. Поэтому я пошел своим путем — написал хелпер, в котором реализовал то, чего мне в плагинах пока не хватает. И хелпер этот будет в составе админки для 0.4. Если публике интересно будет, то распишу потом, что это, зачем, и как юзается.

А так верно пишешь все. Только вот еще с терминами бы разобраться, чтоб друг друга лучше понимать: что есть «делегат», кто есть «делегирующий», а кто «делегируемый» и т.д.
avatar
Ну я предполагаю так: делегируемый объект — это тот, который мы заменяем на свой — делегирующий объект или делегат.
avatar
Кстати, исправление ошибки 1) ведет к необходимости переопределять все шаблоны. Нужно учитывать факт переименования ActionClass в стандартном GetTemplate() — сейчас протестирую еще несколько раз и закомичу фиксы.
avatar
а поподробнее, где это вылезает? я уже достаточно крупный плагин написал с моими вариантами фиксов, вроде бы все гладко…
avatar
Посмотри последний коммит =)

Если мы делегируем экшен, унаследованный от существующего экшена, и внутри экшена имеем ручную установку еванта для выбора шаблона, то по твоей системе вылазила неопределенность. Уже устранено.
avatar
Здорово :)
avatar
Продолжаю переписывать Афишу под 0.4, ещё несколько, на мой взгляд, важных замечаний относительно функционала наших плагинов:

1. Замена "_" на префикс темплейта, а также автоопределение значения from происходит только при сканировании XML-файла. А, например при обычном protected $aDelegates = array(...) этого, к сожалению, не происходит и приходится писать длинные пути вручную.

2. Делегирование подключаемых ({include file="*.tpl"}) шаблонов обрабатывается только в случае, если для них были вручную прописаны делегаты, в отличие от автоматического делегирования шаблонов, вызываемых, например через $this->SetTemplateAction('bill'),
т.к. в первом случае проверяется лишь наличие сохраненного делегата Plugin_GetDelegate('template','...') а во втором добросовестно проверяется наличие нужного шаблона в папке обрабатываемого экшена.
По моему надо сделать такой функционал для обоих случаев, грубо говоря (на уровне пользователя) надо автоматически делегировать все шаблоны, которые у нас есть в папке нужного экшена. Ещё как вариант можно сделать что-то вроде: {include file="*.tpl" delegate=«true»} ну или что-то другое, если автоматическое делегирование почему-то не подходит.

3. В плагине есть возможность размещения нескольких модулей, но директории language и config не проверяются на наличие подпапки modules, подключаются только соответственно лежащие в самих этих папках russian.php и config.php. Иначе говоря, у меня не получилось разделить языковые файлы двух модулей одного плагина.
avatar
1. да
2. по идеи это два механизма предназначенные для разных целей, поэтому и ведут себя по разному. Хотя над делегированием всех шаблонов экшена можно подумать
3. вообще с введением плагинов модули должны перестать быть отдельными функциональными элементами, их роль — это внутренняя библиотека плагина. Т.е. модуль(0.3)->плагин(0.4), а модуль(0.4)->либа, поэтому актуальность конфигов и языковых файлов должна присутствовать только у плагинов
комментарий был удален
avatar
насчет 3го я понял, а что касается 1 и 2, по-моему все таки нужно просто вынести оба функционала в отдельные методы и вызывать их во всех 4-ых случаях. иначе сейчас все довольно неудобно, потому что ещё не до конца допилены функции механизма.
avatar
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.