/** * Parse a package name, or validate a parsed package name array * @param string|array pass in an array of format * array( * 'package' => 'pname', * ['channel' => 'channame',] * ['version' => 'version',] * ['state' => 'state',] * ['group' => 'groupname']) * or a string of format * [channel://][channame/]pname[-version|-state][/group=groupname] * @return array|PEAR_Error */ function parsePackageName($param, $defaultchannel = 'pear.php.net') { $saveparam = $param; if (is_array($param)) { // convert to string for error messages $saveparam = $this->parsedPackageNameToString($param); // process the array if (!isset($param['package'])) { return PEAR::raiseError('parsePackageName(): array $param ' . 'must contain a valid package name in index "param"', 'package', null, null, $param); } if (!isset($param['uri'])) { if (!isset($param['channel'])) { $param['channel'] = $defaultchannel; } } else { $param['channel'] = '__uri'; } } else { $components = @parse_url((string) $param); if (isset($components['scheme'])) { if ($components['scheme'] == 'http') { // uri package $param = array('uri' => $param, 'channel' => '__uri'); } elseif ($components['scheme'] != 'channel') { return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); } } if (!isset($components['path'])) { return PEAR::raiseError('parsePackageName(): array $param ' . 'must contain a valid package name in "' . $param . '"', 'package', null, null, $param); } if (isset($components['host'])) { // remove the leading "/" $components['path'] = substr($components['path'], 1); } if (!isset($components['scheme'])) { if (strpos($components['path'], '/') !== false) { if ($components['path'][0] == '/') { return PEAR::raiseError('parsePackageName(): this is not ' . 'a package name, it begins with "/" in "' . $param . '"', 'invalid', null, null, $param); } $parts = explode('/', $components['path']); $components['host'] = array_shift($parts); if (count($parts) > 1) { $components['path'] = array_pop($parts); $components['host'] .= '/' . implode('/', $parts); } else { $components['path'] = implode('/', $parts); } } else { $components['host'] = $defaultchannel; } } else { if (strpos($components['path'], '/')) { $parts = explode('/', $components['path']); $components['path'] = array_pop($parts); $components['host'] .= '/' . implode('/', $parts); } } if (is_array($param)) { $param['package'] = $components['path']; } else { $param = array('package' => $components['path']); if (isset($components['host'])) { $param['channel'] = $components['host']; } } if (isset($components['fragment'])) { $param['group'] = $components['fragment']; } if (isset($components['user'])) { $param['user'] = $components['user']; } if (isset($components['pass'])) { $param['pass'] = $components['pass']; } if (isset($components['query'])) { parse_str($components['query'], $param['opts']); } // check for extension $pathinfo = pathinfo($param['package']); if (isset($pathinfo['extension']) && in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { $param['extension'] = $pathinfo['extension']; $param['package'] = substr($pathinfo['basename'], 0, strlen($pathinfo['basename']) - 4); } // check for version if (strpos($param['package'], '-')) { $test = explode('-', $param['package']); if (count($test) != 2) { return PEAR::raiseError('parsePackageName(): only one version/state ' . 'delimiter "-" is allowed in "' . $saveparam . '"', 'version', null, null, $param); } list($param['package'], $param['version']) = $test; } } // validation $info = $this->channelExists($param['channel']); if (PEAR::isError($info)) { return $info; } if (!$info) { return PEAR::raiseError('unknown channel "' . $param['channel'] . '" in "' . $saveparam . '"', 'channel', null, null, $param); } $chan = $this->getChannel($param['channel']); if (PEAR::isError($chan)) { return $chan; } if (!$chan) { return PEAR::raiseError("Exception: corrupt registry, could not " . "retrieve channel " . $param['channel'] . " information", 'registry', null, null, $param); } $param['channel'] = $chan->getName(); $validate = $chan->getValidationObject(); $vpackage = $chan->getValidationPackage(); // validate package name if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { return PEAR::raiseError('parsePackageName(): invalid package name "' . $param['package'] . '" in "' . $saveparam . '"', 'package', null, null, $param); } if (isset($param['group'])) { if (!PEAR_Validate::validGroupName($param['group'])) { return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, $param); } } if (isset($param['state'])) { if (!in_array(strtolower($param['state']), $validate->getValidStates())) { return PEAR::raiseError('parsePackageName(): state "' . $param['state'] . '" is not a valid state in "' . $saveparam . '"', 'state', null, null, $param); } } if (isset($param['version'])) { if (isset($param['state'])) { return PEAR::raiseError('parsePackageName(): cannot contain both ' . 'a version and a stability (state) in "' . $saveparam . '"', 'version/state', null, null, $param); } // check whether version is actually a state if (in_array(strtolower($param['version']), $validate->getValidStates())) { $param['state'] = strtolower($param['version']); unset($param['version']); } else { if (!$validate->validVersion($param['version'])) { return PEAR::raiseError('parsePackageName(): "' . $param['version'] . '" is neither a valid version nor a valid state in "' . $saveparam . '"', 'version/state', null, null, $param); } } } return $param; }
function _validateDependencies() { $structure = array('required', '*optional', '*group->name->hint'); if (!$this->_stupidSchemaValidate($structure, $this->_packageInfo['dependencies'], '<dependencies>')) { return false; } foreach (array('required', 'optional') as $simpledep) { if (isset($this->_packageInfo['dependencies'][$simpledep])) { if ($simpledep == 'optional') { $structure = array('*package', '*subpackage', '*extension'); } else { $structure = array('php', 'pearinstaller', '*package', '*subpackage', '*extension', '*os', '*arch'); } if ($this->_stupidSchemaValidate($structure, $this->_packageInfo['dependencies'][$simpledep], "<dependencies><{$simpledep}>")) { foreach (array('package', 'subpackage', 'extension') as $type) { if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; if (!isset($iter[0])) { $iter = array($iter); } foreach ($iter as $package) { if ($type != 'extension') { if (isset($package['uri'])) { if (isset($package['channel'])) { $this->_UrlOrChannel($type, $package['name']); } } else { if (!isset($package['channel'])) { $this->_NoChannel($type, $package['name']); } } } $this->{"_validate{$type}Dep"}($package, "<{$simpledep}>"); } } } if ($simpledep == 'optional') { continue; } foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) { if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; if (!isset($iter[0])) { $iter = array($iter); } foreach ($iter as $package) { $this->{"_validate{$type}Dep"}($package); } } } } } } if (isset($this->_packageInfo['dependencies']['group'])) { $groups = $this->_packageInfo['dependencies']['group']; if (!isset($groups[0])) { $groups = array($groups); } $structure = array('*package', '*subpackage', '*extension'); foreach ($groups as $group) { if ($this->_stupidSchemaValidate($structure, $group, '<group>')) { if (!PEAR_Validate::validGroupName($group['attribs']['name'])) { $this->_invalidDepGroupName($group['attribs']['name']); } foreach (array('package', 'subpackage', 'extension') as $type) { if (isset($group[$type])) { $iter = $group[$type]; if (!isset($iter[0])) { $iter = array($iter); } foreach ($iter as $package) { if ($type != 'extension') { if (isset($package['uri'])) { if (isset($package['channel'])) { $this->_UrlOrChannelGroup($type, $package['name'], $group['name']); } } else { if (!isset($package['channel'])) { $this->_NoChannelGroup($type, $package['name'], $group['name']); } } } $this->{"_validate{$type}Dep"}($package, '<group name="' . $group['attribs']['name'] . '">'); } } } } } } }