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

Раз уж пошло такое бурное обсуждение, то думаю стоит обсудить в отдельном посте :)
Итак, были предложены следующие варианты:
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") в шаблонах тем