示例#1
0
    /**
     *
     * @param string|array pass in an array of format
     *                     array(
     *                      'package' => 'pname',
     *                     ['channel' => 'channame',]
     *                     ['version' => 'version',]
     *                     ['state' => 'state',])
     *                     or a string of format [channame/]pname[-version|-state]
     */
    protected function fromString($param)
    {
        try {
            $pname = Config::parsePackageName($param, true);
        } catch (\PEAR2\Pyrus\ChannelRegistry\ParseException $e) {
            if ($e->why !== 'channel') {
                throw new Exception('invalid package name/package file "' . $param . '"', $e);
            }

            if (Config::current()->auto_discover) {
                try {
                    try {
                        $chan = new \PEAR2\Pyrus\Channel(
                                    new \PEAR2\Pyrus\ChannelFile('https://' . $e->params['channel'] . '/channel.xml',
                                                                false, true));
                    } catch (\Exception $e) {
                        $chan = new \PEAR2\Pyrus\Channel(
                                    new \PEAR2\Pyrus\ChannelFile('http://' . $e->params['channel'] . '/channel.xml',
                                                                false, true));
                    }
                } catch (\Exception $e) {
                    throw new Exception('Cannot auto-discover channel ' . $e->params['channel'], $e);
                }

                Config::current()->channelregistry[] = $chan;
                try {
                    Config::parsePackageName($param, Config::current()->default_channel);
                } catch (\Exception $e) {
                    throw new Exception('invalid package name/package file "' . $param . '"', $e);
                }
            } else {
                \PEAR2\Pyrus\Logger::log(0, 'Channel "' . $param['channel'] .
                    '" is not initialized, use ' .
                    '"pyrus channel-discover ' . $param['channel'] . '" to initialize' .
                    'or pyrus set auto_discover 1');
            }
        }

        $this->parsedname    = $pname;
        $this->explicitVersion = isset($pname['version']) ? $pname['version'] : false;
        $this->explicitState = isset($pname['state']) ? $pname['state'] : false;
        $this->explicitGroup = isset($pname['group']) ? true            : false;

        $reg = Config::current()->registry;
        $version = $reg->info($pname['package'], $pname['channel'], 'version');
        $stability = $reg->info($pname['package'], $pname['channel'], 'state');

        if (!isset(\PEAR2\Pyrus\Main::$options['force']) &&
              !isset(\PEAR2\Pyrus\Main::$options['downloadonly']) &&
              $version && $this->explicitVersion &&
              !isset($pname['group'])) {
            if (version_compare($version, $pname['version'], '>=')) {
                throw new InstalledException(
                    Config::parsedPackageNameToString($pname, true) .
                    ' is already installed and is newer than detected ' .
                    'release version ' . $pname['version']);
            }
        }
        if (!$this->explicitVersion && $stability) {
            // if installed, use stability of the installed package,
            // but only if it is less restrictive than preferred_state.
            // This allows automatic upgrade to a newer beta for 1 package
            // even if preferred_state is stable, for instance.
            $states = \PEAR2\Pyrus\Installer::betterStates(Config::current()->preferred_state);
            $newstates = \PEAR2\Pyrus\Installer::betterStates($stability);
            if (count($newstates) > count($states)) {
                $this->explicitState = $stability;
            }
        }

        $this->type = 'abstract';
        $ret = $this->getRemotePackage($pname);
        if ($this->explicitVersion) {
            $ret->setExplicitVersion($this->explicitVersion);
            $ret->version['release'] = $this->explicitVersion;
        }
        if ($this->explicitState) {
            $ret->setExplicitState($this->explicitState);
        }
        return $ret;
    }