xref: /dokuwiki/inc/Extension/PluginController.php (revision fbccc3e60b320a2e7c7a903f8f5406835ac05b07)
13a7140a1SAndreas Gohr<?php
23a7140a1SAndreas Gohr/**
33a7140a1SAndreas Gohr * Class to encapsulate access to dokuwiki plugins
43a7140a1SAndreas Gohr *
53a7140a1SAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
63a7140a1SAndreas Gohr * @author     Christopher Smith <chris@jalakai.co.uk>
73a7140a1SAndreas Gohr */
83a7140a1SAndreas Gohr
93a7140a1SAndreas Gohrnamespace dokuwiki\Extension;
103a7140a1SAndreas Gohr
113a7140a1SAndreas Gohrclass PluginController
123a7140a1SAndreas Gohr{
133a7140a1SAndreas Gohr
143a7140a1SAndreas Gohr    protected $list_bytype = array();
153a7140a1SAndreas Gohr    protected $tmp_plugins = array();
163a7140a1SAndreas Gohr    protected $plugin_cascade = array('default' => array(), 'local' => array(), 'protected' => array());
173a7140a1SAndreas Gohr    protected $last_local_config_file = '';
183a7140a1SAndreas Gohr
193a7140a1SAndreas Gohr    /**
203a7140a1SAndreas Gohr     * Populates the master list of plugins
213a7140a1SAndreas Gohr     */
223a7140a1SAndreas Gohr    public function __construct()
233a7140a1SAndreas Gohr    {
243a7140a1SAndreas Gohr        $this->loadConfig();
253a7140a1SAndreas Gohr        $this->_populateMasterList();
263a7140a1SAndreas Gohr    }
273a7140a1SAndreas Gohr
283a7140a1SAndreas Gohr    /**
293a7140a1SAndreas Gohr     * Returns a list of available plugins of given type
303a7140a1SAndreas Gohr     *
313a7140a1SAndreas Gohr     * @param $type  string, plugin_type name;
323a7140a1SAndreas Gohr     *               the type of plugin to return,
333a7140a1SAndreas Gohr     *               use empty string for all types
343a7140a1SAndreas Gohr     * @param $all   bool;
353a7140a1SAndreas Gohr     *               false to only return enabled plugins,
363a7140a1SAndreas Gohr     *               true to return both enabled and disabled plugins
373a7140a1SAndreas Gohr     *
383a7140a1SAndreas Gohr     * @return       array of
393a7140a1SAndreas Gohr     *                  - plugin names when $type = ''
403a7140a1SAndreas Gohr     *                  - or plugin component names when a $type is given
413a7140a1SAndreas Gohr     *
423a7140a1SAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
433a7140a1SAndreas Gohr     */
443a7140a1SAndreas Gohr    public function getList($type = '', $all = false)
453a7140a1SAndreas Gohr    {
463a7140a1SAndreas Gohr
473a7140a1SAndreas Gohr        // request the complete list
483a7140a1SAndreas Gohr        if (!$type) {
493a7140a1SAndreas Gohr            return $all ? array_keys($this->tmp_plugins) : array_keys(array_filter($this->tmp_plugins));
503a7140a1SAndreas Gohr        }
513a7140a1SAndreas Gohr
523a7140a1SAndreas Gohr        if (!isset($this->list_bytype[$type]['enabled'])) {
533a7140a1SAndreas Gohr            $this->list_bytype[$type]['enabled'] = $this->_getListByType($type, true);
543a7140a1SAndreas Gohr        }
553a7140a1SAndreas Gohr        if ($all && !isset($this->list_bytype[$type]['disabled'])) {
563a7140a1SAndreas Gohr            $this->list_bytype[$type]['disabled'] = $this->_getListByType($type, false);
573a7140a1SAndreas Gohr        }
583a7140a1SAndreas Gohr
593a7140a1SAndreas Gohr        return $all
603a7140a1SAndreas Gohr            ? array_merge($this->list_bytype[$type]['enabled'], $this->list_bytype[$type]['disabled'])
613a7140a1SAndreas Gohr            : $this->list_bytype[$type]['enabled'];
623a7140a1SAndreas Gohr    }
633a7140a1SAndreas Gohr
643a7140a1SAndreas Gohr    /**
653a7140a1SAndreas Gohr     * Loads the given plugin and creates an object of it
663a7140a1SAndreas Gohr     *
673a7140a1SAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
683a7140a1SAndreas Gohr     *
693a7140a1SAndreas Gohr     * @param  $type     string type of plugin to load
703a7140a1SAndreas Gohr     * @param  $name     string name of the plugin to load
713a7140a1SAndreas Gohr     * @param  $new      bool   true to return a new instance of the plugin, false to use an already loaded instance
723a7140a1SAndreas Gohr     * @param  $disabled bool   true to load even disabled plugins
733a7140a1SAndreas Gohr     * @return PluginInterface|null  the plugin object or null on failure
743a7140a1SAndreas Gohr     */
753a7140a1SAndreas Gohr    public function load($type, $name, $new = false, $disabled = false)
763a7140a1SAndreas Gohr    {
773a7140a1SAndreas Gohr
783a7140a1SAndreas Gohr        //we keep all loaded plugins available in global scope for reuse
793a7140a1SAndreas Gohr        global $DOKU_PLUGINS;
803a7140a1SAndreas Gohr
813a7140a1SAndreas Gohr        list($plugin, /* $component */) = $this->_splitName($name);
823a7140a1SAndreas Gohr
833a7140a1SAndreas Gohr        // check if disabled
843a7140a1SAndreas Gohr        if (!$disabled && $this->isdisabled($plugin)) {
853a7140a1SAndreas Gohr            return null;
863a7140a1SAndreas Gohr        }
873a7140a1SAndreas Gohr
883a7140a1SAndreas Gohr        $class = $type . '_plugin_' . $name;
893a7140a1SAndreas Gohr
903a7140a1SAndreas Gohr        //plugin already loaded?
913a7140a1SAndreas Gohr        if (!empty($DOKU_PLUGINS[$type][$name])) {
923a7140a1SAndreas Gohr            if ($new || !$DOKU_PLUGINS[$type][$name]->isSingleton()) {
933a7140a1SAndreas Gohr                return class_exists($class, true) ? new $class : null;
943a7140a1SAndreas Gohr            } else {
953a7140a1SAndreas Gohr                return $DOKU_PLUGINS[$type][$name];
963a7140a1SAndreas Gohr            }
973a7140a1SAndreas Gohr        }
983a7140a1SAndreas Gohr
993a7140a1SAndreas Gohr        //construct class and instantiate
1003a7140a1SAndreas Gohr        if (!class_exists($class, true)) {
1013a7140a1SAndreas Gohr
1023a7140a1SAndreas Gohr            # the plugin might be in the wrong directory
103f219f385SAndreas Gohr            $inf = confToHash(DOKU_PLUGIN . "$plugin/plugin.info.txt");
1043a7140a1SAndreas Gohr            if ($inf['base'] && $inf['base'] != $plugin) {
1053a7140a1SAndreas Gohr                msg(
1063a7140a1SAndreas Gohr                    sprintf(
1073a7140a1SAndreas Gohr                        "Plugin installed incorrectly. Rename plugin directory '%s' to '%s'.",
1083a7140a1SAndreas Gohr                        hsc($plugin),
1093a7140a1SAndreas Gohr                        hsc(
1103a7140a1SAndreas Gohr                            $inf['base']
1113a7140a1SAndreas Gohr                        )
1123a7140a1SAndreas Gohr                    ), -1
1133a7140a1SAndreas Gohr                );
1143a7140a1SAndreas Gohr            } elseif (preg_match('/^' . DOKU_PLUGIN_NAME_REGEX . '$/', $plugin) !== 1) {
1153a7140a1SAndreas Gohr                msg(
1163a7140a1SAndreas Gohr                    sprintf(
1173a7140a1SAndreas Gohr                        "Plugin name '%s' is not a valid plugin name, only the characters a-z and 0-9 are allowed. " .
1183a7140a1SAndreas Gohr                        'Maybe the plugin has been installed in the wrong directory?', hsc($plugin)
1193a7140a1SAndreas Gohr                    ), -1
1203a7140a1SAndreas Gohr                );
1213a7140a1SAndreas Gohr            }
1223a7140a1SAndreas Gohr            return null;
1233a7140a1SAndreas Gohr        }
1243a7140a1SAndreas Gohr
1253a7140a1SAndreas Gohr        $DOKU_PLUGINS[$type][$name] = new $class;
1263a7140a1SAndreas Gohr        return $DOKU_PLUGINS[$type][$name];
1273a7140a1SAndreas Gohr    }
1283a7140a1SAndreas Gohr
1293a7140a1SAndreas Gohr    /**
1303a7140a1SAndreas Gohr     * Whether plugin is disabled
1313a7140a1SAndreas Gohr     *
1323a7140a1SAndreas Gohr     * @param string $plugin name of plugin
1333a7140a1SAndreas Gohr     * @return bool  true disabled, false enabled
134*fbccc3e6SAndreas Gohr     * @deprecated in favor of the more sensible isEnabled where the return value matches the enabled state
1353a7140a1SAndreas Gohr     */
136*fbccc3e6SAndreas Gohr    public function isDisabled($plugin)
1373a7140a1SAndreas Gohr    {
138*fbccc3e6SAndreas Gohr        dbg_deprecated('isEnabled()');
139*fbccc3e6SAndreas Gohr        return !$this->isEnabled($plugin);
140*fbccc3e6SAndreas Gohr    }
141*fbccc3e6SAndreas Gohr
142*fbccc3e6SAndreas Gohr    /**
143*fbccc3e6SAndreas Gohr     * Check whether plugin is disabled
144*fbccc3e6SAndreas Gohr     *
145*fbccc3e6SAndreas Gohr     * @param string $plugin name of plugin
146*fbccc3e6SAndreas Gohr     * @return bool  true enabled, false disabled
147*fbccc3e6SAndreas Gohr     */
148*fbccc3e6SAndreas Gohr    public function isEnabled($plugin)
149*fbccc3e6SAndreas Gohr    {
150*fbccc3e6SAndreas Gohr        return !empty($this->tmp_plugins[$plugin]);
1513a7140a1SAndreas Gohr    }
1523a7140a1SAndreas Gohr
1533a7140a1SAndreas Gohr    /**
1543a7140a1SAndreas Gohr     * Disable the plugin
1553a7140a1SAndreas Gohr     *
1563a7140a1SAndreas Gohr     * @param string $plugin name of plugin
1573a7140a1SAndreas Gohr     * @return bool  true saving succeed, false saving failed
1583a7140a1SAndreas Gohr     */
1593a7140a1SAndreas Gohr    public function disable($plugin)
1603a7140a1SAndreas Gohr    {
1613a7140a1SAndreas Gohr        if (array_key_exists($plugin, $this->plugin_cascade['protected'])) return false;
1623a7140a1SAndreas Gohr        $this->tmp_plugins[$plugin] = 0;
1633a7140a1SAndreas Gohr        return $this->saveList();
1643a7140a1SAndreas Gohr    }
1653a7140a1SAndreas Gohr
1663a7140a1SAndreas Gohr    /**
1673a7140a1SAndreas Gohr     * Enable the plugin
1683a7140a1SAndreas Gohr     *
1693a7140a1SAndreas Gohr     * @param string $plugin name of plugin
1703a7140a1SAndreas Gohr     * @return bool  true saving succeed, false saving failed
1713a7140a1SAndreas Gohr     */
1723a7140a1SAndreas Gohr    public function enable($plugin)
1733a7140a1SAndreas Gohr    {
1743a7140a1SAndreas Gohr        if (array_key_exists($plugin, $this->plugin_cascade['protected'])) return false;
1753a7140a1SAndreas Gohr        $this->tmp_plugins[$plugin] = 1;
1763a7140a1SAndreas Gohr        return $this->saveList();
1773a7140a1SAndreas Gohr    }
1783a7140a1SAndreas Gohr
1793a7140a1SAndreas Gohr    /**
1803a7140a1SAndreas Gohr     * Returns cascade of the config files
1813a7140a1SAndreas Gohr     *
1823a7140a1SAndreas Gohr     * @return array with arrays of plugin configs
1833a7140a1SAndreas Gohr     */
1843a7140a1SAndreas Gohr    public function getCascade()
1853a7140a1SAndreas Gohr    {
1863a7140a1SAndreas Gohr        return $this->plugin_cascade;
1873a7140a1SAndreas Gohr    }
1883a7140a1SAndreas Gohr
1893a7140a1SAndreas Gohr    protected function _populateMasterList()
1903a7140a1SAndreas Gohr    {
1913a7140a1SAndreas Gohr        global $conf;
1923a7140a1SAndreas Gohr
1933a7140a1SAndreas Gohr        if ($dh = @opendir(DOKU_PLUGIN)) {
1943a7140a1SAndreas Gohr            $all_plugins = array();
1953a7140a1SAndreas Gohr            while (false !== ($plugin = readdir($dh))) {
1963a7140a1SAndreas Gohr                if ($plugin[0] == '.') continue;               // skip hidden entries
1973a7140a1SAndreas Gohr                if (is_file(DOKU_PLUGIN . $plugin)) continue;    // skip files, we're only interested in directories
1983a7140a1SAndreas Gohr
1993a7140a1SAndreas Gohr                if (array_key_exists($plugin, $this->tmp_plugins) && $this->tmp_plugins[$plugin] == 0) {
2003a7140a1SAndreas Gohr                    $all_plugins[$plugin] = 0;
2013a7140a1SAndreas Gohr
2023a7140a1SAndreas Gohr                } elseif ((array_key_exists($plugin, $this->tmp_plugins) && $this->tmp_plugins[$plugin] == 1)) {
2033a7140a1SAndreas Gohr                    $all_plugins[$plugin] = 1;
2043a7140a1SAndreas Gohr                } else {
2053a7140a1SAndreas Gohr                    $all_plugins[$plugin] = 1;
2063a7140a1SAndreas Gohr                }
2073a7140a1SAndreas Gohr            }
2083a7140a1SAndreas Gohr            $this->tmp_plugins = $all_plugins;
2093a7140a1SAndreas Gohr            if (!file_exists($this->last_local_config_file)) {
2103a7140a1SAndreas Gohr                $this->saveList(true);
2113a7140a1SAndreas Gohr            }
2123a7140a1SAndreas Gohr        }
2133a7140a1SAndreas Gohr    }
2143a7140a1SAndreas Gohr
2153a7140a1SAndreas Gohr    /**
2163a7140a1SAndreas Gohr     * Includes the plugin config $files
2173a7140a1SAndreas Gohr     * and returns the entries of the $plugins array set in these files
2183a7140a1SAndreas Gohr     *
2193a7140a1SAndreas Gohr     * @param array $files list of files to include, latter overrides previous
2203a7140a1SAndreas Gohr     * @return array with entries of the $plugins arrays of the included files
2213a7140a1SAndreas Gohr     */
2223a7140a1SAndreas Gohr    protected function checkRequire($files)
2233a7140a1SAndreas Gohr    {
2243a7140a1SAndreas Gohr        $plugins = array();
2253a7140a1SAndreas Gohr        foreach ($files as $file) {
2263a7140a1SAndreas Gohr            if (file_exists($file)) {
2273a7140a1SAndreas Gohr                include_once($file);
2283a7140a1SAndreas Gohr            }
2293a7140a1SAndreas Gohr        }
2303a7140a1SAndreas Gohr        return $plugins;
2313a7140a1SAndreas Gohr    }
2323a7140a1SAndreas Gohr
2333a7140a1SAndreas Gohr    /**
2343a7140a1SAndreas Gohr     * Save the current list of plugins
2353a7140a1SAndreas Gohr     *
2363a7140a1SAndreas Gohr     * @param bool $forceSave ;
2373a7140a1SAndreas Gohr     *              false to save only when config changed
2383a7140a1SAndreas Gohr     *              true to always save
2393a7140a1SAndreas Gohr     * @return bool  true saving succeed, false saving failed
2403a7140a1SAndreas Gohr     */
2413a7140a1SAndreas Gohr    protected function saveList($forceSave = false)
2423a7140a1SAndreas Gohr    {
2433a7140a1SAndreas Gohr        global $conf;
2443a7140a1SAndreas Gohr
2453a7140a1SAndreas Gohr        if (empty($this->tmp_plugins)) return false;
2463a7140a1SAndreas Gohr
2473a7140a1SAndreas Gohr        // Rebuild list of local settings
2483a7140a1SAndreas Gohr        $local_plugins = $this->rebuildLocal();
2493a7140a1SAndreas Gohr        if ($local_plugins != $this->plugin_cascade['local'] || $forceSave) {
2503a7140a1SAndreas Gohr            $file = $this->last_local_config_file;
2513a7140a1SAndreas Gohr            $out = "<?php\n/*\n * Local plugin enable/disable settings\n" .
2523a7140a1SAndreas Gohr                " * Auto-generated through plugin/extension manager\n *\n" .
2533a7140a1SAndreas Gohr                " * NOTE: Plugins will not be added to this file unless there " .
2543a7140a1SAndreas Gohr                "is a need to override a default setting. Plugins are\n" .
2553a7140a1SAndreas Gohr                " *       enabled by default.\n */\n";
2563a7140a1SAndreas Gohr            foreach ($local_plugins as $plugin => $value) {
2573a7140a1SAndreas Gohr                $out .= "\$plugins['$plugin'] = $value;\n";
2583a7140a1SAndreas Gohr            }
2593a7140a1SAndreas Gohr            // backup current file (remove any existing backup)
2603a7140a1SAndreas Gohr            if (file_exists($file)) {
2613a7140a1SAndreas Gohr                $backup = $file . '.bak';
2623a7140a1SAndreas Gohr                if (file_exists($backup)) @unlink($backup);
2633a7140a1SAndreas Gohr                if (!@copy($file, $backup)) return false;
2643a7140a1SAndreas Gohr                if (!empty($conf['fperm'])) chmod($backup, $conf['fperm']);
2653a7140a1SAndreas Gohr            }
2663a7140a1SAndreas Gohr            //check if can open for writing, else restore
2673a7140a1SAndreas Gohr            return io_saveFile($file, $out);
2683a7140a1SAndreas Gohr        }
2693a7140a1SAndreas Gohr        return false;
2703a7140a1SAndreas Gohr    }
2713a7140a1SAndreas Gohr
2723a7140a1SAndreas Gohr    /**
2733a7140a1SAndreas Gohr     * Rebuild the set of local plugins
2743a7140a1SAndreas Gohr     *
2753a7140a1SAndreas Gohr     * @return array array of plugins to be saved in end($config_cascade['plugins']['local'])
2763a7140a1SAndreas Gohr     */
2773a7140a1SAndreas Gohr    protected function rebuildLocal()
2783a7140a1SAndreas Gohr    {
2793a7140a1SAndreas Gohr        //assign to local variable to avoid overwriting
2803a7140a1SAndreas Gohr        $backup = $this->tmp_plugins;
2813a7140a1SAndreas Gohr        //Can't do anything about protected one so rule them out completely
2823a7140a1SAndreas Gohr        $local_default = array_diff_key($backup, $this->plugin_cascade['protected']);
2833a7140a1SAndreas Gohr        //Diff between local+default and default
2843a7140a1SAndreas Gohr        //gives us the ones we need to check and save
2853a7140a1SAndreas Gohr        $diffed_ones = array_diff_key($local_default, $this->plugin_cascade['default']);
2863a7140a1SAndreas Gohr        //The ones which we are sure of (list of 0s not in default)
2873a7140a1SAndreas Gohr        $sure_plugins = array_filter($diffed_ones, array($this, 'negate'));
2883a7140a1SAndreas Gohr        //the ones in need of diff
2893a7140a1SAndreas Gohr        $conflicts = array_diff_key($local_default, $diffed_ones);
2903a7140a1SAndreas Gohr        //The final list
2913a7140a1SAndreas Gohr        return array_merge($sure_plugins, array_diff_assoc($conflicts, $this->plugin_cascade['default']));
2923a7140a1SAndreas Gohr    }
2933a7140a1SAndreas Gohr
2943a7140a1SAndreas Gohr    /**
2953a7140a1SAndreas Gohr     * Build the list of plugins and cascade
2963a7140a1SAndreas Gohr     *
2973a7140a1SAndreas Gohr     */
2983a7140a1SAndreas Gohr    protected function loadConfig()
2993a7140a1SAndreas Gohr    {
3003a7140a1SAndreas Gohr        global $config_cascade;
3013a7140a1SAndreas Gohr        foreach (array('default', 'protected') as $type) {
3023a7140a1SAndreas Gohr            if (array_key_exists($type, $config_cascade['plugins'])) {
3033a7140a1SAndreas Gohr                $this->plugin_cascade[$type] = $this->checkRequire($config_cascade['plugins'][$type]);
3043a7140a1SAndreas Gohr            }
3053a7140a1SAndreas Gohr        }
3063a7140a1SAndreas Gohr        $local = $config_cascade['plugins']['local'];
3073a7140a1SAndreas Gohr        $this->last_local_config_file = array_pop($local);
3083a7140a1SAndreas Gohr        $this->plugin_cascade['local'] = $this->checkRequire(array($this->last_local_config_file));
3093a7140a1SAndreas Gohr        if (is_array($local)) {
3103a7140a1SAndreas Gohr            $this->plugin_cascade['default'] = array_merge(
3113a7140a1SAndreas Gohr                $this->plugin_cascade['default'],
3123a7140a1SAndreas Gohr                $this->checkRequire($local)
3133a7140a1SAndreas Gohr            );
3143a7140a1SAndreas Gohr        }
3153a7140a1SAndreas Gohr        $this->tmp_plugins = array_merge(
3163a7140a1SAndreas Gohr            $this->plugin_cascade['default'],
3173a7140a1SAndreas Gohr            $this->plugin_cascade['local'],
3183a7140a1SAndreas Gohr            $this->plugin_cascade['protected']
3193a7140a1SAndreas Gohr        );
3203a7140a1SAndreas Gohr    }
3213a7140a1SAndreas Gohr
3223a7140a1SAndreas Gohr    /**
3233a7140a1SAndreas Gohr     * Returns a list of available plugin components of given type
3243a7140a1SAndreas Gohr     *
3253a7140a1SAndreas Gohr     * @param string $type plugin_type name; the type of plugin to return,
3263a7140a1SAndreas Gohr     * @param bool $enabled true to return enabled plugins,
3273a7140a1SAndreas Gohr     *                          false to return disabled plugins
3283a7140a1SAndreas Gohr     * @return array of plugin components of requested type
3293a7140a1SAndreas Gohr     */
3303a7140a1SAndreas Gohr    protected function _getListByType($type, $enabled)
3313a7140a1SAndreas Gohr    {
3323a7140a1SAndreas Gohr        $master_list = $enabled
3333a7140a1SAndreas Gohr            ? array_keys(array_filter($this->tmp_plugins))
3343a7140a1SAndreas Gohr            : array_keys(array_filter($this->tmp_plugins, array($this, 'negate')));
3353a7140a1SAndreas Gohr        $plugins = array();
3363a7140a1SAndreas Gohr
3373a7140a1SAndreas Gohr        foreach ($master_list as $plugin) {
3383a7140a1SAndreas Gohr
339f219f385SAndreas Gohr            if (file_exists(DOKU_PLUGIN . "$plugin/$type.php")) {
3403a7140a1SAndreas Gohr                $plugins[] = $plugin;
3413a7140a1SAndreas Gohr                continue;
3423a7140a1SAndreas Gohr            }
3433a7140a1SAndreas Gohr
344f219f385SAndreas Gohr            $typedir = DOKU_PLUGIN . "$plugin/$type/";
3453a7140a1SAndreas Gohr            if (is_dir($typedir)) {
3463a7140a1SAndreas Gohr                if ($dp = opendir($typedir)) {
3473a7140a1SAndreas Gohr                    while (false !== ($component = readdir($dp))) {
3483a7140a1SAndreas Gohr                        if (substr($component, 0, 1) == '.' || strtolower(substr($component, -4)) != ".php") continue;
3493a7140a1SAndreas Gohr                        if (is_file($typedir . $component)) {
3503a7140a1SAndreas Gohr                            $plugins[] = $plugin . '_' . substr($component, 0, -4);
3513a7140a1SAndreas Gohr                        }
3523a7140a1SAndreas Gohr                    }
3533a7140a1SAndreas Gohr                    closedir($dp);
3543a7140a1SAndreas Gohr                }
3553a7140a1SAndreas Gohr            }
3563a7140a1SAndreas Gohr
3573a7140a1SAndreas Gohr        }//foreach
3583a7140a1SAndreas Gohr
3593a7140a1SAndreas Gohr        return $plugins;
3603a7140a1SAndreas Gohr    }
3613a7140a1SAndreas Gohr
3623a7140a1SAndreas Gohr    /**
3633a7140a1SAndreas Gohr     * Split name in a plugin name and a component name
3643a7140a1SAndreas Gohr     *
3653a7140a1SAndreas Gohr     * @param string $name
3663a7140a1SAndreas Gohr     * @return array with
3673a7140a1SAndreas Gohr     *              - plugin name
3683a7140a1SAndreas Gohr     *              - and component name when available, otherwise empty string
3693a7140a1SAndreas Gohr     */
3703a7140a1SAndreas Gohr    protected function _splitName($name)
3713a7140a1SAndreas Gohr    {
3723a7140a1SAndreas Gohr        if (array_search($name, array_keys($this->tmp_plugins)) === false) {
3733a7140a1SAndreas Gohr            return explode('_', $name, 2);
3743a7140a1SAndreas Gohr        }
3753a7140a1SAndreas Gohr
3763a7140a1SAndreas Gohr        return array($name, '');
3773a7140a1SAndreas Gohr    }
3783a7140a1SAndreas Gohr
3793a7140a1SAndreas Gohr    /**
3803a7140a1SAndreas Gohr     * Returns inverse boolean value of the input
3813a7140a1SAndreas Gohr     *
3823a7140a1SAndreas Gohr     * @param mixed $input
3833a7140a1SAndreas Gohr     * @return bool inversed boolean value of input
3843a7140a1SAndreas Gohr     */
3853a7140a1SAndreas Gohr    protected function negate($input)
3863a7140a1SAndreas Gohr    {
3873a7140a1SAndreas Gohr        return !(bool)$input;
3883a7140a1SAndreas Gohr    }
3893a7140a1SAndreas Gohr}
390