Вызов плагинов в темах дизайна

enso_studio@mail.ru

Раз уж пошло такое бурное обсуждение, то думаю стоит обсудить в отдельном посте :)

Итак, были предложены следующие варианты:

1.Eugen Nichikov: вызов событий, используя шаблонный хэлпер

class waViewHelper
{
    /**
     * @param string $app_id Application id.
     * @param string $name Event name.
     * @param null $params Parameters passed to event handlers.
     * @param string $return_type
     * @return null|string|array
     */
    public function event($app_id, $name, &$params = null, $return_type = 'string')
    {
        $result = null;
        if(wa()->appExists($app_id)) {
            $plugins = wa($app_id)->event('custom.'.$name, $params);
            if(is_array($plugins)) {
                if ($return_type == 'string') {
                    $result = '';
                    foreach ($plugins as $plugin) {
                        $result .= $plugin;
                    }
                } elseif ($return_type == 'array') {
                    $result = $plugins;
                }
            }
        }
        return $result;
    }
}

или аналог для хэлперов приложений

class waAppViewHelper
{
    public function event($name, &$params = null, $concat_result = false)
    {
        $result = (array) $this->wa()->event('custom.'.$name, $params);
        if ($concat_result) {
            return implode($result);
        };
        return $result;
    }
}

2. Максим Сердюков: привычные статические методы + и компактная проверка is_callable

{if is_callable(['shopTestPlugin', 'doSmth']) && someClass::enable()}
    {shopTestPlugin::doSmth()} 
{/if}

3. Мои: вызов плагинов через хэлперы приложений

class waAppViewHelper
{
    /**
     * @params array
     */
    protected $plugins;
    /**
     * @param string $plugin_id
     * @param string|null $method
     * @param array $params
     * @return mixed
     */
    public function plugin($plugin_id, $method = null, array $params = array())
    {
        $wa = $this->wa();
        if (!is_array($this->plugins)) {
            $config = $wa->getConfig();
            if ($config->getInfo('plugins')) {
                $this->plugins = array_fill_keys(array_keys($config->getPlugins()), null);
            } else {
                $this->plugins = array();
            }
        }
        if (array_key_exists($plugin_id, $this->plugins)) {
            if (!is_object($this->plugins[$plugin_id])) {
                $this->plugins[$plugin_id] = $wa->getPlugin($plugin_id);
            }
            if ($method) {
                return call_user_func_array(array($this->plugins[$plugin_id], $method), $params);
            }
            return $this->plugins[$plugin_id];
        }
        return null;
    }
}

+ smarty префильтр упрощающий вызов ("синтаксический сахар")

{$wa->app_id->plugin('plugin_id', 'method', $params) ?? 'если плагин недоступен'}
{$var = ($wa->app_id->plugin('plugin_id', 'method', $params) ?? 'если плагин недоступен')}

Если метод плагина доступен, вызываем waAppViewHelper::plugin, иначе возвращаем значение указанное после ??

{* исходный код шаблона: *}
{$badges = ($wa->shop->plugin("addgifts", "badgeHtml", $p) ?? $wa->shop->badgeHtml($p.badge))}

{$foo=($wa->shop->plugin("test", "helper") ?? false)}

{$wa->shop->plugin("test","helper2", ["val" => 1]) ?? $wa_url}

{* код после префильтра: *}
{if $wa->shop && is_callable([$wa->shop->plugin("addgifts"),"badgeHtml"])}{$badges=$wa->shop->plugin("addgifts", "badgeHtml", $p)}{else}{$badges=$wa->shop->badgeHtml($p.badge)}{/if}

{if $wa->shop && is_callable([$wa->shop->plugin("test"),"helper"])}{$foo=$wa->shop->plugin("test","helper")}{else}{$foo=false}{/if}

{if $wa->shop && is_callable([$wa->shop->plugin("test"),"helper2"])}{$wa->shop->plugin("test","helper2")}{else}{$wa_url}{/if}

Код префильтра:

function smarty_prefilter_wa_helper_callback(array $matches)
{
    if (count($matches) == 7) {
        return sprintf(
            '{if %1$s && is_callable([%1$s->plugin(%2$s),%3$s])}{%4$s}{else}{%5$s}{/if}',
            $matches[2],
            $matches[3],
            $matches[4],
            $matches[1],
            $matches[6]
        );
    }
    return sprintf(
        '{if %1$s && is_callable([%1$s->plugin(%2$s),%3$s])}{%4$s=%5$s}{else}{%4$s=%6$s}{/if}',
        $matches[3],
        $matches[4],
        $matches[5],
        $matches[1],
        $matches[2],
        $matches[7]
    );
}

function smarty_prefilter_wa_helper($source, Smarty_Internal_Template $template)
{
    if ($source) {
        $source = preg_replace_callback(
            '~\{(\$[^\s]+)\s*=\s*\(((\$wa->[\w]+)->plugin\((.+?),\s*(.+?)(,.*?)?\))\s*\?\?\s*(.+?)\)\}~ui', 
            'smarty_prefilter_wa_helper_callback', 
            (string) $source
        );
        $source = preg_replace_callback(
            '~\{((\$wa->[\w]+)->plugin\((.+?),\s*(.+?)(,.*?)?\))\s*\?\?\s*(.+?)\}~ui', 
            'smarty_prefilter_wa_helper_callback', 
            $source
        );
    }
    return $source;
}

4. добавить плагины в requirements theme.xml

<requirement property="plugin.app_id.plugin_id" value="1.0.0" strict="1">

+ переменная с инфой о доступности необязательных плагинов (strict="0") в шаблонах тем

15 декабря 2018


    Чтобы добавить комментарий, зарегистрируйтесь или войдите