diff --git a/core/includes/theme.inc b/core/includes/theme.inc index b71e437dcbab51af7031f1de04a5793a3877f225..04b41ce4bf4d5311c671f61022c768ee22a8b2f3 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -343,10 +343,10 @@ function theme_get_setting($setting_name, $theme = NULL) { // Generate the path to the logo image. if ($cache[$theme]->get('logo.use_default')) { - $cache[$theme]->set('logo.url', file_create_url($theme_object->getPath() . '/logo.svg')); + $cache[$theme]->set('logo.url', file_url_transform_relative(file_create_url($theme_object->getPath() . '/logo.svg'))); } elseif ($logo_path = $cache[$theme]->get('logo.path')) { - $cache[$theme]->set('logo.url', file_create_url($logo_path)); + $cache[$theme]->set('logo.url', file_url_transform_relative(file_create_url($logo_path))); } // Generate the path to the favicon. @@ -354,14 +354,14 @@ function theme_get_setting($setting_name, $theme = NULL) { $favicon_path = $cache[$theme]->get('favicon.path'); if ($cache[$theme]->get('favicon.use_default')) { if (file_exists($favicon = $theme_object->getPath() . '/favicon.ico')) { - $cache[$theme]->set('favicon.url', file_create_url($favicon)); + $cache[$theme]->set('favicon.url', file_url_transform_relative(file_create_url($favicon))); } else { - $cache[$theme]->set('favicon.url', file_create_url('core/misc/favicon.ico')); + $cache[$theme]->set('favicon.url', file_url_transform_relative(file_create_url('core/misc/favicon.ico'))); } } elseif ($favicon_path) { - $cache[$theme]->set('favicon.url', file_create_url($favicon_path)); + $cache[$theme]->set('favicon.url', file_url_transform_relative(file_create_url($favicon_path))); } else { $cache[$theme]->set('features.favicon', FALSE); @@ -756,7 +756,7 @@ function template_preprocess_links(&$variables) { */ function template_preprocess_image(&$variables) { if (!empty($variables['uri'])) { - $variables['attributes']['src'] = file_create_url($variables['uri']); + $variables['attributes']['src'] = file_url_transform_relative(file_create_url($variables['uri'])); } // Generate a srcset attribute conforming to the spec at // http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-srcset @@ -764,7 +764,7 @@ function template_preprocess_image(&$variables) { $srcset = array(); foreach ($variables['srcset'] as $src) { // URI is mandatory. - $source = file_create_url($src['uri']); + $source = file_url_transform_relative(file_create_url($src['uri'])); if (isset($src['width']) && !empty($src['width'])) { $source .= ' ' . $src['width']; } diff --git a/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php b/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php index 49e4675e1b7d83e55a3111d168ac6056990d76b5..0f70dbf593eaba961c36d2d3ceb4000efb6786ae 100644 --- a/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php +++ b/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php @@ -135,7 +135,7 @@ public function render(array $css_assets) { // assets: output a LINK tag for a file CSS asset. if (count($css_assets) <= 31) { $element = $link_element_defaults; - $element['#attributes']['href'] = file_create_url($css_asset['data']) . $query_string_separator . $query_string; + $element['#attributes']['href'] = file_url_transform_relative(file_create_url($css_asset['data'])) . $query_string_separator . $query_string; $element['#attributes']['media'] = $css_asset['media']; $element['#browsers'] = $css_asset['browsers']; $elements[] = $element; @@ -148,7 +148,7 @@ public function render(array $css_assets) { // LINK tag. if (!$css_asset['preprocess']) { $element = $link_element_defaults; - $element['#attributes']['href'] = file_create_url($css_asset['data']) . $query_string_separator . $query_string; + $element['#attributes']['href'] = file_url_transform_relative(file_create_url($css_asset['data'])) . $query_string_separator . $query_string; $element['#attributes']['media'] = $css_asset['media']; $element['#browsers'] = $css_asset['browsers']; $elements[] = $element; @@ -168,7 +168,7 @@ public function render(array $css_assets) { // control browser-caching. IE7 does not support a media type on // the @import statement, so we instead specify the media for // the group on the STYLE tag. - $import[] = '@import url("' . Html::escape(file_create_url($next_css_asset['data']) . '?' . $query_string) . '");'; + $import[] = '@import url("' . Html::escape(file_url_transform_relative(file_create_url($next_css_asset['data'])) . '?' . $query_string) . '");'; // Move the outer for loop skip the next item, since we // processed it here. $i = $j; diff --git a/core/lib/Drupal/Core/Asset/CssOptimizer.php b/core/lib/Drupal/Core/Asset/CssOptimizer.php index dc34a237abdf008b588d1ca3298bc7eec539b1f2..704ee571e4e87fe5c0961d912dc9125c1fc8ab42 100644 --- a/core/lib/Drupal/Core/Asset/CssOptimizer.php +++ b/core/lib/Drupal/Core/Asset/CssOptimizer.php @@ -265,7 +265,7 @@ public function rewriteFileURI($matches) { $last = $path; $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path); } - return 'url(' . file_create_url($path) . ')'; + return 'url(' . file_url_transform_relative(file_create_url($path)) . ')'; } } diff --git a/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php b/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php index 70832e9d9d1027b5240043666fed1bde39e58ad0..b0d22f15cf94ca4f95937934da7bd289b35b084e 100644 --- a/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php +++ b/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php @@ -79,7 +79,7 @@ public function render(array $js_assets) { case 'file': $query_string = $js_asset['version'] == -1 ? $default_query_string : 'v=' . $js_asset['version']; $query_string_separator = (strpos($js_asset['data'], '?') !== FALSE) ? '&' : '?'; - $element['#attributes']['src'] = file_create_url($js_asset['data']); + $element['#attributes']['src'] = file_url_transform_relative(file_create_url($js_asset['data'])); // Only add the cache-busting query string if this isn't an aggregate // file. if (!isset($js_asset['preprocessed'])) { diff --git a/core/lib/Drupal/Core/Render/Element/ImageButton.php b/core/lib/Drupal/Core/Render/Element/ImageButton.php index 4ee39a6340f32bb96a737238b7e5c21e6aa79119..f22ae1decf8cd221dfaeb82aa108e64c8f71096a 100644 --- a/core/lib/Drupal/Core/Render/Element/ImageButton.php +++ b/core/lib/Drupal/Core/Render/Element/ImageButton.php @@ -75,7 +75,7 @@ public static function preRenderButton($element) { $element['#attributes']['type'] = 'image'; Element::setAttributes($element, array('id', 'name', 'value')); - $element['#attributes']['src'] = file_create_url($element['#src']); + $element['#attributes']['src'] = file_url_transform_relative(file_create_url($element['#src'])); if (!empty($element['#title'])) { $element['#attributes']['alt'] = $element['#title']; $element['#attributes']['title'] = $element['#title']; diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 5b71c5290bdc10e1c267ddfe1ce7547a13b2b53c..73b2ca9c6554167d4bc8ba225e78b9b2208ccc29 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -135,7 +135,9 @@ public function getFunctions() { new \Twig_SimpleFunction('url', array($this, 'getUrl'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))), new \Twig_SimpleFunction('path', array($this, 'getPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))), new \Twig_SimpleFunction('link', array($this, 'getLink')), - new \Twig_SimpleFunction('file_url', 'file_create_url'), + new \Twig_SimpleFunction('file_url', function ($uri) { + return file_url_transform_relative(file_create_url($uri)); + }), new \Twig_SimpleFunction('attach_library', [$this, 'attachLibrary']), new \Twig_SimpleFunction('active_theme_path', [$this, 'getActiveThemePath']), new \Twig_SimpleFunction('active_theme', [$this, 'getActiveTheme']), diff --git a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php index 5ae5e85b21059bb4200766e41c7a4a535c86da5f..8072060697003963ee23c6ec8f6c3117108ac7f7 100644 --- a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php +++ b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php @@ -298,8 +298,11 @@ public function getJSSettings(EditorEntity $editor) { ); // Finally, set Drupal-specific CKEditor settings. + $root_relative_file_url = function ($uri) { + return file_url_transform_relative(file_create_url($uri)); + }; $settings += array( - 'drupalExternalPlugins' => array_map('file_create_url', $external_plugin_files), + 'drupalExternalPlugins' => array_map($root_relative_file_url, $external_plugin_files), ); // Parse all CKEditor plugin JavaScript files for translations. @@ -421,6 +424,7 @@ public function buildContentsCssJSSetting(EditorEntity $editor) { $this->moduleHandler->alter('ckeditor_css', $css, $editor); $css = array_merge($css, _ckeditor_theme_css()); $css = array_map('file_create_url', $css); + $css = array_map('file_url_transform_relative', $css); return array_values($css); } diff --git a/core/modules/ckeditor/src/Tests/CKEditorTest.php b/core/modules/ckeditor/src/Tests/CKEditorTest.php index 4df0113333105b45792ab1d3748519aa96848676..6a2fd426495ddff320ec23a08e44ec429d1ff0cf 100644 --- a/core/modules/ckeditor/src/Tests/CKEditorTest.php +++ b/core/modules/ckeditor/src/Tests/CKEditorTest.php @@ -90,8 +90,8 @@ function testGetJSSettings() { 'language' => 'en', 'stylesSet' => FALSE, 'drupalExternalPlugins' => array( - 'drupalimage' => file_create_url('core/modules/ckeditor/js/plugins/drupalimage/plugin.js'), - 'drupallink' => file_create_url('core/modules/ckeditor/js/plugins/drupallink/plugin.js'), + 'drupalimage' => file_url_transform_relative(file_create_url('core/modules/ckeditor/js/plugins/drupalimage/plugin.js')), + 'drupallink' => file_url_transform_relative(file_create_url('core/modules/ckeditor/js/plugins/drupallink/plugin.js')), ), ); $expected_config = $this->castSafeStrings($expected_config); @@ -114,9 +114,9 @@ function testGetJSSettings() { $expected_config['toolbar'][0]['items'][] = 'Format'; $expected_config['format_tags'] = 'p;h2;h3;h4;h5;h6'; $expected_config['extraPlugins'] .= ',llama_contextual,llama_contextual_and_button'; - $expected_config['drupalExternalPlugins']['llama_contextual'] = file_create_url('core/modules/ckeditor/tests/modules/js/llama_contextual.js'); - $expected_config['drupalExternalPlugins']['llama_contextual_and_button'] = file_create_url('core/modules/ckeditor/tests/modules/js/llama_contextual_and_button.js'); - $expected_config['contentsCss'][] = file_create_url('core/modules/ckeditor/tests/modules/ckeditor_test.css'); + $expected_config['drupalExternalPlugins']['llama_contextual'] = file_url_transform_relative(file_create_url('core/modules/ckeditor/tests/modules/js/llama_contextual.js')); + $expected_config['drupalExternalPlugins']['llama_contextual_and_button'] = file_url_transform_relative(file_create_url('core/modules/ckeditor/tests/modules/js/llama_contextual_and_button.js')); + $expected_config['contentsCss'][] = file_url_transform_relative(file_create_url('core/modules/ckeditor/tests/modules/ckeditor_test.css')); ksort($expected_config); $this->assertIdentical($expected_config, $this->castSafeStrings($this->ckeditor->getJSSettings($editor)), 'Generated JS settings are correct for customized configuration.'); @@ -261,16 +261,16 @@ function testBuildContentsCssJSSetting() { // Enable the editor_test module, which implements hook_ckeditor_css_alter(). $this->enableModules(array('ckeditor_test')); - $expected[] = file_create_url('core/modules/ckeditor/tests/modules/ckeditor_test.css'); + $expected[] = file_url_transform_relative(file_create_url('core/modules/ckeditor/tests/modules/ckeditor_test.css')); $this->assertIdentical($expected, $this->ckeditor->buildContentsCssJSSetting($editor), '"contentsCss" configuration part of JS settings built correctly while a hook_ckeditor_css_alter() implementation exists.'); // Enable the Bartik theme, which specifies a CKEditor stylesheet. \Drupal::service('theme_handler')->install(['bartik']); \Drupal::service('theme_handler')->setDefault('bartik'); - $expected[] = file_create_url('core/themes/bartik/css/base/elements.css'); - $expected[] = file_create_url('core/themes/bartik/css/components/captions.css'); - $expected[] = file_create_url('core/themes/bartik/css/components/table.css'); - $expected[] = file_create_url('core/themes/bartik/css/components/text-formatted.css'); + $expected[] = file_url_transform_relative(file_create_url('core/themes/bartik/css/base/elements.css')); + $expected[] = file_url_transform_relative(file_create_url('core/themes/bartik/css/components/captions.css')); + $expected[] = file_url_transform_relative(file_create_url('core/themes/bartik/css/components/table.css')); + $expected[] = file_url_transform_relative(file_create_url('core/themes/bartik/css/components/text-formatted.css')); $this->assertIdentical($expected, $this->ckeditor->buildContentsCssJSSetting($editor), '"contentsCss" configuration part of JS settings built correctly while a theme providing a CKEditor stylesheet exists.'); } @@ -479,8 +479,8 @@ protected function getDefaultToolbarConfig() { protected function getDefaultContentsCssConfig() { return array( - file_create_url('core/modules/ckeditor/css/ckeditor-iframe.css'), - file_create_url('core/modules/system/css/components/align.module.css'), + file_url_transform_relative(file_create_url('core/modules/ckeditor/css/ckeditor-iframe.css')), + file_url_transform_relative(file_create_url('core/modules/system/css/components/align.module.css')), ); } diff --git a/core/modules/ckeditor/src/Tests/CKEditorToolbarButtonTest.php b/core/modules/ckeditor/src/Tests/CKEditorToolbarButtonTest.php index 5751f8629ad70792351b2ee569b35188b5d898fd..4b241d7997b1f856cba5b61c8ba06c96213029e7 100644 --- a/core/modules/ckeditor/src/Tests/CKEditorToolbarButtonTest.php +++ b/core/modules/ckeditor/src/Tests/CKEditorToolbarButtonTest.php @@ -57,7 +57,6 @@ protected function setUp() { * Method tests CKEditor image buttons. */ public function testImageButtonDisplay() { - global $base_url; $this->drupalLogin($this->admin_user); // Install the Arabic language (which is RTL) and configure as the default. @@ -75,7 +74,7 @@ public function testImageButtonDisplay() { $json_encode = function($html) { return trim(Json::encode($html), '"'); }; - $markup = $json_encode($base_url . '/core/modules/ckeditor/js/plugins/drupalimage/image.png'); + $markup = $json_encode(file_url_transform_relative(file_create_url('core/modules/ckeditor/js/plugins/drupalimage/image.png'))); $this->assertRaw($markup); } diff --git a/core/modules/color/color.module b/core/modules/color/color.module index 2fbef3034083babad17687e56bd464f39262a00a..055d750f7ddf4dced928b558ed8493ca8b4fa1ca 100644 --- a/core/modules/color/color.module +++ b/core/modules/color/color.module @@ -126,7 +126,7 @@ function color_block_view_pre_render(array $build) { // Override logo. $logo = $config->get('logo'); if ($logo && $build['content']['site_logo'] && preg_match('!' . $theme_key . '/logo.svg$!', $build['content']['site_logo']['#uri'])) { - $build['content']['site_logo']['#uri'] = file_create_url($logo); + $build['content']['site_logo']['#uri'] = file_url_transform_relative(file_create_url($logo)); } return $build; diff --git a/core/modules/color/src/Tests/ColorTest.php b/core/modules/color/src/Tests/ColorTest.php index 4a410644477009ea457a7a45825ba8b3a2af40d6..8e3d7714abe8f894ea3664f59bb998098f10ab26 100644 --- a/core/modules/color/src/Tests/ColorTest.php +++ b/core/modules/color/src/Tests/ColorTest.php @@ -121,7 +121,7 @@ function _testColor($theme, $test_values) { $this->drupalGet('<front>'); $stylesheets = $this->config('color.theme.' . $theme)->get('stylesheets'); foreach ($stylesheets as $stylesheet) { - $this->assertPattern('|' . file_create_url($stylesheet) . '|', 'Make sure the color stylesheet is included in the content. (' . $theme . ')'); + $this->assertPattern('|' . file_url_transform_relative(file_create_url($stylesheet)) . '|', 'Make sure the color stylesheet is included in the content. (' . $theme . ')'); $stylesheet_content = join("\n", file($stylesheet)); $this->assertTrue(strpos($stylesheet_content, 'color: #123456') !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); } @@ -191,7 +191,7 @@ function testLogoSettingOverride() { // Ensure that the overridden logo is present in Bartik, which is colorable. $this->drupalGet('admin/appearance/settings/bartik'); - $this->assertIdentical($GLOBALS['base_url'] . '/' . 'core/misc/druplicon.png', $this->getDrupalSettings()['color']['logo']); + $this->assertIdentical($GLOBALS['base_path'] . 'core/misc/druplicon.png', $this->getDrupalSettings()['color']['logo']); } /** diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 08e94384bc70d12e03f2ea0e571d4e4b4cafb3ba..984773ace17c91673d5bd84c0c145f42efa0789e 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -977,7 +977,12 @@ function file_tokens($type, $tokens, array $data, array $options, BubbleableMeta break; case 'url': + // Ideally, this would use file_url_transform_relative(), but because + // tokens are also often used in e-mails, it's better to keep absolute + // file URLs. The 'url.site' cache context is associated to ensure the + // correct absolute URL is used in case of a multisite setup. $replacements[$original] = file_create_url($file->getFileUri()); + $bubbleable_metadata->addCacheContexts(['url.site']); break; // These tokens are default variations on the chained tokens handled below. @@ -1228,7 +1233,13 @@ function template_preprocess_file_link(&$variables) { $options = array(); $file_entity = ($file instanceof File) ? $file : File::load($file->fid); + // @todo Wrap in file_url_transform_relative(). This is currently + // impossible. As a work-around, we currently add the 'url.site' cache context + // to ensure different file URLs are generated for different sites in a + // multisite setup, including HTTP and HTTPS versions of the same site. + // Fix in https://www.drupal.org/node/2646744. $url = file_create_url($file_entity->getFileUri()); + $variables['#cache']['contexts'][] = 'url.site'; $mime_type = $file->getMimeType(); // Set options as per anchor format described at diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php index ae5ca764b2183cc8cd891df3f753bf13c4a87a38..6417488e52b24a70b21737e24d583faeeb23cc9e 100644 --- a/core/modules/file/src/Entity/File.php +++ b/core/modules/file/src/Entity/File.php @@ -70,6 +70,8 @@ public function setFileUri($uri) { /** * {@inheritdoc} + * + * @see file_url_transform_relative() */ public function url($rel = 'canonical', $options = array()) { return file_create_url($this->getFileUri()); diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php b/core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php index fbe14f09ba95c50af42e6891958856de75e55aed..798babd73c13fcfc5aeb0e19731b8bbea44d1260 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/BaseFieldFileFormatterBase.php @@ -52,6 +52,8 @@ public function viewElements(FieldItemListInterface $items, $langcode) { $url = NULL; // Add support to link to the entity itself. if ($this->getSetting('link_to_file')) { + // @todo Wrap in file_url_transform_relative(). This is currently + // impossible. See below. $url = file_create_url($items->getEntity()->uri->value); } @@ -63,6 +65,16 @@ public function viewElements(FieldItemListInterface $items, $langcode) { '#type' => 'link', '#title' => $view_value, '#url' => Url::fromUri($url), + // @todo Remove the 'url.site' cache context by using a relative file + // URL (file_url_transform_relative()). This is currently impossible + // because #type => link requires a Url object, and Url objects do not + // support relative URLs: they require fully qualified URLs. Fix in + // https://www.drupal.org/node/2646744. + '#cache' => [ + 'contexts' => [ + 'url.site', + ], + ], ]; } else { diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php index 0a2a855bcdfab5f4343080111cd19d408466d22c..c86cc8e0d99061f6e0c26047df90c4092ab49348 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php @@ -55,6 +55,9 @@ public function settingsForm(array $form, FormStateInterface $form_state) { protected function viewValue(FieldItemInterface $item) { $value = $item->value; if ($this->getSetting('file_download_path')) { + // @todo Wrap in file_url_transform_relative(). This is currently + // impossible. See BaseFieldFileFormatterBase::viewElements(). Fix in + // https://www.drupal.org/node/2646744. $value = file_create_url($value); } return $value; diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php index ab479f32f3c61ad07e85d09f359479f40959af44..2f0a65f67be2506f7827a2422750ba56ae358921 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php @@ -33,6 +33,9 @@ public function viewElements(FieldItemListInterface $items, $langcode) { $entity->rss_elements[] = array( 'key' => 'enclosure', 'attributes' => array( + // In RSS feeds, it is necessary to use absolute URLs. The 'url.site' + // cache context is already associated with RSS feed responses, so it + // does not need to be specified here. 'url' => file_create_url($file->getFileUri()), 'length' => $file->getSize(), 'type' => $file->getMimeType(), diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php index 6f2264e91d792d53fdbf3ac14bf179953df642b8..0795be2002ce0e4e66ef754e71d794b68123f25f 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php @@ -30,7 +30,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) { $elements[$delta] = array( - '#markup' => file_create_url($file->getFileUri()), + '#markup' => file_url_transform_relative(file_create_url($file->getFileUri())), '#cache' => array( 'tags' => $file->getCacheTags(), ), diff --git a/core/modules/file/src/Plugin/views/field/File.php b/core/modules/file/src/Plugin/views/field/File.php index 615aa9f8e98c2cac0cd59553573ac5833c9ca8bb..0b9c6965ddc1e3da9bbceec71bf49e58cc516144 100644 --- a/core/modules/file/src/Plugin/views/field/File.php +++ b/core/modules/file/src/Plugin/views/field/File.php @@ -69,6 +69,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { protected function renderLink($data, ResultRow $values) { if (!empty($this->options['link_to_file']) && $data !== NULL && $data !== '') { $this->options['alter']['make_link'] = TRUE; + // @todo Wrap in file_url_transform_relative(). This is currently + // impossible. As a work-around, we could add the 'url.site' cache context + // to ensure different file URLs are generated for different sites in a + // multisite setup, including HTTP and HTTPS versions of the same site. + // But unfortunately it's impossible to bubble a cache context here. + // Fix in https://www.drupal.org/node/2646744. $this->options['alter']['path'] = file_create_url($this->getValue($values, 'uri')); } diff --git a/core/modules/file/src/Tests/FileTokenReplaceTest.php b/core/modules/file/src/Tests/FileTokenReplaceTest.php index 93a6c67a87dc8a4abdc432721bb160e442ca7012..bfc85de3d4919d4c3141cc41f09dfe55b3de5620 100644 --- a/core/modules/file/src/Tests/FileTokenReplaceTest.php +++ b/core/modules/file/src/Tests/FileTokenReplaceTest.php @@ -66,7 +66,8 @@ function testFileTokenReplacement() { $metadata_tests['[file:path]'] = $base_bubbleable_metadata; $metadata_tests['[file:mime]'] = $base_bubbleable_metadata; $metadata_tests['[file:size]'] = $base_bubbleable_metadata; - $metadata_tests['[file:url]'] = $base_bubbleable_metadata; + $bubbleable_metadata = clone $base_bubbleable_metadata; + $metadata_tests['[file:url]'] = $bubbleable_metadata->addCacheContexts(['url.site']); $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[file:created]'] = $bubbleable_metadata->addCacheTags(['rendered']); $metadata_tests['[file:created:short]'] = $bubbleable_metadata; diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc index b3d4a6e7df2b7b0a34c2d4b6dd2539906a49ffa7..777e43855a4124e29ed5ca0bf866c14e61470618 100644 --- a/core/modules/image/image.admin.inc +++ b/core/modules/image/image.admin.inc @@ -34,7 +34,7 @@ function template_preprocess_image_style_preview(&$variables) { $original_path = \Drupal::config('image.settings')->get('preview_image'); $original_image = $image_factory->get($original_path); $variables['original'] = array( - 'url' => file_create_url($original_path), + 'url' => file_url_transform_relative(file_create_url($original_path)), 'width' => $original_image->getWidth(), 'height' => $original_image->getHeight(), ); @@ -55,7 +55,7 @@ function template_preprocess_image_style_preview(&$variables) { } $preview_image = $image_factory->get($preview_file); $variables['derivative'] = array( - 'url' => file_create_url($preview_file), + 'url' => file_url_transform_relative(file_create_url($preview_file)), 'width' => $preview_image->getWidth(), 'height' => $preview_image->getHeight(), ); diff --git a/core/modules/image/src/ImageStyleInterface.php b/core/modules/image/src/ImageStyleInterface.php index 95072915148cdb3ba4d3aaeeb20188f366630a0a..e1cad03bbba6f683300934d0405b4a1608cd1794 100644 --- a/core/modules/image/src/ImageStyleInterface.php +++ b/core/modules/image/src/ImageStyleInterface.php @@ -70,6 +70,7 @@ public function buildUri($uri); * in an <img> tag. Requesting the URL will cause the image to be created. * * @see \Drupal\image\Controller\ImageStyleDownloadController::deliver() + * @see file_url_transform_relative() */ public function buildUrl($path, $clean_urls = NULL); diff --git a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php index 57204152732ca43db034286af8b836fa8849b9b5..55b613a8ff50101fde1d6643fec42daece2f7a63 100644 --- a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php +++ b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php @@ -199,9 +199,16 @@ public function viewElements(FieldItemListInterface $items, $langcode) { } foreach ($files as $delta => $file) { + $cache_contexts = array(); if (isset($link_file)) { $image_uri = $file->getFileUri(); + // @todo Wrap in file_url_transform_relative(). This is currently + // impossible. As a work-around, we currently add the 'url.site' cache + // context to ensure different file URLs are generated for different + // sites in a multisite setup, including HTTP and HTTPS versions of the + // same site. Fix in https://www.drupal.org/node/2646744. $url = Url::fromUri(file_create_url($image_uri)); + $cache_contexts[] = 'url.site'; } $cache_tags = Cache::mergeTags($cache_tags, $file->getCacheTags()); @@ -219,6 +226,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { '#url' => $url, '#cache' => array( 'tags' => $cache_tags, + 'contexts' => $cache_contexts, ), ); } diff --git a/core/modules/image/src/Tests/ImageAdminStylesTest.php b/core/modules/image/src/Tests/ImageAdminStylesTest.php index 08f0adf9abf744270c45a9c474206ebcf1cb59b5..fb59a4809a0755a8103e5508124598af01becbef 100644 --- a/core/modules/image/src/Tests/ImageAdminStylesTest.php +++ b/core/modules/image/src/Tests/ImageAdminStylesTest.php @@ -307,7 +307,7 @@ function testStyleReplacement() { // Test that image is displayed using newly created style. $this->drupalGet('node/' . $nid); - $this->assertRaw($style->buildUrl($original_uri), format_string('Image displayed using style @style.', array('@style' => $style_name))); + $this->assertRaw(file_url_transform_relative($style->buildUrl($original_uri)), format_string('Image displayed using style @style.', array('@style' => $style_name))); // Rename the style and make sure the image field is updated. $new_style_name = strtolower($this->randomMachineName(10)); @@ -322,7 +322,7 @@ function testStyleReplacement() { // Reload the image style using the new name. $style = ImageStyle::load($new_style_name); - $this->assertRaw($style->buildUrl($original_uri), 'Image displayed using style replacement style.'); + $this->assertRaw(file_url_transform_relative($style->buildUrl($original_uri)), 'Image displayed using style replacement style.'); // Delete the style and choose a replacement style. $edit = array( @@ -334,7 +334,7 @@ function testStyleReplacement() { $replacement_style = ImageStyle::load('thumbnail'); $this->drupalGet('node/' . $nid); - $this->assertRaw($replacement_style->buildUrl($original_uri), 'Image displayed using style replacement style.'); + $this->assertRaw(file_url_transform_relative($replacement_style->buildUrl($original_uri)), 'Image displayed using style replacement style.'); } /** @@ -441,7 +441,7 @@ function testConfigImport() { // Test that image is displayed using newly created style. $this->drupalGet('node/' . $nid); - $this->assertRaw($style->buildUrl($original_uri), format_string('Image displayed using style @style.', array('@style' => $style_name))); + $this->assertRaw(file_url_transform_relative($style->buildUrl($original_uri)), format_string('Image displayed using style @style.', array('@style' => $style_name))); // Copy config to sync, and delete the image style. $sync = $this->container->get('config.storage.sync'); diff --git a/core/modules/image/src/Tests/ImageDimensionsTest.php b/core/modules/image/src/Tests/ImageDimensionsTest.php index 683756a089b3fb9def323430377a26d3c8997224..f232d71197e48201fc701d2ffbf43cc271373507 100644 --- a/core/modules/image/src/Tests/ImageDimensionsTest.php +++ b/core/modules/image/src/Tests/ImageDimensionsTest.php @@ -41,7 +41,7 @@ function testImageDimensions() { $style = ImageStyle::create(array('name' => 'test', 'label' => 'Test')); $style->save(); $generated_uri = 'public://styles/test/public/'. \Drupal::service('file_system')->basename($original_uri); - $url = $style->buildUrl($original_uri); + $url = file_url_transform_relative($style->buildUrl($original_uri)); $variables = array( '#theme' => 'image_style', @@ -70,7 +70,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="120" height="60" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -91,7 +91,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="60" height="120" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -113,7 +113,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -135,7 +135,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -153,7 +153,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -174,7 +174,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); @@ -194,7 +194,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="30" height="30" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -215,7 +215,7 @@ function testImageDimensions() { $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="41" height="41" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -254,10 +254,10 @@ function testImageDimensions() { ]; // PNG original image. Should be resized to 100x100. $generated_uri = 'public://styles/test_uri/public/'. \Drupal::service('file_system')->basename($original_uri); - $url = $style->buildUrl($original_uri); + $url = file_url_transform_relative($style->buildUrl($original_uri)); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="100" height="100" alt="" class="image-style-test-uri" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); @@ -267,11 +267,11 @@ function testImageDimensions() { $file = $files[1]; $original_uri = file_unmanaged_copy($file->uri, 'public://', FILE_EXISTS_RENAME); $generated_uri = 'public://styles/test_uri/public/'. \Drupal::service('file_system')->basename($original_uri); - $url = $style->buildUrl($original_uri); + $url = file_url_transform_relative($style->buildUrl($original_uri)); $variables['#uri'] = $original_uri; $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="50" height="50" alt="" class="image-style-test-uri" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); - $this->drupalGet($url); + $this->drupalGet($this->getAbsoluteUrl($url)); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); diff --git a/core/modules/image/src/Tests/ImageFieldDisplayTest.php b/core/modules/image/src/Tests/ImageFieldDisplayTest.php index 53ba09f076e59a9c1488586381bacfa47a6cc9f3..2ae0fa45fd185d27642002d68d376cd4da1450fe 100644 --- a/core/modules/image/src/Tests/ImageFieldDisplayTest.php +++ b/core/modules/image/src/Tests/ImageFieldDisplayTest.php @@ -127,6 +127,8 @@ function _testImageFieldFormatters($scheme) { $default_output = '<a href="' . file_create_url($image_uri) . '">' . $renderer->renderRoot($image) . '</a>'; $this->drupalGet('node/' . $nid); $this->assertCacheTag($file->getCacheTags()[0]); + // @todo Remove in https://www.drupal.org/node/2646744. + $this->assertCacheContext('url.site'); $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags'); $this->assertTrue(!preg_match('/ image_style\:/', $cache_tags_header), 'No image style cache tag found.'); $this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.'); @@ -165,7 +167,7 @@ function _testImageFieldFormatters($scheme) { '//a[@href=:path]/img[@src=:url and @alt=:alt and @width=:width and @height=:height]', array( ':path' => $node->url(), - ':url' => file_create_url($image['#uri']), + ':url' => file_url_transform_relative(file_create_url($image['#uri'])), ':width' => $image['#width'], ':height' => $image['#height'], ':alt' => $alt, @@ -256,7 +258,7 @@ function testImageFieldSettings() { $node = $node_storage->load($nid); $file = $node->{$field_name}->entity; - $url = file_create_url(ImageStyle::load('medium')->buildUrl($file->getFileUri())); + $url = file_url_transform_relative(file_create_url(ImageStyle::load('medium')->buildUrl($file->getFileUri()))); $this->assertTrue($this->cssSelect('img[width=40][height=20][class=image-style-medium][src="' . $url . '"]')); // Add alt/title fields to the image and verify that they are displayed. diff --git a/core/modules/image/src/Tests/ImageThemeFunctionTest.php b/core/modules/image/src/Tests/ImageThemeFunctionTest.php index 060a8afb26c298fb8a6eb848bdf4d25da405440b..44f649ef679f732e83ea4bdee90a1a6bd75dba05 100644 --- a/core/modules/image/src/Tests/ImageThemeFunctionTest.php +++ b/core/modules/image/src/Tests/ImageThemeFunctionTest.php @@ -75,7 +75,7 @@ function testImageFormatterTheme() { // Create a style. $style = ImageStyle::create(array('name' => 'test', 'label' => 'Test')); $style->save(); - $url = $style->buildUrl($original_uri); + $url = file_url_transform_relative($style->buildUrl($original_uri)); // Create a test entity with the image field set. $entity = entity_create('entity_test'); @@ -137,7 +137,7 @@ function testImageStyleTheme() { // Create a style. $style = ImageStyle::create(array('name' => 'image_test', 'label' => 'Test')); $style->save(); - $url = $style->buildUrl($original_uri); + $url = file_url_transform_relative($style->buildUrl($original_uri)); // Create the base element that we'll use in the tests below. $base_element = array( diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module index d36782d70f76dfc65d95a0059d2e19f3dbc9003b..7df1da81a9f63cd8ff637108fa664cfb607eee8a 100644 --- a/core/modules/responsive_image/responsive_image.module +++ b/core/modules/responsive_image/responsive_image.module @@ -391,7 +391,7 @@ function responsive_image_build_source_attributes(ImageInterface $image, array $ // Use the image width as key so we can sort the array later on. // Images within a srcset should be sorted from small to large, since // the first matching source will be used. - $srcset[intval($dimensions['width'])] = file_create_url(_responsive_image_image_style_url($image_style_name, $image->getSource())) . ' ' . $dimensions['width'] . 'w'; + $srcset[intval($dimensions['width'])] = _responsive_image_image_style_url($image_style_name, $image->getSource()) . ' ' . $dimensions['width'] . 'w'; $sizes = array_merge(explode(',', $image_style_mapping['image_mapping']['sizes']), $sizes); } break; @@ -405,7 +405,7 @@ function responsive_image_build_source_attributes(ImageInterface $image, array $ // be sorted from small to large, since the first matching source will // be used. We multiply it by 100 so multipliers with up to two decimals // can be used. - $srcset[intval(Unicode::substr($multiplier, 0, -1) * 100)] = file_create_url(_responsive_image_image_style_url($image_style_mapping['image_mapping'], $image->getSource())) . ' ' . $multiplier; + $srcset[intval(Unicode::substr($multiplier, 0, -1) * 100)] = _responsive_image_image_style_url($image_style_mapping['image_mapping'], $image->getSource()) . ' ' . $multiplier; break; } } @@ -495,9 +495,9 @@ function _responsive_image_image_style_url($style_name, $path) { } $entity = ImageStyle::load($style_name); if ($entity instanceof Drupal\image\Entity\ImageStyle) { - return $entity->buildUrl($path); + return file_url_transform_relative($entity->buildUrl($path)); } - return file_create_url($path); + return file_url_transform_relative(file_create_url($path)); } /** diff --git a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php index d1290cb2a5fb76db0176b86cef2f587fe91a3161..e66cb82255e1ab2b6c30a5f39ea10a414da790b5 100644 --- a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php +++ b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php @@ -230,7 +230,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { foreach ($files as $delta => $file) { // Link the <picture> element to the original file. if (isset($link_file)) { - $url = Url::fromUri(file_create_url($file->getFileUri())); + $url = file_url_transform_relative(file_create_url($file->getFileUri())); } // Extract field item attributes for the theme function, and unset them // from the $item so that the field template does not re-render them. diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php index f535f3f25cd5573a8a816a0d257ad83e5c34812a..e8e7aaee3ffbf775b8701c0dcba3a49ff92aeaf1 100644 --- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php +++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php @@ -245,7 +245,7 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = $display->setComponent($field_name, $display_options) ->save(); - $default_output = '<a href="' . file_create_url($image_uri) . '"><picture'; + $default_output = '<a href="' . file_url_transform_relative(file_create_url($image_uri)) . '"><picture'; $this->drupalGet('node/' . $nid); $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags'); $this->assertTrue(!preg_match('/ image_style\:/', $cache_tags_header), 'No image style cache tag found.'); @@ -290,10 +290,10 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = $this->assertRaw('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='); $thumbnail_style = ImageStyle::load('thumbnail'); // Assert the output of the 'srcset' attribute (small multipliers first). - $this->assertRaw('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 1x, ' . $thumbnail_style->buildUrl($image_uri) . ' 1.5x'); + $this->assertRaw('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 1x, ' . file_url_transform_relative($thumbnail_style->buildUrl($image_uri)) . ' 1.5x'); $this->assertRaw('/styles/medium/'); // Assert the output of the original image. - $this->assertRaw(file_create_url($image_uri) . ' 3x'); + $this->assertRaw(file_url_transform_relative(file_create_url($image_uri)) . ' 3x'); // Assert the output of the breakpoints. $this->assertRaw('media="(min-width: 0px)"'); $this->assertRaw('media="(min-width: 560px)"'); @@ -302,7 +302,7 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = $this->assertPattern('/media="\(min-width: 560px\)".+?sizes="\(min-width: 700px\) 700px, 100vw"/'); // Assert the output of the 'srcset' attribute (small images first). $medium_style = ImageStyle::load('medium'); - $this->assertRaw($medium_style->buildUrl($image_uri) . ' 220w, ' . $large_style->buildUrl($image_uri) . ' 360w'); + $this->assertRaw(file_url_transform_relative($medium_style->buildUrl($image_uri)) . ' 220w, ' . file_url_transform_relative($large_style->buildUrl($image_uri)) . ' 360w'); $this->assertRaw('media="(min-width: 851px)"'); } $this->assertRaw('/styles/large/'); @@ -322,7 +322,7 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = '#alt' => $alt, '#srcset' => array( array( - 'uri' => $large_style->buildUrl($image->getSource()), + 'uri' => file_url_transform_relative($large_style->buildUrl($image->getSource())), ), ), ); @@ -404,7 +404,7 @@ public function testResponsiveImageFieldFormattersEmptyMediaQuery() { $thumbnail_style = ImageStyle::load('thumbnail'); $node = $node_storage->load($nid); $image_uri = File::load($node->{$field_name}->target_id)->getFileUri(); - $this->assertPattern('/srcset="' . preg_quote($thumbnail_style->buildUrl($image_uri), '/') . ' 1x".+?media="\(min-width: 0px\)"/'); + $this->assertPattern('/srcset="' . preg_quote(file_url_transform_relative($thumbnail_style->buildUrl($image_uri)), '/') . ' 1x".+?media="\(min-width: 0px\)"/'); } /** @@ -450,7 +450,7 @@ public function testResponsiveImageFieldFormattersOneSource() { $medium_style = ImageStyle::load('medium'); $node = $node_storage->load($nid); $image_uri = File::load($node->{$field_name}->target_id)->getFileUri(); - $this->assertRaw('<img srcset="' . $medium_style->buildUrl($image_uri) . ' 1x, ' . $large_style->buildUrl($image_uri) . ' 2x"'); + $this->assertRaw('<img srcset="' . file_url_transform_relative($medium_style->buildUrl($image_uri)) . ' 1x, ' . file_url_transform_relative($large_style->buildUrl($image_uri)) . ' 2x"'); } /** @@ -510,7 +510,7 @@ private function assertResponsiveImageFieldFormattersLink($link_type) { switch ($link_type) { case 'file': // Make sure the link to the file is present. - $this->assertPattern('/<a(.*?)href="' . preg_quote(file_create_url($image_uri), '/') . '"(.*?)><picture/'); + $this->assertPattern('/<a(.*?)href="' . preg_quote(file_url_transform_relative(file_create_url($image_uri)), '/') . '"(.*?)><picture/'); break; case 'content': diff --git a/core/modules/simpletest/src/Tests/SimpleTestTest.php b/core/modules/simpletest/src/Tests/SimpleTestTest.php index 41d114ea6d10ef9c9c37d2efdcb5d858f9cd5bb6..812c1b249ac768efe7775ac4e17140037c74b124 100644 --- a/core/modules/simpletest/src/Tests/SimpleTestTest.php +++ b/core/modules/simpletest/src/Tests/SimpleTestTest.php @@ -333,7 +333,7 @@ function getTestResults() { $assertion['file'] = $this->asText($row->td[2]); $assertion['line'] = $this->asText($row->td[3]); $assertion['function'] = $this->asText($row->td[4]); - $ok_url = file_create_url('core/misc/icons/73b355/check.svg'); + $ok_url = file_url_transform_relative(file_create_url('core/misc/icons/73b355/check.svg')); $assertion['status'] = ($row->td[5]->img['src'] == $ok_url) ? 'Pass' : 'Fail'; $results['assertions'][] = $assertion; } diff --git a/core/modules/system/src/Tests/Common/AttachedAssetsTest.php b/core/modules/system/src/Tests/Common/AttachedAssetsTest.php index e3a516e322183326755671d5a903c64dd9c920ec..3ab2d31520cf7d6ad2a9b40bf0c79b936cecc1f7 100644 --- a/core/modules/system/src/Tests/Common/AttachedAssetsTest.php +++ b/core/modules/system/src/Tests/Common/AttachedAssetsTest.php @@ -96,8 +96,8 @@ function testAddFiles() { $rendered_css = $this->renderer->renderPlain($css_render_array); $rendered_js = $this->renderer->renderPlain($js_render_array); $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; - $this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . file_create_url('core/modules/system/tests/modules/common_test/bar.css') . '?' . $query_string . '" media="all" />'), FALSE, 'Rendering an external CSS file.'); - $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/foo.js') . '?' . $query_string . '"></script>'), FALSE, 'Rendering an external JavaScript file.'); + $this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/bar.css')) . '?' . $query_string . '" media="all" />'), FALSE, 'Rendering an external CSS file.'); + $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/foo.js')) . '?' . $query_string . '"></script>'), FALSE, 'Rendering an external JavaScript file.'); } /** @@ -150,7 +150,7 @@ function testAttributes() { $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js); $rendered_js = $this->renderer->renderPlain($js_render_array); $expected_1 = '<script src="http://example.com/deferred-external.js" foo="bar" defer></script>'; - $expected_2 = '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/deferred-internal.js') . '?v=1" defer bar="foo"></script>'; + $expected_2 = '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/deferred-internal.js')) . '?v=1" defer bar="foo"></script>'; $this->assertNotIdentical(strpos($rendered_js, $expected_1), FALSE, 'Rendered external JavaScript with correct defer and random attributes.'); $this->assertNotIdentical(strpos($rendered_js, $expected_2), FALSE, 'Rendered internal JavaScript with correct defer and random attributes.'); } @@ -166,7 +166,7 @@ function testAggregatedAttributes() { $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js); $rendered_js = $this->renderer->renderPlain($js_render_array); $expected_1 = '<script src="http://example.com/deferred-external.js" foo="bar" defer></script>'; - $expected_2 = '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/deferred-internal.js') . '?v=1" defer bar="foo"></script>'; + $expected_2 = '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/deferred-internal.js')) . '?v=1" defer bar="foo"></script>'; $this->assertNotIdentical(strpos($rendered_js, $expected_1), FALSE, 'Rendered external JavaScript with correct defer and random attributes.'); $this->assertNotIdentical(strpos($rendered_js, $expected_2), FALSE, 'Rendered internal JavaScript with correct defer and random attributes.'); } @@ -186,7 +186,7 @@ function testAggregation() { $rendered_footer_js = \Drupal::service('asset.js.collection_renderer')->render($footer_js); $this->assertEqual(2, count($rendered_footer_js), 'There are 2 JavaScript assets in the footer.'); $this->assertEqual('drupal-settings-json', $rendered_footer_js[0]['#attributes']['data-drupal-selector'], 'The first of the two JavaScript assets in the footer has drupal settings.'); - $this->assertEqual('http://', substr($rendered_footer_js[1]['#attributes']['src'], 0, 7), 'The second of the two JavaScript assets in the footer has the sole aggregated JavaScript asset.'); + $this->assertEqual(0, strpos($rendered_footer_js[1]['#attributes']['src'], base_path()), 'The second of the two JavaScript assets in the footer has the sole aggregated JavaScript asset.'); } /** @@ -237,9 +237,9 @@ function testHeaderHTML() { $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js); $rendered_js = $this->renderer->renderPlain($js_render_array); $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; - $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/header.js') . '?' . $query_string . '"></script>'), FALSE, 'The JS asset in common_test/js-header appears in the header.'); - $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/misc/drupal.js')), FALSE, 'The JS asset of the direct dependency (core/drupal) of common_test/js-header appears in the header.'); - $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/assets/vendor/domready/ready.min.js')), FALSE, 'The JS asset of the indirect dependency (core/domready) of common_test/js-header appears in the header.'); + $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/header.js')) . '?' . $query_string . '"></script>'), FALSE, 'The JS asset in common_test/js-header appears in the header.'); + $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/misc/drupal.js'))), FALSE, 'The JS asset of the direct dependency (core/drupal) of common_test/js-header appears in the header.'); + $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/assets/vendor/domready/ready.min.js'))), FALSE, 'The JS asset of the indirect dependency (core/domready) of common_test/js-header appears in the header.'); } /** @@ -267,8 +267,8 @@ function testBrowserConditionalComments() { $js = $this->assetResolver->getJsAssets($assets, FALSE)[1]; $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js); $rendered_js = $this->renderer->renderPlain($js_render_array); - $expected_1 = "<!--[if lte IE 8]>\n" . '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/old-ie.js') . '?' . $default_query_string . '"></script>' . "\n<![endif]-->"; - $expected_2 = "<!--[if !IE]><!-->\n" . '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/no-ie.js') . '?' . $default_query_string . '"></script>' . "\n<!--<![endif]-->"; + $expected_1 = "<!--[if lte IE 8]>\n" . '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/old-ie.js')) . '?' . $default_query_string . '"></script>' . "\n<![endif]-->"; + $expected_2 = "<!--[if !IE]><!-->\n" . '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/no-ie.js')) . '?' . $default_query_string . '"></script>' . "\n<!--<![endif]-->"; $this->assertNotIdentical(strpos($rendered_js, $expected_1), FALSE, 'Rendered JavaScript within downlevel-hidden conditional comments.'); $this->assertNotIdentical(strpos($rendered_js, $expected_2), FALSE, 'Rendered JavaScript within downlevel-revealed conditional comments.'); @@ -476,8 +476,8 @@ function testAddJsFileWithQueryString() { $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js); $rendered_js = $this->renderer->renderPlain($js_render_array); $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; - $this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . str_replace('&', '&', file_create_url('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2')) . '&' . $query_string . '" media="all" />'), FALSE, 'CSS file with query string gets version query string correctly appended..'); - $this->assertNotIdentical(strpos($rendered_js, '<script src="' . str_replace('&', '&', file_create_url('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2')) . '&' . $query_string . '"></script>'), FALSE, 'JavaScript file with query string gets version query string correctly appended.'); + $this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . str_replace('&', '&', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2'))) . '&' . $query_string . '" media="all" />'), FALSE, 'CSS file with query string gets version query string correctly appended..'); + $this->assertNotIdentical(strpos($rendered_js, '<script src="' . str_replace('&', '&', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2'))) . '&' . $query_string . '"></script>'), FALSE, 'JavaScript file with query string gets version query string correctly appended.'); } } diff --git a/core/modules/system/src/Tests/System/ThemeTest.php b/core/modules/system/src/Tests/System/ThemeTest.php index 5a079ec18c5e83ec4e5caa243768f66c4a6ec13c..c2f5a5750685c6c6609e51fe01ac4803bff5a98c 100644 --- a/core/modules/system/src/Tests/System/ThemeTest.php +++ b/core/modules/system/src/Tests/System/ThemeTest.php @@ -65,27 +65,27 @@ function testThemeSettings() { // Raw stream wrapper URI. $file->uri => array( 'form' => file_uri_target($file->uri), - 'src' => file_create_url($file->uri), + 'src' => file_url_transform_relative(file_create_url($file->uri)), ), // Relative path within the public filesystem. file_uri_target($file->uri) => array( 'form' => file_uri_target($file->uri), - 'src' => file_create_url($file->uri), + 'src' => file_url_transform_relative(file_create_url($file->uri)), ), // Relative path to a public file. $file_relative => array( 'form' => $file_relative, - 'src' => file_create_url($file->uri), + 'src' => file_url_transform_relative(file_create_url($file->uri)), ), // Relative path to an arbitrary file. 'core/misc/druplicon.png' => array( 'form' => 'core/misc/druplicon.png', - 'src' => $GLOBALS['base_url'] . '/' . 'core/misc/druplicon.png', + 'src' => base_path() . 'core/misc/druplicon.png', ), // Relative path to a file in a theme. $default_theme_path . '/logo.svg' => array( 'form' => $default_theme_path . '/logo.svg', - 'src' => $GLOBALS['base_url'] . '/' . $default_theme_path . '/logo.svg', + 'src' => base_path() . $default_theme_path . '/logo.svg', ), ); foreach ($supported_paths as $input => $expected) { @@ -186,7 +186,7 @@ function testThemeSettings() { ':rel' => 'home', ) ); - $this->assertEqual($elements[0]['src'], file_create_url($uploaded_filename)); + $this->assertEqual($elements[0]['src'], file_url_transform_relative(file_create_url($uploaded_filename))); $this->container->get('theme_handler')->install(array('bartik')); diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php index 283b41d4b502f642590122ee8f8136656c16840b..4e2e563af7bbef7bf0bfae3dd87c25a5f097fd5a 100644 --- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php +++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php @@ -125,7 +125,7 @@ public function testTwigUrlToString() { */ public function testTwigFileUrls() { $this->drupalGet('/twig-theme-test/file-url'); - $filepath = file_create_url('core/modules/system/tests/modules/twig_theme_test/twig_theme_test.js'); + $filepath = file_url_transform_relative(file_create_url('core/modules/system/tests/modules/twig_theme_test/twig_theme_test.js')); $this->assertRaw('<div>file_url: ' . $filepath . '</div>'); } diff --git a/core/modules/system/src/Tests/Theme/ImageTest.php b/core/modules/system/src/Tests/Theme/ImageTest.php index 87b403c75a005aed542fa1f3f0019008689ff107..d0f93df20d7da633f7eb82b2980cbc5db2577815 100644 --- a/core/modules/system/src/Tests/Theme/ImageTest.php +++ b/core/modules/system/src/Tests/Theme/ImageTest.php @@ -8,6 +8,7 @@ namespace Drupal\system\Tests\Theme; use Drupal\simpletest\KernelTestBase; +use Symfony\Component\HttpFoundation\Request; /** * Tests built-in image theme functions. @@ -32,9 +33,17 @@ class ImageTest extends KernelTestBase { protected function setUp() { parent::setUp(); + + // The code under test uses file_url_transform_relative(), which relies on + // the Request containing the correct hostname. KernelTestBase doesn't set + // it, so push another request onto the stack to ensure it's correct. + $request = Request::create('/', 'GET', [], [], [], $_SERVER); + $this->container = $this->kernel->getContainer(); + $this->container->get('request_stack')->push($request); + $this->testImages = array( - '/core/misc/druplicon.png', - '/core/misc/loading.gif', + 'core/misc/druplicon.png', + 'core/misc/loading.gif', ); } @@ -75,7 +84,7 @@ function testThemeImageWithSrc() { $this->render($image); // Make sure the src attribute has the correct value. - $this->assertRaw(file_create_url($image['#uri']), 'Correct output for an image with the src attribute.'); + $this->assertRaw(file_url_transform_relative(file_create_url($image['#uri'])), 'Correct output for an image with the src attribute.'); } /** @@ -103,7 +112,7 @@ function testThemeImageWithSrcsetMultiplier() { $this->render($image); // Make sure the srcset attribute has the correct value. - $this->assertRaw(file_create_url($this->testImages[0]) . ' 1x, ' . file_create_url($this->testImages[1]) . ' 2x', 'Correct output for image with srcset attribute and multipliers.'); + $this->assertRaw(file_url_transform_relative(file_create_url($this->testImages[0])) . ' 1x, ' . file_url_transform_relative(file_create_url($this->testImages[1])) . ' 2x', 'Correct output for image with srcset attribute and multipliers.'); } /** @@ -135,7 +144,7 @@ function testThemeImageWithSrcsetWidth() { $this->render($image); // Make sure the srcset attribute has the correct value. - $this->assertRaw(file_create_url($this->testImages[0]) . ' ' . $widths[0] . ', ' . file_create_url($this->testImages[1]) . ' ' . $widths[1], 'Correct output for image with srcset attribute and width descriptors.'); + $this->assertRaw(file_url_transform_relative(file_create_url($this->testImages[0])) . ' ' . $widths[0] . ', ' . file_url_transform_relative(file_create_url($this->testImages[1])) . ' ' . $widths[1], 'Correct output for image with srcset attribute and width descriptors.'); } } diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestJavaScriptTest.php b/core/modules/system/src/Tests/Update/UpdatePathTestJavaScriptTest.php index f7ff4c336f9be787e2b53708f30eeb990a9755b6..d949dae7315c892b57855568deb613c0a1ec7338 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathTestJavaScriptTest.php +++ b/core/modules/system/src/Tests/Update/UpdatePathTestJavaScriptTest.php @@ -43,7 +43,9 @@ protected function doSelectionTest() { if (!isset($script['src'])) { continue; } - $src = (string) $script['src']; + // Source is a root-relative URL. Transform it to an absolute URL to allow + // file_get_contents() to access the file. + $src = preg_replace('#^' . $GLOBALS['base_path'] . '(.*)#i', $GLOBALS['base_url'] . '/' . '${1}', (string) $script['src']); $file_content = file_get_contents($src); if (strpos($file_content, 'window.drupalSettings =') !== FALSE) { diff --git a/core/modules/user/src/Tests/UserPictureTest.php b/core/modules/user/src/Tests/UserPictureTest.php index bd28934e64998ab0d39da543f0b65a901e7bd848..9fa28a355b3daffe5efa49854a5702b7fcc9daff 100644 --- a/core/modules/user/src/Tests/UserPictureTest.php +++ b/core/modules/user/src/Tests/UserPictureTest.php @@ -100,7 +100,7 @@ function testPictureOnNodeComment() { $image_style_id = $this->config('core.entity_view_display.user.user.compact')->get('content.user_picture.settings.image_style'); $style = ImageStyle::load($image_style_id); - $image_url = $style->buildUrl($file->getfileUri()); + $image_url = file_url_transform_relative($style->buildUrl($file->getfileUri())); $alt_text = 'Profile picture for user ' . $this->webUser->getUsername(); // Verify that the image is displayed on the node page. diff --git a/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php b/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php index eab4fe4cd8b92f1bb12017969b0b7823e5e6ec63..48a92ee1e12c3baf9af1dee2d820c0204cd7dbae 100644 --- a/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php @@ -9,9 +9,9 @@ namespace { /** - * CssRenderer uses file_create_url(), which *is* available when using the - * Simpletest test runner, but not when using the PHPUnit test runner; hence - * this hack. + * CssCollectionRenderer uses file_create_url() & file_url_transform_relative(), + * which *are* available when using the Simpletest test runner, but not when + * using the PHPUnit test runner; hence this hack. */ if (!function_exists('file_create_url')) { @@ -23,6 +23,17 @@ function file_create_url($uri) { return 'file_create_url:' . $uri; } +} +if (!function_exists('file_url_transform_relative')) { + + /** + * Temporary mock of file_url_transform_relative, until that is moved into + * Component/Utility. + */ + function file_url_transform_relative($uri) { + return 'file_url_transform_relative:' . $uri; + } + } } @@ -153,7 +164,7 @@ function providerTestRender() { 0 => array('group' => 0, 'type' => 'file', 'media' => 'all', 'preprocess' => TRUE, 'data' => 'public://css/file-all', 'browsers' => array()), ), array( - 0 => $create_link_element(file_create_url('public://css/file-all') . '?0', 'all'), + 0 => $create_link_element(file_url_transform_relative(file_create_url('public://css/file-all')) . '?0', 'all'), ), ), // 31 file CSS assets: expect 31 link elements. @@ -192,37 +203,37 @@ function providerTestRender() { 30 => $create_file_css_asset('public://css/31.css'), ), array( - 0 => $create_link_element(file_create_url('public://css/1.css') . '?0'), - 1 => $create_link_element(file_create_url('public://css/2.css') . '?0'), - 2 => $create_link_element(file_create_url('public://css/3.css') . '?0'), - 3 => $create_link_element(file_create_url('public://css/4.css') . '?0'), - 4 => $create_link_element(file_create_url('public://css/5.css') . '?0'), - 5 => $create_link_element(file_create_url('public://css/6.css') . '?0'), - 6 => $create_link_element(file_create_url('public://css/7.css') . '?0'), - 7 => $create_link_element(file_create_url('public://css/8.css') . '?0'), - 8 => $create_link_element(file_create_url('public://css/9.css') . '?0'), - 9 => $create_link_element(file_create_url('public://css/10.css') . '?0'), - 10 => $create_link_element(file_create_url('public://css/11.css') . '?0'), - 11 => $create_link_element(file_create_url('public://css/12.css') . '?0'), - 12 => $create_link_element(file_create_url('public://css/13.css') . '?0'), - 13 => $create_link_element(file_create_url('public://css/14.css') . '?0'), - 14 => $create_link_element(file_create_url('public://css/15.css') . '?0'), - 15 => $create_link_element(file_create_url('public://css/16.css') . '?0'), - 16 => $create_link_element(file_create_url('public://css/17.css') . '?0'), - 17 => $create_link_element(file_create_url('public://css/18.css') . '?0'), - 18 => $create_link_element(file_create_url('public://css/19.css') . '?0'), - 19 => $create_link_element(file_create_url('public://css/20.css') . '?0'), - 20 => $create_link_element(file_create_url('public://css/21.css') . '?0'), - 21 => $create_link_element(file_create_url('public://css/22.css') . '?0'), - 22 => $create_link_element(file_create_url('public://css/23.css') . '?0'), - 23 => $create_link_element(file_create_url('public://css/24.css') . '?0'), - 24 => $create_link_element(file_create_url('public://css/25.css') . '?0'), - 25 => $create_link_element(file_create_url('public://css/26.css') . '?0'), - 26 => $create_link_element(file_create_url('public://css/27.css') . '?0'), - 27 => $create_link_element(file_create_url('public://css/28.css') . '?0'), - 28 => $create_link_element(file_create_url('public://css/29.css') . '?0'), - 29 => $create_link_element(file_create_url('public://css/30.css') . '?0'), - 30 => $create_link_element(file_create_url('public://css/31.css') . '?0'), + 0 => $create_link_element(file_url_transform_relative(file_create_url('public://css/1.css')) . '?0'), + 1 => $create_link_element(file_url_transform_relative(file_create_url('public://css/2.css')) . '?0'), + 2 => $create_link_element(file_url_transform_relative(file_create_url('public://css/3.css')) . '?0'), + 3 => $create_link_element(file_url_transform_relative(file_create_url('public://css/4.css')) . '?0'), + 4 => $create_link_element(file_url_transform_relative(file_create_url('public://css/5.css')) . '?0'), + 5 => $create_link_element(file_url_transform_relative(file_create_url('public://css/6.css')) . '?0'), + 6 => $create_link_element(file_url_transform_relative(file_create_url('public://css/7.css')) . '?0'), + 7 => $create_link_element(file_url_transform_relative(file_create_url('public://css/8.css')) . '?0'), + 8 => $create_link_element(file_url_transform_relative(file_create_url('public://css/9.css')) . '?0'), + 9 => $create_link_element(file_url_transform_relative(file_create_url('public://css/10.css')) . '?0'), + 10 => $create_link_element(file_url_transform_relative(file_create_url('public://css/11.css')) . '?0'), + 11 => $create_link_element(file_url_transform_relative(file_create_url('public://css/12.css')) . '?0'), + 12 => $create_link_element(file_url_transform_relative(file_create_url('public://css/13.css')) . '?0'), + 13 => $create_link_element(file_url_transform_relative(file_create_url('public://css/14.css')) . '?0'), + 14 => $create_link_element(file_url_transform_relative(file_create_url('public://css/15.css')) . '?0'), + 15 => $create_link_element(file_url_transform_relative(file_create_url('public://css/16.css')) . '?0'), + 16 => $create_link_element(file_url_transform_relative(file_create_url('public://css/17.css')) . '?0'), + 17 => $create_link_element(file_url_transform_relative(file_create_url('public://css/18.css')) . '?0'), + 18 => $create_link_element(file_url_transform_relative(file_create_url('public://css/19.css')) . '?0'), + 19 => $create_link_element(file_url_transform_relative(file_create_url('public://css/20.css')) . '?0'), + 20 => $create_link_element(file_url_transform_relative(file_create_url('public://css/21.css')) . '?0'), + 21 => $create_link_element(file_url_transform_relative(file_create_url('public://css/22.css')) . '?0'), + 22 => $create_link_element(file_url_transform_relative(file_create_url('public://css/23.css')) . '?0'), + 23 => $create_link_element(file_url_transform_relative(file_create_url('public://css/24.css')) . '?0'), + 24 => $create_link_element(file_url_transform_relative(file_create_url('public://css/25.css')) . '?0'), + 25 => $create_link_element(file_url_transform_relative(file_create_url('public://css/26.css')) . '?0'), + 26 => $create_link_element(file_url_transform_relative(file_create_url('public://css/27.css')) . '?0'), + 27 => $create_link_element(file_url_transform_relative(file_create_url('public://css/28.css')) . '?0'), + 28 => $create_link_element(file_url_transform_relative(file_create_url('public://css/29.css')) . '?0'), + 29 => $create_link_element(file_url_transform_relative(file_create_url('public://css/30.css')) . '?0'), + 30 => $create_link_element(file_url_transform_relative(file_create_url('public://css/31.css')) . '?0'), ), ), // 32 file CSS assets with the same properties: expect 2 style elements. @@ -263,40 +274,40 @@ function providerTestRender() { ), array( 0 => $create_style_element(' -@import url("' . file_create_url('public://css/1.css') . '?0"); -@import url("' . file_create_url('public://css/2.css') . '?0"); -@import url("' . file_create_url('public://css/3.css') . '?0"); -@import url("' . file_create_url('public://css/4.css') . '?0"); -@import url("' . file_create_url('public://css/5.css') . '?0"); -@import url("' . file_create_url('public://css/6.css') . '?0"); -@import url("' . file_create_url('public://css/7.css') . '?0"); -@import url("' . file_create_url('public://css/8.css') . '?0"); -@import url("' . file_create_url('public://css/9.css') . '?0"); -@import url("' . file_create_url('public://css/10.css') . '?0"); -@import url("' . file_create_url('public://css/11.css') . '?0"); -@import url("' . file_create_url('public://css/12.css') . '?0"); -@import url("' . file_create_url('public://css/13.css') . '?0"); -@import url("' . file_create_url('public://css/14.css') . '?0"); -@import url("' . file_create_url('public://css/15.css') . '?0"); -@import url("' . file_create_url('public://css/16.css') . '?0"); -@import url("' . file_create_url('public://css/17.css') . '?0"); -@import url("' . file_create_url('public://css/18.css') . '?0"); -@import url("' . file_create_url('public://css/19.css') . '?0"); -@import url("' . file_create_url('public://css/20.css') . '?0"); -@import url("' . file_create_url('public://css/21.css') . '?0"); -@import url("' . file_create_url('public://css/22.css') . '?0"); -@import url("' . file_create_url('public://css/23.css') . '?0"); -@import url("' . file_create_url('public://css/24.css') . '?0"); -@import url("' . file_create_url('public://css/25.css') . '?0"); -@import url("' . file_create_url('public://css/26.css') . '?0"); -@import url("' . file_create_url('public://css/27.css') . '?0"); -@import url("' . file_create_url('public://css/28.css') . '?0"); -@import url("' . file_create_url('public://css/29.css') . '?0"); -@import url("' . file_create_url('public://css/30.css') . '?0"); -@import url("' . file_create_url('public://css/31.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/1.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/2.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/3.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/4.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/5.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/6.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/7.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/8.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/9.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/10.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/11.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/12.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/13.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/14.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/15.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/16.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/17.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/18.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/19.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/20.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/21.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/22.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/23.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/24.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/25.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/26.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/27.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/28.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/29.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/30.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/31.css')) . '?0"); ', 'all'), 1 => $create_style_element(' -@import url("' . file_create_url('public://css/32.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/32.css')) . '?0"); ', 'all'), ), ), @@ -340,46 +351,46 @@ function providerTestRender() { ), array( 0 => $create_style_element(' -@import url("' . file_create_url('public://css/1.css') . '?0"); -@import url("' . file_create_url('public://css/2.css') . '?0"); -@import url("' . file_create_url('public://css/3.css') . '?0"); -@import url("' . file_create_url('public://css/4.css') . '?0"); -@import url("' . file_create_url('public://css/5.css') . '?0"); -@import url("' . file_create_url('public://css/6.css') . '?0"); -@import url("' . file_create_url('public://css/7.css') . '?0"); -@import url("' . file_create_url('public://css/8.css') . '?0"); -@import url("' . file_create_url('public://css/9.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/1.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/2.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/3.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/4.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/5.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/6.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/7.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/8.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/9.css')) . '?0"); ', 'all'), 1 => $create_style_element(' -@import url("' . file_create_url('public://css/10.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/10.css')) . '?0"); ', 'screen'), 2 => $create_style_element(' -@import url("' . file_create_url('public://css/11.css') . '?0"); -@import url("' . file_create_url('public://css/12.css') . '?0"); -@import url("' . file_create_url('public://css/13.css') . '?0"); -@import url("' . file_create_url('public://css/14.css') . '?0"); -@import url("' . file_create_url('public://css/15.css') . '?0"); -@import url("' . file_create_url('public://css/16.css') . '?0"); -@import url("' . file_create_url('public://css/17.css') . '?0"); -@import url("' . file_create_url('public://css/18.css') . '?0"); -@import url("' . file_create_url('public://css/19.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/11.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/12.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/13.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/14.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/15.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/16.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/17.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/18.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/19.css')) . '?0"); ', 'all'), 3 => $create_style_element(' -@import url("' . file_create_url('public://css/20.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/20.css')) . '?0"); ', 'print'), 4 => $create_style_element(' -@import url("' . file_create_url('public://css/21.css') . '?0"); -@import url("' . file_create_url('public://css/22.css') . '?0"); -@import url("' . file_create_url('public://css/23.css') . '?0"); -@import url("' . file_create_url('public://css/24.css') . '?0"); -@import url("' . file_create_url('public://css/25.css') . '?0"); -@import url("' . file_create_url('public://css/26.css') . '?0"); -@import url("' . file_create_url('public://css/27.css') . '?0"); -@import url("' . file_create_url('public://css/28.css') . '?0"); -@import url("' . file_create_url('public://css/29.css') . '?0"); -@import url("' . file_create_url('public://css/30.css') . '?0"); -@import url("' . file_create_url('public://css/31.css') . '?0"); -@import url("' . file_create_url('public://css/32.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/21.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/22.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/23.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/24.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/25.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/26.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/27.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/28.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/29.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/30.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/31.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/32.css')) . '?0"); ', 'all'), ), ), @@ -422,40 +433,40 @@ function providerTestRender() { ), array( 0 => $create_style_element(' -@import url("' . file_create_url('public://css/1.css') . '?0"); -@import url("' . file_create_url('public://css/2.css') . '?0"); -@import url("' . file_create_url('public://css/3.css') . '?0"); -@import url("' . file_create_url('public://css/4.css') . '?0"); -@import url("' . file_create_url('public://css/5.css') . '?0"); -@import url("' . file_create_url('public://css/6.css') . '?0"); -@import url("' . file_create_url('public://css/7.css') . '?0"); -@import url("' . file_create_url('public://css/8.css') . '?0"); -@import url("' . file_create_url('public://css/9.css') . '?0"); -@import url("' . file_create_url('public://css/10.css') . '?0"); -@import url("' . file_create_url('public://css/11.css') . '?0"); -@import url("' . file_create_url('public://css/12.css') . '?0"); -@import url("' . file_create_url('public://css/13.css') . '?0"); -@import url("' . file_create_url('public://css/14.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/1.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/2.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/3.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/4.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/5.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/6.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/7.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/8.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/9.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/10.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/11.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/12.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/13.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/14.css')) . '?0"); ', 'all'), - 1 => $create_link_element(file_create_url('public://css/15.css') . '?0'), + 1 => $create_link_element(file_url_transform_relative(file_create_url('public://css/15.css')) . '?0'), 2 => $create_style_element(' -@import url("' . file_create_url('public://css/16.css') . '?0"); -@import url("' . file_create_url('public://css/17.css') . '?0"); -@import url("' . file_create_url('public://css/18.css') . '?0"); -@import url("' . file_create_url('public://css/19.css') . '?0"); -@import url("' . file_create_url('public://css/20.css') . '?0"); -@import url("' . file_create_url('public://css/21.css') . '?0"); -@import url("' . file_create_url('public://css/22.css') . '?0"); -@import url("' . file_create_url('public://css/23.css') . '?0"); -@import url("' . file_create_url('public://css/24.css') . '?0"); -@import url("' . file_create_url('public://css/25.css') . '?0"); -@import url("' . file_create_url('public://css/26.css') . '?0"); -@import url("' . file_create_url('public://css/27.css') . '?0"); -@import url("' . file_create_url('public://css/28.css') . '?0"); -@import url("' . file_create_url('public://css/29.css') . '?0"); -@import url("' . file_create_url('public://css/30.css') . '?0"); -@import url("' . file_create_url('public://css/31.css') . '?0"); -@import url("' . file_create_url('public://css/32.css') . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/16.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/17.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/18.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/19.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/20.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/21.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/22.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/23.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/24.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/25.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/26.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/27.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/28.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/29.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/30.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/31.css')) . '?0"); +@import url("' . file_url_transform_relative(file_create_url('public://css/32.css')) . '?0"); ', 'all'), ), ), diff --git a/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php b/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php index 03bb980f32cc2a96fe97c9614a5132613664f8ce..5922bf1f67583bbdd07e54797554b5d596a46021 100644 --- a/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php @@ -9,7 +9,8 @@ namespace { /** - * CssOptimizer uses file_create_url(), which *is* available when using the + * CssOptimizer uses file_create_url(), file_uri_scheme() and + * file_url_transform_relative(), which *are* available when using the * Simpletest test runner, but not when using the PHPUnit test runner; hence * this hack. */ @@ -31,6 +32,17 @@ function file_uri_scheme($uri) { return FALSE; } +} +if (!function_exists('file_url_transform_relative')) { + + /** + * Temporary mock of file_url_transform_relative, until that is moved into + * Component/Utility. + */ + function file_url_transform_relative($uri) { + return 'file_url_transform_relative:' . $uri; + } + } } @@ -48,6 +60,11 @@ function file_uri_scheme($uri) { */ class CssOptimizerUnitTest extends UnitTestCase { + /** + * {@inheritdoc} + */ + protected $backupGlobals = FALSE; + /** * A CSS asset optimizer. * @@ -65,7 +82,8 @@ protected function setUp() { * Provides data for the CSS asset optimizing test. */ function providerTestOptimize() { - $path = dirname(__FILE__) . '/css_test_files/'; + $path = 'core/tests/Drupal/Tests/Core/Asset/css_test_files/'; + $absolute_path = dirname(__FILE__) . '/css_test_files/'; return array( // File. Tests: // - Stripped comments and white-space. @@ -82,7 +100,7 @@ function providerTestOptimize() { 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'basename' => 'css_input_without_import.css', ), - file_get_contents($path . 'css_input_without_import.css.optimized.css'), + file_get_contents($absolute_path . 'css_input_without_import.css.optimized.css'), ), // File. Tests: // - Proper URLs in imported files. (https://www.drupal.org/node/265719) @@ -102,7 +120,7 @@ function providerTestOptimize() { 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'basename' => 'css_input_with_import.css', ), - str_replace('url(images/icon.png)', 'url(' . file_create_url($path . 'images/icon.png') . ')', file_get_contents($path . 'css_input_with_import.css.optimized.css')), + str_replace('url(images/icon.png)', 'url(' . file_url_transform_relative(file_create_url($path . 'images/icon.png')) . ')', file_get_contents($absolute_path . 'css_input_with_import.css.optimized.css')), ), // File. Tests: // - Retain comment hacks. @@ -117,7 +135,7 @@ function providerTestOptimize() { 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'basename' => 'comment_hacks.css', ), - file_get_contents($path . 'comment_hacks.css.optimized.css'), + file_get_contents($absolute_path . 'comment_hacks.css.optimized.css'), ), // File in subfolder. Tests: // - CSS import path is properly interpreted. @@ -134,7 +152,7 @@ function providerTestOptimize() { 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'basename' => 'css_input_with_import.css', ), - str_replace('url(../images/icon.png)', 'url(' . file_create_url($path . 'images/icon.png') . ')', file_get_contents($path . 'css_subfolder/css_input_with_import.css.optimized.css')), + str_replace('url(../images/icon.png)', 'url(' . file_url_transform_relative(file_create_url($path . 'images/icon.png')) . ')', file_get_contents($absolute_path . 'css_subfolder/css_input_with_import.css.optimized.css')), ), // File. Tests: // - Any @charaset declaration at the beginning of a file should be @@ -150,7 +168,7 @@ function providerTestOptimize() { 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'basename' => 'charset_sameline.css', ), - file_get_contents($path . 'charset.css.optimized.css'), + file_get_contents($absolute_path . 'charset.css.optimized.css'), ), array( array( @@ -163,7 +181,7 @@ function providerTestOptimize() { 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'basename' => 'charset_newline.css', ), - file_get_contents($path . 'charset.css.optimized.css'), + file_get_contents($absolute_path . 'charset.css.optimized.css'), ), array( array( @@ -226,7 +244,18 @@ function providerTestOptimize() { * @dataProvider providerTestOptimize */ function testOptimize($css_asset, $expected) { + global $base_path; + $original_base_path = $base_path; + $base_path = '/'; + + // \Drupal\Core\Asset\CssOptimizer::loadFile() relies on the current working + // directory being the one that is used when index.php is the entry point. + // Note: PHPUnit automatically restores the original working directory. + chdir(realpath(__DIR__ . '/../../../../../../')); + $this->assertEquals($expected, $this->optimizer->optimize($css_asset), 'Group of file CSS assets optimized correctly.'); + + $base_path = $original_base_path; } /**