/** * Get dependencies list/install order info * * * @param string $chanName * @param string $package * @param Mage_Connect_Singleconfig $cache * @param Mage_Connect_Config $config * @param mixed $versionMax * @param mixed $versionMin * @return mixed */ public function getDependenciesList($chanName, $package, $cache, $config, $versionMax = false, $versionMin = false, $withDepsRecursive = true, $forceRemote = false) { static $level = 0; static $_depsHash = array(); static $_deps = array(); static $_failed = array(); $level++; try { $chanName = $cache->chanName($chanName); $rest = new Mage_Connect_Rest($config->protocol); $rest->setChannel($cache->chanUrl($chanName)); $releases = $rest->getReleases($package); if (!$releases || !count($releases)) { throw new Exception("No releases for: '{$package}', skipping"); } $state = $config->preffered_state ? $confg->preffered_state : 'devel'; $version = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax, $state); if (!$version) { throw new Exception("Version for '{$package}' was not detected"); } $packageInfo = $rest->getPackageReleaseInfo($package, $version); if (false === $packageInfo) { throw new Exception("Package release '{$package}' not found on server"); } unset($rest); $dependencies = $packageInfo->getDependencyPackages(); $keyOuter = $chanName . "/" . $package; //print "Processing outer: {$keyOuter} \n"; $_depsHash[$keyOuter] = array('name' => $package, 'channel' => $chanName, 'downloaded_version' => $version, 'min' => $versionMin, 'max' => $versionMax, 'packages' => $dependencies); if ($withDepsRecursive) { $flds = array('name', 'channel', 'min', 'max'); $fldsCount = count($flds); foreach ($dependencies as $row) { foreach ($flds as $key) { $varName = "p" . ucfirst($key); ${$varName} = $row[$key]; } $method = __FUNCTION__; $keyInner = $pChannel . "/" . $pName; if (!isset($_depsHash[$keyInner])) { $_deps[] = $row; $this->{$method}($pChannel, $pName, $cache, $config, $pMax, $pMin, $withDepsRecursive, $forceRemote, false); } else { $downloaded = $_depsHash[$keyInner]['downloaded_version']; $hasMin = $_depsHash[$keyInner]['min']; $hasMax = $_depsHash[$keyInner]['max']; if ($pMin === $hasMin && $pMax === $hasMax) { //var_dump("Equal requirements, skipping"); continue; } if ($cache->versionInRange($downloaded, $pMin, $pMax)) { //var_dump("Downloaded package matches new range too"); continue; } $names = array("pMin", "pMax", "hasMin", "hasMax"); for ($i = 0, $c = count($names); $i < $c; $i++) { if (!isset(${$names}[$i])) { continue; } if (false !== ${$names}[$i]) { continue; } ${$names}[$i] = $i % 2 == 0 ? "0" : "999999999"; } if (!$cache->hasVersionRangeIntersect($pMin, $pMax, $hasMin, $hasMax)) { $reason = "Detected {$pName} conflict of versions: {$hasMin}-{$hasMax} and {$pMin}-{$pMax}"; unset($_depsHash[$keyInner]); $_failed[] = array('name' => $pName, 'channel' => $pChannel, 'max' => $pMax, 'min' => $pMin, 'reason' => $reason); continue; } $newMaxIsLess = version_compare($pMax, $hasMax, "<"); $newMinIsGreater = version_compare($pMin, $hasMin, ">"); $forceMax = $newMaxIsLess ? $pMax : $hasMax; $forceMin = $newMinIsGreater ? $pMin : $hasMin; //var_dump("Trying to process {$pName} : max {$forceMax} - min {$forceMin}"); $this->{$method}($pChannel, $pName, $cache, $config, $forceMax, $forceMin, $withDepsRecursive, $forceRemote); } } } } catch (Exception $e) { $_failed[] = array('name' => $package, 'channel' => $chanName, 'max' => $versionMax, 'min' => $versionMin, 'reason' => $e->getMessage()); } $level--; if ($level == 0) { $out = $this->processDepsHash($_depsHash); $deps = $_deps; $failed = $_failed; $_depsHash = array(); $_deps = array(); $_failed = array(); return array('deps' => $deps, 'result' => $out, 'failed' => $failed); } }
/** * Get dependencies list/install order info * * * @param string $chanName * @param string $package * @param Mage_Connect_Singleconfig $cache * @param Mage_Connect_Config $config * @param mixed $versionMax * @param mixed $versionMin * @param boolean $withDepsRecursive * @param boolean $forceRemote * @param Mage_Connect_Rest $rest * @return mixed */ public function getDependenciesList($chanName, $package, $cache, $config, $versionMax = false, $versionMin = false, $withDepsRecursive = true, $forceRemote = false, $rest = null) { static $level = 0; static $_depsHash = array(); static $_deps = array(); static $_failed = array(); $install_state = 'install'; $version = ''; $stability = ''; $message = ''; $dependencies = array(); $level++; try { $chanName = $cache->chanName($chanName); if (!$rest) { $rest = new Mage_Connect_Rest($config->protocol); } $rest->setChannel($cache->chanUrl($chanName)); $releases = $rest->getReleases($package); if (!$releases || !count($releases)) { throw new Exception("No releases for '{$package}', skipping"); } $state = $config->preffered_state ? $confg->preffered_state : 'devel'; $version = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax, $state); if (!$version) { throw new Exception("Version for '{$package}' was not detected"); } $packageInfo = $rest->getPackageReleaseInfo($package, $version); if (false === $packageInfo) { throw new Exception("Package release '{$package}' not found on server"); } $stability = $packageInfo->getStability(); /** * @todo check is package already installed */ if ($installedPackage = $cache->isPackageInstalled($package)) { if ($chanName == $installedPackage['channel']) { /** * @todo check versions!!! */ if (version_compare($version, $installedPackage['version'], '>')) { $install_state = 'upgrade'; } elseif (version_compare($version, $installedPackage['version'], '<')) { $version = $installedPackage['version']; $stability = $installedPackage['stability']; $install_state = 'wrong_version'; } else { $install_state = 'already_installed'; } } else { $install_state = 'incompatible'; } } $deps_tmp = $packageInfo->getDependencyPackages(); /** * @todo Select distinct packages grouped by name */ $dependencies = array(); foreach ($deps_tmp as $row) { if (isset($dependencies[$row['name']])) { if ($installedPackageDep = $cache->isPackageInstalled($row['name'])) { if ($installedPackageDep['channel'] == $row['channel']) { $dependencies[$row['name']] = $row; } } elseif ($config->root_channel == $row['channel']) { $dependencies[$row['name']] = $row; } } else { $dependencies[$row['name']] = $row; } } /** * @todo When we are building dependencies tree we should base this calculations not on full key as on a * unique value but check it by parts. First part which should be checked is EXTENSION_NAME also this part * should be unique globally not per channel. */ // $keyOuter = $chanName . "/" . $package; $keyOuter = $package; $this->addHashData($_depsHash, $package, $chanName, $version, $stability, $versionMin, $versionMax, $install_state, $message, $dependencies); if ($withDepsRecursive && 'incompatible' != $install_state) { $flds = array('name', 'channel', 'min', 'max'); $fldsCount = count($flds); foreach ($dependencies as $row) { foreach ($flds as $key) { $varName = "p" . ucfirst($key); ${$varName} = $row[$key]; } $method = __FUNCTION__; /** * @todo When we are building dependencies tree we should base this calculations not on full key as * on a unique value but check it by parts. First part which should be checked is EXTENSION_NAME * also this part should be unique globally not per channel. */ //$keyInner = $pChannel . "/" . $pName; $keyInner = $pName; if (!isset($_depsHash[$keyInner])) { $_deps[] = $row; $this->{$method}($pChannel, $pName, $cache, $config, $pMax, $pMin, $withDepsRecursive, $forceRemote, $rest); } else { $downloaded = $_depsHash[$keyInner]['downloaded_version']; $hasMin = $_depsHash[$keyInner]['min']; $hasMax = $_depsHash[$keyInner]['max']; if ($pMin === $hasMin && $pMax === $hasMax) { //var_dump("Equal requirements, skipping"); continue; } if ($cache->versionInRange($downloaded, $pMin, $pMax)) { //var_dump("Downloaded package matches new range too"); continue; } $names = array("pMin", "pMax", "hasMin", "hasMax"); for ($i = 0, $c = count($names); $i < $c; $i++) { if (!isset(${$names}[$i])) { continue; } if (false !== ${$names}[$i]) { continue; } ${$names}[$i] = $i % 2 == 0 ? "0" : "999999999"; } if (!$cache->hasVersionRangeIntersect($pMin, $pMax, $hasMin, $hasMax)) { $reason = "Detected {$pName} conflict of versions: {$hasMin}-{$hasMax} and {$pMin}-{$pMax}"; unset($_depsHash[$keyInner]); $_failed[] = array('name' => $pName, 'channel' => $pChannel, 'max' => $pMax, 'min' => $pMin, 'reason' => $reason); continue; } $newMaxIsLess = version_compare($pMax, $hasMax, "<"); $newMinIsGreater = version_compare($pMin, $hasMin, ">"); $forceMax = $newMaxIsLess ? $pMax : $hasMax; $forceMin = $newMinIsGreater ? $pMin : $hasMin; //var_dump("Trying to process {$pName} : max {$forceMax} - min {$forceMin}"); $this->{$method}($pChannel, $pName, $cache, $config, $forceMax, $forceMin, $withDepsRecursive, $forceRemote, $rest); } } } unset($rest); } catch (Exception $e) { $_failed[] = array('name' => $package, 'channel' => $chanName, 'max' => $versionMax, 'min' => $versionMin, 'reason' => $e->getMessage()); } $level--; if ($level == 0) { $out = $this->processDepsHash($_depsHash, false); $deps = $_deps; $failed = $_failed; $_depsHash = array(); $_deps = array(); $_failed = array(); return array('deps' => $deps, 'result' => $out, 'failed' => $failed); } }
/** * Get dependencies list/install order info * * @param string $chanName * @param string $package * @param Mage_Connect_Singleconfig $cache * @param Mage_Connect_Config $config * @param mixed $versionMax * @param mixed $versionMin * @param boolean $withDepsRecursive * @param boolean $forceRemote * @param Mage_Connect_Rest $rest * @return mixed */ public function getDependenciesList($chanName, $package, $cache, $config, $versionMax = false, $versionMin = false, $withDepsRecursive = true, $forceRemote = false, $rest = null) { static $level = 0; static $_depsHash = array(); static $_deps = array(); static $_failed = array(); $install_state = self::INSTALL_STATE_INSTALL; $version = ''; $message = ''; $level++; try { $chanName = $cache->chanName($chanName); if (!$rest) { $rest = new Mage_Connect_Rest($config->protocol); } $rest->setChannel($cache->chanUrl($chanName)); $releases = $rest->getReleases($package); if (!$releases || !count($releases)) { throw new Exception("No releases for '{$package}', skipping"); } $state = $config->preferred_state ? $config->preferred_state : 'stable'; /** * Check current package version first */ $installedPackage = $cache->getPackage($chanName, $package); if ($installedPackage && is_array($installedPackage)) { $installedRelease = array(array('v' => $installedPackage['version'], 's' => $installedPackage['stability'])); $version = $cache->detectVersionFromRestArray($installedRelease, $versionMin, $versionMax, $state); } if (!$version) { $version = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax, $state); } if (!$version) { $versionState = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax); if ($versionState) { /** @var $packageInfo Mage_Connect_Package */ $packageInfo = $rest->getPackageReleaseInfo($package, $versionState); if (false !== $packageInfo) { $stability = $packageInfo->getStability(); throw new Exception("Extension is '{$stability}' please check(or change) stability settings" . " on Magento Connect Manager"); } } throw new Exception("Version for '{$package}' was not detected"); } $packageInfo = $rest->getPackageReleaseInfo($package, $version); if (false === $packageInfo) { throw new Exception("Package release '{$package}' not found on server"); } $stability = $packageInfo->getStability(); /** * check is package already installed */ if ($installedPackage = $cache->isPackageInstalled($package)) { if ($chanName == $installedPackage['channel']) { /** * check versions */ if (version_compare($version, $installedPackage['version'], '>')) { $install_state = self::INSTALL_STATE_UPGRADE; } elseif (version_compare($version, $installedPackage['version'], '<')) { $version = $installedPackage['version']; $stability = $installedPackage['stability']; $install_state = self::INSTALL_STATE_WRONG_VERSION; } else { $install_state = self::INSTALL_STATE_ALREADY_INSTALLED; } } else { $install_state = self::INSTALL_STATE_INCOMPATIBLE; } } $deps_tmp = $packageInfo->getDependencyPackages(); /** * Select distinct packages grouped by name */ $dependencies = array(); foreach ($deps_tmp as $row) { if (isset($dependencies[$row['name']])) { if ($installedPackageDep = $cache->isPackageInstalled($row['name'])) { if ($installedPackageDep['channel'] == $row['channel']) { $dependencies[$row['name']] = $row; } } elseif ($config->root_channel == $row['channel']) { $dependencies[$row['name']] = $row; } } else { $dependencies[$row['name']] = $row; } } /** * When we are building dependencies tree we should base this calculations not on full key as on a * unique value but check it by parts. First part which should be checked is EXTENSION_NAME also this part * should be unique globally not per channel. */ if (self::INSTALL_STATE_INCOMPATIBLE != $install_state) { $this->addHashData($_depsHash, $package, $chanName, $version, $stability, $versionMin, $versionMax, $install_state, $message, $dependencies); } if ($withDepsRecursive && self::INSTALL_STATE_INCOMPATIBLE != $install_state) { $flds = array('name', 'channel', 'min', 'max'); foreach ($dependencies as $row) { /** * Converts an array to variables * @var $pChannel string Channel Name * @var $pName string Package Name * @var $pMax string Maximum version number * @var $pMin string Minimum version number */ foreach ($flds as $key) { $varName = "p" . ucfirst($key); ${$varName} = $row[$key]; } $method = __FUNCTION__; /** * When we are building dependencies tree we should base this calculations not on full key as * on a unique value but check it by parts. First part which should be checked is EXTENSION_NAME * also this part should be unique globally not per channel. */ $keyInner = $pName; if (!isset($_depsHash[$keyInner])) { $_deps[] = $row; $this->{$method}($pChannel, $pName, $cache, $config, $pMax, $pMin, $withDepsRecursive, $forceRemote, $rest); } else { $downloaded = $_depsHash[$keyInner]['downloaded_version']; $hasMin = $_depsHash[$keyInner]['min']; $hasMax = $_depsHash[$keyInner]['max']; if ($pMin === $hasMin && $pMax === $hasMax) { continue; } if ($cache->versionInRange($downloaded, $pMin, $pMax)) { continue; } $names = array("pMin", "pMax", "hasMin", "hasMax"); for ($i = 0, $c = count($names); $i < $c; $i++) { if (!isset(${$names}[$i])) { continue; } if (false !== ${$names}[$i]) { continue; } ${$names}[$i] = $i % 2 == 0 ? "0" : "999999999"; } if (!$cache->hasVersionRangeIntersect($pMin, $pMax, $hasMin, $hasMax)) { $reason = "Detected {$pName} conflict of versions: {$hasMin}-{$hasMax} and {$pMin}-{$pMax}"; unset($_depsHash[$keyInner]); $_failed[] = array('name' => $pName, 'channel' => $pChannel, 'max' => $pMax, 'min' => $pMin, 'reason' => $reason); continue; } $newMaxIsLess = version_compare($pMax, $hasMax, "<"); $newMinIsGreater = version_compare($pMin, $hasMin, ">"); $forceMax = $newMaxIsLess ? $pMax : $hasMax; $forceMin = $newMinIsGreater ? $pMin : $hasMin; $this->{$method}($pChannel, $pName, $cache, $config, $forceMax, $forceMin, $withDepsRecursive, $forceRemote, $rest); } } } unset($rest); } catch (Exception $e) { $_failed[] = array('name' => $package, 'channel' => $chanName, 'max' => $versionMax, 'min' => $versionMin, 'reason' => $e->getMessage()); } $level--; if ($level == 0) { $out = $this->processDepsHash($_depsHash, false); $deps = $_deps; $failed = $_failed; $_depsHash = array(); $_deps = array(); $_failed = array(); return array('deps' => $deps, 'result' => $out, 'failed' => $failed); } return null; }