5 * Contains Drupal\Console\Utils\Site.
8 namespace Drupal\Console\Utils;
10 use Drupal\Core\Cache\Cache;
11 use Symfony\Component\DomCrawler\Crawler;
12 use GuzzleHttp\Client;
17 * @package Drupal\Console\Utils
22 protected $entityTypeManager;
25 private $bundles = [];
26 private $vocabularies = [];
30 * DebugCommand constructor.
32 * @param Client $httpClient
35 protected $httpClient;
38 * ServerCommand constructor.
41 * @param $entityTypeManager
43 public function __construct($appRoot, $entityTypeManager, Client $httpClient)
45 $this->appRoot = $appRoot;
46 $this->entityTypeManager = $entityTypeManager;
47 $this->httpClient = $httpClient;
53 public function getDrupalVersion()
55 return \Drupal::VERSION;
59 * Auxiliary function to get all available drupal caches.
61 * @return \Drupal\Core\Cache\CacheBackendInterface[] The all available drupal caches
63 public function getCaches()
66 foreach (Cache::getBins() as $name => $bin) {
67 $this->caches[$name] = $bin;
75 * Validate if a string is a valid cache.
77 * @param string $cache The cache name
79 * @return mixed The cache name if valid or FALSE if not valid
81 public function isValidCache($cache)
83 // Get the valid caches
84 $caches = $this->getCaches();
85 $cacheKeys = array_keys($caches);
88 if (!in_array($cache, array_values($cacheKeys))) {
98 public function getBundles()
100 if (!$this->bundles) {
101 $nodeTypes = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
103 foreach ($nodeTypes as $nodeType) {
104 $this->bundles[$nodeType->id()] = $nodeType->label();
108 return $this->bundles;
114 public function getVocabularies()
116 if (!$this->vocabularies) {
117 $vocabularies = $this->entityTypeManager->getStorage('taxonomy_vocabulary')->loadMultiple();
119 foreach ($vocabularies as $vocabulary) {
120 $this->vocabularies[$vocabulary->id()] = $vocabulary->label();
124 return $this->vocabularies;
128 * @param bool|FALSE $reset
129 * @param bool|FALSE $authenticated
130 * @param bool|FALSE $anonymous
134 public function getRoles($reset=false, $authenticated=false, $anonymous=false)
136 if ($reset || !$this->roles) {
137 $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple();
138 if (!$authenticated) {
139 unset($roles['authenticated']);
142 unset($roles['anonymous']);
144 foreach ($roles as $role) {
145 $this->roles[$role->id()] = $role->label();
159 public function getProjectReleases($module, $limit = 10, $stable = false)
165 $projectPageResponse = $this->httpClient->getUrlAsString(
167 'https://updates.drupal.org/release-history/%s/8.x',
172 if ($projectPageResponse->getStatusCode() != 200) {
173 throw new \Exception('Invalid path.');
177 $crawler = new Crawler($projectPageResponse->getBody()->getContents());
178 $filter = './project/releases/release/version';
180 $filter = './project/releases/release[not(version_extra)]/version';
183 foreach ($crawler->filterXPath($filter) as $element) {
184 $releases[] = $element->nodeValue;
187 if (count($releases)>$limit) {
188 array_splice($releases, $limit);
197 * @param null $destination
198 * @return null|string
200 public function downloadProjectRelease($project, $release, $destination = null)
203 $releases = $this->getProjectReleases($project, 1);
204 $release = current($releases);
208 $destination = sprintf(
215 $releaseFilePath = sprintf(
216 'https://ftp.drupal.org/files/projects/%s-%s.tar.gz',
221 if ($this->downloadFile($releaseFilePath, $destination)) {
228 public function downloadFile($url, $destination)
230 $this->httpClient->get($url, ['sink' => $destination]);
232 return file_exists($destination);
236 * Gets Drupal modules releases from Packagist API.
238 * @param string $module
240 * @param bool $unstable
244 public function getPackagistModuleReleases($module, $limit = 10, $unstable = true)
246 if (!trim($module)) {
250 return $this->getComposerReleases(
252 'http://packagist.drupal-composer.org/packages/drupal/%s.json',
261 * Gets Drupal releases from Packagist API.
265 * @param bool $unstable
269 private function getComposerReleases($url, $limit = 10, $unstable = false)
275 $packagistResponse = $this->httpClient->getUrlAsString($url);
277 if ($packagistResponse->getStatusCode() != 200) {
278 throw new \Exception('Invalid path.');
282 $packagistJson = json_decode(
283 $packagistResponse->getBody()->getContents()
285 } catch (\Exception $e) {
289 $versions = array_keys((array)$packagistJson->package->versions);
291 // Remove Drupal 7 versions
293 foreach ($versions as $version) {
294 if (0 === strpos($version, "7.") || 0 === strpos($version, "dev-7.")) {
295 unset($versions[$i]);
301 foreach ($versions as $key => $version) {
302 if (strpos($version, "-")) {
303 unset($versions[$key]);
308 if (is_array($versions)) {
309 return array_slice($versions, 0, $limit);
316 * @Todo: Remove when issue https://www.drupal.org/node/2556025 get resolved
318 * Rebuilds all caches even when Drupal itself does not work.
320 * @param \Composer\Autoload\ClassLoader $class_loader
322 * @param \Symfony\Component\HttpFoundation\Request $request
323 * The current request.
327 public function drupal_rebuild($class_loader, \Symfony\Component\HttpFoundation\Request $request)
329 // Remove Drupal's error and exception handlers; they rely on a working
330 // service container and other subsystems and will only cause a fatal error
331 // that hides the actual error.
332 restore_error_handler();
333 restore_exception_handler();
335 // Force kernel to rebuild php cache.
336 \Drupal\Core\PhpStorage\PhpStorageFactory::get('twig')->deleteAll();
338 // Bootstrap up to where caches exist and clear them.
339 $kernel = new \Drupal\Core\DrupalKernel('prod', $class_loader);
340 $kernel->setSitePath(\Drupal\Core\DrupalKernel::findSitePath($request));
342 // Invalidate the container.
343 $kernel->invalidateContainer();
345 // Prepare a NULL request.
346 $kernel->prepareLegacyRequest($request);
348 foreach (Cache::getBins() as $bin) {
352 // Disable recording of cached pages.
353 \Drupal::service('page_cache_kill_switch')->trigger();
355 drupal_flush_all_caches();
357 // Restore Drupal's error and exception handlers.
358 // @see \Drupal\Core\DrupalKernel::boot()
359 set_error_handler('_drupal_error_handler');
360 set_exception_handler('_drupal_exception_handler');