1<?php
2
3require_once dirname(__FILE__).'/accesscheck.php';
4require_once dirname(__FILE__).'/EmailSender.php';
5include_once dirname(__FILE__).'/defaultplugin.php';
6require_once dirname(__FILE__).'/AnalyticsQuery.php';
7
8$GLOBALS['plugins'] = array();
9$GLOBALS['editorplugin'] = false;
10$GLOBALS['authenticationplugin'] = false;
11$GLOBALS['emailsenderplugin'] = false;
12$GLOBALS['analyticsqueryplugin'] = false;
13
14$pluginRootDirs = array();
15if (PLUGIN_ROOTDIRS != '') {
16    $pluginRootDirs = explode(';', PLUGIN_ROOTDIRS);
17}
18$pluginRootDirs[] = PLUGIN_ROOTDIR;
19$pluginRootDirs = array_filter(array_unique($pluginRootDirs));
20$pluginFiles = array();
21
22foreach ($pluginRootDirs as $pluginRootDir) {
23    //# try to expand to subdir of the admin dir
24    if (!is_dir($pluginRootDir)) {
25        $pluginRootDir = dirname(__FILE__).'/'.$pluginRootDir;
26    }
27
28//  print '<h3>'.$pluginRootDir.'</h3>';
29    if (is_dir($pluginRootDir) && ($dh = opendir($pluginRootDir))) {
30        while (false !== ($file = readdir($dh))) {
31            if ($file != '.' && $file != '..' && !preg_match('/~$/', $file)) {
32                //        print $pluginRootDir.' '.$file.'<br/>';
33                if (is_file($pluginRootDir.'/'.$file) && preg_match("/\.php$/", $file)) {
34                    //          print "ADD $file<br/>";
35                    array_push($pluginFiles, $pluginRootDir.'/'.$file);
36                } elseif (is_dir($pluginRootDir.'/'.$file.'/plugins')) {
37                    //         print 'SUBROOT'.$pluginRootDir.' '.$file.'<br/>';
38                    $subRoot = $pluginRootDir.'/'.$file.'/plugins';
39                    $subDir = opendir($subRoot);
40                    while (false !== ($subFile = readdir($subDir))) {
41                        if (is_file($subRoot.'/'.$subFile) && preg_match("/\.php$/", $subFile)) {
42                            //              print "ADD $subFile<br/>";
43                            array_push($pluginFiles, $subRoot.'/'.$subFile);
44                        } else {
45                            //              print "NOT A FILE: $subRoot.'/'.$subFile<br/>";
46                        }
47                    }
48                } else {
49                    //          print 'NOT A DIR: '.$pluginRootDir.'/'.$file.'/plugins<br/>';
50                }
51            }
52        }
53        closedir($dh);
54    }
55}
56
57$auto_enable_plugins = array();
58if (isset($GLOBALS['plugins_autoenable'])) {
59    $auto_enable_plugins = $GLOBALS['plugins_autoenable'];
60}
61
62//var_dump($pluginFiles);exit;
63$disabled_plugins = unserialize(getConfig('plugins_disabled'));
64if (is_array($disabled_plugins)) {
65    foreach ($disabled_plugins as $pl => $plstate) {
66        if (!empty($plstate) && !in_array($pl, $auto_enable_plugins)) {
67            $GLOBALS['plugins_disabled'][] = $pl;
68        }
69    }
70}
71
72//var_dump($GLOBALS['plugins_disabled']);exit;
73foreach ($pluginFiles as $file) {
74    list($className, $ext) = explode('.', basename($file));
75    if (preg_match("/[\w]+/", $className)) {
76        // && !in_array($className,$GLOBALS['plugins_disabled'])) {
77        if (!class_exists($className)) {
78            include_once $file;
79            if (class_exists($className)) {
80                $pluginInstance = new $className();
81                $pluginInstance->origin = $file;
82                //  print "Instance $className<br/>";
83                //# bit of a duplication of plugins, but $GLOBALS['plugins'] should only contain active ones
84                //# using "allplugins" allow listing them, and switch on/off in the plugins page
85                $GLOBALS['allplugins'][$className] = $pluginInstance;
86
87                if (!in_array($className, $GLOBALS['plugins_disabled'])) {
88                    $plugin_initialised = getConfig(md5('plugin-'.$className.'-initialised'));
89
90                    if (!empty($plugin_initialised)) {
91                        $GLOBALS['plugins'][$className] = $pluginInstance;
92                        $pluginInstance->enabled = true;
93                    } elseif (in_array($className, $auto_enable_plugins)) {
94                        $GLOBALS['plugins'][$className] = $pluginInstance;
95                        $pluginInstance->initialise();
96                        $pluginInstance->enabled = true;
97                    } else {
98                        // plugin is not enabled and not disabled, so disable it and don't process this plugin any further
99                        $pluginInstance->enabled = false;
100                        $disabled_plugins[$className] = 1;
101                        saveConfig('plugins_disabled', serialize($disabled_plugins), 0);
102                        continue;
103                    }
104                    // remember the first plugins that provide editor, authentication or email sending
105                    if (!$GLOBALS['editorplugin'] && $pluginInstance->editorProvider && method_exists($pluginInstance,
106                            'editor')
107                    ) {
108                        $GLOBALS['editorplugin'] = $className;
109                    }
110                    if (!$GLOBALS['authenticationplugin'] && $pluginInstance->authProvider && method_exists($pluginInstance,
111                            'validateLogin')
112                    ) {
113                        $GLOBALS['authenticationplugin'] = $className;
114                    }
115
116                    if (!$GLOBALS['emailsenderplugin'] && $pluginInstance instanceof EmailSender) {
117                        $GLOBALS['emailsenderplugin'] = $pluginInstance;
118                    }
119
120                    if (!$GLOBALS['analyticsqueryplugin'] && $pluginInstance instanceof AnalyticsQuery) {
121                        $GLOBALS['analyticsqueryplugin'] = $pluginInstance;
122                        // Add 'plugin' as an option on the Settings page
123                        $default_config['analytic_tracker']['values'] += array('plugin' => $analyticsqueryplugin->name);
124                    }
125
126                    if (!empty($pluginInstance->DBstruct)) {
127                        foreach ($pluginInstance->DBstruct as $tablename => $tablecolumns) {
128                            $GLOBALS['tables'][$className.'_'.$tablename] = $GLOBALS['table_prefix'].$className.'_'.$tablename;
129                        }
130                    }
131                } else {
132                    $pluginInstance->enabled = false;
133                    dbg($className.' disabled');
134                }
135            } else {
136                Error('initialisation of plugin '.$className.' failed');
137            }
138            //print "$className = ".$pluginInstance->name."<br/>";
139        }
140    }
141}
142//  Activate plugins in descending priority order
143uasort(
144    $plugins,
145    function($a, $b) {
146        return $b->priority - $a->priority;
147    }
148);
149
150foreach ($plugins as $className => $pluginInstance) {
151    if (!pluginCanEnable($className)) {
152        // an already enabled plugin now does not meet its dependencies, do not enable it
153        $pluginInstance->enabled = false;
154        unset($plugins[$className]);
155        continue;
156    }
157    $pluginInstance->activate();
158}
159
160$GLOBALS['pluginsendformats'] = array();
161foreach ($GLOBALS['plugins'] as $className => $pluginInstance) {
162    $plugin_sendformats = $pluginInstance->sendFormats();
163    if (is_array($plugin_sendformats) && count($plugin_sendformats)) {
164        foreach ($plugin_sendformats as $val => $desc) {
165            $val = preg_replace("/\W/", '', strtolower(trim($val)));
166            $GLOBALS['pluginsendformats'][$val] = $className;
167        }
168    }
169}
170
171function upgradePlugins($toUpgrade)
172{
173    foreach ($toUpgrade as $pluginname) {
174        //    print '<h2>Upgrading '.$pluginname. '</h2><br/> ';
175//    print md5('plugin-'.$pluginname.'-versiondate');
176        $currentDate = getConfig(md5('plugin-'.$pluginname.'-versiondate'));
177//    print 'CUrrent '.$currentDate;
178        if ($GLOBALS['allplugins'][$pluginname]->upgrade($currentDate)) {
179            //      print "Saving ".'plugin-'.$pluginname.'-versiondate';
180            SaveConfig(md5('plugin-'.$pluginname.'-versiondate'), date('Y-m-d'), 0);
181        }
182    }
183}
184
185$commandlinePluginPages = array();
186$commandlinePlugins = array();
187if (count($GLOBALS['plugins'])) {
188    foreach ($GLOBALS['plugins'] as $pluginName => $plugin) {
189        $cl_pages = $plugin->commandlinePluginPages;
190        if (count($cl_pages)) {
191            $commandlinePlugins[] = $pluginName;
192            $commandlinePluginPages[$pluginName] = $cl_pages;
193        }
194    }
195}
196
197/*
198  * central function to call a method on all plugins
199  * not sure to go down this route yet, MD 201212
200  */
201
202function pluginsCall($method)
203{
204    $args = func_get_args();
205    $m = array_shift($args); // the first is the method itself
206    foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
207        if (method_exists($plugin, $method)) {
208            $plugin->$method($args);
209        }
210    }
211}
212
213function pluginCanEnable($plugin)
214{
215    global $allplugins;
216
217    $canEnable = false;
218
219    if (isset($allplugins[$plugin])) {
220        $dependencies = $allplugins[$plugin]->dependencyCheck();
221        $dependencyDesc = array_search(false, $dependencies);
222
223        if ($dependencyDesc === false) {
224            $canEnable = true;
225        } else {
226            $allplugins[$plugin]->dependencyFailure = $dependencyDesc;
227        }
228    }
229
230    return $canEnable;
231}
232