Yaffs site version 1.1
[yaffs-website] / vendor / drupal / console / src / Utils / DrupalApi.php
1 <?php
2
3 /**
4  * @file
5  * Contains Drupal\Console\Utils\Site.
6  */
7
8 namespace Drupal\Console\Utils;
9
10 use Drupal\Core\Cache\Cache;
11 use Symfony\Component\DomCrawler\Crawler;
12 use GuzzleHttp\Client;
13
14 /**
15  * Class DrupalHelper
16  *
17  * @package Drupal\Console\Utils
18  */
19 class DrupalApi
20 {
21     protected $appRoot;
22     protected $entityTypeManager;
23
24     private $caches = [];
25     private $bundles = [];
26     private $vocabularies = [];
27     private $roles = [];
28
29     /**
30      * DebugCommand constructor.
31      *
32      * @param Client  $httpClient
33      */
34
35     protected $httpClient;
36
37     /**
38      * ServerCommand constructor.
39      *
40      * @param $appRoot
41      * @param $entityTypeManager
42      */
43     public function __construct($appRoot, $entityTypeManager, Client $httpClient)
44     {
45         $this->appRoot = $appRoot;
46         $this->entityTypeManager = $entityTypeManager;
47         $this->httpClient = $httpClient;
48     }
49
50     /**
51      * @return string
52      */
53     public function getDrupalVersion()
54     {
55         return \Drupal::VERSION;
56     }
57
58     /**
59      * Auxiliary function to get all available drupal caches.
60      *
61      * @return \Drupal\Core\Cache\CacheBackendInterface[] The all available drupal caches
62      */
63     public function getCaches()
64     {
65         if (!$this->caches) {
66             foreach (Cache::getBins() as $name => $bin) {
67                 $this->caches[$name] = $bin;
68             }
69         }
70
71         return $this->caches;
72     }
73
74     /**
75      * Validate if a string is a valid cache.
76      *
77      * @param string $cache The cache name
78      *
79      * @return mixed The cache name if valid or FALSE if not valid
80      */
81     public function isValidCache($cache)
82     {
83         // Get the valid caches
84         $caches = $this->getCaches();
85         $cacheKeys = array_keys($caches);
86         $cacheKeys[] = 'all';
87
88         if (!in_array($cache, array_values($cacheKeys))) {
89             return false;
90         }
91
92         return $cache;
93     }
94
95     /**
96      * @return array
97      */
98     public function getBundles()
99     {
100         if (!$this->bundles) {
101             $nodeTypes = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
102
103             foreach ($nodeTypes as $nodeType) {
104                 $this->bundles[$nodeType->id()] = $nodeType->label();
105             }
106         }
107
108         return $this->bundles;
109     }
110
111     /**
112      * @return array
113      */
114     public function getVocabularies()
115     {
116         if (!$this->vocabularies) {
117             $vocabularies = $this->entityTypeManager->getStorage('taxonomy_vocabulary')->loadMultiple();
118
119             foreach ($vocabularies as $vocabulary) {
120                 $this->vocabularies[$vocabulary->id()] = $vocabulary->label();
121             }
122         }
123
124         return $this->vocabularies;
125     }
126
127     /**
128      * @param bool|FALSE $reset
129      * @param bool|FALSE $authenticated
130      * @param bool|FALSE $anonymous
131      *
132      * @return array
133      */
134     public function getRoles($reset=false, $authenticated=true, $anonymous=false)
135     {
136         if ($reset || !$this->roles) {
137             $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple();
138             if (!$authenticated) {
139                 unset($roles['authenticated']);
140             }
141             if (!$anonymous) {
142                 unset($roles['anonymous']);
143             }
144             foreach ($roles as $role) {
145                 $this->roles[$role->id()] = $role->label();
146             }
147         }
148
149         return $this->roles;
150     }
151
152     /**
153      * @param $module
154      * @param $limit
155      * @param $stable
156      * @return array
157      * @throws \Exception
158      */
159     public function getProjectReleases($module, $limit = 10, $stable = false)
160     {
161         if (!$module) {
162             return [];
163         }
164
165         $projectPageResponse = $this->httpClient->getUrlAsString(
166             sprintf(
167                 'https://updates.drupal.org/release-history/%s/8.x',
168                 $module
169             )
170         );
171
172         if ($projectPageResponse->getStatusCode() != 200) {
173             throw new \Exception('Invalid path.');
174         }
175
176         $releases = [];
177         $crawler = new Crawler($projectPageResponse->getBody()->getContents());
178         $filter = './project/releases/release/version';
179         if ($stable) {
180             $filter = './project/releases/release[not(version_extra)]/version';
181         }
182
183         foreach ($crawler->filterXPath($filter) as $element) {
184             $releases[] = $element->nodeValue;
185         }
186
187         if (count($releases)>$limit) {
188             array_splice($releases, $limit);
189         }
190
191         return $releases;
192     }
193
194     /**
195      * @param $project
196      * @param $release
197      * @param null    $destination
198      * @return null|string
199      */
200     public function downloadProjectRelease($project, $release, $destination = null)
201     {
202         if (!$release) {
203             $releases = $this->getProjectReleases($project, 1);
204             $release = current($releases);
205         }
206
207         if (!$destination) {
208             $destination = sprintf(
209                 '%s/%s.tar.gz',
210                 sys_get_temp_dir(),
211                 $project
212             );
213         }
214
215         $releaseFilePath = sprintf(
216             'https://ftp.drupal.org/files/projects/%s-%s.tar.gz',
217             $project,
218             $release
219         );
220
221         if ($this->downloadFile($releaseFilePath, $destination)) {
222             return $destination;
223         }
224
225         return null;
226     }
227
228     public function downloadFile($url, $destination)
229     {
230         $this->httpClient->get($url, ['sink' => $destination]);
231
232         return file_exists($destination);
233     }
234
235     /**
236      * Gets Drupal modules releases from Packagist API.
237      *
238      * @param string $module
239      * @param int    $limit
240      * @param bool   $unstable
241      *
242      * @return array
243      */
244     public function getPackagistModuleReleases($module, $limit = 10, $unstable = true)
245     {
246         if (!trim($module)) {
247             return [];
248         }
249
250         return $this->getComposerReleases(
251             sprintf(
252                 'http://packagist.drupal-composer.org/packages/drupal/%s.json',
253                 trim($module)
254             ),
255             $limit,
256             $unstable
257         );
258     }
259
260     /**
261      * Gets Drupal releases from Packagist API.
262      *
263      * @param string $url
264      * @param int    $limit
265      * @param bool   $unstable
266      *
267      * @return array
268      */
269     private function getComposerReleases($url, $limit = 10, $unstable = false)
270     {
271         if (!$url) {
272             return [];
273         }
274
275         $packagistResponse = $this->httpClient->getUrlAsString($url);
276
277         if ($packagistResponse->getStatusCode() != 200) {
278             throw new \Exception('Invalid path.');
279         }
280
281         try {
282             $packagistJson = json_decode(
283                 $packagistResponse->getBody()->getContents()
284             );
285         } catch (\Exception $e) {
286             return [];
287         }
288
289         $versions = array_keys((array)$packagistJson->package->versions);
290
291         // Remove Drupal 7 versions
292         $i = 0;
293         foreach ($versions as $version) {
294             if (0 === strpos($version, "7.") || 0 === strpos($version, "dev-7.")) {
295                 unset($versions[$i]);
296             }
297             $i++;
298         }
299
300         if (!$unstable) {
301             foreach ($versions as $key => $version) {
302                 if (strpos($version, "-")) {
303                     unset($versions[$key]);
304                 }
305             }
306         }
307
308         if (is_array($versions)) {
309             return array_slice($versions, 0, $limit);
310         }
311
312         return [];
313     }
314
315     /**
316      * @Todo: Remove when issue https://www.drupal.org/node/2556025 get resolved
317      *
318      * Rebuilds all caches even when Drupal itself does not work.
319      *
320      * @param \Composer\Autoload\ClassLoader            $class_loader
321      *   The class loader.
322      * @param \Symfony\Component\HttpFoundation\Request $request
323      *   The current request.
324      *
325      * @see rebuild.php
326      */
327     public function drupal_rebuild($class_loader, \Symfony\Component\HttpFoundation\Request $request)
328     {
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();
334
335         // Force kernel to rebuild php cache.
336         \Drupal\Core\PhpStorage\PhpStorageFactory::get('twig')->deleteAll();
337
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));
341
342         // Invalidate the container.
343         $kernel->invalidateContainer();
344
345         // Prepare a NULL request.
346         $kernel->prepareLegacyRequest($request);
347
348         foreach (Cache::getBins() as $bin) {
349             $bin->deleteAll();
350         }
351
352         // Disable recording of cached pages.
353         \Drupal::service('page_cache_kill_switch')->trigger();
354
355         drupal_flush_all_caches();
356
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');
361     }
362 }