home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / tmp / PEAR-1.7.1 / PEAR / Command / Install.php < prev    next >
Encoding:
PHP Script  |  2008-02-15  |  48.9 KB  |  1,189 lines

  1. <?php
  2. /**
  3.  * PEAR_Command_Install (install, upgrade, upgrade-all, uninstall, bundle, run-scripts commands)
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   pear
  14.  * @package    PEAR
  15.  * @author     Stig Bakken <ssb@php.net>
  16.  * @author     Greg Beaver <cellog@php.net>
  17.  * @copyright  1997-2008 The PHP Group
  18.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  19.  * @version    CVS: $Id: Install.php,v 1.140 2008/01/29 03:21:01 cellog Exp $
  20.  * @link       http://pear.php.net/package/PEAR
  21.  * @since      File available since Release 0.1
  22.  */
  23.  
  24. /**
  25.  * base class
  26.  */
  27. require_once 'PEAR/Command/Common.php';
  28.  
  29. /**
  30.  * PEAR commands for installation or deinstallation/upgrading of
  31.  * packages.
  32.  *
  33.  * @category   pear
  34.  * @package    PEAR
  35.  * @author     Stig Bakken <ssb@php.net>
  36.  * @author     Greg Beaver <cellog@php.net>
  37.  * @copyright  1997-2008 The PHP Group
  38.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  39.  * @version    Release: 1.7.1
  40.  * @link       http://pear.php.net/package/PEAR
  41.  * @since      Class available since Release 0.1
  42.  */
  43. class PEAR_Command_Install extends PEAR_Command_Common
  44. {
  45.     // {{{ properties
  46.  
  47.     var $commands = array(
  48.         'install' => array(
  49.             'summary' => 'Install Package',
  50.             'function' => 'doInstall',
  51.             'shortcut' => 'i',
  52.             'options' => array(
  53.                 'force' => array(
  54.                     'shortopt' => 'f',
  55.                     'doc' => 'will overwrite newer installed packages',
  56.                     ),
  57.                 'loose' => array(
  58.                     'shortopt' => 'l',
  59.                     'doc' => 'do not check for recommended dependency version',
  60.                     ),
  61.                 'nodeps' => array(
  62.                     'shortopt' => 'n',
  63.                     'doc' => 'ignore dependencies, install anyway',
  64.                     ),
  65.                 'register-only' => array(
  66.                     'shortopt' => 'r',
  67.                     'doc' => 'do not install files, only register the package as installed',
  68.                     ),
  69.                 'soft' => array(
  70.                     'shortopt' => 's',
  71.                     'doc' => 'soft install, fail silently, or upgrade if already installed',
  72.                     ),
  73.                 'nobuild' => array(
  74.                     'shortopt' => 'B',
  75.                     'doc' => 'don\'t build C extensions',
  76.                     ),
  77.                 'nocompress' => array(
  78.                     'shortopt' => 'Z',
  79.                     'doc' => 'request uncompressed files when downloading',
  80.                     ),
  81.                 'installroot' => array(
  82.                     'shortopt' => 'R',
  83.                     'arg' => 'DIR',
  84.                     'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
  85.                     ),
  86.                 'packagingroot' => array(
  87.                     'shortopt' => 'P',
  88.                     'arg' => 'DIR',
  89.                     'doc' => 'root directory used when packaging files, like RPM packaging',
  90.                     ),
  91.                 'ignore-errors' => array(
  92.                     'doc' => 'force install even if there were errors',
  93.                     ),
  94.                 'alldeps' => array(
  95.                     'shortopt' => 'a',
  96.                     'doc' => 'install all required and optional dependencies',
  97.                     ),
  98.                 'onlyreqdeps' => array(
  99.                     'shortopt' => 'o',
  100.                     'doc' => 'install all required dependencies',
  101.                     ),
  102.                 'offline' => array(
  103.                     'shortopt' => 'O',
  104.                     'doc' => 'do not attempt to download any urls or contact channels',
  105.                     ),
  106.                 'pretend' => array(
  107.                     'shortopt' => 'p',
  108.                     'doc' => 'Only list the packages that would be downloaded',
  109.                     ),
  110.                 ),
  111.             'doc' => '[channel/]<package> ...
  112. Installs one or more PEAR packages.  You can specify a package to
  113. install in four ways:
  114.  
  115. "Package-1.0.tgz" : installs from a local file
  116.  
  117. "http://example.com/Package-1.0.tgz" : installs from
  118. anywhere on the net.
  119.  
  120. "package.xml" : installs the package described in
  121. package.xml.  Useful for testing, or for wrapping a PEAR package in
  122. another package manager such as RPM.
  123.  
  124. "Package[-version/state][.tar]" : queries your default channel\'s server
  125. ({config master_server}) and downloads the newest package with
  126. the preferred quality/state ({config preferred_state}).
  127.  
  128. To retrieve Package version 1.1, use "Package-1.1," to retrieve
  129. Package state beta, use "Package-beta."  To retrieve an uncompressed
  130. file, append .tar (make sure there is no file by the same name first)
  131.  
  132. To download a package from another channel, prefix with the channel name like
  133. "channel/Package"
  134.  
  135. More than one package may be specified at once.  It is ok to mix these
  136. four ways of specifying packages.
  137. '),
  138.         'upgrade' => array(
  139.             'summary' => 'Upgrade Package',
  140.             'function' => 'doInstall',
  141.             'shortcut' => 'up',
  142.             'options' => array(
  143.                 'force' => array(
  144.                     'shortopt' => 'f',
  145.                     'doc' => 'overwrite newer installed packages',
  146.                     ),
  147.                 'loose' => array(
  148.                     'shortopt' => 'l',
  149.                     'doc' => 'do not check for recommended dependency version',
  150.                     ),
  151.                 'nodeps' => array(
  152.                     'shortopt' => 'n',
  153.                     'doc' => 'ignore dependencies, upgrade anyway',
  154.                     ),
  155.                 'register-only' => array(
  156.                     'shortopt' => 'r',
  157.                     'doc' => 'do not install files, only register the package as upgraded',
  158.                     ),
  159.                 'nobuild' => array(
  160.                     'shortopt' => 'B',
  161.                     'doc' => 'don\'t build C extensions',
  162.                     ),
  163.                 'nocompress' => array(
  164.                     'shortopt' => 'Z',
  165.                     'doc' => 'request uncompressed files when downloading',
  166.                     ),
  167.                 'installroot' => array(
  168.                     'shortopt' => 'R',
  169.                     'arg' => 'DIR',
  170.                     'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
  171.                     ),
  172.                 'ignore-errors' => array(
  173.                     'doc' => 'force install even if there were errors',
  174.                     ),
  175.                 'alldeps' => array(
  176.                     'shortopt' => 'a',
  177.                     'doc' => 'install all required and optional dependencies',
  178.                     ),
  179.                 'onlyreqdeps' => array(
  180.                     'shortopt' => 'o',
  181.                     'doc' => 'install all required dependencies',
  182.                     ),
  183.                 'offline' => array(
  184.                     'shortopt' => 'O',
  185.                     'doc' => 'do not attempt to download any urls or contact channels',
  186.                     ),
  187.                 'pretend' => array(
  188.                     'shortopt' => 'p',
  189.                     'doc' => 'Only list the packages that would be downloaded',
  190.                     ),
  191.                 ),
  192.             'doc' => '<package> ...
  193. Upgrades one or more PEAR packages.  See documentation for the
  194. "install" command for ways to specify a package.
  195.  
  196. When upgrading, your package will be updated if the provided new
  197. package has a higher version number (use the -f option if you need to
  198. upgrade anyway).
  199.  
  200. More than one package may be specified at once.
  201. '),
  202.         'upgrade-all' => array(
  203.             'summary' => 'Upgrade All Packages',
  204.             'function' => 'doUpgradeAll',
  205.             'shortcut' => 'ua',
  206.             'options' => array(
  207.                 'nodeps' => array(
  208.                     'shortopt' => 'n',
  209.                     'doc' => 'ignore dependencies, upgrade anyway',
  210.                     ),
  211.                 'register-only' => array(
  212.                     'shortopt' => 'r',
  213.                     'doc' => 'do not install files, only register the package as upgraded',
  214.                     ),
  215.                 'nobuild' => array(
  216.                     'shortopt' => 'B',
  217.                     'doc' => 'don\'t build C extensions',
  218.                     ),
  219.                 'nocompress' => array(
  220.                     'shortopt' => 'Z',
  221.                     'doc' => 'request uncompressed files when downloading',
  222.                     ),
  223.                 'installroot' => array(
  224.                     'shortopt' => 'R',
  225.                     'arg' => 'DIR',
  226.                     'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
  227.                     ),
  228.                 'ignore-errors' => array(
  229.                     'doc' => 'force install even if there were errors',
  230.                     ),
  231.                 'loose' => array(
  232.                     'doc' => 'do not check for recommended dependency version',
  233.                     ),
  234.                 ),
  235.             'doc' => '
  236. Upgrades all packages that have a newer release available.  Upgrades are
  237. done only if there is a release available of the state specified in
  238. "preferred_state" (currently {config preferred_state}), or a state considered
  239. more stable.
  240. '),
  241.         'uninstall' => array(
  242.             'summary' => 'Un-install Package',
  243.             'function' => 'doUninstall',
  244.             'shortcut' => 'un',
  245.             'options' => array(
  246.                 'nodeps' => array(
  247.                     'shortopt' => 'n',
  248.                     'doc' => 'ignore dependencies, uninstall anyway',
  249.                     ),
  250.                 'register-only' => array(
  251.                     'shortopt' => 'r',
  252.                     'doc' => 'do not remove files, only register the packages as not installed',
  253.                     ),
  254.                 'installroot' => array(
  255.                     'shortopt' => 'R',
  256.                     'arg' => 'DIR',
  257.                     'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
  258.                     ),
  259.                 'ignore-errors' => array(
  260.                     'doc' => 'force install even if there were errors',
  261.                     ),
  262.                 'offline' => array(
  263.                     'shortopt' => 'O',
  264.                     'doc' => 'do not attempt to uninstall remotely',
  265.                     ),
  266.                 ),
  267.             'doc' => '[channel/]<package> ...
  268. Uninstalls one or more PEAR packages.  More than one package may be
  269. specified at once.  Prefix with channel name to uninstall from a
  270. channel not in your default channel ({config default_channel})
  271. '),
  272.         'bundle' => array(
  273.             'summary' => 'Unpacks a Pecl Package',
  274.             'function' => 'doBundle',
  275.             'shortcut' => 'bun',
  276.             'options' => array(
  277.                 'destination' => array(
  278.                    'shortopt' => 'd',
  279.                     'arg' => 'DIR',
  280.                     'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)',
  281.                     ),
  282.                 'force' => array(
  283.                     'shortopt' => 'f',
  284.                     'doc' => 'Force the unpacking even if there were errors in the package',
  285.                 ),
  286.             ),
  287.             'doc' => '<package>
  288. Unpacks a Pecl Package into the selected location. It will download the
  289. package if needed.
  290. '),
  291.         'run-scripts' => array(
  292.             'summary' => 'Run Post-Install Scripts bundled with a package',
  293.             'function' => 'doRunScripts',
  294.             'shortcut' => 'rs',
  295.             'options' => array(
  296.             ),
  297.             'doc' => '<package>
  298. Run post-installation scripts in package <package>, if any exist.
  299. '),
  300.     );
  301.  
  302.     // }}}
  303.     // {{{ constructor
  304.  
  305.     /**
  306.      * PEAR_Command_Install constructor.
  307.      *
  308.      * @access public
  309.      */
  310.     function PEAR_Command_Install(&$ui, &$config)
  311.     {
  312.         parent::PEAR_Command_Common($ui, $config);
  313.     }
  314.  
  315.     // }}}
  316.  
  317.     /**
  318.      * For unit testing purposes
  319.      */
  320.     function &getDownloader(&$ui, $options, &$config)
  321.     {
  322.         if (!class_exists('PEAR_Downloader')) {
  323.             require_once 'PEAR/Downloader.php';
  324.         }
  325.         $a = &new PEAR_Downloader($ui, $options, $config);
  326.         return $a;
  327.     }
  328.  
  329.     /**
  330.      * For unit testing purposes
  331.      */
  332.     function &getInstaller(&$ui)
  333.     {
  334.         if (!class_exists('PEAR_Installer')) {
  335.             require_once 'PEAR/Installer.php';
  336.         }
  337.         $a = &new PEAR_Installer($ui);
  338.         return $a;
  339.     }
  340.  
  341.     function enableExtension($binaries, $type)
  342.     {
  343.         if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
  344.             return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
  345.         }
  346.         $ini = $this->_parseIni($phpini);
  347.         if (PEAR::isError($ini)) {
  348.             return $ini;
  349.         }
  350.         $line = 0;
  351.         if ($type == 'extsrc' || $type == 'extbin') {
  352.             $search = 'extensions';
  353.             $enable = 'extension';
  354.         } else {
  355.             $search = 'zend_extensions';
  356.             ob_start();
  357.             phpinfo(INFO_GENERAL);
  358.             $info = ob_get_contents();
  359.             ob_end_clean();
  360.             $debug = function_exists('leak') ? '_debug' : '';
  361.             $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
  362.             $enable = 'zend_extension' . $debug . $ts;
  363.         }
  364.         foreach ($ini[$search] as $line => $extension) {
  365.             if (in_array($extension, $binaries, true) || in_array(
  366.                   $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
  367.                 // already enabled - assume if one is, all are
  368.                 return true;
  369.             }
  370.         }
  371.         if ($line) {
  372.             $newini = array_slice($ini['all'], 0, $line);
  373.         } else {
  374.             $newini = array();
  375.         }
  376.         foreach ($binaries as $binary) {
  377.             if ($ini['extension_dir']) {
  378.                 $binary = basename($binary);
  379.             }
  380.             $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n");
  381.         }
  382.         $newini = array_merge($newini, array_slice($ini['all'], $line));
  383.         $fp = @fopen($phpini, 'wb');
  384.         if (!$fp) {
  385.             return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
  386.         }
  387.         foreach ($newini as $line) {
  388.             fwrite($fp, $line);
  389.         }
  390.         fclose($fp);
  391.         return true;
  392.     }
  393.  
  394.     function disableExtension($binaries, $type)
  395.     {
  396.         if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
  397.             return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
  398.         }
  399.         $ini = $this->_parseIni($phpini);
  400.         if (PEAR::isError($ini)) {
  401.             return $ini;
  402.         }
  403.         $line = 0;
  404.         if ($type == 'extsrc' || $type == 'extbin') {
  405.             $search = 'extensions';
  406.             $enable = 'extension';
  407.         } else {
  408.             $search = 'zend_extensions';
  409.             ob_start();
  410.             phpinfo(INFO_GENERAL);
  411.             $info = ob_get_contents();
  412.             ob_end_clean();
  413.             $debug = function_exists('leak') ? '_debug' : '';
  414.             $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
  415.             $enable = 'zend_extension' . $debug . $ts;
  416.         }
  417.         $found = false;
  418.         foreach ($ini[$search] as $line => $extension) {
  419.             if (in_array($extension, $binaries, true) || in_array(
  420.                   $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
  421.                 $found = true;
  422.                 break;
  423.             }
  424.         }
  425.         if (!$found) {
  426.             // not enabled
  427.             return true;
  428.         }
  429.         $fp = @fopen($phpini, 'wb');
  430.         if (!$fp) {
  431.             return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
  432.         }
  433.         if ($line) {
  434.             $newini = array_slice($ini['all'], 0, $line);
  435.             // delete the enable line
  436.             $newini = array_merge($newini, array_slice($ini['all'], $line + 1));
  437.         } else {
  438.             $newini = array_slice($ini['all'], 1);
  439.         }
  440.         foreach ($newini as $line) {
  441.             fwrite($fp, $line);
  442.         }
  443.         fclose($fp);
  444.         return true;
  445.     }
  446.  
  447.     function _parseIni($filename)
  448.     {
  449.         if (file_exists($filename)) {
  450.             if (filesize($filename) > 300000) {
  451.                 return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting');
  452.             }
  453.             ob_start();
  454.             phpinfo(INFO_GENERAL);
  455.             $info = ob_get_contents();
  456.             ob_end_clean();
  457.             $debug = function_exists('leak') ? '_debug' : '';
  458.             $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
  459.             $zend_extension_line = 'zend_extension' . $debug . $ts;
  460.             $all = @file($filename);
  461.             if (!$all) {
  462.                 return PEAR::raiseError('php.ini "' . $filename .'" could not be read');
  463.             }
  464.             $zend_extensions = $extensions = array();
  465.             // assume this is right, but pull from the php.ini if it is found
  466.             $extension_dir = ini_get('extension_dir');
  467.             foreach ($all as $linenum => $line) {
  468.                 $line = trim($line);
  469.                 if (!$line) {
  470.                     continue;
  471.                 }
  472.                 if ($line[0] == ';') {
  473.                     continue;
  474.                 }
  475.                 if (strtolower(substr($line, 0, 13)) == 'extension_dir') {
  476.                     $line = trim(substr($line, 13));
  477.                     if ($line[0] == '=') {
  478.                         $x = trim(substr($line, 1));
  479.                         $x = explode(';', $x);
  480.                         $extension_dir = str_replace('"', '', array_shift($x));
  481.                         continue;
  482.                     }
  483.                 }
  484.                 if (strtolower(substr($line, 0, 9)) == 'extension') {
  485.                     $line = trim(substr($line, 9));
  486.                     if ($line[0] == '=') {
  487.                         $x = trim(substr($line, 1));
  488.                         $x = explode(';', $x);
  489.                         $extensions[$linenum] = str_replace('"', '', array_shift($x));
  490.                         continue;
  491.                     }
  492.                 }
  493.                 if (strtolower(substr($line, 0, strlen($zend_extension_line))) ==
  494.                       $zend_extension_line) {
  495.                     $line = trim(substr($line, strlen($zend_extension_line)));
  496.                     if ($line[0] == '=') {
  497.                         $x = trim(substr($line, 1));
  498.                         $x = explode(';', $x);
  499.                         $zend_extensions[$linenum] = str_replace('"', '', array_shift($x));
  500.                         continue;
  501.                     }
  502.                 }
  503.             }
  504.             return array(
  505.                 'extensions' => $extensions,
  506.                 'zend_extensions' => $zend_extensions,
  507.                 'extension_dir' => $extension_dir,
  508.                 'all' => $all,
  509.             );
  510.         } else {
  511.             return PEAR::raiseError('php.ini "' . $filename . '" does not exist');
  512.         }
  513.     }
  514.  
  515.     // {{{ doInstall()
  516.  
  517.     function doInstall($command, $options, $params)
  518.     {
  519.         if (!class_exists('PEAR_PackageFile')) {
  520.             require_once 'PEAR/PackageFile.php';
  521.         }
  522.         if (empty($this->installer)) {
  523.             $this->installer = &$this->getInstaller($this->ui);
  524.         }
  525.         if ($command == 'upgrade' || $command == 'upgrade-all') {
  526.             $options['upgrade'] = true;
  527.         } else {
  528.             $packages = $params;
  529.         }
  530.         if (isset($options['installroot']) && isset($options['packagingroot'])) {
  531.             return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot');
  532.         }
  533.         $reg = &$this->config->getRegistry();
  534.         $instreg = &$reg; // instreg used to check if package is installed
  535.         if (isset($options['packagingroot']) && !isset($options['upgrade'])) {
  536.             $packrootphp_dir = $this->installer->_prependPath(
  537.                 $this->config->get('php_dir', null, 'pear.php.net'),
  538.                 $options['packagingroot']);
  539.             $instreg = new PEAR_Registry($packrootphp_dir); // other instreg!
  540.  
  541.             if ($this->config->get('verbose') > 2) {
  542.                 $this->ui->outputData('using package root: ' . $options['packagingroot']);
  543.             }
  544.         }
  545.         $abstractpackages = array();
  546.         $otherpackages = array();
  547.         // parse params
  548.         PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  549.         foreach($params as $param) {
  550.             if (strpos($param, 'http://') === 0) {
  551.                 $otherpackages[] = $param;
  552.                 continue;
  553.             }
  554.             if (strpos($param, 'channel://') === false && @file_exists($param)) {
  555.                 if (isset($options['force'])) {
  556.                     $otherpackages[] = $param;
  557.                     continue;
  558.                 }
  559.                 $pkg = new PEAR_PackageFile($this->config);
  560.                 $pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING);
  561.                 if (PEAR::isError($pf)) {
  562.                     $otherpackages[] = $param;
  563.                     continue;
  564.                 }
  565.                 if ($reg->packageExists($pf->getPackage(), $pf->getChannel()) &&
  566.                       version_compare($pf->getVersion(),
  567.                       $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel()),
  568.                       '<=')) {
  569.                     if ($this->config->get('verbose')) {
  570.                         $this->ui->outputData('Ignoring installed package ' .
  571.                             $reg->parsedPackageNameToString(
  572.                             array('package' => $pf->getPackage(),
  573.                                   'channel' => $pf->getChannel()), true));
  574.                     }
  575.                     continue;
  576.                 }
  577.                 $otherpackages[] = $param;
  578.                 continue;
  579.             }
  580.             $e = $reg->parsePackageName($param, $this->config->get('default_channel'));
  581.             if (PEAR::isError($e)) {
  582.                 $otherpackages[] = $param;
  583.             } else {
  584.                 $abstractpackages[] = $e;
  585.             }
  586.         }
  587.         PEAR::staticPopErrorHandling();
  588.  
  589.         // if there are any local package .tgz or remote static url, we can't
  590.         // filter.  The filter only works for abstract packages
  591.         if (count($abstractpackages) && !isset($options['force'])) {
  592.             // when not being forced, only do necessary upgrades/installs
  593.             if (isset($options['upgrade'])) {
  594.                 $abstractpackages = $this->_filterUptodatePackages($abstractpackages,
  595.                     $command);
  596.             } else {
  597.                 foreach ($abstractpackages as $i => $package) {
  598.                     if (isset($package['group'])) {
  599.                         // do not filter out install groups
  600.                         continue;
  601.                     }
  602.                     if ($instreg->packageExists($package['package'], $package['channel'])) {
  603.                         if ($this->config->get('verbose')) {
  604.                             $this->ui->outputData('Ignoring installed package ' .
  605.                                 $reg->parsedPackageNameToString($package, true));
  606.                         }
  607.                         unset($abstractpackages[$i]);
  608.                     }
  609.                 }
  610.             }
  611.             $abstractpackages =
  612.                 array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
  613.         } elseif (count($abstractpackages)) {
  614.             $abstractpackages =
  615.                 array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
  616.         }
  617.  
  618.  
  619.         $packages = array_merge($abstractpackages, $otherpackages);
  620.         if (!count($packages)) {
  621.             $this->ui->outputData('Nothing to ' . $command);
  622.             return true;
  623.         }
  624.  
  625.         $this->downloader = &$this->getDownloader($this->ui, $options, $this->config);
  626.         $errors = array();
  627.         $binaries = array();
  628.         $downloaded = array();
  629.         $downloaded = &$this->downloader->download($packages);
  630.         if (PEAR::isError($downloaded)) {
  631.             return $this->raiseError($downloaded);
  632.         }
  633.         $errors = $this->downloader->getErrorMsgs();
  634.         if (count($errors)) {
  635.             $err = array();
  636.             $err['data'] = array();
  637.             foreach ($errors as $error) {
  638.                 $err['data'][] = array($error);
  639.             }
  640.             $err['headline'] = 'Install Errors';
  641.             $this->ui->outputData($err);
  642.             if (!count($downloaded)) {
  643.                 return $this->raiseError("$command failed");
  644.             }
  645.         }
  646.         $data = array(
  647.             'headline' => 'Packages that would be Installed'
  648.         );
  649.         if (isset($options['pretend'])) {
  650.             foreach ($downloaded as $package) {
  651.                 $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage()));
  652.             }
  653.             $this->ui->outputData($data, 'pretend');
  654.             return true;
  655.         }
  656.         $this->installer->setOptions($options);
  657.         $this->installer->sortPackagesForInstall($downloaded);
  658.         if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) {
  659.             $this->raiseError($err->getMessage());
  660.             return true;
  661.         }
  662.         $extrainfo = array();
  663.         $binaries = array();
  664.         foreach ($downloaded as $param) {
  665.             PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  666.             $info = $this->installer->install($param, $options);
  667.             PEAR::staticPopErrorHandling();
  668.             if (PEAR::isError($info)) {
  669.                 $oldinfo = $info;
  670.                 $pkg = &$param->getPackageFile();
  671.                 if ($info->getCode() != PEAR_INSTALLER_NOBINARY) {
  672.                     if (!($info = $pkg->installBinary($this->installer))) {
  673.                         $this->ui->outputData('ERROR: ' .$oldinfo->getMessage());
  674.                         continue;
  675.                     }
  676.                     // we just installed a different package than requested,
  677.                     // let's change the param and info so that the rest of this works
  678.                     $param = $info[0];
  679.                     $info = $info[1];
  680.                 }
  681.             }
  682.             if (is_array($info)) {
  683.                 if ($param->getPackageType() == 'extsrc' ||
  684.                       $param->getPackageType() == 'extbin' ||
  685.                       $param->getPackageType() == 'zendextsrc' ||
  686.                       $param->getPackageType() == 'zendextbin') {
  687.                     $pkg = &$param->getPackageFile();
  688.                     if ($instbin = $pkg->getInstalledBinary()) {
  689.                         $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel());
  690.                     } else {
  691.                         $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel());
  692.                     }
  693.  
  694.                     foreach ($instpkg->getFilelist() as $name => $atts) {
  695.                         $pinfo = pathinfo($atts['installed_as']);
  696.                         if (!isset($pinfo['extension']) ||
  697.                               in_array($pinfo['extension'], array('c', 'h'))) {
  698.                             continue; // make sure we don't match php_blah.h
  699.                         }
  700.                         if ((strpos($pinfo['basename'], 'php_') === 0 &&
  701.                               $pinfo['extension'] == 'dll') ||
  702.                               // most unices
  703.                               $pinfo['extension'] == 'so' ||
  704.                               // hp-ux
  705.                               $pinfo['extension'] == 'sl') {
  706.                             $binaries[] = array($atts['installed_as'], $pinfo);
  707.                             break;
  708.                         }
  709.                     }
  710.                     if (count($binaries)) {
  711.                         foreach ($binaries as $pinfo) {
  712.                             PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  713.                             $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType());
  714.                             PEAR::staticPopErrorHandling();
  715.                             if (PEAR::isError($ret)) {
  716.                                 $extrainfo[] = $ret->getMessage();
  717.                                 if ($param->getPackageType() == 'extsrc' ||
  718.                                       $param->getPackageType() == 'extbin') {
  719.                                     $exttype = 'extension';
  720.                                 } else {
  721.                                     ob_start();
  722.                                     phpinfo(INFO_GENERAL);
  723.                                     $info = ob_get_contents();
  724.                                     ob_end_clean();
  725.                                     $debug = function_exists('leak') ? '_debug' : '';
  726.                                     $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
  727.                                     $exttype = 'zend_extension' . $debug . $ts;
  728.                                 }
  729.                                 $extrainfo[] = 'You should add "' . $exttype . '=' .
  730.                                     $pinfo[1]['basename'] . '" to php.ini';
  731.                             } else {
  732.                                 $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() .
  733.                                     ' enabled in php.ini';
  734.                             }
  735.                         }
  736.                     }
  737.                 }
  738.                 if ($this->config->get('verbose') > 0) {
  739.                     $channel = $param->getChannel();
  740.                     $label = $reg->parsedPackageNameToString(
  741.                         array(
  742.                             'channel' => $channel,
  743.                             'package' => $param->getPackage(),
  744.                             'version' => $param->getVersion(),
  745.                         ));
  746.                     $out = array('data' => "$command ok: $label");
  747.                     if (isset($info['release_warnings'])) {
  748.                         $out['release_warnings'] = $info['release_warnings'];
  749.                     }
  750.                     $this->ui->outputData($out, $command);
  751.                     if (!isset($options['register-only']) && !isset($options['offline'])) {
  752.                         if ($this->config->isDefinedLayer('ftp')) {
  753.                             PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  754.                             $info = $this->installer->ftpInstall($param);
  755.                             PEAR::staticPopErrorHandling();
  756.                             if (PEAR::isError($info)) {
  757.                                 $this->ui->outputData($info->getMessage());
  758.                                 $this->ui->outputData("remote install failed: $label");
  759.                             } else {
  760.                                 $this->ui->outputData("remote install ok: $label");
  761.                             }
  762.                         }
  763.                     }
  764.                 }
  765.                 $deps = $param->getDeps();
  766.                 if ($deps) {
  767.                     if (isset($deps['group'])) {
  768.                         $groups = $deps['group'];
  769.                         if (!isset($groups[0])) {
  770.                             $groups = array($groups);
  771.                         }
  772.                         foreach ($groups as $group) {
  773.                             if ($group['attribs']['name'] == 'default') {
  774.                                 // default group is always installed, unless the user
  775.                                 // explicitly chooses to install another group
  776.                                 continue;
  777.                             }
  778.                             $extrainfo[] = $param->getPackage() . ': Optional feature ' .
  779.                                 $group['attribs']['name'] . ' available (' .
  780.                                 $group['attribs']['hint'] . ')';
  781.                         }
  782.                         $extrainfo[] = $param->getPackage() .
  783.                             ': To install optional features use "pear install ' .
  784.                             $reg->parsedPackageNameToString(
  785.                                 array('package' => $param->getPackage(),
  786.                                       'channel' => $param->getChannel()), true) .
  787.                                   '#featurename"';
  788.                     }
  789.                 }
  790.                 $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel());
  791.                 // $pkg may be NULL if install is a 'fake' install via --packagingroot
  792.                 if (is_object($pkg)) {
  793.                     $pkg->setConfig($this->config);
  794.                     if ($list = $pkg->listPostinstallScripts()) {
  795.                         $pn = $reg->parsedPackageNameToString(array('channel' =>
  796.                            $param->getChannel(), 'package' => $param->getPackage()), true);
  797.                         $extrainfo[] = $pn . ' has post-install scripts:';
  798.                         foreach ($list as $file) {
  799.                             $extrainfo[] = $file;
  800.                         }
  801.                         $extrainfo[] = $param->getPackage() .
  802.                             ': Use "pear run-scripts ' . $pn . '" to finish setup.';
  803.                         $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
  804.                     }
  805.                 }
  806.             } else {
  807.                 return $this->raiseError("$command failed");
  808.             }
  809.         }
  810.         if (count($extrainfo)) {
  811.             foreach ($extrainfo as $info) {
  812.                 $this->ui->outputData($info);
  813.             }
  814.         }
  815.         return true;
  816.     }
  817.  
  818.     // }}}
  819.     // {{{ doUpgradeAll()
  820.  
  821.     function doUpgradeAll($command, $options, $params)
  822.     {
  823.         $reg = &$this->config->getRegistry();
  824.         $toUpgrade = array();
  825.         foreach ($reg->listChannels() as $channel) {
  826.             if ($channel == '__uri') {
  827.                 continue;
  828.             }
  829.  
  830.             // parse name with channel
  831.             foreach ($reg->listPackages($channel) as $name) {
  832.                 $toUpgrade[] = $reg->parsedPackageNameToString(array(
  833.                         'channel' => $channel,
  834.                         'package' => $name
  835.                     ));
  836.             }
  837.         }
  838.  
  839.         $err = $this->doInstall('upgrade-all', $options, $toUpgrade);
  840.         if (PEAR::isError($err)) {
  841.             $this->ui->outputData($err->getMessage(), $command);
  842.         }
  843.    }
  844.  
  845.     // }}}
  846.     // {{{ doUninstall()
  847.  
  848.     function doUninstall($command, $options, $params)
  849.     {
  850.         if (empty($this->installer)) {
  851.             $this->installer = &$this->getInstaller($this->ui);
  852.         }
  853.         if (isset($options['remoteconfig'])) {
  854.             $e = $this->config->readFTPConfigFile($options['remoteconfig']);
  855.             if (!PEAR::isError($e)) {
  856.                 $this->installer->setConfig($this->config);
  857.             }
  858.         }
  859.         if (sizeof($params) < 1) {
  860.             return $this->raiseError("Please supply the package(s) you want to uninstall");
  861.         }
  862.         $reg = &$this->config->getRegistry();
  863.         $newparams = array();
  864.         $binaries = array();
  865.         $badparams = array();
  866.         foreach ($params as $pkg) {
  867.             $channel = $this->config->get('default_channel');
  868.             PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  869.             $parsed = $reg->parsePackageName($pkg, $channel);
  870.             PEAR::staticPopErrorHandling();
  871.             if (!$parsed || PEAR::isError($parsed)) {
  872.                 $badparams[] = $pkg;
  873.                 continue;
  874.             }
  875.             $package = $parsed['package'];
  876.             $channel = $parsed['channel'];
  877.             $info = &$reg->getPackage($package, $channel);
  878.             if ($info === null &&
  879.                  ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) {
  880.                 // make sure this isn't a package that has flipped from pear to pecl but
  881.                 // used a package.xml 1.0
  882.                 $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net';
  883.                 $info = &$reg->getPackage($package, $testc);
  884.                 if ($info !== null) {
  885.                     $channel = $testc;
  886.                 }
  887.             }
  888.             if ($info === null) {
  889.                 $badparams[] = $pkg;
  890.             } else {
  891.                 $newparams[] = &$info;
  892.                 // check for binary packages (this is an alias for those packages if so)
  893.                 if ($installedbinary = $info->getInstalledBinary()) {
  894.                     $this->ui->log('adding binary package ' .
  895.                         $reg->parsedPackageNameToString(array('channel' => $channel,
  896.                             'package' => $installedbinary), true));
  897.                     $newparams[] = &$reg->getPackage($installedbinary, $channel);
  898.                 }
  899.                 // add the contents of a dependency group to the list of installed packages
  900.                 if (isset($parsed['group'])) {
  901.                     $group = $info->getDependencyGroup($parsed['group']);
  902.                     if ($group) {
  903.                         $installed = &$reg->getInstalledGroup($group);
  904.                         if ($installed) {
  905.                             foreach ($installed as $i => $p) {
  906.                                 $newparams[] = &$installed[$i];
  907.                             }
  908.                         }
  909.                     }
  910.                 }
  911.             }
  912.         }
  913.         $err = $this->installer->sortPackagesForUninstall($newparams);
  914.         if (PEAR::isError($err)) {
  915.             $this->ui->outputData($err->getMessage(), $command);
  916.             return true;
  917.         }
  918.         $params = $newparams;
  919.         // twist this to use it to check on whether dependent packages are also being uninstalled
  920.         // for circular dependencies like subpackages
  921.         $this->installer->setUninstallPackages($newparams);
  922.         $params = array_merge($params, $badparams);
  923.         $binaries = array();
  924.         foreach ($params as $pkg) {
  925.             $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
  926.             if ($err = $this->installer->uninstall($pkg, $options)) {
  927.                 $this->installer->popErrorHandling();
  928.                 if (PEAR::isError($err)) {
  929.                     $this->ui->outputData($err->getMessage(), $command);
  930.                     continue;
  931.                 }
  932.                 if ($pkg->getPackageType() == 'extsrc' ||
  933.                       $pkg->getPackageType() == 'extbin' ||
  934.                       $pkg->getPackageType() == 'zendextsrc' ||
  935.                       $pkg->getPackageType() == 'zendextbin') {
  936.                     if ($instbin = $pkg->getInstalledBinary()) {
  937.                         continue; // this will be uninstalled later
  938.                     }
  939.  
  940.                     foreach ($pkg->getFilelist() as $name => $atts) {
  941.                         $pinfo = pathinfo($atts['installed_as']);
  942.                         if (!isset($pinfo['extension']) ||
  943.                               in_array($pinfo['extension'], array('c', 'h'))) {
  944.                             continue; // make sure we don't match php_blah.h
  945.                         }
  946.                         if ((strpos($pinfo['basename'], 'php_') === 0 &&
  947.                               $pinfo['extension'] == 'dll') ||
  948.                               // most unices
  949.                               $pinfo['extension'] == 'so' ||
  950.                               // hp-ux
  951.                               $pinfo['extension'] == 'sl') {
  952.                             $binaries[] = array($atts['installed_as'], $pinfo);
  953.                             break;
  954.                         }
  955.                     }
  956.                     if (count($binaries)) {
  957.                         foreach ($binaries as $pinfo) {
  958.                             PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  959.                             $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
  960.                             PEAR::staticPopErrorHandling();
  961.                             if (PEAR::isError($ret)) {
  962.                                 $extrainfo[] = $ret->getMessage();
  963.                                 if ($pkg->getPackageType() == 'extsrc' ||
  964.                                       $pkg->getPackageType() == 'extbin') {
  965.                                     $exttype = 'extension';
  966.                                 } else {
  967.                                     ob_start();
  968.                                     phpinfo(INFO_GENERAL);
  969.                                     $info = ob_get_contents();
  970.                                     ob_end_clean();
  971.                                     $debug = function_exists('leak') ? '_debug' : '';
  972.                                     $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
  973.                                     $exttype = 'zend_extension' . $debug . $ts;
  974.                                 }
  975.                                 $this->ui->outputData('Unable to remove "' . $exttype . '=' .
  976.                                     $pinfo[1]['basename'] . '" from php.ini', $command);
  977.                             } else {
  978.                                 $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
  979.                                     ' disabled in php.ini', $command);
  980.                             }
  981.                         }
  982.                     }
  983.                 }
  984.                 $savepkg = $pkg;
  985.                 if ($this->config->get('verbose') > 0) {
  986.                     if (is_object($pkg)) {
  987.                         $pkg = $reg->parsedPackageNameToString($pkg);
  988.                     }
  989.                     $this->ui->outputData("uninstall ok: $pkg", $command);
  990.                 }
  991.                 if (!isset($options['offline']) && is_object($savepkg) &&
  992.                       defined('PEAR_REMOTEINSTALL_OK')) {
  993.                     if ($this->config->isDefinedLayer('ftp')) {
  994.                         $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
  995.                         $info = $this->installer->ftpUninstall($savepkg);
  996.                         $this->installer->popErrorHandling();
  997.                         if (PEAR::isError($info)) {
  998.                             $this->ui->outputData($info->getMessage());
  999.                             $this->ui->outputData("remote uninstall failed: $pkg");
  1000.                         } else {
  1001.                             $this->ui->outputData("remote uninstall ok: $pkg");
  1002.                         }
  1003.                     }
  1004.                 }
  1005.             } else {
  1006.                 $this->installer->popErrorHandling();
  1007.                 if (is_object($pkg)) {
  1008.                     $pkg = $reg->parsedPackageNameToString($pkg);
  1009.                 }
  1010.                 return $this->raiseError("uninstall failed: $pkg");
  1011.             }
  1012.         }
  1013.         return true;
  1014.     }
  1015.  
  1016.     // }}}
  1017.  
  1018.  
  1019.     // }}}
  1020.     // {{{ doBundle()
  1021.     /*
  1022.     (cox) It just downloads and untars the package, does not do
  1023.             any check that the PEAR_Installer::_installFile() does.
  1024.     */
  1025.  
  1026.     function doBundle($command, $options, $params)
  1027.     {
  1028.         $downloader = &$this->getDownloader($this->ui, array('force' => true, 'nodeps' => true,
  1029.             'soft' => true, 'downloadonly' => true), $this->config);
  1030.         $reg = &$this->config->getRegistry();
  1031.         if (sizeof($params) < 1) {
  1032.             return $this->raiseError("Please supply the package you want to bundle");
  1033.         }
  1034.  
  1035.         if (isset($options['destination'])) {
  1036.             if (!is_dir($options['destination'])) {
  1037.                 System::mkdir('-p ' . $options['destination']);
  1038.             }
  1039.             $dest = realpath($options['destination']);
  1040.         } else {
  1041.             $pwd = getcwd();
  1042.             if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) {
  1043.                 $dest = $pwd . DIRECTORY_SEPARATOR . 'ext';
  1044.             } else {
  1045.                 $dest = $pwd;
  1046.             }
  1047.         }
  1048.         PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  1049.         $err = $downloader->setDownloadDir($dest);
  1050.         PEAR::staticPopErrorHandling();
  1051.         if (PEAR::isError($err)) {
  1052.             return PEAR::raiseError('download directory "' . $dest .
  1053.                 '" is not writeable.');
  1054.         }
  1055.         $result = &$downloader->download(array($params[0]));
  1056.         if (PEAR::isError($result)) {
  1057.             return $result;
  1058.         }
  1059.         if (!isset($result[0])) {
  1060.             return $this->raiseError('unable to unpack ' . $params[0]);
  1061.         }
  1062.         $pkgfile = &$result[0]->getPackageFile();
  1063.         $pkgname = $pkgfile->getName();
  1064.         $pkgversion = $pkgfile->getVersion();
  1065.  
  1066.         // Unpacking -------------------------------------------------
  1067.         $dest .= DIRECTORY_SEPARATOR . $pkgname;
  1068.         $orig = $pkgname . '-' . $pkgversion;
  1069.  
  1070.         $tar = &new Archive_Tar($pkgfile->getArchiveFile());
  1071.         if (!$tar->extractModify($dest, $orig)) {
  1072.             return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile());
  1073.         }
  1074.         $this->ui->outputData("Package ready at '$dest'");
  1075.     // }}}
  1076.     }
  1077.  
  1078.     // }}}
  1079.  
  1080.     function doRunScripts($command, $options, $params)
  1081.     {
  1082.         if (!isset($params[0])) {
  1083.             return $this->raiseError('run-scripts expects 1 parameter: a package name');
  1084.         }
  1085.         $reg = &$this->config->getRegistry();
  1086.         PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  1087.         $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
  1088.         PEAR::staticPopErrorHandling();
  1089.         if (PEAR::isError($parsed)) {
  1090.             return $this->raiseError($parsed);
  1091.         }
  1092.         $package = &$reg->getPackage($parsed['package'], $parsed['channel']);
  1093.         if (is_object($package)) {
  1094.             $package->setConfig($this->config);
  1095.             $package->runPostinstallScripts();
  1096.         } else {
  1097.             return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry');
  1098.         }
  1099.         $this->ui->outputData('Install scripts complete', $command);
  1100.         return true;
  1101.     }
  1102.  
  1103.     /**
  1104.      * Given a list of packages, filter out those ones that are already up to date
  1105.      *
  1106.      * @param $packages: packages, in parsed array format !
  1107.      * @return list of packages that can be upgraded
  1108.      */
  1109.     function _filterUptodatePackages($packages, $command)
  1110.     {
  1111.         $reg = &$this->config->getRegistry();
  1112.         $latestReleases = array();
  1113.  
  1114.         $ret = array();
  1115.         foreach($packages as $package) {
  1116.             if (isset($package['group'])) {
  1117.                 $ret[] = $package;
  1118.                 continue;
  1119.             }
  1120.             $channel = $package['channel'];
  1121.             $name = $package['package'];
  1122.  
  1123.             if (!$reg->packageExists($name, $channel)) {
  1124.                 $ret[] = $package;
  1125.                 continue;
  1126.             }
  1127.             if (!isset($latestReleases[$channel])) {
  1128.                 // fill in cache for this channel
  1129.                 $chan = &$reg->getChannel($channel);
  1130.                 if (PEAR::isError($chan)) {
  1131.                     return $this->raiseError($chan);
  1132.                 }
  1133.                 if ($chan->supportsREST($this->config->get('preferred_mirror',
  1134.                                                            null, $channel)) &&
  1135.                       $base = $chan->getBaseURL('REST1.0',
  1136.                                                 $this->config->get('preferred_mirror',
  1137.                                                                    null, $channel)))
  1138.                 {
  1139.                     $dorest = true;
  1140.                 } else {
  1141.                     $dorest = false;
  1142.                     $remote = &$this->config->getRemote($this->config);
  1143.                 }
  1144.                 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  1145.                 if ($dorest) {
  1146.                     $rest = &$this->config->getREST('1.0', array());
  1147.                     $installed = array_flip($reg->listPackages($channel));
  1148.                     $latest = $rest->listLatestUpgrades($base,
  1149.                         $this->config->get('preferred_state', null, $channel), $installed,
  1150.                         $channel, $reg);
  1151.                 } else {
  1152.                     $latest = $remote->call("package.listLatestReleases",
  1153.                         $this->config->get('preferred_state', null, $channel));
  1154.                     unset($remote);
  1155.                 }
  1156.                 PEAR::staticPopErrorHandling();
  1157.                 if (PEAR::isError($latest)) {
  1158.                     $this->ui->outputData('Error getting channel info from ' . $channel .
  1159.                         ': ' . $latest->getMessage());
  1160.                     continue;
  1161.                 }
  1162.  
  1163.                 $latestReleases[$channel] = array_change_key_case($latest);
  1164.             }
  1165.  
  1166.             // check package for latest release
  1167.             if (isset($latestReleases[$channel][strtolower($name)])) {
  1168.                 // if not set, up to date
  1169.                 $inst_version = $reg->packageInfo($name, 'version', $channel);
  1170.                 $channel_version = $latestReleases[$channel][strtolower($name)]['version'];
  1171.                 if (version_compare($channel_version, $inst_version, "le")) {
  1172.                     // installed version is up-to-date
  1173.                     continue;
  1174.                 }
  1175.                 // maintain BC
  1176.                 if ($command == 'upgrade-all') {
  1177.                     $this->ui->outputData(array('data' => 'Will upgrade ' .
  1178.                         $reg->parsedPackageNameToString($package)), $command);
  1179.                 }
  1180.                 $ret[] = $package;
  1181.             }
  1182.         }
  1183.  
  1184.         return $ret;
  1185.     }
  1186.  
  1187. }
  1188. ?>
  1189.