aboutsummaryrefslogtreecommitdiff
path: root/lib/dokuwiki/inc/plugincontroller.class.php
blob: 4400a41870c7ef6f55afdb9ea49d1ea2accf9146 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<?php
/**
 * Class to encapsulate access to dokuwiki plugins
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 */

// plugin related constants
if(!defined('DOKU_PLUGIN'))  define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');

class Doku_Plugin_Controller {

    var $list_enabled = array();
    var $list_disabled = array();
    var $list_bytype = array();

    function Doku_Plugin_Controller() {
        $this->_populateMasterList();
    }

    /**
     * Returns a list of available plugins of given type
     *
     * @param $type  string, plugin_type name;
     *               the type of plugin to return,
     *               use empty string for all types
     * @param $all   bool;
     *               false to only return enabled plugins,
     *               true to return both enabled and disabled plugins
     *
     * @return       array of plugin names
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     */
    function getList($type='',$all=false){

        // request the complete list
        if (!$type) {
            return $all ? array_merge($this->list_enabled,$this->list_disabled) : $this->list_enabled;
        }

        if (!isset($this->list_bytype[$type]['enabled'])) {
            $this->list_bytype[$type]['enabled'] = $this->_getListByType($type,true);
        }
        if ($all && !isset($this->list_bytype[$type]['disabled'])) {
            $this->list_bytype[$type]['disabled'] = $this->_getListByType($type,false);
        }

        return $all ? array_merge($this->list_bytype[$type]['enabled'],$this->list_bytype[$type]['disabled']) : $this->list_bytype[$type]['enabled'];
    }

    /**
     * Loads the given plugin and creates an object of it
     *
     * @author Andreas Gohr <andi@splitbrain.org>
     *
     * @param  $type string     type of plugin to load
     * @param  $name string     name of the plugin to load
     * @param  $new  bool       true to return a new instance of the plugin, false to use an already loaded instance
     * @return objectreference  the plugin object or null on failure
     */
    function &load($type,$name,$new=false){
        //we keep all loaded plugins available in global scope for reuse
        global $DOKU_PLUGINS;

        //plugin already loaded?
        if(!empty($DOKU_PLUGINS[$type][$name])){
            if ($new  && !$DOKU_PLUGINS[$type][$name]->isSingleton()) {
                $class = $type.'_plugin_'.$name;
                return class_exists($class) ? new $class : null;
            } else {
                return $DOKU_PLUGINS[$type][$name];
            }
        }

        //try to load the wanted plugin file
        list($plugin,$component) = $this->_splitName($name);
        $dir = $this->get_directory($plugin);
        $file = $component ? "$type/$component.php" : "$type.php";

        if(!is_file(DOKU_PLUGIN."$dir/$file")){
            return null;
        }

        if (!include_once(DOKU_PLUGIN."$dir/$file")) {
            return null;
        }

        //construct class and instantiate
        $class = $type.'_plugin_'.$name;
        if (!class_exists($class)) return null;

        $DOKU_PLUGINS[$type][$name] = new $class;
        return $DOKU_PLUGINS[$type][$name];
    }

    function isdisabled($plugin) {
        return (array_search($plugin, $this->list_enabled) === false);
    }

    function enable($plugin) {
        if (array_search($plugin, $this->list_disabled) !== false) {
            return @unlink(DOKU_PLUGIN.$plugin.'/disabled');
        }
        return false;
    }

    function disable($plugin) {
        if (array_search($plugin, $this->list_enabled) !== false) {
            return @touch(DOKU_PLUGIN.$plugin.'/disabled');
        }
        return false;
    }

    function get_directory($plugin) {
        return $plugin;
    }

    function _populateMasterList() {
        if ($dh = opendir(DOKU_PLUGIN)) {
            while (false !== ($plugin = readdir($dh))) {
                if ($plugin == '.' || $plugin == '..' || $plugin == 'tmp') continue;
                if (is_file(DOKU_PLUGIN.$plugin)) continue;

                if (substr($plugin,-9) == '.disabled') {
                    // the plugin was disabled by rc2009-01-26
                    // disabling mechanism was changed back very soon again
                    // to keep everything simple we just skip the plugin completely
                }elseif(@file_exists(DOKU_PLUGIN.$plugin.'/disabled')){
                    $this->list_disabled[] = $plugin;
                } else {
                    $this->list_enabled[] = $plugin;
                }
            }
        }
    }

    function _getListByType($type, $enabled) {
        $master_list = $enabled ? $this->list_enabled : $this->list_disabled;

        $plugins = array();
        foreach ($master_list as $plugin) {
            $dir = $this->get_directory($plugin);

            if (@file_exists(DOKU_PLUGIN."$dir/$type.php")){
                $plugins[] = $plugin;
            } else {
                if ($dp = @opendir(DOKU_PLUGIN."$dir/$type/")) {
                    while (false !== ($component = readdir($dp))) {
                        if (substr($component,0,1) == '.' || strtolower(substr($component, -4)) != ".php") continue;
                        if (is_file(DOKU_PLUGIN."$dir/$type/$component")) {
                            $plugins[] = $plugin.'_'.substr($component, 0, -4);
                        }
                    }
                    closedir($dp);
                }
            }
        }

        return $plugins;
    }

    function _splitName($name) {
        if (array_search($name, $this->list_enabled + $this->list_disabled) === false) {
            return explode('_',$name,2);
        }

        return array($name,'');
    }

}