appRoot = $appRoot; $this->entityTypeManager = $entityTypeManager; $this->httpClient = $httpClient; } /** * @return string */ public function getDrupalVersion() { return \Drupal::VERSION; } /** * Auxiliary function to get all available drupal caches. * * @return \Drupal\Core\Cache\CacheBackendInterface[] The all available drupal caches */ public function getCaches() { if (!$this->caches) { foreach (Cache::getBins() as $name => $bin) { $this->caches[$name] = $bin; } } return $this->caches; } /** * Validate if a string is a valid cache. * * @param string $cache The cache name * * @return mixed The cache name if valid or FALSE if not valid */ public function isValidCache($cache) { // Get the valid caches $caches = $this->getCaches(); $cacheKeys = array_keys($caches); $cacheKeys[] = 'all'; if (!in_array($cache, array_values($cacheKeys))) { return false; } return $cache; } /** * @return array */ public function getBundles() { if (!$this->bundles) { $nodeTypes = $this->entityTypeManager->getStorage('node_type')->loadMultiple(); foreach ($nodeTypes as $nodeType) { $this->bundles[$nodeType->id()] = $nodeType->label(); } } return $this->bundles; } /** * @return array */ public function getVocabularies() { if (!$this->vocabularies) { $vocabularies = $this->entityTypeManager->getStorage('taxonomy_vocabulary')->loadMultiple(); foreach ($vocabularies as $vocabulary) { $this->vocabularies[$vocabulary->id()] = $vocabulary->label(); } } return $this->vocabularies; } /** * @param bool|FALSE $reset * @param bool|FALSE $authenticated * @param bool|FALSE $anonymous * * @return array */ public function getRoles($reset=false, $authenticated=true, $anonymous=false) { if ($reset || !$this->roles) { $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple(); if (!$authenticated) { unset($roles['authenticated']); } if (!$anonymous) { unset($roles['anonymous']); } foreach ($roles as $role) { $this->roles[$role->id()] = $role->label(); } } return $this->roles; } /** * @param $module * @param $limit * @param $stable * @return array * @throws \Exception */ public function getProjectReleases($module, $limit = 10, $stable = false) { if (!$module) { return []; } $projectPageResponse = $this->httpClient->getUrlAsString( sprintf( 'https://updates.drupal.org/release-history/%s/8.x', $module ) ); if ($projectPageResponse->getStatusCode() != 200) { throw new \Exception('Invalid path.'); } $releases = []; $crawler = new Crawler($projectPageResponse->getBody()->getContents()); $filter = './project/releases/release/version'; if ($stable) { $filter = './project/releases/release[not(version_extra)]/version'; } foreach ($crawler->filterXPath($filter) as $element) { $releases[] = $element->nodeValue; } if (count($releases)>$limit) { array_splice($releases, $limit); } return $releases; } /** * @param $project * @param $release * @param null $destination * @return null|string */ public function downloadProjectRelease($project, $release, $destination = null) { if (!$release) { $releases = $this->getProjectReleases($project, 1); $release = current($releases); } if (!$destination) { $destination = sprintf( '%s/%s.tar.gz', sys_get_temp_dir(), $project ); } $releaseFilePath = sprintf( 'https://ftp.drupal.org/files/projects/%s-%s.tar.gz', $project, $release ); if ($this->downloadFile($releaseFilePath, $destination)) { return $destination; } return null; } public function downloadFile($url, $destination) { $this->httpClient->get($url, ['sink' => $destination]); return file_exists($destination); } /** * Gets Drupal modules releases from Packagist API. * * @param string $module * @param int $limit * @param bool $unstable * * @return array */ public function getPackagistModuleReleases($module, $limit = 10, $unstable = true) { if (!trim($module)) { return []; } return $this->getComposerReleases( sprintf( 'http://packagist.drupal-composer.org/packages/drupal/%s.json', trim($module) ), $limit, $unstable ); } /** * Gets Drupal releases from Packagist API. * * @param string $url * @param int $limit * @param bool $unstable * * @return array */ private function getComposerReleases($url, $limit = 10, $unstable = false) { if (!$url) { return []; } $packagistResponse = $this->httpClient->getUrlAsString($url); if ($packagistResponse->getStatusCode() != 200) { throw new \Exception('Invalid path.'); } try { $packagistJson = json_decode( $packagistResponse->getBody()->getContents() ); } catch (\Exception $e) { return []; } $versions = array_keys((array)$packagistJson->package->versions); // Remove Drupal 7 versions $i = 0; foreach ($versions as $version) { if (0 === strpos($version, "7.") || 0 === strpos($version, "dev-7.")) { unset($versions[$i]); } $i++; } if (!$unstable) { foreach ($versions as $key => $version) { if (strpos($version, "-")) { unset($versions[$key]); } } } if (is_array($versions)) { return array_slice($versions, 0, $limit); } return []; } /** * @Todo: Remove when issue https://www.drupal.org/node/2556025 get resolved * * Rebuilds all caches even when Drupal itself does not work. * * @param \Composer\Autoload\ClassLoader $class_loader * The class loader. * @param \Symfony\Component\HttpFoundation\Request $request * The current request. * * @see rebuild.php */ public function drupal_rebuild($class_loader, \Symfony\Component\HttpFoundation\Request $request) { // Remove Drupal's error and exception handlers; they rely on a working // service container and other subsystems and will only cause a fatal error // that hides the actual error. restore_error_handler(); restore_exception_handler(); // Force kernel to rebuild php cache. \Drupal\Core\PhpStorage\PhpStorageFactory::get('twig')->deleteAll(); // Bootstrap up to where caches exist and clear them. $kernel = new \Drupal\Core\DrupalKernel('prod', $class_loader); $kernel->setSitePath(\Drupal\Core\DrupalKernel::findSitePath($request)); // Invalidate the container. $kernel->invalidateContainer(); // Prepare a NULL request. $kernel->prepareLegacyRequest($request); foreach (Cache::getBins() as $bin) { $bin->deleteAll(); } // Disable recording of cached pages. \Drupal::service('page_cache_kill_switch')->trigger(); drupal_flush_all_caches(); // Restore Drupal's error and exception handlers. // @see \Drupal\Core\DrupalKernel::boot() set_error_handler('_drupal_error_handler'); set_exception_handler('_drupal_exception_handler'); } }