Некоторые вопросы по разработке плагинов

1
Написал около десятка плагинов, но мне кажется я не все понял о наследовании в 0.4.2

1) как в шаблоне использовать данные конфига для foreach, elseif?
Пример:
{if {cfg name='path.root.web'}}
    это естественно не работает, как правильно?
    если мы делегируем только шаблон и у нас нет возможности присвоить
    переменной значение конфига в блоке/экшене/хуке
{/if}

я пока решаю эту проблему таким костылем

{php}
if ((Config::Get('plugin.name.value')) && $oUserCurrent {
    {/php}
    вот такой костыль
    {php}
}
{/php}


2) Как обстоят дела с наследованием экшенов?
Если мне приходится вмешаться в регистрацию, чтобы добавить проверку, мне приходится переопределять метод класса регистрации, должен быть лучший путь

class PluginExample extends Plugin {

    /**
     * Делегирование регистрации
     */
    public $aInherits = array(
        'action' => array('ActionLogin', 'ActionRegistration', 'ActionTalk'),
    );

    ...
}


class PluginExample_ActionRegistration extends PluginExample_Inherit_ActionRegistration {

    protected function EventIndex() {
    ...
    $this->PluginAntistatist_Antistatist_addLogin($oUser->getLogin());
    ...
    }

выдирать ради этого целый метод это большой костыль. вроде можно повесить свой код на конец или начало выполнения метода модуля регистрации, но что, если надо вывести сделать проверку и в экшене регистрации вывести ошибку, совать ее в модуль не правильно?

3) вот если мне необходимо изменить голосование за топики, строчку

<li class="minus"><a href="#" onclick="lsVote.vote({$oTopic->getId()},this,-5,'topic'); return false;"></a></li>

как мне это лучше сделать? каким образом переопределить файл аякса, принимающий запрос на изменение рейтинга топика, а так же можно ли изменить саму эту строчку, не делегируя целиком шаблоны topic.tpl и topic_list.tpl и закрывая тем самым эти шаблоны от изменения другими плагинами?

Вопрос про делегириование

 
Мне нужно делегировать 3 различных экшена, а точнее наследовать, чтобы изменить в них ивенты


protected $aDelegates = array(
                        'action' => array('ActionTopic'=>'PluginAntispam_ActionTopic')
                        );


Проблема в том, что тут можно прописать только один экшен, иначе каждый последующий перезапишет элемент action массива $aDelegates,
так как же мне несколько делегатов сделать?

Новые возможности по переопределению/наследованию классов LiveStreet

44
В LS появилась новая возможность для разработчиков плагинов — наследование классов. Идея была высказана еще avadim'ом здесь.
Эта возможность позволит удобно переопределять различные методы одного класса (модуля, экшена, сущности, маппера) разными плагинами без конфликтов.
Главное отличие от делегирование — не происходит блокировки переопределения класса для других плагинов. Также есть возможность переопределения одного метода разными плагинами, но здесь разработчикам нужно быть очень осторожными и делать так, чтоб свести вероятность конфликта к минимуму.

Как использовать.
Например, нужно переопределить метод получения пути до аватара у сущности пользователя в плагине Test. В плагине необходимо объявить те классы, которые будут наследоваться. Объявление происходит в свойстве $aInherits:
<?php
class PluginTest extends Plugin {
    
    protected $aInherits=array(
       'entity'  =>array('ModuleUser_EntityUser'=>'_ModuleSide_EntityUser')
    );

    public function Activate() {        
        return true;
    }
    
    public function Init() {        
    }
}
?>


Читать дальше
  • +7
  • 02 июня 2010, 00:28
  • ort

Плагин aceAdminPanel – новые возможности для разработчиков плагинов

16
Прямо так и хочется начать: «Кролики – это не только ценный мех, но и три-четыре килограмма легкоусвояемого мяса» :)

А все потому, что плагин админки (aceAdminPanel) – это не только облегчение работы администратора сайта, но и новые возможности для разработчиков, пишущих различные расширения для движка. Здесь я расскажу об одной интересной фиче, которую я смог реализовать в плагине, и которая дает гораздо больше возможностей при создании плагинов, чем стандартные средства.

Читать дальше

Переопределение методов модулей с помощью ...Hook'ов!

28
В LiveStreet 0.4 появилась возможность переопределять не только целиком модули, но и отдельные методы. Это позволить разным плагинам бесконфликтно переопределять разные методы одного модуля.

Принцип действия этого механизма основан на Hook'ах:
  1. Вызов каждого метода сопровождается выполнением хуков — module_ModuleName_MethodName_before и module_ModuleName_MethodName_after, соответственно ДО и ПОСЛЕ вызова метода модуля. В первом случаи в хук передаются параметры вызова метода, во втором передается результат выполнения метода модуля.
  2. На module_ModuleName_MethodName_before можно повесить специальный хук — delegate, результат выполнения которого и будет «результатом» выполнения метода модуля

Пример:
<?php 
class HookTest extends Hook {
	public function RegisterHook() {
		$this->AddDelegateHook('module_text_parser_before','testHook',__CLASS__,-3);
	}

	public function testHook($aVars) {
		return 'Topic text > '.$aVars[0];
	}
}
?>


Читать дальше
  • +10
  • 26 марта 2010, 17:46
  • ort

Помогите разобраться с делегированием (или хуками)

2
Сделал я плагин для своего сайта. Плагин очень специфический, и вряд ли кому пока пригодится в том виде, какой есть. Но, если есть пожелания по его доработке — пишите, если наши пожелания совпадут, то допилю и поделюсь бесплатно. Вроде как все работает как надо, но для того, чтобы добавить в информацию о пользователе информацию из плагина, мне пришлось дописывать строчки в системные модули, что совсем нехорошо.

Читать дальше

Помогите с написанием плагина

1
Хочу аккуратно подкорректировать LS под свои нужды. Решил использовать LS 0.4 и сделать плагин.

Я добавил новый тип топика и для этого типа топика хочу допилить (посредством плагина) TopicEntity_Topic парой функций, т.е. расширить его. Тыкаюсь, тыкаюсь и ничего не получается…

На сколько я понимаю, мне нужно делегировать «entity» и создать свой(внутри плагина) Topic.entity.class.php с таким содержанием:

require_once(Config::Get('path.root.server').'/classes/modules/topic/entity/Topic.entity.class.php');

class PluginMyTopic_TopicEntity_Topic extends TopicEntity_Topic
{
    public function setMyData($data) {
        if ($this->getType()!='myTopicType') {
    		return;
    	}
    	$this->extractExtra();
    	$this->aExtra['mydata']=$data;
    	$this->setExtra($this->aExtra);
    }
........


Вобщем, туплю я и ничего у меня не получается… Можете подсказать, как точно должно выглядеть делегирование и описание класса?
  • 0
  • 13 марта 2010, 03:02
  • Mmaxx

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

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

Итак, по порядку, что уже было:
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 — также с нетерпением ждем описания функционала кастомных модулей.