Version 1
[yaffs-website] / vendor / webflo / drupal-finder / src / DrupalFinder.php
1 <?php
2
3 /**
4  * @file
5  * Contains \DrupalFinder\DrupalFinder.
6  */
7
8 namespace DrupalFinder;
9
10 class DrupalFinder
11 {
12     /**
13      * Drupal web public directory.
14      *
15      * @var string
16      */
17     private $drupalRoot;
18
19     /**
20      * Drupal package composer directory.
21      *
22      * @var bool
23      */
24     private $composerRoot;
25
26     public function locateRoot($start_path)
27     {
28         $this->drupalRoot = false;
29         $this->composerRoot = false;
30
31         foreach (array(true, false) as $follow_symlinks) {
32             $path = $start_path;
33             if ($follow_symlinks && is_link($path)) {
34                 $path = realpath($path);
35             }
36             // Check the start path.
37             if ($this->isValidRoot($path)) {
38                 return true;
39             } else {
40                 // Move up dir by dir and check each.
41                 while ($path = $this->shiftPathUp($path)) {
42                     if ($follow_symlinks && is_link($path)) {
43                         $path = realpath($path);
44                     }
45                     if ($this->isValidRoot($path)) {
46                         return true;
47                     }
48                 }
49             }
50         }
51
52         return false;
53     }
54
55     /**
56      * Returns parent directory.
57      *
58      * @param string
59      *   Path to start from
60      *
61      * @return string|false
62      *   Parent path of given path or false when $path is filesystem root
63      */
64     private function shiftPathUp($path)
65     {
66         $parent = dirname($path);
67
68         return in_array($parent, ['.', $path]) ? false : $parent;
69     }
70
71     /**
72      * @param $path
73      *
74      * @return bool
75      */
76     protected function isValidRoot($path)
77     {
78         if (!empty($path) && is_dir($path) && file_exists($path . '/autoload.php') && file_exists($path . '/composer.json')) {
79             // Additional check for the presence of core/composer.json to
80             // grant it is not a Drupal 7 site with a base folder named "core".
81             $candidate = 'core/includes/common.inc';
82             if (file_exists($path . '/' . $candidate) && file_exists($path . '/core/core.services.yml')) {
83                 if (file_exists($path . '/core/misc/drupal.js') || file_exists($path . '/core/assets/js/drupal.js')) {
84                     $this->composerRoot = $path;
85                     $this->drupalRoot = $path;
86                 }
87             }
88         }
89         if (!empty($path) && is_dir($path) && file_exists($path . '/composer.json')) {
90             $json = json_decode(
91                 file_get_contents($path . '/composer.json'),
92                 true
93             );
94             if (is_array($json)) {
95                 if (isset($json['extra']['installer-paths']) && is_array($json['extra']['installer-paths'])) {
96                     foreach ($json['extra']['installer-paths'] as $install_path => $items) {
97                         if (in_array('type:drupal-core', $items) || in_array('drupal/core', $items)) {
98                             $this->composerRoot = $path;
99                             $this->drupalRoot = $path . '/' . substr(
100                                 $install_path,
101                                 0,
102                                 -5
103                             );
104                         }
105                     }
106                 }
107             }
108         }
109
110         return $this->drupalRoot && $this->composerRoot;
111     }
112
113     /**
114      * @return string
115      */
116     public function getDrupalRoot()
117     {
118         return $this->drupalRoot;
119     }
120
121     /**
122      * @return string
123      */
124     public function getComposerRoot()
125     {
126         return $this->composerRoot;
127     }
128 }