From d6877baca9b8c56ce3e1565791fa260cdc983d95 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 21 Nov 2010 00:37:54 -0500 Subject: Load data for all plugins on plugin management page. include.php: file to include to make creation of entry points easy index.php: move most of this file into include.php (and include it) plugindata.php: a separate entry point using include.php; load ALL plugins found, and write data gathered to plugindata.out.php .gitignore: add plugindata.out.php actions/pluginsadminpanel.php: * use plugindata.out.php's common_plugindata() instead of StatusNet::getPlugins() * give a button linking to plugindata.php, to refresh plugin data lib/pluginlist.php: * use plugindata.out.php's common_plugindata() instead of thowing the 'PluginVersion' event to currently enabled plugins * for the enable/disable forms: was: if (!$disabled) now: if ($enabled && (!$disabled)) lib/statusnet.php: move the list of filenames for a plugin into it's own public static function; this is used by plugindata.php --- .gitignore | 1 + actions/pluginsadminpanel.php | 19 ++-- include.php | 215 ++++++++++++++++++++++++++++++++++++++++++ index.php | 178 +--------------------------------- lib/pluginlist.php | 13 +-- lib/statusnet.php | 26 +++-- plugindata.php | 99 +++++++++++++++++++ 7 files changed, 353 insertions(+), 198 deletions(-) create mode 100644 include.php create mode 100644 plugindata.php diff --git a/.gitignore b/.gitignore index 217622c84..d0bc62298 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ good-config.php lac08.log php.log .DS_Store +plugindata.out.php diff --git a/actions/pluginsadminpanel.php b/actions/pluginsadminpanel.php index c1f4fe253..db76e6b3d 100644 --- a/actions/pluginsadminpanel.php +++ b/actions/pluginsadminpanel.php @@ -67,7 +67,10 @@ class PluginsadminpanelAction extends AdminPanelAction // TRANS: Instructions at top of plugin admin page. return _('Additional plugins can be enabled and configured manually. ' . 'See the online plugin ' . - 'documentation for more details.'); + 'documentation for more details.'). + '
'. + ''. + '
'; } /** @@ -83,19 +86,18 @@ class PluginsadminpanelAction extends AdminPanelAction // TRANS: Admin form section header $this->element('legend', null, _('Default plugins'), 'default'); - $this->showDefaultPlugins(); + $this->showPlugins(); $this->elementEnd('fieldset'); } /** - * Until we have a general plugin metadata infrastructure, for now - * we'll just list up the ones we know from the global default - * plugins list. + * Show a list of all plugins listed in 'plugindata.out.php' */ - protected function showDefaultPlugins() + protected function showPlugins() { - $plugins = array_keys(StatusNet::getPlugins()); + require_once INSTALLDIR.'/plugindata.out.php'; + $plugins = array_keys(common_plugindata()); natsort($plugins); if ($plugins) { @@ -103,8 +105,7 @@ class PluginsadminpanelAction extends AdminPanelAction $list->show(); } else { $this->element('p', null, - _('All default plugins have been disabled from the ' . - 'site\'s configuration file.')); + _('No plugins found.')); } } } diff --git a/include.php b/include.php new file mode 100644 index 000000000..b5a08c384 --- /dev/null +++ b/include.php @@ -0,0 +1,215 @@ +. + * + * @category StatusNet + * @package StatusNet + * @author Brenda Wallace + * @author Brion Vibber + * @author Christopher Vollick + * @author CiaranG + * @author Craig Andrews + * @author Evan Prodromou + * @author Gina Haeussge + * @author James Walker + * @author Jeffery To + * @author Mike Cochrane + * @author Robin Millette + * @author Sarven Capadisli + * @author Tom Adams + * @author Zach Copley + * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org + * + * @license GNU Affero General Public License http://www.gnu.org/licenses/ + */ + +define('INSTALLDIR', dirname(__FILE__)); +define('GNUSOCIAL', true); +define('STATUSNET', true); +define('LACONICA', true); // compatibility + +function getPath($req) +{ + if ((common_config('site', 'fancy') || !array_key_exists('PATH_INFO', $_SERVER)) + && array_key_exists('p', $req) + ) { + return $req['p']; + } else if (array_key_exists('PATH_INFO', $_SERVER)) { + $path = $_SERVER['PATH_INFO']; + $script = $_SERVER['SCRIPT_NAME']; + if (substr($path, 0, mb_strlen($script)) == $script) { + return substr($path, mb_strlen($script)); + } else { + return $path; + } + } else { + return null; + } +} + +/** + * logs and then displays error messages + * + * @return void + */ +function handleError($error) +{ + try { + + if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { + return; + } + + $logmsg = "PEAR error: " . $error->getMessage(); + if ($error instanceof PEAR_Exception && common_config('site', 'logdebug')) { + $logmsg .= " : ". $error->toText(); + } + // DB queries often end up with a lot of newlines; merge to a single line + // for easier grepability... + $logmsg = str_replace("\n", " ", $logmsg); + common_log(LOG_ERR, $logmsg); + + // @fixme backtrace output should be consistent with exception handling + if (common_config('site', 'logdebug')) { + $bt = $error->getTrace(); + foreach ($bt as $n => $line) { + common_log(LOG_ERR, formatBacktraceLine($n, $line)); + } + } + if ($error instanceof DB_DataObject_Error + || $error instanceof DB_Error + || ($error instanceof PEAR_Exception && $error->getCode() == -24) + ) { + //If we run into a DB error, assume we can't connect to the DB at all + //so set the current user to null, so we don't try to access the DB + //while rendering the error page. + global $_cur; + $_cur = null; + + $msg = sprintf( + _( + 'The database for %s isn\'t responding correctly, '. + 'so the site won\'t work properly. '. + 'The site admins probably know about the problem, '. + 'but you can contact them at %s to make sure. '. + 'Otherwise, wait a few minutes and try again.' + ), + common_config('site', 'name'), + common_config('site', 'email') + ); + } else { + $msg = _( + 'An important error occured, probably related to email setup. '. + 'Check logfiles for more info..' + ); + } + + $dac = new DBErrorAction($msg, 500); + $dac->showPage(); + + } catch (Exception $e) { + echo _('An error occurred.'); + } + exit(-1); +} + +set_exception_handler('handleError'); + +require_once INSTALLDIR . '/lib/common.php'; + +/** + * Format a backtrace line for debug output roughly like debug_print_backtrace() does. + * Exceptions already have this built in, but PEAR error objects just give us the array. + * + * @param int $n line number + * @param array $line per-frame array item from debug_backtrace() + * @return string + */ +function formatBacktraceLine($n, $line) +{ + $out = "#$n "; + if (isset($line['class'])) $out .= $line['class']; + if (isset($line['type'])) $out .= $line['type']; + if (isset($line['function'])) $out .= $line['function']; + $out .= '('; + if (isset($line['args'])) { + $args = array(); + foreach ($line['args'] as $arg) { + // debug_print_backtrace seems to use var_export + // but this gets *very* verbose! + $args[] = gettype($arg); + } + $out .= implode(',', $args); + } + $out .= ')'; + $out .= ' called at ['; + if (isset($line['file'])) $out .= $line['file']; + if (isset($line['line'])) $out .= ':' . $line['line']; + $out .= ']'; + return $out; +} + +function setupRW() +{ + global $config; + + static $alwaysRW = array('session', 'remember_me'); + + // We ensure that these tables always are used + // on the master DB + + $config['db']['database_rw'] = $config['db']['database']; + $config['db']['ini_rw'] = INSTALLDIR.'/classes/statusnet.ini'; + + foreach ($alwaysRW as $table) { + $config['db']['table_'.$table] = 'rw'; + } +} + +function checkMirror($action_obj, $args) +{ + global $config; + + if (common_config('db', 'mirror') && $action_obj->isReadOnly($args)) { + if (is_array(common_config('db', 'mirror'))) { + // "load balancing", ha ha + $arr = common_config('db', 'mirror'); + $k = array_rand($arr); + $mirror = $arr[$k]; + } else { + $mirror = common_config('db', 'mirror'); + } + + // everyone else uses the mirror + + $config['db']['database'] = $mirror; + } +} + +function isLoginAction($action) +{ + static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp', 'opensearch', 'rsd'); + + $login = null; + + if (Event::handle('LoginAction', array($action, &$login))) { + $login = in_array($action, $loginActions); + } + + return $login; +} + diff --git a/index.php b/index.php index 0aceeda55..32f14b5c6 100644 --- a/index.php +++ b/index.php @@ -37,183 +37,7 @@ * @license GNU Affero General Public License http://www.gnu.org/licenses/ */ -define('INSTALLDIR', dirname(__FILE__)); -define('STATUSNET', true); -define('LACONICA', true); // compatibility - -$user = null; -$action = null; - -function getPath($req) -{ - if ((common_config('site', 'fancy') || !array_key_exists('PATH_INFO', $_SERVER)) - && array_key_exists('p', $req) - ) { - return $req['p']; - } else if (array_key_exists('PATH_INFO', $_SERVER)) { - $path = $_SERVER['PATH_INFO']; - $script = $_SERVER['SCRIPT_NAME']; - if (substr($path, 0, mb_strlen($script)) == $script) { - return substr($path, mb_strlen($script)); - } else { - return $path; - } - } else { - return null; - } -} - -/** - * logs and then displays error messages - * - * @return void - */ -function handleError($error) -{ - try { - - if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { - return; - } - - $logmsg = "PEAR error: " . $error->getMessage(); - if ($error instanceof PEAR_Exception && common_config('site', 'logdebug')) { - $logmsg .= " : ". $error->toText(); - } - // DB queries often end up with a lot of newlines; merge to a single line - // for easier grepability... - $logmsg = str_replace("\n", " ", $logmsg); - common_log(LOG_ERR, $logmsg); - - // @fixme backtrace output should be consistent with exception handling - if (common_config('site', 'logdebug')) { - $bt = $error->getTrace(); - foreach ($bt as $n => $line) { - common_log(LOG_ERR, formatBacktraceLine($n, $line)); - } - } - if ($error instanceof DB_DataObject_Error - || $error instanceof DB_Error - || ($error instanceof PEAR_Exception && $error->getCode() == -24) - ) { - //If we run into a DB error, assume we can't connect to the DB at all - //so set the current user to null, so we don't try to access the DB - //while rendering the error page. - global $_cur; - $_cur = null; - - $msg = sprintf( - _( - 'The database for %s isn\'t responding correctly, '. - 'so the site won\'t work properly. '. - 'The site admins probably know about the problem, '. - 'but you can contact them at %s to make sure. '. - 'Otherwise, wait a few minutes and try again.' - ), - common_config('site', 'name'), - common_config('site', 'email') - ); - } else { - $msg = _( - 'An important error occured, probably related to email setup. '. - 'Check logfiles for more info..' - ); - } - - $dac = new DBErrorAction($msg, 500); - $dac->showPage(); - - } catch (Exception $e) { - echo _('An error occurred.'); - } - exit(-1); -} - -set_exception_handler('handleError'); - -require_once INSTALLDIR . '/lib/common.php'; - -/** - * Format a backtrace line for debug output roughly like debug_print_backtrace() does. - * Exceptions already have this built in, but PEAR error objects just give us the array. - * - * @param int $n line number - * @param array $line per-frame array item from debug_backtrace() - * @return string - */ -function formatBacktraceLine($n, $line) -{ - $out = "#$n "; - if (isset($line['class'])) $out .= $line['class']; - if (isset($line['type'])) $out .= $line['type']; - if (isset($line['function'])) $out .= $line['function']; - $out .= '('; - if (isset($line['args'])) { - $args = array(); - foreach ($line['args'] as $arg) { - // debug_print_backtrace seems to use var_export - // but this gets *very* verbose! - $args[] = gettype($arg); - } - $out .= implode(',', $args); - } - $out .= ')'; - $out .= ' called at ['; - if (isset($line['file'])) $out .= $line['file']; - if (isset($line['line'])) $out .= ':' . $line['line']; - $out .= ']'; - return $out; -} - -function setupRW() -{ - global $config; - - static $alwaysRW = array('session', 'remember_me'); - - // We ensure that these tables always are used - // on the master DB - - $config['db']['database_rw'] = $config['db']['database']; - $config['db']['ini_rw'] = INSTALLDIR.'/classes/statusnet.ini'; - - foreach ($alwaysRW as $table) { - $config['db']['table_'.$table] = 'rw'; - } -} - -function checkMirror($action_obj, $args) -{ - global $config; - - if (common_config('db', 'mirror') && $action_obj->isReadOnly($args)) { - if (is_array(common_config('db', 'mirror'))) { - // "load balancing", ha ha - $arr = common_config('db', 'mirror'); - $k = array_rand($arr); - $mirror = $arr[$k]; - } else { - $mirror = common_config('db', 'mirror'); - } - - // everyone else uses the mirror - - $config['db']['database'] = $mirror; - } -} - -function isLoginAction($action) -{ - static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp', 'opensearch', 'rsd'); - - $login = null; - - if (Event::handle('LoginAction', array($action, &$login))) { - $login = in_array($action, $loginActions); - } - - return $login; -} +require('include.php'); function main() { diff --git a/lib/pluginlist.php b/lib/pluginlist.php index 07a17ba39..0e1a81249 100644 --- a/lib/pluginlist.php +++ b/lib/pluginlist.php @@ -154,11 +154,13 @@ class PluginListItem extends Widget */ protected function getControlForm() { - $key = 'disable-' . $this->plugin; - if (common_config('plugins', $key)) { - return new PluginEnableForm($this->out, $this->plugin); - } else { + $enabled = array_key_exists($this->plugin, StatusNet::getPlugins()); + $disabled = common_config('plugins', 'disable-'.$this->plugin); + + if ( $enabled && (!$disabled) ) { // then return new PluginDisableForm($this->out, $this->plugin); + } else { + return new PluginEnableForm($this->out, $this->plugin); } } @@ -204,8 +206,7 @@ class PluginListItem extends Widget protected static function getPluginVersions() { if (!is_array(self::$versions)) { - $versions = array(); - Event::handle('PluginVersion', array(&$versions)); + $versions = common_plugindata(); self::$versions = $versions; } return self::$versions; diff --git a/lib/statusnet.php b/lib/statusnet.php index f8bf87960..63d8cb3da 100644 --- a/lib/statusnet.php +++ b/lib/statusnet.php @@ -33,6 +33,25 @@ class StatusNet protected static $is_api; protected static $plugins = array(); + /** + * Return a list of possible filenames that plugin $name can be in. + * + * @param string $name class name & plugin file/subdir name + */ + public static function pluginFiles($name) { + $name = ucfirst($name); + $pluginclass = "{$name}Plugin"; + + $files = array("local/plugins/{$pluginclass}.php", + "local/plugins/{$name}/{$pluginclass}.php", + "local/{$pluginclass}.php", + "local/{$name}/{$pluginclass}.php", + "plugins/{$pluginclass}.php", + "plugins/{$name}/{$pluginclass}.php"); + + return $files; + } + /** * Configure and instantiate a plugin into the current configuration. * Class definitions will be loaded from standard paths if necessary. @@ -50,12 +69,7 @@ class StatusNet if (!class_exists($pluginclass)) { - $files = array("local/plugins/{$pluginclass}.php", - "local/plugins/{$name}/{$pluginclass}.php", - "local/{$pluginclass}.php", - "local/{$name}/{$pluginclass}.php", - "plugins/{$pluginclass}.php", - "plugins/{$name}/{$pluginclass}.php"); + $files = self::pluginFiles($name); foreach ($files as $file) { $fullpath = INSTALLDIR.'/'.$file; diff --git a/plugindata.php b/plugindata.php new file mode 100644 index 000000000..58c5bacda --- /dev/null +++ b/plugindata.php @@ -0,0 +1,99 @@ +. + * + * @category StatusNet + * @package StatusNet + * @author Luke Shumaker + * @copyright 2010 Free Software Foundation, Inc http://www.fsf.org + * + * @license GNU Affero General Public License http://www.gnu.org/licenses/ + */ + +require('include.php'); + +function main() { + // Check permissions + + if (!common_logged_in()) { + // TRANS: Client error message thrown when trying to load plugin data while not logged in. + echo(_('Not logged in.')."\n"); + return false; + } + $user = common_current_user(); + assert(!empty($user)); + if (!$user->hasRight(Right::CONFIGURESITE)) { + // TRANS: Client error message thrown when a user tries to load plugin data but has no access rights. + echo(_('You cannot make changes to this site.')."\n"); + return false; + } + + // Do stuff + + $possibleFiles = StatusNet::pluginFiles('*'); + foreach ($possibleFiles as $pattern) { + $regex = '/'.str_replace('/','\/',str_replace('*','(.*)',$pattern)).'/'; + $matches = glob($pattern); + foreach ($matches as $file) { + $name = preg_replace($regex,'\1',$file); + loadPlugin($name,$file,$data); + } + } + $redirect = isset($_SERVER['HTTP_REFERER']); + + $fileName = 'plugindata.out.php'; + $fh = fopen($fileName, 'w'); + if (!$fh) { + $redirect = false; + // TRANS: Client error message thrown when plugindata.out.php can't be opened + echo(_("ERROR: cannot open 'plugindata.out.php' for writing.")."\n"); + } + fwrite($fh, "onPluginVersion($newData); + foreach ($newData as $pluginInfo) { + $data[$pluginName] = $pluginInfo; + } + } +} + +main(); -- cgit v1.2.3-54-g00ecf