diff --git a/core/includes/common.inc b/core/includes/common.inc index 92db595..714723d 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -1506,6 +1506,10 @@ function drupal_set_time_limit($time_limit) { /** * Returns the path to a system item (module, theme, etc.). * + * This function should only be used when including a file containing PHP code; + * the 'module://', 'profile://' and 'theme://' stream wrappers should be used + * for other use cases. + * * @param $type * The type of the item (i.e. theme, theme_engine, module, profile). * @param $name diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php index 232e47e..04460ce 100644 --- a/core/lib/Drupal/Core/Routing/RouteBuilder.php +++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php @@ -87,7 +87,7 @@ public function rebuild() { // a given item came from. foreach ($this->moduleHandler->getModuleList() as $module => $filename) { $collection = new RouteCollection(); - $routing_file = DRUPAL_ROOT . '/' . dirname($filename) . '/' . $module . '.routing.yml'; + $routing_file = "module://{$module}/{$module}.routing.yml";; if (file_exists($routing_file)) { $routes = $parser->parse(file_get_contents($routing_file)); if (!empty($routes)) { diff --git a/core/lib/Drupal/Core/StreamWrapper/ModuleStream.php b/core/lib/Drupal/Core/StreamWrapper/ModuleStream.php new file mode 100644 index 0000000..7dc5de5 --- /dev/null +++ b/core/lib/Drupal/Core/StreamWrapper/ModuleStream.php @@ -0,0 +1,25 @@ +getSystemName()); + } +} diff --git a/core/lib/Drupal/Core/StreamWrapper/ProfileStream.php b/core/lib/Drupal/Core/StreamWrapper/ProfileStream.php new file mode 100644 index 0000000..30e07f7 --- /dev/null +++ b/core/lib/Drupal/Core/StreamWrapper/ProfileStream.php @@ -0,0 +1,41 @@ +getSystemName()); + } +} diff --git a/core/lib/Drupal/Core/StreamWrapper/SystemStream.php b/core/lib/Drupal/Core/StreamWrapper/SystemStream.php new file mode 100644 index 0000000..9aed213 --- /dev/null +++ b/core/lib/Drupal/Core/StreamWrapper/SystemStream.php @@ -0,0 +1,77 @@ +uri; + } + + $uri_parts = explode('://', $uri, 2); + if ($uri_parts == $uri) { + // The delimiter ('://') was not found in $uri, malformed $uri passed. + throw new \InvalidArgumentException('Malformed $uri parameter passed: %s', $uri); + } + else { + list($scheme, $target) = $uri_parts; + } + + $pos = strpos($target, '/'); + return $pos === FALSE ? $target : substr($target, 0, $pos); + } + + protected function getTarget($uri = NULL) { + if (!isset($uri)) { + $uri = $this->uri; + } + + $uri_parts = explode('://', $uri, 2); + if ($uri_parts == $uri) { + // The delimiter ('://') was not found in $uri, malformed $uri passed. + throw new \InvalidArgumentException('Malformed $uri parameter passed: %s', $uri); + } + else { + list($scheme, $target) = $uri_parts; + } + + // Remove erroneous leading or trailing, forward-slashes and backslashes. + $target = trim($target, '\/'); + + // Remove the module/theme/profile name form the file path. + $target = substr($target, strlen($this->getSystemName())); + + // Trim again. + $target = trim($target, '\/'); + return $target; + } + + /** + * Overrides getExternalUrl(). + * + * Return the HTML URI of a system file. + */ + public function getExternalUrl() { + $dir = $this->getDirectoryPath(); + if (empty($dir)) { + return FALSE; + } + + $path = str_replace('\\', '/', $this->getTarget()); + return $GLOBALS['base_url'] . '/' . $dir . '/' . drupal_encode_path($path); + } +} diff --git a/core/lib/Drupal/Core/StreamWrapper/ThemeStream.php b/core/lib/Drupal/Core/StreamWrapper/ThemeStream.php new file mode 100644 index 0000000..a20922b --- /dev/null +++ b/core/lib/Drupal/Core/StreamWrapper/ThemeStream.php @@ -0,0 +1,43 @@ +getSystemName()); + } + + /** + * Override SystemSteam::getSystemName() to support theme://current and + * theme://admin. + */ + protected function getSystemName($uri = NULL) { + global $theme_key; + $name = parent::getSystemName($uri); + if ($name == 'current') { + return $theme_key; + } + else if ($name == 'admin') { + return variable_get('admin_theme', 'seven'); + } + else { + return $name; + } + } +} diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 87fe50d..9aad827 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2146,6 +2146,24 @@ function system_stream_wrappers() { 'description' => t('Temporary local files for upload and previews.'), 'type' => STREAM_WRAPPERS_LOCAL_HIDDEN, ), + 'module' => array( + 'name' => t('Module files'), + 'class' => 'Drupal\Core\StreamWrapper\ModuleStream', + 'description' => t('Local module files.'), + 'type' => STREAM_WRAPPERS_READ, + ), + 'theme' => array( + 'name' => t('Theme files'), + 'class' => 'Drupal\Core\StreamWrapper\ThemeStream', + 'description' => t('Local theme files.'), + 'type' => STREAM_WRAPPERS_READ, + ), + 'profile' => array( + 'name' => t('Profile files'), + 'class' => 'Drupal\Core\StreamWrapper\ProfileStream', + 'description' => t('Local profile files.'), + 'type' => STREAM_WRAPPERS_READ, + ), ); // Only register the private file stream wrapper if a file path has been set. diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php index b0cbb7b..7f140db 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php @@ -1943,7 +1943,7 @@ public function buildOptionsForm(&$form, &$form_state) { // Field templates aren't registered the normal way...and they're always // this one, anyhow. - $output .= '
' . check_plain(file_get_contents(drupal_get_path('module', 'views') . '/templates/views-view-field.tpl.php')) . '
'; + $output .= '
' . check_plain(file_get_contents("module://views/templates/views-view-field.tpl.php")) . '
'; $form['analysis'] = array( '#markup' => '
' . $output . '
',