src/PEAR/Command/Install.php
function doUninstall($command, $options, $params)
    {
        if (count($params) < 1) {
            return $this->raiseError("Please supply the package(s) you want to uninstall");
        }

        if (empty($this->installer)) {
            $this->installer = &$this->getInstaller($this->ui);
        }

        if (isset($options['remoteconfig'])) {
            $e = $this->config->readFTPConfigFile($options['remoteconfig']);
            if (!PEAR::isError($e)) {
                $this->installer->setConfig($this->config);
            }
        }

        $reg = &$this->config->getRegistry();
        $newparams = array();
        $binaries = array();
        $badparams = array();
        foreach ($params as $pkg) {
            $channel = $this->config->get('default_channel');
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
            $parsed = $reg->parsePackageName($pkg, $channel);
            PEAR::staticPopErrorHandling();
            if (!$parsed || PEAR::isError($parsed)) {
                $badparams[] = $pkg;
                continue;
            }
            $package = $parsed['package'];
            $channel = $parsed['channel'];
            $info = &$reg->getPackage($package, $channel);
            if ($info === null &&
                 ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) {
                // make sure this isn't a package that has flipped from pear to pecl but
                // used a package.xml 1.0
                $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net';
                $info = &$reg->getPackage($package, $testc);
                if ($info !== null) {
                    $channel = $testc;
                }
            }
            if ($info === null) {
                $badparams[] = $pkg;
            } else {
                $newparams[] = &$info;
                // check for binary packages (this is an alias for those packages if so)
                if ($installedbinary = $info->getInstalledBinary()) {
                    $this->ui->log('adding binary package ' .
                        $reg->parsedPackageNameToString(array('channel' => $channel,
                            'package' => $installedbinary), true));
                    $newparams[] = &$reg->getPackage($installedbinary, $channel);
                }
                // add the contents of a dependency group to the list of installed packages
                if (isset($parsed['group'])) {
                    $group = $info->getDependencyGroup($parsed['group']);
                    if ($group) {
                        $installed = $reg->getInstalledGroup($group);
                        if ($installed) {
                            foreach ($installed as $i => $p) {
                                $newparams[] = &$installed[$i];
                            }
                        }
                    }
                }
            }
        }
        $err = $this->installer->sortPackagesForUninstall($newparams);
        if (PEAR::isError($err)) {
            $this->ui->outputData($err->getMessage(), $command);
            return true;
        }
        $params = $newparams;
        // twist this to use it to check on whether dependent packages are also being uninstalled
        // for circular dependencies like subpackages
        $this->installer->setUninstallPackages($newparams);
        $params = array_merge($params, $badparams);
        $binaries = array();
        foreach ($params as $pkg) {
            $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
            if ($err = $this->installer->uninstall($pkg, $options)) {
                $this->installer->popErrorHandling();
                if (PEAR::isError($err)) {
                    $this->ui->outputData($err->getMessage(), $command);
                    continue;
                }
                if ($pkg->getPackageType() == 'extsrc' ||
                      $pkg->getPackageType() == 'extbin' ||
                      $pkg->getPackageType() == 'zendextsrc' ||
                      $pkg->getPackageType() == 'zendextbin') {
                    if ($instbin = $pkg->getInstalledBinary()) {
                        continue; // this will be uninstalled later
                    }

                    foreach ($pkg->getFilelist() as $name => $atts) {
                        $pinfo = pathinfo($atts['installed_as']);
                        if (!isset($pinfo['extension']) ||
                              in_array($pinfo['extension'], array('c', 'h'))) {
                            continue; // make sure we don't match php_blah.h
                        }
                        if ((strpos($pinfo['basename'], 'php_') === 0 &&
                              $pinfo['extension'] == 'dll') ||
                              // most unices
                              $pinfo['extension'] == 'so' ||
                              // hp-ux
                              $pinfo['extension'] == 'sl') {
                            $binaries[] = array($atts['installed_as'], $pinfo);
                            break;
                        }
                    }
                    if (count($binaries)) {
                        foreach ($binaries as $pinfo) {
                            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
                            $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
                            PEAR::staticPopErrorHandling();
                            if (PEAR::isError($ret)) {
                                $extrainfo[] = $ret->getMessage();
                                if ($pkg->getPackageType() == 'extsrc' ||
                                      $pkg->getPackageType() == 'extbin') {
                                    $exttype = 'extension';
                                } else {
                                    ob_start();
                                    phpinfo(INFO_GENERAL);
                                    $info = ob_get_contents();
                                    ob_end_clean();
                                    $debug = function_exists('leak') ? '_debug' : '';
                                    $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
                                    $exttype = 'zend_extension' . $debug . $ts;
                                }
                                $this->ui->outputData('Unable to remove "' . $exttype . '=' .
                                    $pinfo[1]['basename'] . '" from php.ini', $command);
                            } else {
                                $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
                                    ' disabled in php.ini', $command);
                            }
                        }
                    }
                }
                $savepkg = $pkg;
                if ($this->config->get('verbose') > 0) {
                    if (is_object($pkg)) {
                        $pkg = $reg->parsedPackageNameToString($pkg);
                    }
                    $this->ui->outputData("uninstall ok: $pkg", $command);
                }
                if (!isset($options['offline']) && is_object($savepkg) &&
                      defined('PEAR_REMOTEINSTALL_OK')) {
                    if ($this->config->isDefinedLayer('ftp')) {
                        $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
                        $info = $this->installer->ftpUninstall($savepkg);
                        $this->installer->popErrorHandling();
                        if (PEAR::isError($info)) {
                            $this->ui->outputData($info->getMessage());
                            $this->ui->outputData("remote uninstall failed: $pkg");
                        } else {
                            $this->ui->outputData("remote uninstall ok: $pkg");
                        }
                    }
                }
            } else {
                $this->installer->popErrorHandling();
                if (!is_object($pkg)) {
                    return $this->raiseError("uninstall failed: $pkg");
                }
                $pkg = $reg->parsedPackageNameToString($pkg);
            }
        }

        return true;
    }
function doUninstall($command, $options, $params)
    {
        if (count($params) < 1) {
            return $this->raiseError("Please supply the package(s) you want to uninstall");
        }

        if (empty($this->installer)) {
            $this->installer = &$this->getInstaller($this->ui);
        }

        if (isset($options['remoteconfig'])) {
            $e = $this->config->readFTPConfigFile($options['remoteconfig']);
            if (!PEAR::isError($e)) {
                $this->installer->setConfig($this->config);
            }
        }

        $reg = &$this->config->getRegistry();
        $newparams = array();
        $binaries = array();
        $badparams = array();
        foreach ($params as $pkg) {
            $channel = $this->config->get('default_channel');
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
            $parsed = $reg->parsePackageName($pkg, $channel);
            PEAR::staticPopErrorHandling();
            if (!$parsed || PEAR::isError($parsed)) {
                $badparams[] = $pkg;
                continue;
            }
            $package = $parsed['package'];
            $channel = $parsed['channel'];
            $info = &$reg->getPackage($package, $channel);
            if ($info === null &&
                 ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) {
                // make sure this isn't a package that has flipped from pear to pecl but
                // used a package.xml 1.0
                $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net';
                $info = &$reg->getPackage($package, $testc);
                if ($info !== null) {
                    $channel = $testc;
                }
            }
            if ($info === null) {
                $badparams[] = $pkg;
            } else {
                $newparams[] = &$info;
                // check for binary packages (this is an alias for those packages if so)
                if ($installedbinary = $info->getInstalledBinary()) {
                    $this->ui->log('adding binary package ' .
                        $reg->parsedPackageNameToString(array('channel' => $channel,
                            'package' => $installedbinary), true));
                    $newparams[] = &$reg->getPackage($installedbinary, $channel);
                }
                // add the contents of a dependency group to the list of installed packages
                if (isset($parsed['group'])) {
                    $group = $info->getDependencyGroup($parsed['group']);
                    if ($group) {
                        $installed = $reg->getInstalledGroup($group);
                        if ($installed) {
                            foreach ($installed as $i => $p) {
                                $newparams[] = &$installed[$i];
                            }
                        }
                    }
                }
            }
        }
        $err = $this->installer->sortPackagesForUninstall($newparams);
        if (PEAR::isError($err)) {
            $this->ui->outputData($err->getMessage(), $command);
            return true;
        }
        $params = $newparams;
        // twist this to use it to check on whether dependent packages are also being uninstalled
        // for circular dependencies like subpackages
        $this->installer->setUninstallPackages($newparams);
        $params = array_merge($params, $badparams);
        $binaries = array();
        foreach ($params as $pkg) {
            $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
            if ($err = $this->installer->uninstall($pkg, $options)) {
                $this->installer->popErrorHandling();
                if (PEAR::isError($err)) {
                    $this->ui->outputData($err->getMessage(), $command);
                    continue;
                }
                if ($pkg->getPackageType() == 'extsrc' ||
                      $pkg->getPackageType() == 'extbin' ||
                      $pkg->getPackageType() == 'zendextsrc' ||
                      $pkg->getPackageType() == 'zendextbin') {
                    if ($instbin = $pkg->getInstalledBinary()) {
                        continue; // this will be uninstalled later
                    }

                    foreach ($pkg->getFilelist() as $name => $atts) {
                        $pinfo = pathinfo($atts['installed_as']);
                        if (!isset($pinfo['extension']) ||
                              in_array($pinfo['extension'], array('c', 'h'))) {
                            continue; // make sure we don't match php_blah.h
                        }
                        if ((strpos($pinfo['basename'], 'php_') === 0 &&
                              $pinfo['extension'] == 'dll') ||
                              // most unices
                              $pinfo['extension'] == 'so' ||
                              // hp-ux
                              $pinfo['extension'] == 'sl') {
                            $binaries[] = array($atts['installed_as'], $pinfo);
                            break;
                        }
                    }
                    if (count($binaries)) {
                        foreach ($binaries as $pinfo) {
                            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
                            $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
                            PEAR::staticPopErrorHandling();
                            if (PEAR::isError($ret)) {
                                $extrainfo[] = $ret->getMessage();
                                if ($pkg->getPackageType() == 'extsrc' ||
                                      $pkg->getPackageType() == 'extbin') {
                                    $exttype = 'extension';
                                } else {
                                    ob_start();
                                    phpinfo(INFO_GENERAL);
                                    $info = ob_get_contents();
                                    ob_end_clean();
                                    $debug = function_exists('leak') ? '_debug' : '';
                                    $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
                                    $exttype = 'zend_extension' . $debug . $ts;
                                }
                                $this->ui->outputData('Unable to remove "' . $exttype . '=' .
                                    $pinfo[1]['basename'] . '" from php.ini', $command);
                            } else {
                                $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
                                    ' disabled in php.ini', $command);
                            }
                        }
                    }
                }
                $savepkg = $pkg;
                if ($this->config->get('verbose') > 0) {
                    if (is_object($pkg)) {
                        $pkg = $reg->parsedPackageNameToString($pkg);
                    }
                    $this->ui->outputData("uninstall ok: $pkg", $command);
                }
                if (!isset($options['offline']) && is_object($savepkg) &&
                      defined('PEAR_REMOTEINSTALL_OK')) {
                    if ($this->config->isDefinedLayer('ftp')) {
                        $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
                        $info = $this->installer->ftpUninstall($savepkg);
                        $this->installer->popErrorHandling();
                        if (PEAR::isError($info)) {
                            $this->ui->outputData($info->getMessage());
                            $this->ui->outputData("remote uninstall failed: $pkg");
                        } else {
                            $this->ui->outputData("remote uninstall ok: $pkg");
                        }
                    }
                }
            } else {
                $this->installer->popErrorHandling();
                if (!is_object($pkg)) {
                    return $this->raiseError("uninstall failed: $pkg");
                }
                $pkg = $reg->parsedPackageNameToString($pkg);
            }
        }

        return true;
    }
{{{ doUninstall()