engine_type = $type; $this->engine = $engine; if (is_null($config)) { $config = array(); } $config += array( 'cache-duration' => drush_get_option('cache-duration-releasexml', self::CACHE_LIFETIME), ); $this->engine_config = $config; $this->cache = array(); } /** * Returns configured cache duration. */ public function getCacheDuration() { return $this->engine_config['cache-duration']; } /** * Returns a project's release info from the update service. * * @param array $request * A request array. * * @param bool $refresh * Whether to discard cached object. * * @return \Drush\UpdateService\Project */ public function get($request, $refresh = FALSE) { if ($refresh || !isset($this->cache[$request['name']])) { $project_release_info = Project::getInstance($request, $this->getCacheDuration()); if ($project_release_info && !$project_release_info->isValid()) { $project_release_info = FALSE; } $this->cache[$request['name']] = $project_release_info; } return $this->cache[$request['name']]; } /** * Delete cached update service file of a project. * * @param array $request * A request array. */ public function clearCached(array $request) { if (isset($this->cache[$request['name']])) { unset($this->cache[$request['name']]); } $url = Project::buildFetchUrl($request); $cache_file = drush_download_file_name($url); if (file_exists($cache_file)) { unlink($cache_file); } } /** * Select the most appropriate release for a project, based on a strategy. * * @param Array &$request * A request array. * The array will be expanded with the project type. * @param String $restrict_to * One of: * 'dev': Forces choosing a -dev release. * 'version': Forces choosing a point release. * '': No restriction. * Default is ''. * @param String $select * Strategy for selecting a release, should be one of: * - auto: Try to select the latest release, if none found allow the user * to choose. * - always: Force the user to choose a release. * - never: Try to select the latest release, if none found then fail. * - ignore: Ignore and return NULL. * If no supported release is found, allow to ask the user to choose one. * @param Boolean $all * In case $select = TRUE this indicates that all available releases will be * offered the user to choose. * * @return array * The selected release. */ public function selectReleaseBasedOnStrategy($request, $restrict_to = '', $select = 'never', $all = FALSE, $version = NULL) { if (!in_array($select, array('auto', 'never', 'always', 'ignore'))) { return drush_set_error('DRUSH_PM_UNKNOWN_SELECT_STRATEGY', dt("Error: select strategy must be one of: auto, never, always, ignore", array())); } $project_release_info = $this->get($request); if (!$project_release_info) { return FALSE; } if ($select != 'always') { if (isset($request['version'])) { $release = $project_release_info->getSpecificRelease($request['version']); if ($release === FALSE) { return drush_set_error('DRUSH_PM_COULD_NOT_FIND_VERSION', dt("Could not locate !project version !version.", array( '!project' => $request['name'], '!version' => $request['version'], ))); } } if ($restrict_to == 'dev') { // If you specified a specific release AND --dev, that is either // redundant (okay), or contradictory (error). if (!empty($release)) { if ($release['version_extra'] != 'dev') { return drush_set_error('DRUSH_PM_COULD_NOT_FIND_VERSION', dt("You requested both --dev and !project version !version, which is not a '-dev' release.", array( '!project' => $request['name'], '!version' => $request['version'], ))); } } else { $release = $project_release_info->getDevRelease(); if ($release === FALSE) { return drush_set_error('DRUSH_PM_NO_DEV_RELEASE', dt('There is no development release for project !project.', array('!project' => $request['name']))); } } } // If there was no specific release requested, try to identify the most appropriate release. if (empty($release)) { $release = $project_release_info->getRecommendedOrSupportedRelease(); } if ($release) { return $release; } else { $message = dt('There are no stable releases for project !project.', array('!project' => $request['name'])); if ($select == 'never') { return drush_set_error('DRUSH_PM_NO_STABLE_RELEASE', $message); } drush_log($message, LogLevel::WARNING); if ($select == 'ignore') { return NULL; } } } // At this point the only chance is to ask the user to choose a release. if ($restrict_to == 'dev') { $filter = 'dev'; } elseif ($all) { $filter = 'all'; } else { $filter = ''; } $releases = $project_release_info->filterReleases($filter, $version); // Special checking: Drupal 6 is EOL, so there are no stable // releases for ANY contrib project. In this case, we'll default // to the best release, unless the user specified --select. $version_major = drush_drupal_major_version(); if (($select != 'always') && ($version_major < 7)) { $bestRelease = Project::getBestRelease($releases); if (!empty($bestRelease)) { $message = dt('Drupal !major has reached EOL, so there are no stable releases for any contrib projects. Selected the best release, !project.', array('!major' => $version_major, '!project' => $bestRelease['name'])); drush_log($message, LogLevel::WARNING); return $bestRelease; } } $options = array(); foreach($releases as $release) { $options[$release['version']] = array($release['version'], '-', gmdate('Y-M-d', $release['date']), '-', implode(', ', $release['release_status'])); } $choice = drush_choice($options, dt('Choose one of the available releases for !project:', array('!project' => $request['name']))); if (!$choice) { return drush_user_abort(); } return $releases[$choice]; } /** * Check if a project is available in the update service. * * Optionally check for consistency by comparing given project type and * the type obtained from the update service. * * @param array $request * A request array. * @param string $type * Optional. If provided, will do a consistent check of the project type. * * @return boolean * True if the project exists and type matches. */ public function checkProject($request, $type = NULL) { $project_release_info = $this->get($request); if (!$project_release_info) { return FALSE; } if ($type) { if ($project_release_info->getType() != $type) { return FALSE; } } return TRUE; } }