84 |
86 |
85 **!* / |
87 **!* / |
86 </code> |
88 </code> |
87 * And finally, the format for upgrade schemas: |
89 * And finally, the format for upgrade schemas: |
88 <code> |
90 <code> |
89 /**!upgrade from = "0.1-alpha1" to = "0.1-alpha2" ** |
91 /**!upgrade from = "0.1-alpha1"; to = "0.1-alpha2"; ** |
90 |
92 |
91 **!* / |
93 **!* / |
92 </code> |
94 </code> |
|
95 * As a courtesy to your users, we ask that you also include an "uninstall" block that reverses any changes your plugin makes |
|
96 * to the database upon installation. The syntax is identical to that of the install block. |
|
97 * |
93 * Remember that upgrades will always be done incrementally, so if the user is upgrading 0.1-alpha2 to 0.1, Enano's plugin |
98 * Remember that upgrades will always be done incrementally, so if the user is upgrading 0.1-alpha2 to 0.1, Enano's plugin |
94 * engine will run the 0.1-alpha2 to 0.1-beta1 upgrader, then the 0.1-beta1 to 0.1 upgrader, going by the versions listed in |
99 * engine will run the 0.1-alpha2 to 0.1-beta1 upgrader, then the 0.1-beta1 to 0.1 upgrader, going by the versions listed in |
95 * the example metadata block above. |
100 * the example metadata block above. As with the standard Enano installer, prefixing a query with '@' will cause it to be |
|
101 * performed "blindly", e.g. not checked for errors. |
96 * |
102 * |
97 * All of this information is effective as of Enano 1.1.4. |
103 * All of this information is effective as of Enano 1.1.4. |
98 */ |
104 */ |
99 |
105 |
100 // Plugin manager "2.0" |
106 // Plugin manager "2.0" |
108 $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); |
114 $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); |
109 echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>'; |
115 echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>'; |
110 echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>'; |
116 echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>'; |
111 return; |
117 return; |
112 } |
118 } |
|
119 |
|
120 $plugin_list = $plugins->get_plugin_list(); |
113 |
121 |
114 // Are we processing an AJAX request from the smartform? |
122 // Are we processing an AJAX request from the smartform? |
115 if ( $paths->getParam(0) == 'action.json' ) |
123 if ( $paths->getParam(0) == 'action.json' ) |
116 { |
124 { |
117 // Set to application/json to discourage advertisement scripts |
125 // Set to application/json to discourage advertisement scripts |
131 // Is the action to perform specified? |
139 // Is the action to perform specified? |
132 if ( isset($request['mode']) ) |
140 if ( isset($request['mode']) ) |
133 { |
141 { |
134 switch ( $request['mode'] ) |
142 switch ( $request['mode'] ) |
135 { |
143 { |
|
144 case 'install': |
|
145 // did they specify a plugin to operate on? |
|
146 if ( !isset($request['plugin']) ) |
|
147 { |
|
148 $return = array( |
|
149 'mode' => 'error', |
|
150 'error' => 'No plugin specified.', |
|
151 ); |
|
152 break; |
|
153 } |
|
154 |
|
155 $return = $plugins->install_plugin($request['plugin'], $plugin_list); |
|
156 break; |
|
157 case 'upgrade': |
|
158 // did they specify a plugin to operate on? |
|
159 if ( !isset($request['plugin']) ) |
|
160 { |
|
161 $return = array( |
|
162 'mode' => 'error', |
|
163 'error' => 'No plugin specified.', |
|
164 ); |
|
165 break; |
|
166 } |
|
167 |
|
168 $return = $plugins->upgrade_plugin($request['plugin'], $plugin_list); |
|
169 break; |
|
170 case 'uninstall': |
|
171 // did they specify a plugin to operate on? |
|
172 if ( !isset($request['plugin']) ) |
|
173 { |
|
174 $return = array( |
|
175 'mode' => 'error', |
|
176 'error' => 'No plugin specified.', |
|
177 ); |
|
178 break; |
|
179 } |
|
180 |
|
181 $return = $plugins->uninstall_plugin($request['plugin'], $plugin_list); |
|
182 break; |
|
183 case 'disable': |
|
184 case 'enable': |
|
185 $flags_col = ( $request['mode'] == 'disable' ) ? |
|
186 "plugin_flags | " . PLUGIN_DISABLED : |
|
187 "plugin_flags & ~" . PLUGIN_DISABLED; |
|
188 // did they specify a plugin to operate on? |
|
189 if ( !isset($request['plugin']) ) |
|
190 { |
|
191 $return = array( |
|
192 'mode' => 'error', |
|
193 'error' => 'No plugin specified.', |
|
194 ); |
|
195 break; |
|
196 } |
|
197 // is the plugin in the directory and already installed? |
|
198 if ( !isset($plugin_list[$request['plugin']]) || ( |
|
199 isset($plugin_list[$request['plugin']]) && !$plugin_list[$request['plugin']]['installed'] |
|
200 )) |
|
201 { |
|
202 $return = array( |
|
203 'mode' => 'error', |
|
204 'error' => 'Invalid plugin specified.', |
|
205 ); |
|
206 break; |
|
207 } |
|
208 // get plugin id |
|
209 $dataset =& $plugin_list[$request['plugin']]; |
|
210 if ( empty($dataset['plugin id']) ) |
|
211 { |
|
212 $return = array( |
|
213 'mode' => 'error', |
|
214 'error' => 'Couldn\'t retrieve plugin ID.', |
|
215 ); |
|
216 break; |
|
217 } |
|
218 // perform update |
|
219 $q = $db->sql_query('UPDATE ' . table_prefix . "plugins SET plugin_flags = $flags_col WHERE plugin_id = {$dataset['plugin id']};"); |
|
220 if ( !$q ) |
|
221 $db->die_json(); |
|
222 |
|
223 $return = array( |
|
224 'success' => true |
|
225 ); |
|
226 break; |
|
227 case 'import': |
|
228 // import all of the plugin_* config entries |
|
229 $q = $db->sql_query('SELECT config_name, config_value FROM ' . table_prefix . "config WHERE config_name LIKE 'plugin_%';"); |
|
230 if ( !$q ) |
|
231 $db->die_json(); |
|
232 |
|
233 while ( $row = $db->fetchrow($q) ) |
|
234 { |
|
235 $plugin_filename = preg_replace('/^plugin_/', '', $row['config_name']); |
|
236 if ( isset($plugin_list[$plugin_filename]) && !@$plugin_list[$plugin_filename]['installed'] ) |
|
237 { |
|
238 $return = $plugins->install_plugin($plugin_filename, $plugin_list); |
|
239 if ( !$return['success'] ) |
|
240 break 2; |
|
241 if ( $row['config_value'] == '0' ) |
|
242 { |
|
243 $fn_db = $db->escape($plugin_filename); |
|
244 $q = $db->sql_query('UPDATE ' . table_prefix . "plugins SET plugin_flags = plugin_flags | " . PLUGIN_DISABLED . " WHERE plugin_filename = '$fn_db';"); |
|
245 if ( !$q ) |
|
246 $db->die_json(); |
|
247 } |
|
248 } |
|
249 } |
|
250 $db->free_result($q); |
|
251 |
|
252 $q = $db->sql_query('DELETE FROM ' . table_prefix . "config WHERE config_name LIKE 'plugin_%';"); |
|
253 if ( !$q ) |
|
254 $db->die_json(); |
|
255 |
|
256 $return = array('success' => true); |
|
257 break; |
136 default: |
258 default: |
137 // The requested action isn't something this script knows how to do |
259 // The requested action isn't something this script knows how to do |
138 $return = array( |
260 $return = array( |
139 'mode' => 'error', |
261 'mode' => 'error', |
140 'error' => 'Unknown mode "' . $request['mode'] . '" sent in request' |
262 'error' => 'Unknown mode "' . $request['mode'] . '" sent in request' |
176 |
298 |
177 // |
299 // |
178 // Not a JSON request, output normal HTML interface |
300 // Not a JSON request, output normal HTML interface |
179 // |
301 // |
180 |
302 |
181 // Scan all plugins |
|
182 $plugin_list = array(); |
|
183 |
|
184 if ( $dirh = @opendir( ENANO_ROOT . '/plugins' ) ) |
|
185 { |
|
186 while ( $dh = @readdir($dirh) ) |
|
187 { |
|
188 if ( !preg_match('/\.php$/i', $dh) ) |
|
189 continue; |
|
190 $fullpath = ENANO_ROOT . "/plugins/$dh"; |
|
191 // it's a PHP file, attempt to read metadata |
|
192 // pass 1: try to read a !info block |
|
193 $blockdata = $plugins->parse_plugin_blocks($fullpath, 'info'); |
|
194 if ( empty($blockdata) ) |
|
195 { |
|
196 // no !info block, check for old header |
|
197 $fh = @fopen($fullpath, 'r'); |
|
198 if ( !$fh ) |
|
199 // can't read, bail out |
|
200 continue; |
|
201 $plugin_data = array(); |
|
202 for ( $i = 0; $i < 8; $i++ ) |
|
203 { |
|
204 $plugin_data[] = @fgets($fh, 8096); |
|
205 } |
|
206 // close our file handle |
|
207 fclose($fh); |
|
208 // is the header correct? |
|
209 if ( trim($plugin_data[0]) != '<?php' || trim($plugin_data[1]) != '/*' ) |
|
210 { |
|
211 // nope. get out. |
|
212 continue; |
|
213 } |
|
214 // parse all the variables |
|
215 $plugin_meta = array(); |
|
216 for ( $i = 2; $i <= 7; $i++ ) |
|
217 { |
|
218 if ( !preg_match('/^([A-z0-9 ]+?): (.+?)$/', trim($plugin_data[$i]), $match) ) |
|
219 continue 2; |
|
220 $plugin_meta[ strtolower($match[1]) ] = $match[2]; |
|
221 } |
|
222 } |
|
223 else |
|
224 { |
|
225 // parse JSON block |
|
226 $plugin_data =& $blockdata[0]['value']; |
|
227 $plugin_data = enano_clean_json(enano_trim_json($plugin_data)); |
|
228 try |
|
229 { |
|
230 $plugin_meta_uc = enano_json_decode($plugin_data); |
|
231 } |
|
232 catch ( Exception $e ) |
|
233 { |
|
234 continue; |
|
235 } |
|
236 // convert all the keys to lowercase |
|
237 $plugin_meta = array(); |
|
238 foreach ( $plugin_meta_uc as $key => $value ) |
|
239 { |
|
240 $plugin_meta[ strtolower($key) ] = $value; |
|
241 } |
|
242 } |
|
243 if ( !isset($plugin_meta) || !is_array(@$plugin_meta) ) |
|
244 { |
|
245 // parsing didn't work. |
|
246 continue; |
|
247 } |
|
248 // check for required keys |
|
249 $required_keys = array('plugin name', 'plugin uri', 'description', 'author', 'version', 'author uri'); |
|
250 foreach ( $required_keys as $key ) |
|
251 { |
|
252 if ( !isset($plugin_meta[$key]) ) |
|
253 // not set, skip this plugin |
|
254 continue 2; |
|
255 } |
|
256 // decide if it's a system plugin |
|
257 $plugin_meta['system plugin'] = in_array($dh, $plugins->system_plugins); |
|
258 // reset installed variable |
|
259 $plugin_meta['installed'] = false; |
|
260 $plugin_meta['status'] = 0; |
|
261 // all checks passed |
|
262 $plugin_list[$dh] = $plugin_meta; |
|
263 } |
|
264 } |
|
265 // gather info about installed plugins |
|
266 $q = $db->sql_query('SELECT plugin_filename, plugin_version, plugin_flags FROM ' . table_prefix . 'plugins;'); |
|
267 if ( !$q ) |
|
268 $db->_die(); |
|
269 while ( $row = $db->fetchrow() ) |
|
270 { |
|
271 if ( !isset($plugin_list[ $row['plugin_filename'] ]) ) |
|
272 { |
|
273 // missing plugin file, don't report (for now) |
|
274 continue; |
|
275 } |
|
276 $filename =& $row['plugin_filename']; |
|
277 $plugin_list[$filename]['installed'] = true; |
|
278 $plugin_list[$filename]['status'] = PLUGIN_INSTALLED; |
|
279 if ( $row['plugin_version'] != $plugin_list[$filename]['version'] ) |
|
280 { |
|
281 $plugin_list[$filename]['status'] |= PLUGIN_OUTOFDATE; |
|
282 $plugin_list[$filename]['version installed'] = $row['plugin_version']; |
|
283 } |
|
284 if ( $row['plugin_flags'] & PLUGIN_DISABLED ) |
|
285 { |
|
286 $plugin_list[$filename]['status'] |= PLUGIN_DISABLED; |
|
287 } |
|
288 } |
|
289 $db->free_result(); |
|
290 |
|
291 // sort it all out by filename |
|
292 ksort($plugin_list); |
|
293 |
|
294 // start printing things out |
303 // start printing things out |
295 acp_start_form(); |
|
296 ?> |
304 ?> |
297 <div class="tblholder"> |
305 <div class="tblholder"> |
298 <table border="0" cellspacing="1" cellpadding="5"> |
306 <table border="0" cellspacing="1" cellpadding="5"> |
299 <?php |
307 <?php |
300 $rowid = '2'; |
308 $rowid = '2'; |