From: Stig Bakken Date: Mon, 18 Mar 2002 17:39:52 +0000 (+0000) Subject: * Refactoring of "pear" command internals. Highlights: X-Git-Tag: php-4.3.0dev-ZendEngine2-Preview1~1265 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a036fe5b728f2dfc57568b0c8058b71c2fb30438;p=php * Refactoring of "pear" command internals. Highlights: - user interface abstraction, making a Gtk installer should only be a matter of implementing PEAR_CommandUI_Gtk plus a "pear-gtk" executable - separated code into command classes, able to specify one or more commands - no more "pear-get" :-) * fixed use of PEAR_Config::singleton to avoid object copying --- diff --git a/pear/DB.php b/pear/DB.php index 86125a2b60..22cff1f81c 100644 --- a/pear/DB.php +++ b/pear/DB.php @@ -261,6 +261,9 @@ class DB @$obj =& new $classname; + if (isset($options['connect_ondemand']) && !extension_loaded("overload")) { + unset($options['connect_ondemand']); + } if (is_array($options)) { foreach ($options as $option => $value) { $test = $obj->setOption($option, $value); @@ -271,11 +274,14 @@ class DB } else { $obj->setOption('persistent', $options); } - $err = $obj->connect($dsninfo, $obj->getOption('persistent')); - - if (DB::isError($err)) { - $err->addUserInfo($dsn); - return $err; + if (!$obj->getOption('connect_ondemand')) { + $err = $obj->connect($dsninfo, $obj->getOption('persistent')); + if (DB::isError($err)) { + $err->addUserInfo($dsn); + return $err; + } + } else { + $obj->dsn = $dsninfo; } return $obj; diff --git a/pear/Makefile.frag b/pear/Makefile.frag index 11362207d4..5ae5c55257 100644 --- a/pear/Makefile.frag +++ b/pear/Makefile.frag @@ -20,6 +20,8 @@ PEAR_SUBDIRS = \ Mail \ Net \ PEAR \ + PEAR/Command \ + PEAR/CommandUI \ Schedule \ XML @@ -67,6 +69,13 @@ PEAR_FILES = \ Net/Socket.php \ PEAR.php \ PEAR/Autoloader.php \ + PEAR/Command.php \ + PEAR/Command/Common.php \ + PEAR/Command/Config.php \ + PEAR/Command/Install.php \ + PEAR/Command/Login.php \ + PEAR/CommandResponse.php \ + PEAR/CommandUI/CLI.php \ PEAR/Common.php \ PEAR/Config.php \ PEAR/Dependency.php \ @@ -79,17 +88,6 @@ PEAR_FILES = \ System.php \ XML/Parser.php -PEAR_COMMAND_LIBS = \ - pearcmd-common.php \ - pearcmd-help.php \ - pearcmd-info.php \ - pearcmd-install.php \ - pearcmd-list.php \ - pearcmd-package.php \ - pearcmd-remote-list.php \ - pearcmd-show-config.php \ - pearcmd-uninstall.php - install-pear: @if $(mkinstalldirs) $(INSTALL_ROOT)$(peardir); then \ for i in $(PEAR_SUBDIRS); do \ @@ -131,10 +129,6 @@ install-programs: for prog in phpextdist; do \ echo "Installing program: $$prog"; \ $(INSTALL) -m 755 $(srcdir)/scripts/$$prog $(INSTALL_ROOT)$(bindir)/$$prog; \ - done; \ - for lib in $(PEAR_COMMAND_LIBS); do \ - echo "Installing program library: $$lib"; \ - $(INSTALL) -m 644 $(srcdir)/scripts/$$lib $(INSTALL_ROOT)$(bindir)/$$lib; \ done HEADER_DIRS = \ diff --git a/pear/PEAR/Command.php b/pear/PEAR/Command.php index 49807d0339..d7944c6777 100644 --- a/pear/PEAR/Command.php +++ b/pear/PEAR/Command.php @@ -27,6 +27,12 @@ require_once "PEAR.php"; */ $GLOBALS['_PEAR_Command_commandlist'] = array(); +/** + * Which user interface class is being used. + * @var string class name + */ +$GLOBALS['_PEAR_Command_uiclass'] = 'PEAR_CommandUI_CLI'; + /** * PEAR command class, a simple factory class for administrative * commands. @@ -82,17 +88,40 @@ class PEAR_Command * * @access public */ - function factory(&$config, $command) + function factory($command) { if (empty($GLOBALS['_PEAR_Command_commandlist'])) { PEAR_Command::registerCommands(); } if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; - $obj =& new $class($config); + $obj = &new $class(PEAR_Command::getUIObject()); return $obj; } - return PEAR::raiseError("unknown command: $command"); + return PEAR::raiseError("unknown command `$command'"); + } + + function &getUIObject() + { + global $_PEAR_Command_uiclass, $_PEAR_Command_uiobject; + if (empty($_PEAR_Command_uiobject)) { + $_PEAR_Command_uiobject = &new $_PEAR_Command_uiclass; + } + return $_PEAR_Command_uiobject; + } + + function setUIClass($uiclass) + { + $GLOBALS['_PEAR_Command_uiclass'] = $uiclass; + $file = str_replace("_", "/", $uiclass) . '.php'; + include_once $file; + return class_exists(strtolower($uiclass)); + } + + function setUIType($uitype) + { + $uiclass = 'PEAR_CommandUI_' . $uitype; + return PEAR_Command::setUIClass($uiclass); } /** @@ -119,13 +148,16 @@ class PEAR_Command } $dp = @opendir($dir); if (empty($dp)) { - return PEAR::raiseError("PEAR_Command::registerCommands: opendir($dir) failed"); + return PEAR::raiseError("PEAR_Command::registerCommands: ". + "opendir($dir) failed"); } if (!$merge) { $GLOBALS['_PEAR_Command_commandlist'] = array(); } while ($entry = readdir($dp)) { - if ($entry{0} == '.' || substr($entry, -4) != '.php' || $entry == 'Common.php') { + if ($entry{0} == '.' || substr($entry, -4) != '.php' || + $entry == 'Common.php') + { continue; } $class = "PEAR_Command_".substr($entry, 0, -4); @@ -149,6 +181,9 @@ class PEAR_Command */ function getCommands() { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } return $GLOBALS['_PEAR_Command_commandlist']; } } diff --git a/pear/PEAR/Command/Common.php b/pear/PEAR/Command/Common.php index e54c1694f1..0fc50f4aaf 100644 --- a/pear/PEAR/Command/Common.php +++ b/pear/PEAR/Command/Common.php @@ -19,7 +19,7 @@ // $Id$ require_once "PEAR.php"; -require_once "PEAR/CommandResponse.php"; +//require_once "PEAR/CommandResponse.php"; class PEAR_Command_Common extends PEAR { @@ -31,15 +31,22 @@ class PEAR_Command_Common extends PEAR */ var $config; + /** + * User Interface object, for all interaction with the user. + * @var object + */ + var $ui; + /** * PEAR_Command_Common constructor. * * @access public */ - function PEAR_Command_Common() + function PEAR_Command_Common(&$ui) { parent::PEAR(); - $this->config = PEAR_Config::singleton(); + $this->config = &PEAR_Config::singleton(); + $this->ui = $ui; } /** @@ -56,13 +63,13 @@ class PEAR_Command_Common extends PEAR * * @see PEAR_CommandResponse */ +/* function &makeResponse($status, $message, $encoding = null) { - $obj =& new PEAR_CommandResponse($status, $message, $encoding); + $obj = &new PEAR_CommandResponse($status, $message, $encoding); return $obj; } - - +*/ } ?> \ No newline at end of file diff --git a/pear/PEAR/Command/Config.php b/pear/PEAR/Command/Config.php new file mode 100644 index 0000000000..9664f57fe7 --- /dev/null +++ b/pear/PEAR/Command/Config.php @@ -0,0 +1,127 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id$ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Config.php"; + +/** + * PEAR commands for managing configuration data. + * + */ +class PEAR_Command_Config extends PEAR_Command_Common +{ + // {{{ properties + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Config constructor. + * + * @access public + */ + function PEAR_Command_Config($ui) + { + parent::PEAR_Command_Common($ui); + } + + // }}} + + // {{{ getCommands() + + /** + * Return a list of all the commands defined by this class. + * @return array list of commands + * @access public + */ + function getCommands() + { + return array('config-show', 'config-get', 'config-set'); + } + + // }}} + // {{{ run() + + function run($command, $options, $params) + { + $cf = $this->config; + $failmsg = ''; + switch ($command) { + case 'config-show': { + $keys = $cf->getKeys(); + if (isset($params[0]) && $cf->isDefined($params[0])) { + foreach ($keys as $key) { + $type = $cf->getType($key); + if ($type == 'password') { + $this->ui->displayLine("$key = ********"); + } else { + $this->ui->displayLine("$key = " . $cf->get($key, $params[0])); + } + } + } else { + foreach ($keys as $key) { + $type = $cf->getType($key); + if ($type == 'password') { + $this->ui->displayLine("$key = ********"); + } else { + $this->ui->displayLine("$key = " . $cf->get($key)); + } + } + } + break; + } + case 'config-get': { + if (sizeof($params) < 1 || sizeof($params) > 2) { + $failmsg .= "config-get expects 1 or 2 parameters"; + } elseif (sizeof($params) == 1) { + $this->ui->displayLine("$params[0] = " . $cf->get($params[0])); + } else { + $this->ui->displayLine("($params[1])$params[0] = " . + $cf->get($params[0], $params[1])); + } + break; + } + case 'config-set': { + if (sizeof($params) < 2 || sizeof($params) > 3) { + $failmsg .= "config-set expects 2 or 3 parameters"; + break; + } else { + if (!call_user_func_array(array($cf, 'set'), $params)) + { + $failmsg = "config-set (" . + implode(", ", $params) . ") failed"; + } + } + break; + } + default: { + return false; + } + } + if ($failmsg) { + return $this->raiseError($failmsg); + } + return true; + } + + // }}} +} + +?> \ No newline at end of file diff --git a/pear/PEAR/Command/Install.php b/pear/PEAR/Command/Install.php index 0d99f85b1a..658f4a7b29 100644 --- a/pear/PEAR/Command/Install.php +++ b/pear/PEAR/Command/Install.php @@ -28,6 +28,8 @@ require_once "PEAR/Installer.php"; */ class PEAR_Command_Install extends PEAR_Command_Common { + // {{{ properties + /** Stack of executing commands, to make run() re-entrant * @var array */ @@ -38,16 +40,24 @@ class PEAR_Command_Install extends PEAR_Command_Common */ var $command; // XXX UNUSED + // }}} + + // {{{ constructor + /** * PEAR_Command_Install constructor. * * @access public */ - function PEAR_Command_Install() + function PEAR_Command_Install($ui) { - parent::PEAR_Command_Common(); + parent::PEAR_Command_Common($ui); } + // }}} + + // {{{ getCommands() + /** * Return a list of all the commands defined by this class. * @return array list of commands @@ -58,14 +68,16 @@ class PEAR_Command_Install extends PEAR_Command_Common return array('install', 'uninstall', 'upgrade'); } + // }}} + // {{{ run() + function run($command, $options, $params) { $installer =& new PEAR_Installer($options['php_dir'], $options['ext_dir'], $options['doc_dir']); $installer->debug = @$options['verbose']; - $status = PEAR_COMMAND_SUCCESS; - ob_start(); + $failmsg = ''; switch ($command) { case 'install': case 'upgrade': { @@ -73,27 +85,31 @@ class PEAR_Command_Install extends PEAR_Command_Common $options['upgrade'] = true; } if ($installer->install($params[0], $options, $this->config)) { - print "install ok\n"; + $this->ui->displayLine("install ok"); } else { - print "install failed\n"; - $status = PEAR_COMMAND_FAILURE; + $failmsg = "install failed"; } break; } case 'uninstall': { if ($installer->uninstall($params[0], $uninstall_options)) { - print "uninstall ok\n"; + $this->ui->displayLine("uninstall ok"); } else { - print "uninstall failed\n"; - $status = PEAR_COMMAND_FAILURE; + $failmsg = "uninstall failed"; } break; } + default: { + return false; + } } - $output = ob_get_contents(); - ob_end_clean(); - return $this->makeResponse($status, $output); + if ($failmsg) { + return $this->raiseError($failmsg); + } + return true; } + + // }}} } ?> \ No newline at end of file diff --git a/pear/PEAR/Command/Login.php b/pear/PEAR/Command/Login.php new file mode 100644 index 0000000000..e01da96088 --- /dev/null +++ b/pear/PEAR/Command/Login.php @@ -0,0 +1,107 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id$ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Remote.php"; +require_once "PEAR/Config.php"; + +/** + * PEAR commands for managing configuration data. + * + */ +class PEAR_Command_Login extends PEAR_Command_Common +{ + // {{{ properties + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Login constructor. + * + * @access public + */ + function PEAR_Command_Login($ui) + { + parent::PEAR_Command_Common($ui); + } + + // }}} + + // {{{ getCommands() + + /** + * Return a list of all the commands defined by this class. + * @return array list of commands + * @access public + */ + function getCommands() + { + return array('login', 'logout'); + } + + // }}} + // {{{ run() + + function run($command, $options, $params) + { + $cf = $this->config; + $failmsg = ''; + $server = $cf->get('master_server'); + switch ($command) { + case 'login': { + $username = $cf->get('username'); + if (empty($username)) { + $this->ui->displayLine("Logging in to $server."); + $username = trim($this->ui->userDialog('Username')); + $cf->set('username', $username); + } else { + $this->ui->displayLine("Logging in as `$username' to $server."); + } + $password = trim($this->ui->userDialog('Password', 'password')); + $cf->set('password', $password); + $cf->store(); + $remote = new PEAR_Remote; + $ok = $remote->call('logintest'); + print "logintest=";var_dump($ok); + break; + } + case 'logout': { + $this->ui->displayLine("Logging out from $server."); + $cf->remove('username'); + $cf->remove('password'); + $cf->store(); + break; + } + default: { + $failmsg = "unknown command: $command"; + break; + } + } + if ($failmsg) { + return $this->raiseError($failmsg); + } + return true; + } + + // }}} +} + +?> \ No newline at end of file diff --git a/pear/PEAR/CommandUI/CLI.php b/pear/PEAR/CommandUI/CLI.php new file mode 100644 index 0000000000..816abde4b4 --- /dev/null +++ b/pear/PEAR/CommandUI/CLI.php @@ -0,0 +1,94 @@ +output_mode) { + $this->endOutput(); + } + } + + function displayLine($text) + { + print "$text\n"; + } + + function userDialog($prompt, $type = 'text') + { + if ($type == 'password') { + system('stty -echo'); + } + print "$prompt : "; + $fp = fopen("php://stdin", "r"); + $line = fgets($fp, 2048); + fclose($fp); + if ($type == 'password') { + system('stty echo'); + print "\n"; + } + return $line; + } + + function userConfirm($prompt, $default = 'yes') + { + static $positives = array('y', 'yes', 'on', '1'); + static $negatives = array('n', 'no', 'off', '0'); + print "$prompt [$default] : "; + $fp = fopen("php://stdin", "r"); + $line = fgets($fp, 2048); + fclose($fp); + $answer = strtolower(trim($line)); + if (empty($answer)) { + $answer = $default; + } + if (in_array($answer, $positives)) { + return true; + } + if (in_array($answer, $negatives)) { + return false; + } + if (in_array($default, $positives)) { + return true; + } + return false; + } + + function setOutputMode($mode, $params = array()) + { + $this->output_mode = $mode; + $this->output_mode_params = $params; + } + + function startOutput($mode) + { + if ($this->output_mode) { + $this->endOutput(); + } + switch ($mode) { + } + } + + function endOutput($mode = null) + { + if ($mode === null) { + $mode = $this->output_mode; + } + $this->output_mode = ''; + switch ($mode) { + } + } +} + +?> \ No newline at end of file diff --git a/pear/PEAR/Config.php b/pear/PEAR/Config.php index 1cb4c8eb59..75d38a2ddd 100644 --- a/pear/PEAR/Config.php +++ b/pear/PEAR/Config.php @@ -24,7 +24,7 @@ require_once 'PEAR.php'; * Last created PEAR_Config instance. * @var object */ -$GLOBALS['_PEAR_Config_last_instance'] = null; +$GLOBALS['_PEAR_Config_instance'] = null; define('PEAR_CONFIG_DEFAULT_DOCDIR', PHP_DATADIR.DIRECTORY_SEPARATOR.'pear'.DIRECTORY_SEPARATOR.'doc'); @@ -165,7 +165,6 @@ class PEAR_Config extends PEAR $this->layers = array_keys($this->configuration); $this->files['user'] = $user_file; $this->files['system'] = $system_file; - $GLOBALS['_PEAR_Config_last_instance'] = &$this; if ($user_file && file_exists($user_file)) { $this->readConfigFile($user_file); } @@ -175,6 +174,7 @@ class PEAR_Config extends PEAR foreach ($this->configuration_info as $key => $info) { $this->configuration['default'][$key] = $info['default']; } + //$GLOBALS['_PEAR_Config_instance'] = &$this; } // }}} @@ -197,11 +197,12 @@ class PEAR_Config extends PEAR */ function &singleton($user_file = '', $system_file = '') { - if (empty($GLOBALS['_PEAR_Config_last_instance'])) { - $obj =& new PEAR_Config($user_file, $system_file); - $GLOBALS['_PEAR_Config_last_instance'] = &$obj; + if (is_object($GLOBALS['_PEAR_Config_instance'])) { + return $GLOBALS['_PEAR_Config_instance']; } - return $GLOBALS['_PEAR_Config_last_instance']; + $GLOBALS['_PEAR_Config_instance'] = + &new PEAR_Config($user_file, $system_file); + return $GLOBALS['_PEAR_Config_instance']; } // }}} @@ -318,7 +319,7 @@ class PEAR_Config extends PEAR } $data = $this->configuration[$layer]; $this->_encodeOutput($data); - if (!@is_writeable($file)) { + if (@file_exists($file) && !@is_writeable($file)) { return $this->raiseError("no write access to $file!"); } $fp = @fopen($file, "w"); @@ -637,6 +638,23 @@ class PEAR_Config extends PEAR return false; } + // }}} + // {{{ store([layer]) + + /** + * Stores configuration data in a layer. + * + * @param string config layer to store + * + * @return bool TRUE on success, or PEAR error on failure + * + * @access public + */ + function store($layer = 'user') + { + return $this->writeConfigFile(null, $layer); + } + // }}} // {{{ toDefault(key) diff --git a/pear/PEAR/Remote.php b/pear/PEAR/Remote.php index 7f397b7221..2b12c3b73a 100644 --- a/pear/PEAR/Remote.php +++ b/pear/PEAR/Remote.php @@ -19,6 +19,7 @@ // $Id$ require_once 'PEAR.php'; +require_once 'PEAR/Config.php'; /** * This is a class for doing remote operations against the central @@ -28,16 +29,19 @@ class PEAR_Remote extends PEAR { // {{{ properties - var $config_object = null; + var $config = null; // }}} // {{{ PEAR_Remote(config_object) - function PEAR_Remote($config_object) + function PEAR_Remote($config = null) { $this->PEAR(); - $this->config_object = $config_object; + if ($config === null) { + $config = &PEAR_Config::singleton(); + } + $this->config = $config; } // }}} @@ -51,7 +55,7 @@ class PEAR_Remote extends PEAR } $method = str_replace("_", ".", $method); $request = xmlrpc_encode_request($method, $params); - $server_host = $this->config_object->get("master_server"); + $server_host = $this->config->get("master_server"); if (empty($server_host)) { return $this->raiseError("PEAR_Remote::call: no master_server configured"); } @@ -61,13 +65,30 @@ class PEAR_Remote extends PEAR return $this->raiseError("PEAR_Remote::call: fsockopen(`$server_host', $server_port) failed"); } $len = strlen($request); - fwrite($fp, ("POST /xmlrpc.php HTTP/1.0\r\n". - "Host: $server_host:$server_port\r\n". - "Content-type: text/xml\r\n". - "Content-length: $len\r\n". - "\r\n$request")); + $req_headers = "Host: $server_host:$server_port\r\n" . + "Content-type: text/xml\r\n" . + "Content-length: $len\r\n"; + $username = $this->config->get('username'); + $password = $this->config->get('password'); + if ($username && $password) { + $tmp = base64_encode("$username:$password"); + $req_headers .= "Authorization: Basic $auth\r\n"; + } + fwrite($fp, ("POST /xmlrpc.php HTTP/1.0\r\n$req_headers\r\n$request")); $response = ''; - while (trim(fgets($fp, 2048)) != ''); // skip headers + $line1 = fgets($fp, 2048); + if (!preg_match('!^HTTP/[0-9\.]+ (\d+) (.*)!', $line1, &$matches)) { + return $this->raiseError("PEAR_Remote: invalid HTTP response from XML-RPC server"); + } + switch ($matches[1]) { + case "200": + break; + case "401": + return $this->raiseError("PEAR_Remote: authorization required, please log in first"); + default: + return $this->raiseError("PEAR_Remote: unexpected HTTP response: $matches[1] $matches[2]"); + } + while (trim(fgets($fp, 2048)) != ''); // skip rest of headers while ($chunk = fread($fp, 10240)) { $response .= $chunk; } diff --git a/pear/scripts/pear.in b/pear/scripts/pear.in index d7bb854b53..8afc9c8b84 100644 --- a/pear/scripts/pear.in +++ b/pear/scripts/pear.in @@ -20,33 +20,181 @@ // require_once 'PEAR.php'; -require_once 'PEAR/Common.php'; -require_once 'PEAR/Registry.php'; +require_once "PEAR/Config.php"; +require_once "PEAR/Command.php"; +require_once "Console/Getopt.php"; error_reporting(E_ALL & ~E_NOTICE); -$subcommands = array( - 'help' => 'help [command]', - 'uninstall' => 'uninstall [-r] ', - 'package' => 'package [package info file]', - 'info' => 'info', - 'list' => 'list', - 'show-config' => 'show-config', -); +PEAR_Command::setUIType('CLI'); +$all_commands = PEAR_Command::getCommands(); -$command_options = array( - "list" => "v", - "uninstall" => "fr", -); +$progname = basename($argv[0]); -include "pearcmd-common.php"; +PEAR::setErrorHandling(PEAR_ERROR_DIE, "$progname: %s\n"); +$argv = Console_Getopt::readPHPArgv(); -if (isset($subcommands[$command])) { - include "pearcmd-$command.php"; -} elseif (!$store_default_config && !$store_user_config) { - usage(); +PEAR::pushErrorHandling(PEAR_ERROR_CALLBACK, 'usage'); +$options = Console_Getopt::getopt($argv, "c:C:d:D:h?sSqu:v"); +PEAR::popErrorHandling(); + +$opts = $options[0]; + +$pear_user_config = ''; +$pear_system_config = ''; +$store_user_config = false; +$store_system_config = false; +$verbose = 1; + +foreach ($opts as $opt) { + switch ($opt[0]) { + case 'c': + $pear_user_config = $opt[1]; + break; + case 'C': + $pear_system_config = $opt[1]; + break; + } +} + +$config = &PEAR_Config::singleton($pear_user_config, $pear_system_config); +$verbose = $config->get("verbose"); + +foreach ($opts as $opt) { + $param = $opt[1]; + switch ($opt[0]) { + case 'd': + list($key, $value) = explode('=', $param); + $config->set($key, $value, 'user'); + break; + case 'D': + list($key, $value) = explode('=', $param); + $config->set($key, $value, 'system'); + break; + case 's': + $store_user_config = true; + break; + case 'S': + $store_system_config = true; + break; + case 'u': + $config->remove($param, 'user'); + break; + case 'v': + $verbose++; + break; + case 'q': + $verbose--; + break; + } +} + +if ($store_system_config) { + $config->store('system'); +} + +if ($store_user_config) { + $config->store('user'); +} + +$command = (isset($options[1][1])) ? $options[1][1] : null; + +if (empty($command) && ($store_user_config || $store_system_config)) { + exit; +} + +if (empty($all_commands[$command]) || $command == 'help') { + usage(null, @$options[1][2]); } +$cmd = PEAR_Command::factory($command); +if (PEAR::isError($cmd)) { + die($cmd->getMessage()); +} +$ok = $cmd->run($command, $cmdopts, $cmdargs); +if ($ok === false) { + PEAR::raiseError("unknown command `$command'"); +} + +exit; + +// {{{ usage() + +function usage($error = null, $helpsubject = null) +{ + global $progname, $all_commands; + $stderr = fopen('php://stderr', 'w'); + if (PEAR::isError($error)) { + fputs($stderr, $error->getMessage()); + } elseif ($error !== null) { + fputs($stderr, $error); + } + fputs($stderr, + "Usage: $progname [options] command [command-options] \n"); + if ($helpsubject == "options") { + fputs($stderr, + "Options:\n". + " -v increase verbosity level (default 1)\n". + " -q be quiet, decrease verbosity level\n". + " -c file find user configuration in `file'\n". + " -C file find system configuration in `file'\n". + " -d foo=bar set user config variable `foo' to `bar'\n". + " -D foo=bar set system config variable `foo' to `bar'\n". + " -s store user configuration\n". + " -S store system configuration\n". + " -u foo unset `foo' in the user configuration\n". + " -h, -? display help/usage (this message)\n"); + } else { + fputs($stderr, + "Type \"$progname help options\" to list all options.\n"); + } + fputs($stderr, + "Commands:\n " . implode("\n ", array_keys($all_commands)) . + "\n"); + fclose($stderr); + exit; +} + +// }}} +// {{{ present_array() + +function present_array(&$arr, $keys = null) +{ + if ($keys === null) { + $keys = array_keys($arr); + } + $longest_key = max(array_map("strlen", array_keys($arr))) + 2; + $format_string = "%{$longest_key}s : %s\n"; + foreach ($keys as $k) { + if (is_array($arr[$k])) { + foreach ($arr[$k] as $i => $value) { + $x = "$k #$i"; + $cont = array(); + foreach(array_keys($value) as $val) { + $cont[] = "$val=" . $value[$val]; + } + $v = implode(", ", $cont); + printf($format_string, $x, $v); + } + continue; + } else { + $v = $arr[$k]; + printf($format_string, $k, $v); + } + } +} + +// }}} +// {{{ heading() + +function heading($text) +{ + $l = strlen(trim($text)); + print rtrim($text) . "\n" . str_repeat("=", $l) . "\n"; +} + +// }}} + /* * Local variables: * tab-width: 4 diff --git a/pear/tests/pear_config.phpt b/pear/tests/pear_config.phpt index 08163b331d..162d64c981 100644 --- a/pear/tests/pear_config.phpt +++ b/pear/tests/pear_config.phpt @@ -20,8 +20,11 @@ $config = new PEAR_Config("user.conf", "system.conf"); dump_array("files", $config->files); print "#2 testing: singleton\n"; -$cf2 = PEAR_Config::singleton(); -dump_array("files", $cf2->files); +$o1 = &PEAR_Config::singleton(); +$o1->blah = 'blah'; +$o2 = &PEAR_Config::singleton(); +var_dump($o1->blah); +@var_dump($o2->blah); print "#3 testing: readConfigFile\n"; $config->readConfigFile("user2.conf", "user"); @@ -167,7 +170,8 @@ function dump_config(&$obj, $layer = null) { #1 testing: constructor files: system="system.conf" user="user.conf" #2 testing: singleton -files: system="system.conf" user="user.conf" +string(4) "blah" +string(4) "blah" #3 testing: readConfigFile user: verbose="2" system: master_server="pear.php.net"