5 * Contains \DrupalFinder\DrupalFinder.
8 namespace DrupalFinder;
13 * Drupal web public directory.
20 * Drupal package composer directory.
24 private $composerRoot;
26 public function locateRoot($start_path)
28 $this->drupalRoot = false;
29 $this->composerRoot = false;
31 foreach (array(true, false) as $follow_symlinks) {
33 if ($follow_symlinks && is_link($path)) {
34 $path = realpath($path);
36 // Check the start path.
37 if ($this->isValidRoot($path)) {
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);
45 if ($this->isValidRoot($path)) {
56 * Returns parent directory.
61 * @return string|false
62 * Parent path of given path or false when $path is filesystem root
64 private function shiftPathUp($path)
66 $parent = dirname($path);
68 return in_array($parent, ['.', $path]) ? false : $parent;
76 protected function isValidRoot($path)
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;
89 if (!empty($path) && is_dir($path) && file_exists($path . '/composer.json')) {
91 file_get_contents($path . '/composer.json'),
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(
110 return $this->drupalRoot && $this->composerRoot;
116 public function getDrupalRoot()
118 return $this->drupalRoot;
124 public function getComposerRoot()
126 return $this->composerRoot;