示例#1
0
 /**
  * Get dependencies list/install order info
  *
  * @param string $chanName
  * @param string $package
  * @param \Magento\Framework\Connect\Singleconfig $cache
  * @param \Magento\Framework\Connect\Config $config
  * @param mixed $versionMax
  * @param mixed $versionMin
  * @param boolean $withDepsRecursive
  * @param boolean $forceRemote
  * @param \Magento\Framework\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 \Magento\Framework\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 \Magento\Framework\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;
 }
示例#2
0
 /**
  * Display/get installation information for package
  * @param string $command
  * @param array $options
  * @param array $params
  * @return void|array
  */
 public function doPackagePrepare($command, $options, $params)
 {
     $this->cleanupParams($params);
     $channelAuth = array();
     if (isset($options['auth'])) {
         $channelAuth = $options['auth'];
         $options['auth'] = null;
     }
     try {
         if (count($params) < 2) {
             return $this->doError($command, "Argument count should be >= 2");
         }
         $channel = $params[0];
         $package = $params[1];
         $argVersionMin = isset($params[3]) ? $params[3] : false;
         $argVersionMax = isset($params[2]) ? $params[2] : false;
         $ftp = empty($options['ftp']) ? false : $options['ftp'];
         $packager = $this->getPackager();
         if ($ftp) {
             list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
         } else {
             $cache = $this->getSconfig();
             $config = $this->config();
         }
         $rest = new \Magento\Framework\Connect\Rest($config->protocol);
         if (!empty($channelAuth)) {
             $rest->getLoader()->setCredentials($channelAuth['username'], $channelAuth['password']);
         }
         $cache->checkChannel($channel, $config, $rest);
         $data = $packager->getDependenciesList($channel, $package, $cache, $config, $argVersionMax, $argVersionMin, true, false, $rest);
         $result = array();
         foreach ($data['result'] as $_package) {
             $_result['channel'] = $_package['channel'];
             $_result['name'] = $_package['name'];
             $_result['version'] = $_package['downloaded_version'];
             $_result['stability'] = $_package['stability'];
             $_result['install_state'] = $_package['install_state'];
             $_result['message'] = $_package['message'];
             $result[] = $_result;
         }
         if (!count($data['result']) && isset($data['failed']) && !empty($data['failed'])) {
             foreach ($data['failed'] as $_package) {
                 $reason = $_package['channel'] . '/' . $_package['name'] . ': ' . $_package['reason'];
                 $this->doError($command, $reason);
             }
         }
         $this->ui()->output(array($command => array('data' => $result, 'title' => "Package installation information for {$params[1]}: ")));
     } catch (\Exception $e) {
         $this->doError($command, $e->getMessage());
     }
 }
示例#3
0
 /**
  * Check channel, add if valid name and not exist
  *
  * @param string $chanName
  * @param \Magento\Framework\Connect\Config $config
  * @param \Magento\Framework\Connect\Rest $rest
  * @return bool
  * @throws \Exception
  */
 public function checkChannel($chanName, $config, $rest = null)
 {
     if ($this->isChannel($chanName)) {
         return true;
     }
     $_validator = new \Magento\Framework\Connect\Validator();
     if ($this->isChannelName($chanName)) {
         $uri = $this->chanUrl($chanName);
     } elseif ($_validator->validateUrl($chanName)) {
         $uri = $chanName;
     } elseif ($chanName) {
         $uri = $config->protocol . '://' . $chanName;
     } else {
         throw new \Exception("'{$chanName}' is not existant channel name / valid uri");
     }
     if ($uri && !$this->isChannel($uri)) {
         if (!isset($rest)) {
             $rest = new \Magento\Framework\Connect\Rest($config->protocol);
         }
         $rest->setChannel($uri);
         $data = $rest->getChannelInfo();
         $data->uri = $uri;
         $this->addChannel($data->name, $uri);
     }
     return $this->isChannel($uri);
 }
示例#4
0
 /**
  * Get dependencies list/install order info
  *
  * @param string $chanName
  * @param string $package
  * @param Singleconfig $cache
  * @param Config $config
  * @param string|false $versionMax
  * @param string|false $versionMin
  * @param bool $withDepsRecursive
  * @param bool $forceRemote
  * @return array|void
  * @throws \Exception
  */
 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 \Magento\Framework\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);
     }
 }