diff -r b2fb50d572c7 -r 21e11f564463 plugins/admin/PluginManager.php --- a/plugins/admin/PluginManager.php Wed Apr 09 19:27:02 2008 -0400 +++ b/plugins/admin/PluginManager.php Wed Apr 09 22:37:37 2008 -0400 @@ -26,7 +26,7 @@ * * The format for the special comment blocks is: - /**!blocktype( param1 = "value1" [ param2 = "value2" ... ] )** + /**!blocktype( param1 = "value1"; [ param2 = "value2"; ... ] )** ... block content ... @@ -58,7 +58,9 @@ /**!language** { + // each entry at this level should be an ISO-639-1 language code. eng: { + // from here on in is the standard langauge file format categories: [ 'meta', 'foo', 'bar' ], strings: { meta: { @@ -86,13 +88,17 @@ * And finally, the format for upgrade schemas: - /**!upgrade from = "0.1-alpha1" to = "0.1-alpha2" ** + /**!upgrade from = "0.1-alpha1"; to = "0.1-alpha2"; ** **!* / + * As a courtesy to your users, we ask that you also include an "uninstall" block that reverses any changes your plugin makes + * to the database upon installation. The syntax is identical to that of the install block. + * * Remember that upgrades will always be done incrementally, so if the user is upgrading 0.1-alpha2 to 0.1, Enano's plugin * 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 - * the example metadata block above. + * the example metadata block above. As with the standard Enano installer, prefixing a query with '@' will cause it to be + * performed "blindly", e.g. not checked for errors. * * All of this information is effective as of Enano 1.1.4. */ @@ -111,6 +117,8 @@ return; } + $plugin_list = $plugins->get_plugin_list(); + // Are we processing an AJAX request from the smartform? if ( $paths->getParam(0) == 'action.json' ) { @@ -133,6 +141,120 @@ { switch ( $request['mode'] ) { + case 'install': + // did they specify a plugin to operate on? + if ( !isset($request['plugin']) ) + { + $return = array( + 'mode' => 'error', + 'error' => 'No plugin specified.', + ); + break; + } + + $return = $plugins->install_plugin($request['plugin'], $plugin_list); + break; + case 'upgrade': + // did they specify a plugin to operate on? + if ( !isset($request['plugin']) ) + { + $return = array( + 'mode' => 'error', + 'error' => 'No plugin specified.', + ); + break; + } + + $return = $plugins->upgrade_plugin($request['plugin'], $plugin_list); + break; + case 'uninstall': + // did they specify a plugin to operate on? + if ( !isset($request['plugin']) ) + { + $return = array( + 'mode' => 'error', + 'error' => 'No plugin specified.', + ); + break; + } + + $return = $plugins->uninstall_plugin($request['plugin'], $plugin_list); + break; + case 'disable': + case 'enable': + $flags_col = ( $request['mode'] == 'disable' ) ? + "plugin_flags | " . PLUGIN_DISABLED : + "plugin_flags & ~" . PLUGIN_DISABLED; + // did they specify a plugin to operate on? + if ( !isset($request['plugin']) ) + { + $return = array( + 'mode' => 'error', + 'error' => 'No plugin specified.', + ); + break; + } + // is the plugin in the directory and already installed? + if ( !isset($plugin_list[$request['plugin']]) || ( + isset($plugin_list[$request['plugin']]) && !$plugin_list[$request['plugin']]['installed'] + )) + { + $return = array( + 'mode' => 'error', + 'error' => 'Invalid plugin specified.', + ); + break; + } + // get plugin id + $dataset =& $plugin_list[$request['plugin']]; + if ( empty($dataset['plugin id']) ) + { + $return = array( + 'mode' => 'error', + 'error' => 'Couldn\'t retrieve plugin ID.', + ); + break; + } + // perform update + $q = $db->sql_query('UPDATE ' . table_prefix . "plugins SET plugin_flags = $flags_col WHERE plugin_id = {$dataset['plugin id']};"); + if ( !$q ) + $db->die_json(); + + $return = array( + 'success' => true + ); + break; + case 'import': + // import all of the plugin_* config entries + $q = $db->sql_query('SELECT config_name, config_value FROM ' . table_prefix . "config WHERE config_name LIKE 'plugin_%';"); + if ( !$q ) + $db->die_json(); + + while ( $row = $db->fetchrow($q) ) + { + $plugin_filename = preg_replace('/^plugin_/', '', $row['config_name']); + if ( isset($plugin_list[$plugin_filename]) && !@$plugin_list[$plugin_filename]['installed'] ) + { + $return = $plugins->install_plugin($plugin_filename, $plugin_list); + if ( !$return['success'] ) + break 2; + if ( $row['config_value'] == '0' ) + { + $fn_db = $db->escape($plugin_filename); + $q = $db->sql_query('UPDATE ' . table_prefix . "plugins SET plugin_flags = plugin_flags | " . PLUGIN_DISABLED . " WHERE plugin_filename = '$fn_db';"); + if ( !$q ) + $db->die_json(); + } + } + } + $db->free_result($q); + + $q = $db->sql_query('DELETE FROM ' . table_prefix . "config WHERE config_name LIKE 'plugin_%';"); + if ( !$q ) + $db->die_json(); + + $return = array('success' => true); + break; default: // The requested action isn't something this script knows how to do $return = array( @@ -178,121 +300,7 @@ // Not a JSON request, output normal HTML interface // - // Scan all plugins - $plugin_list = array(); - - if ( $dirh = @opendir( ENANO_ROOT . '/plugins' ) ) - { - while ( $dh = @readdir($dirh) ) - { - if ( !preg_match('/\.php$/i', $dh) ) - continue; - $fullpath = ENANO_ROOT . "/plugins/$dh"; - // it's a PHP file, attempt to read metadata - // pass 1: try to read a !info block - $blockdata = $plugins->parse_plugin_blocks($fullpath, 'info'); - if ( empty($blockdata) ) - { - // no !info block, check for old header - $fh = @fopen($fullpath, 'r'); - if ( !$fh ) - // can't read, bail out - continue; - $plugin_data = array(); - for ( $i = 0; $i < 8; $i++ ) - { - $plugin_data[] = @fgets($fh, 8096); - } - // close our file handle - fclose($fh); - // is the header correct? - if ( trim($plugin_data[0]) != ' $value ) - { - $plugin_meta[ strtolower($key) ] = $value; - } - } - if ( !isset($plugin_meta) || !is_array(@$plugin_meta) ) - { - // parsing didn't work. - continue; - } - // check for required keys - $required_keys = array('plugin name', 'plugin uri', 'description', 'author', 'version', 'author uri'); - foreach ( $required_keys as $key ) - { - if ( !isset($plugin_meta[$key]) ) - // not set, skip this plugin - continue 2; - } - // decide if it's a system plugin - $plugin_meta['system plugin'] = in_array($dh, $plugins->system_plugins); - // reset installed variable - $plugin_meta['installed'] = false; - $plugin_meta['status'] = 0; - // all checks passed - $plugin_list[$dh] = $plugin_meta; - } - } - // gather info about installed plugins - $q = $db->sql_query('SELECT plugin_filename, plugin_version, plugin_flags FROM ' . table_prefix . 'plugins;'); - if ( !$q ) - $db->_die(); - while ( $row = $db->fetchrow() ) - { - if ( !isset($plugin_list[ $row['plugin_filename'] ]) ) - { - // missing plugin file, don't report (for now) - continue; - } - $filename =& $row['plugin_filename']; - $plugin_list[$filename]['installed'] = true; - $plugin_list[$filename]['status'] = PLUGIN_INSTALLED; - if ( $row['plugin_version'] != $plugin_list[$filename]['version'] ) - { - $plugin_list[$filename]['status'] |= PLUGIN_OUTOFDATE; - $plugin_list[$filename]['version installed'] = $row['plugin_version']; - } - if ( $row['plugin_flags'] & PLUGIN_DISABLED ) - { - $plugin_list[$filename]['status'] |= PLUGIN_DISABLED; - } - } - $db->free_result(); - - // sort it all out by filename - ksort($plugin_list); - // start printing things out - acp_start_form(); ?>
@@ -324,7 +332,7 @@ { $color = '_red'; $status = $lang->get('acppl_lbl_status_need_upgrade'); - $buttons = 'uninstall|update'; + $buttons = 'uninstall|upgrade'; } else if ( $data['installed'] && $data['status'] & PLUGIN_DISABLED ) { @@ -389,7 +397,7 @@
$status
-
$plugin_basics
@@ -410,5 +418,18 @@
'; + // are there still old style plugin entries? + $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "config WHERE config_name LIKE 'plugin_%';"); + if ( !$q ) + $db->_die(); + + $count = $db->numrows(); + $db->free_result($q); + + if ( $count > 0 ) + { + echo '

' . $lang->get('acppl_msg_old_entries_title') . '

'; + echo '

' . $lang->get('acppl_msg_old_entries_body') . '

'; + echo '

' . $lang->get('acppl_btn_import_old') . '

'; + } }