From 4ac7577d9710095019c911d80c4ad48163b4e403 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 14 Jun 2017 23:42:59 -0700 Subject: [PATCH] CRM-19303 - Drupal - Fix various path computations for multisite A few changes: * Move logic out of `CRM_Utils_System_Base` to `CRM_Utils_System_DrupalBase` so that it's easier to read. * Update `[civicrm.files]`: First, try to use `sites/{$name}/files/civicrm`. Otherwise, use `sites/default/files/civicrm`. * Note: The `$name` is parsed/validated the same way as `civicrm.config.php`. It takes the full HTTP_HOST and then tries various substrings. * Update `[civicrm.root]`: Compare `$civicrm_root` and `cmsRootPath()` to determine the relative path. Then, combine `CIVICRM_UF_BASEURL` with relpath. (This is the same as WordPress.) --- CRM/Utils/System/Base.php | 26 -------- CRM/Utils/System/DrupalBase.php | 106 +++++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 48 deletions(-) diff --git a/CRM/Utils/System/Base.php b/CRM/Utils/System/Base.php index a66fba129e..e71f7edfa5 100644 --- a/CRM/Utils/System/Base.php +++ b/CRM/Utils/System/Base.php @@ -593,15 +593,6 @@ abstract class CRM_Utils_System_Base { $tempURL = str_replace("/administrator/", "/", $baseURL); $filesURL = $tempURL . "media/civicrm/"; } - elseif ($this->is_drupal) { - $siteName = $config->userSystem->parseDrupalSiteName($civicrm_root); - if ($siteName) { - $filesURL = $baseURL . "sites/$siteName/files/civicrm/"; - } - else { - $filesURL = $baseURL . "sites/default/files/civicrm/"; - } - } elseif ($config->userFramework == 'UnitTests') { $filesURL = $baseURL . "sites/default/files/civicrm/"; } @@ -648,23 +639,6 @@ abstract class CRM_Utils_System_Base { elseif ($config->userFramework == 'WordPress') { $userFrameworkResourceURL = CIVICRM_PLUGIN_URL . "civicrm/"; } - elseif ($this->is_drupal) { - // Drupal setting - // check and see if we are installed in sites/all (for D5 and above) - // we dont use checkURL since drupal generates an error page and throws - // the system for a loop on lobo's macosx box - // or in modules - $cmsPath = $config->userSystem->cmsRootPath(); - $userFrameworkResourceURL = $baseURL . str_replace("$cmsPath/", '', - str_replace('\\', '/', $civicrm_root) - ); - - $siteName = $config->userSystem->parseDrupalSiteName($civicrm_root); - if ($siteName) { - $civicrmDirName = trim(basename($civicrm_root)); - $userFrameworkResourceURL = $baseURL . "sites/$siteName/modules/$civicrmDirName/"; - } - } else { $userFrameworkResourceURL = NULL; } diff --git a/CRM/Utils/System/DrupalBase.php b/CRM/Utils/System/DrupalBase.php index c0ce0f49c1..bd5740c699 100644 --- a/CRM/Utils/System/DrupalBase.php +++ b/CRM/Utils/System/DrupalBase.php @@ -58,6 +58,51 @@ abstract class CRM_Utils_System_DrupalBase extends CRM_Utils_System_Base { $this->supports_form_extensions = TRUE; } + /** + * @inheritDoc + */ + public function getCiviSourceStorage() { + global $civicrm_root; + + // Don't use $config->userFrameworkBaseURL; it has garbage on it. + // More generally, we shouldn't be using $config here. + if (!defined('CIVICRM_UF_BASEURL')) { + throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL'); + } + + $cmsUrl = CIVICRM_UF_BASEURL; + if (CRM_Utils_System::isSSL()) { + $cmsUrl = str_replace('http://', 'https://', $cmsUrl); + } + $civiRelPath = CRM_Utils_File::relativize(realpath($civicrm_root), realpath($this->cmsRootPath())); + $civiUrl = rtrim($cmsUrl, '/') . '/' . ltrim($civiRelPath, ' /'); + return array( + 'url' => CRM_Utils_File::addTrailingSlash($civiUrl, '/'), + 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root), + ); + } + + /** + * @inheritdoc + */ + public function getDefaultFileStorage() { + $config = CRM_Core_Config::singleton(); + $baseURL = CRM_Utils_System::languageNegotiationURL($config->userFrameworkBaseURL, FALSE, TRUE); + + $siteName = $this->parseDrupalSiteName('/files/civicrm'); + if ($siteName) { + $filesURL = $baseURL . "sites/$siteName/files/civicrm/"; + } + else { + $filesURL = $baseURL . "sites/default/files/civicrm/"; + } + + return array( + 'url' => $filesURL, + 'path' => CRM_Utils_File::baseFilePath(), + ); + } + /** * @inheritDoc */ @@ -546,33 +591,50 @@ abstract class CRM_Utils_System_DrupalBase extends CRM_Utils_System_Base { } /** - * Parse the name of the drupal site. - * - * @param string $civicrm_root + * Determine if Drupal multi-site applies to the current request -- and, + * specifically, determine the name of the multisite folder. * + * @param string $flagFile + * Check if $flagFile exists inside the site dir. * @return null|string + * string, e.g. `bar.example.com` if using multisite. + * NULL if using the default site. */ - public function parseDrupalSiteName($civicrm_root) { - $siteName = NULL; - if (strpos($civicrm_root, - DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . 'all' . DIRECTORY_SEPARATOR . 'modules' - ) === FALSE - ) { - $startPos = strpos($civicrm_root, - DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR - ); - $endPos = strpos($civicrm_root, - DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR - ); - if ($startPos && $endPos) { - // if component is in sites/SITENAME/modules - $siteName = substr($civicrm_root, - $startPos + 7, - $endPos - $startPos - 7 - ); + private function parseDrupalSiteName($flagFile = '') { + $phpSelf = array_key_exists('PHP_SELF', $_SERVER) ? $_SERVER['PHP_SELF'] : ''; + $httpHost = array_key_exists('HTTP_HOST', $_SERVER) ? $_SERVER['HTTP_HOST'] : ''; + if (empty($httpHost)) { + $httpHost = parse_url(CIVICRM_UF_BASEURL, PHP_URL_HOST); + if (parse_url(CIVICRM_UF_BASEURL, PHP_URL_PORT)) { + $httpHost .= ':' . parse_url(CIVICRM_UF_BASEURL, PHP_URL_PORT); + } + } + + $confdir = $this->cmsRootPath() . '/sites'; + + if (file_exists($confdir . "/sites.php")) { + include $confdir . "/sites.php"; + } + else { + $sites = array(); + } + + $uri = explode('/', $phpSelf); + $server = explode('.', implode('.', array_reverse(explode(':', rtrim($httpHost, '.'))))); + for ($i = count($uri) - 1; $i > 0; $i--) { + for ($j = count($server); $j > 0; $j--) { + $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i)); + if (file_exists("$confdir/$dir" . $flagFile)) { + \Civi::$statics[__CLASS__]['drupalSiteName'] = $dir; + return \Civi::$statics[__CLASS__]['drupalSiteName']; + } + // check for alias + if (isset($sites[$dir]) && file_exists("$confdir/{$sites[$dir]}" . $flagFile)) { + \Civi::$statics[__CLASS__]['drupalSiteName'] = $sites[$dir]; + return \Civi::$statics[__CLASS__]['drupalSiteName']; + } } } - return $siteName; } } -- 2.25.1