diff --git a/src/Composer/Installers/DrupalInstaller.php b/src/Composer/Installers/DrupalInstaller.php index 193e6008..76014e44 100644 --- a/src/Composer/Installers/DrupalInstaller.php +++ b/src/Composer/Installers/DrupalInstaller.php @@ -1,12 +1,134 @@ 'modules/{$name}/', - 'theme' => 'themes/{$name}/', - 'profile' => 'profiles/{$name}/', - 'drush' => 'drush/{$name}/', + 'module' => '{$root}/modules/{$name}/', + 'theme' => '{$root}/themes/{$name}/', + 'profile' => '{$root}/profiles/{$name}/', + 'drush' => '{$root}/drush/{$name}/', ); + + /** + * {@inheritDoc} + */ + public function inflectPackageVars($vars) + { + // Find Drupal's root directory. + $root = $this->locateDrupalRoot(); + if ($root) { + // If we are installing on Drupal 5, 6 or 7, use "sites/all". + if (version_compare($this->drupalMajorVersion($root), '8', '<')) { + $root .= '/sites/all'; + } + } + else { + // If it's not a valid directory, then use the current directory. + $root = '.'; + } + + // Inject Drupal's root directory into the variables array. + $vars['root'] = $root; + + return $vars; + } + + /** + * Checks whether given path qualifies as a Drupal root. + * + * @param $path + * The relative path to common.inc (varies by Drupal version), or FALSE if + * not a Drupal root. + */ + protected function validDrupalRoot($path) { + if (!empty($path) && is_dir($path)) { + $candidates = array('includes/common.inc', 'core/includes/common.inc'); + foreach ($candidates as $candidate) { + if (file_exists($path . '/' . $candidate)) { + return $candidate; + } + } + } + + return false; + } + + /** + * Exhaustive depth-first search to try and locate the Drupal root directory. + */ + protected function locateDrupalRoot($path = '') + { + $path = empty($path) ? getcwd() : $path; + do { + if ($this->validDrupalRoot($path)) { + return $path; + } + } + while ($path = dirname($path) && $path != DIRECTORY_SEPARATOR); + + return false; + } + + /** + * Return the user's home directory. + */ + protected function serverHome() { + $home = getenv('HOME'); + + if (empty($home)) { + if (!empty($_SERVER['HOMEDRIVE']) && !empty($_SERVER['HOMEPATH'])) { + // On a Windows server. + $home = $_SERVER['HOMEDRIVE'] . $_SERVER['HOMEPATH']; + } + } + + return empty($home) ? NULL : $home; + } + + /** + * Retrieves Drupal version. + * + * @return string A version string similar to 7.22-dev. + */ + protected function drupalVersion($drupal_root = null) { + if (($drupal_root != null) || ($drupal_root = $this->locateDrupalRoot())) { + // Drupal 7 stores VERSION in includes/bootstrap.inc, while Drupal 8 + // uses core/includes/bootstrap.inc. + $version_constant_paths = array('/modules/system/system.module', '/includes/bootstrap.inc', '/core/includes/bootstrap.inc'); + foreach ($version_constant_paths as $path) { + if (file_exists($drupal_root . $path)) { + require_once $drupal_root . $path; + } + } + + if (defined('VERSION')) { + return VERSION; + } + } + } + + /** + * Retrieves Drupal's major version number. + */ + protected function drupalMajorVersion($drupal_root = null) + { + $major_version = false; + if ($version = $this->drupalVersion($drupal_root)) { + $version_parts = explode('.', $version); + if (is_numeric($version_parts[0])) { + $major_version = (integer) $version_parts[0]; + } + } + + return $major_version; + } } diff --git a/tests/Composer/Installers/Test/InstallerTest.php b/tests/Composer/Installers/Test/InstallerTest.php index eb83f86e..a5db111c 100644 --- a/tests/Composer/Installers/Test/InstallerTest.php +++ b/tests/Composer/Installers/Test/InstallerTest.php @@ -137,10 +137,10 @@ public function dataForTestInstallPath() array('cakephp-plugin', 'Plugin/Ftp/', 'shama/ftp'), array('codeigniter-library', 'libraries/my_package/', 'shama/my_package'), array('codeigniter-module', 'modules/my_package/', 'shama/my_package'), - array('drupal-module', 'modules/my_module/', 'shama/my_module'), - array('drupal-theme', 'themes/my_module/', 'shama/my_module'), - array('drupal-profile', 'profiles/my_module/', 'shama/my_module'), - array('drupal-drush', 'drush/my_module/', 'shama/my_module'), + array('drupal-module', './modules/my_module/', 'shama/my_module'), + array('drupal-theme', './themes/my_module/', 'shama/my_module'), + array('drupal-profile', './profiles/my_module/', 'shama/my_module'), + array('drupal-drush', './drush/my_module/', 'shama/my_module'), array('fuel-module', 'fuel/app/modules/module/', 'fuel/module'), array('fuel-package', 'fuel/packages/orm/', 'fuel/orm'), array('joomla-plugin', 'plugins/my_plugin/', 'shama/my_plugin'),