/** * Get a download URL for a dependency, or an array containing the * latest version and its release info. * * If a bundle is specified, then an array of information * will be returned * @param string package.xml version for the dependency (1.0 or 2.0) * @param array dependency information * @param array dependent package information * @param string preferred state * @param string installed version of this dependency * @return bool|array */ function getDepDownloadURL($xsdversion, $dependency, $deppackage, $prefstate = 'stable', $installed = false) { $info = package::info($dependency['name'], 'releases', true); if (!count($info)) { return false; } $states = release::betterStates($prefstate, true); if (!$states) { return PEAR::raiseError("getDownloadURL: preferred state '{$prefstate}' " . 'is not a valid stability state'); } $exclude = array(); $min = $max = $recommended = false; if ($xsdversion == '1.0') { $pinfo['package'] = $dependency['name']; $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this switch ($dependency['rel']) { case 'ge': $min = $dependency['version']; break; case 'gt': $min = $dependency['version']; $exclude = array($dependency['version']); break; case 'eq': $recommended = $dependency['version']; break; case 'lt': $max = $dependency['version']; $exclude = array($dependency['version']); break; case 'le': $max = $dependency['version']; break; case 'ne': $exclude = array($dependency['version']); break; } } elseif ($xsdversion == '2.0') { $pinfo['package'] = $dependency['name']; if ($dependency['channel'] != 'pecl.php.net' && $dependency['channel'] != 'pear.php.net') { return PEAR::raiseError('getDepDownloadURL channel must be pecl.php.net'); } $min = isset($dependency['min']) ? $dependency['min'] : false; $max = isset($dependency['max']) ? $dependency['max'] : false; $recommended = isset($dependency['recommended']) ? $dependency['recommended'] : false; if (isset($dependency['exclude'])) { if (!isset($dependency['exclude'][0])) { $exclude = array($dependency['exclude']); } } } $found = false; $release = false; foreach ($info as $ver => $release) { if (in_array($ver, $exclude)) { // skip excluded versions continue; } // allow newer releases to say "I'm OK with the dependent package" if ($xsdversion == '2.0' && isset($release['compatibility'])) { if (isset($release['compatibility'][$deppackage['channel']][$deppackage['package']]) && in_array($ver, $release['compatibility'][$deppackage['channel']][$deppackage['package']])) { $recommended = $ver; } } if ($recommended) { if ($ver != $recommended) { // if we want a specific // version, then skip all others continue; } else { if (!in_array($release['state'], $states)) { // the stability is too low, but we must return the // recommended version if possible return array('version' => $ver, 'info' => package::getPackageFile($dependency['name'], $ver)); } } } if ($min && version_compare($ver, $min, 'lt')) { // skip too old versions continue; } if ($max && version_compare($ver, $max, 'gt')) { // skip too new versions continue; } if ($installed && version_compare($ver, $installed, '<')) { continue; } if (in_array($release['state'], $states)) { // if in the preferred state... $found = true; // ... then use it break; } } if ($found) { return array('version' => $ver, 'info' => package::getPackageFile($dependency['name'], $ver), 'url' => 'http://' . $_SERVER['SERVER_NAME'] . '/get/' . $pinfo['package'] . '-' . $ver); } else { reset($info); list($ver, $release) = each($info); return array('version' => $ver, 'info' => package::getPackageFile($dependency['name'], $ver)); } }