/** * @param array all packages to be installed */ function analyzeDependencies(&$params, $force = false) { if (isset($this->_options['downloadonly'])) { return; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $redo = true; $reset = $hasfailed = $failed = false; while ($redo) { $redo = false; foreach ($params as $i => $param) { $deps = $param->getDeps(); if (!$deps) { $depchecker =& $this->getDependency2Object($this->config, $this->getOptions(), $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); $send = $param->getPackageFile(); $installcheck = $depchecker->validatePackage($send, $this, $params); if (PEAR::isError($installcheck)) { if (!isset($this->_options['soft'])) { $this->log(0, $installcheck->getMessage()); } $hasfailed = true; $params[$i] = false; $reset = true; $redo = true; $failed = false; PEAR_Downloader_Package::removeDuplicates($params); continue 2; } continue; } if (!$reset && $param->alreadyValidated() && !$force) { continue; } if (count($deps)) { $depchecker =& $this->getDependency2Object($this->config, $this->getOptions(), $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); $send = $param->getPackageFile(); if ($send === null) { $send = $param->getDownloadURL(); } $installcheck = $depchecker->validatePackage($send, $this, $params); if (PEAR::isError($installcheck)) { if (!isset($this->_options['soft'])) { $this->log(0, $installcheck->getMessage()); } $hasfailed = true; $params[$i] = false; $reset = true; $redo = true; $failed = false; PEAR_Downloader_Package::removeDuplicates($params); continue 2; } $failed = false; if (isset($deps['required']) && is_array($deps['required'])) { foreach ($deps['required'] as $type => $dep) { // note: Dependency2 will never return a PEAR_Error if ignore-errors // is specified, so soft is needed to turn off logging if (!isset($dep[0])) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, true, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } else { foreach ($dep as $d) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($d, true, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } } if (isset($deps['optional']) && is_array($deps['optional'])) { foreach ($deps['optional'] as $type => $dep) { if (!isset($dep[0])) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } else { foreach ($dep as $d) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($d, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } } } $groupname = $param->getGroup(); if (isset($deps['group']) && $groupname) { if (!isset($deps['group'][0])) { $deps['group'] = array($deps['group']); } $found = false; foreach ($deps['group'] as $group) { if ($group['attribs']['name'] == $groupname) { $found = true; break; } } if ($found) { unset($group['attribs']); foreach ($group as $type => $dep) { if (!isset($dep[0])) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } else { foreach ($dep as $d) { if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($d, false, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } } } } } else { foreach ($deps as $dep) { if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) { $failed = true; if (!isset($this->_options['soft'])) { $this->log(0, $e->getMessage()); } } elseif (is_array($e) && !$param->alreadyValidated()) { if (!isset($this->_options['soft'])) { $this->log(0, $e[0]); } } } } $params[$i]->setValidated(); } if ($failed) { $hasfailed = true; $params[$i] = false; $reset = true; $redo = true; $failed = false; PEAR_Downloader_Package::removeDuplicates($params); continue 2; } } } PEAR::staticPopErrorHandling(); if ($hasfailed && (isset($this->_options['ignore-errors']) || isset($this->_options['nodeps']))) { // this is probably not needed, but just in case if (!isset($this->_options['soft'])) { $this->log(0, 'WARNING: dependencies failed'); } } }
/** * @static */ function mergeDependencies(&$params) { $newparams = array(); $bundles = array(); foreach ($params as $i => $param) { if (!$param->isBundle()) { continue; } $bundles[] = $i; $pf =& $param->getPackageFile(); $newdeps = array(); $contents = $pf->getBundledPackages(); if (!is_array($contents)) { $contents = array($contents); } foreach ($contents as $file) { $filecontents = $pf->getFileContents($file); $dl =& $param->getDownloader(); $options = $dl->getOptions(); $fp = @fopen($dl->getDownloadDir() . DIRECTORY_SEPARATOR . $file, 'wb'); if (!$fp) { continue; } fwrite($fp, $filecontents, strlen($filecontents)); fclose($fp); if ($s = $params[$i]->explicitState()) { $obj->setExplicitState($s); } $obj =& new PEAR_Downloader_Package($params[$i]->getDownloader()); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $e = $obj->_fromFile($a = $dl->getDownloadDir() . DIRECTORY_SEPARATOR . $file); PEAR::popErrorHandling(); if (PEAR::isError($e)) { if (!isset($options['soft'])) { $dl->log(0, $e->getMessage()); } continue; } $j =& $obj; if (!PEAR_Downloader_Package::willDownload($j, array_merge($params, $newparams)) && !$param->isInstalled($j)) { $newparams[] =& $j; } } } foreach ($bundles as $i) { unset($params[$i]); // remove bundles - only their contents matter for installation } PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices if (count($newparams)) { // add in bundled packages for install foreach ($newparams as $i => $unused) { $params[] =& $newparams[$i]; } $newparams = array(); } foreach ($params as $i => $param) { $newdeps = array(); foreach ($param->_downloadDeps as $dep) { if (!PEAR_Downloader_Package::willDownload($dep, array_merge($params, $newparams)) && !$param->isInstalled($dep)) { $newdeps[] = $dep; } else { // detect versioning conflicts here } } // convert the dependencies into PEAR_Downloader_Package objects for the next time // around $params[$i]->_downloadDeps = array(); foreach ($newdeps as $dep) { $obj =& new PEAR_Downloader_Package($params[$i]->getDownloader()); if ($s = $params[$i]->explicitState()) { $obj->setExplicitState($s); } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $e = $obj->fromDepURL($dep); PEAR::popErrorHandling(); if (PEAR::isError($e)) { if (!isset($options['soft'])) { $obj->_downloader->log(0, $e->getMessage()); } continue; } $e = $obj->detectDependencies($params); if (PEAR::isError($e)) { if (!isset($options['soft'])) { $obj->_downloader->log(0, $e->getMessage()); } } $j =& $obj; $newparams[] =& $j; } } if (count($newparams)) { foreach ($newparams as $i => $unused) { $params[] =& $newparams[$i]; } return true; } else { return false; } }