Missing li-tag added to avoid XHTML error
[mailer.git] / inc / load_extensions.php
1 <?php
2 /************************************************************************
3  * MXChange v0.2.1                                    Start: 06/26/2004 *
4  * ===============                              Last change: 07/01/2005 *
5  *                                                                      *
6  * -------------------------------------------------------------------- *
7  * File              : load_extensions.php                              *
8  * -------------------------------------------------------------------- *
9  * Short description : Load all extensions                              *
10  * -------------------------------------------------------------------- *
11  * Kurzbeschreibung  : Alle Erweiterungen laden                         *
12  * -------------------------------------------------------------------- *
13  * @TODO Rewrite this whole file to load_cache-extensions.php           *
14  * -------------------------------------------------------------------- *
15  * $Revision::                                                        $ *
16  * $Date::                                                            $ *
17  * $Tag:: 0.2.1-FINAL                                                 $ *
18  * $Author::                                                          $ *
19  * Needs to be in all Files and every File needs "svn propset           *
20  * svn:keywords Date Revision" (autoprobset!) at least!!!!!!            *
21  * -------------------------------------------------------------------- *
22  * Copyright (c) 2003 - 2008 by Roland Haeder                           *
23  * For more information visit: http://www.mxchange.org                  *
24  *                                                                      *
25  * This program is free software; you can redistribute it and/or modify *
26  * it under the terms of the GNU General Public License as published by *
27  * the Free Software Foundation; either version 2 of the License, or    *
28  * (at your option) any later version.                                  *
29  *                                                                      *
30  * This program is distributed in the hope that it will be useful,      *
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
33  * GNU General Public License for more details.                         *
34  *                                                                      *
35  * You should have received a copy of the GNU General Public License    *
36  * along with this program; if not, write to the Free Software          *
37  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,               *
38  * MA  02110-1301  USA                                                  *
39  ************************************************************************/
40
41 // Some security stuff...
42 if (!defined('__SECURITY')) {
43         $INC = substr(dirname(__FILE__), 0, strpos(dirname(__FILE__), '/inc') + 4) . '/security.php';
44         require($INC);
45 }
46
47 // Init variables
48 EXT_INIT_CSS_FILES();
49 $add = '';
50
51 // Init cache instance and array
52 $GLOBALS['cache_instance'] = null;
53 $GLOBALS['cache_array'] = array();
54
55 // Skip loading extensions
56 if ((!isInstalled()) || (isInstalling())) {
57         // Init filter system here
58         initFilterSystem();
59
60         // Skip loading
61         return;
62 } // END - if
63
64 // Initialize array for "always keep active extensions"
65 $GLOBALS['cache_array']['active_extensions'] = array();
66
67 // By default no cache is set
68 $GLOBALS['cache_mode'] = 'no';
69
70 // Load sql_patchrs extension alone
71 if (!LOAD_EXTENSION('sql_patches')) {
72         // Could not load sql_patches! ARGH!!!
73         trigger_error('Cannot load extension sql_patches.');
74 } // END - if
75
76 // Init inc pool array
77 INIT_INC_POOL();
78
79 //
80 // Load extensions
81 //
82 if (EXT_IS_ACTIVE('cache')) {
83         // Load cache extension alone
84         if (!LOAD_EXTENSION('cache')) {
85                 // Extension 'cache' was not loaded
86                 trigger_error('Cannot load extension cache.');
87         } // END - if
88
89         // Check extension cache
90         switch (($GLOBALS['cache_instance']->loadCacheFile('extensions', true)) && ($GLOBALS['cache_instance']->extensionVersionMatches('sql_patches'))) {
91                 case true : $GLOBALS['cache_mode'] = 'load'; break;
92                 case false: $GLOBALS['cache_mode'] = 'init'; break;
93         }
94
95         // Do we need to init the cache?
96         if (($GLOBALS['cache_mode'] == 'init') && (getConfig('cache_exts') == 'Y')) {
97                 // Init cache file
98                 $GLOBALS['cache_instance']->init('EXTENSIONS');
99                 $GLOBALS['cache_instance']->storeExtensionVersion('sql_patches');
100         } elseif (getConfig('cache_exts') != 'Y') {
101                 // Cache will not be created for extensions
102                 $GLOBALS['cache_mode'] = 'skip';
103         }
104 } // END - if
105
106 // Load cache?
107 if ($GLOBALS['cache_mode'] == 'load') {
108         // Init include array
109         $EXT_POOL = array();
110
111         // Re-initialize handler
112         $GLOBALS['cache_instance']->loadCacheFile('extensions', true);
113
114         // Load extension data from cache file
115         $EXT_DUMMY = $GLOBALS['cache_instance']->getArrayFromCache();
116
117         // Is the cache file fine?
118         if (!isset($EXT_DUMMY['ext_name'])) {
119                 // Cache file is damaged so kill it
120                 $GLOBALS['cache_instance']->destroyCacheFile();
121
122                 // Retry it
123                 require(__FILE__);
124                 return;
125         } // END -  if
126
127         // Begin with the cache preparation of extensions
128         $EXT_NAMES = array();
129         foreach ($EXT_DUMMY['ext_name'] as $k => $name) {
130                 // Load CSS file
131                 if ($EXT_DUMMY['ext_css'][$k] == 'Y') EXT_ADD_CSS_FILE($name . '.css');
132
133                 // Load extension file itself
134                 if ((($EXT_DUMMY['ext_active'][$k] == 'Y') || ($EXT_DUMMY['ext_keep'][$k] == 'Y') || (IS_ADMIN())) && (!in_array($name, array('sql_patches', 'cache')))) {
135                         $EXT_POOL[] = $name;
136                 } // END - if
137
138                 // Version number
139                 $EXT_DUMMY['ext_version'][$name] = $EXT_DUMMY['ext_version'][$k];
140                 unset($EXT_DUMMY['ext_version'][$k]);
141
142                 // Extension is active
143                 $EXT_DUMMY['ext_active'][$name] = $EXT_DUMMY['ext_active'][$k];
144                 unset($EXT_DUMMY['ext_active'][$k]);
145
146                 // Ext menu
147                 $EXT_DUMMY['ext_menu'][$name] = $EXT_DUMMY['ext_menu'][$k];
148                 unset($EXT_DUMMY['ext_menu'][$k]);
149
150                 // Extension id
151                 $EXT_DUMMY['ext_id'][$name] = $EXT_DUMMY['ext_id'][$k];
152                 $id = $EXT_DUMMY['ext_id'][$name];
153                 unset($EXT_DUMMY['ext_id'][$k]);
154
155                 // Add ext name
156                 $EXT_NAMES[$id] = $name;
157
158                 // Add deprecated flag (defaults to 'not deprecated')
159                 $EXT_DUMMY['ext_deprecated'][$name] = 'N';
160
161                 // Mark it as active extension
162                 $GLOBALS['cache_array']['active_extensions']['$name'] = $EXT_DUMMY['ext_keep'][$k];
163                 unset($EXT_DUMMY['ext_keep'][$k]);
164
165                 // Remove unneccessary data from memory
166                 unset($EXT_DUMMY['ext_css'][$k]);
167         } // END - foreach
168
169         // Write dummy array back
170         $EXT_DUMMY['ext_name'] = $EXT_NAMES;
171         unset($EXT_NAMES);
172
173         // Loading cache is done so let's free some memory!
174         unset($EXT_DUMMY['ext_keep']);
175         unset($EXT_DUMMY['ext_css']);
176         $GLOBALS['cache_array']['extensions'] = $EXT_DUMMY;
177         unset($EXT_DUMMY);
178
179         // No database load needed
180         $res_ext_crt = false;
181
182         // Load all extension files
183         foreach ($EXT_POOL as $ext) {
184                 LOAD_EXTENSION($ext);
185         } // END - foreach
186
187         // Init filter system
188         initFilterSystem();
189
190         // Load more cache files (like admins)
191         loadIncludeOnce('inc/load_cache.php');
192
193         // Remove array
194         unset($EXT_POOL);
195 } else {
196         // If current user is not admin load only activated extensions. But load
197         // them all if we are going to init the cache files. The admin shall use
198         // every available extension for testing purposes.
199         if ((!IS_ADMIN()) && ($GLOBALS['cache_mode'] != 'init')) $add = " WHERE `ext_active`='Y'";
200
201         if (GET_EXT_VERSION('sql_patches') >= '0.0.6') {
202                 // Query with CSS file from DB
203                 $res_ext_crt = SQL_QUERY("SELECT id AS ext_id, ext_name, ext_has_css AS ext_css, ext_active, ext_version
204 FROM `{!_MYSQL_PREFIX!}_extensions`" . $add . "
205 ORDER BY ext_name", __FILE__, __LINE__);
206         } else {
207                 // Old obsolete query string
208                 $res_ext_crt = SQL_QUERY("SELECT id AS ext_id, ext_name, ext_name, ext_active, ext_version
209 FROM `{!_MYSQL_PREFIX!}_extensions`" . $add . "
210 ORDER BY ext_name", __FILE__, __LINE__);
211         }
212 }
213
214 // Array for removed but not uninstalled extensions
215 $DEL = array();
216
217 // At least one found?
218 if ((SQL_NUMROWS($res_ext_crt) > 0) && ((($GLOBALS['cache_mode'] == 'init') && ($GLOBALS['output_mode'] != '1') && ($GLOBALS['output_mode'] != '-1')) || ($GLOBALS['cache_mode'] == 'no'))) {
219         // Extensions are registered so we load them
220         while ($content = SQL_FETCHARRAY($res_ext_crt)) {
221                 // Get menu entry
222                 $content['ext_menu'] = 'N';
223                 if (MODULE_HAS_MENU($content['ext_name'], true)) {
224                         $content['ext_menu'] = 'Y';
225                 } // END - if
226
227                 // Generate FQFN for extension
228                 $FQFN = sprintf("%sinc/extensions/ext-%s.php", constant('PATH'), $content['ext_name']);
229
230                 // Does the extension file exists?
231                 if (isFileReadable($FQFN)) {
232                         // By default no extension is always active, except sql_patches
233                         EXT_SET_ALWAYS_ACTIVE('N');
234
235                         // Load extension
236                         if (($content['ext_name'] != 'sql_patches') && (($content['ext_name'] != 'cache') || (!EXT_IS_ACTIVE('cache')))) {
237                                 // Load extension
238                                 LOAD_EXTENSION($content['ext_name']);
239                         } else {
240                                 // Keep sql_patches always active
241                                 EXT_SET_ALWAYS_ACTIVE('Y');
242                         }
243
244                         // Transfer EXT_ALWAYS_ACTIVE flag
245                         $content['ext_keep'] = EXT_GET_ALWAYS_ACTIVE();
246
247                         // CSS file handling:
248                         if ((!isset($content['ext_css'])) || ($content['ext_css'] == 'Y')) {
249                                 // Create FQFN for the CSS file
250                                 $FQFN = sprintf("%stheme/%s/css/%s.css", constant('PATH'), getCurrentTheme(), $content['ext_name']);
251
252                                 // Is the file there?
253                                 if (isFileReadable($FQFN)) {
254                                         // CSS file for extension was found (use only relative path for now!)
255                                         EXT_ADD_CSS_FILE($content['ext_name'] . '.css');
256                                         $content['ext_css'] = 'Y';
257                                 } else {
258                                         // Don't load CSS file
259                                         $content['ext_css'] = 'N';
260                                 }
261                         } // END - if
262
263                         // Shall we cache?
264                         if ($GLOBALS['cache_mode'] == 'init') {
265                                 // Add cache row
266                                 $GLOBALS['cache_instance']->addRow($content);
267                         } elseif ($GLOBALS['cache_mode'] == 'no') {
268                                 // Remember this value for later usage
269                                 $GLOBALS['cache_array']['active_extensions'][$content['ext_name']] = EXT_GET_ALWAYS_ACTIVE();
270                         }
271                 } elseif (!isFileReadable($FQFN)) {
272                         // Deleted extension file so we mark it for removal from DB
273                         $DEL[] = $content['ext_name'];
274                 }
275         } // END - while
276
277         // Init filter system
278         initFilterSystem();
279
280         if ($GLOBALS['cache_mode'] == 'init') {
281                 // Close cache file
282                 $GLOBALS['cache_instance']->finalize();
283
284                 // Load more cache files (like admins)
285                 loadIncludeOnce('inc/load_cache.php');
286         } // END - if
287
288         // Free memory
289         SQL_FREERESULT($res_ext_crt);
290 } elseif (!EXT_IS_ACTIVE('cache')) {
291         // Init filter system even when there are no extensions installed. #16
292         initFilterSystem();
293 }
294
295 // Run the filter
296 runFilterChain('load_includes');
297
298 // Uninstall extensions that are no longer in our system
299 if (!empty($DEL[0])) {
300         // Remove extensions from two tables: extension registry and tasks table
301         foreach ($DEL as $del_ext) {
302                 // First remove entry from extensions table
303                 SQL_QUERY_ESC("DELETE LOW_PRIORITY FROM `{!_MYSQL_PREFIX!}_extensions` WHERE `ext_name`='%s' LIMIT 1",
304                 array($del_ext), __FILE__, __LINE__);
305
306                 // Remove (maybe?) found tasks (main task and possible updates
307                 SQL_QUERY_ESC("DELETE LOW_PRIORITY FROM `{!_MYSQL_PREFIX!}_task_system` WHERE subject='[%s:]' AND (task_type='EXTENSION' OR task_type='EXTENSION_UPDATE')",
308                 array($del_ext), __FILE__, __LINE__);
309         } // END - foreach
310
311         // I think it's not neccessary to run the optimization function here
312         // because we didn't delete so much data from database. Can you aggree?
313 } // END - if
314
315 //
316 ?>