diff --git a/core/includes/theme.inc b/core/includes/theme.inc index c77ddd0..36d7cc1 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1394,6 +1394,17 @@ function theme_get_setting($setting_name, $theme = NULL) { } } + // A dummy query-string is added to filenames, to gain control over + // browser-caching. The string changes on every update or full cache + // flush, forcing browsers to load a new copy of the files, as the + // URL changed. + try { + $query_string = \Drupal::state()->get('system.css_js_query_string') ?: '0'; + } + catch(Exception $e) { + $query_string = '0'; + } + // Generate the path to the logo image. if ($cache[$theme]->get('features.logo')) { $logo_path = $cache[$theme]->get('logo.path'); @@ -1401,7 +1412,8 @@ function theme_get_setting($setting_name, $theme = NULL) { $cache[$theme]->set('logo.url', file_create_url(dirname($theme_object->filename) . '/logo.png')); } elseif ($logo_path) { - $cache[$theme]->set('logo.url', file_create_url($logo_path)); + $query_string_separator = (strpos($logo_path, '?') !== FALSE) ? '&' : '?'; + $cache[$theme]->set('logo.url', file_create_url($logo_path) . $query_string_separator . $query_string); } } @@ -1422,6 +1434,10 @@ function theme_get_setting($setting_name, $theme = NULL) { else { $cache[$theme]->set('features.favicon', FALSE); } + if (!empty($favicon_path)) { + $query_string_separator = (strpos($favicon_path, '?') !== FALSE) ? '&' : '?'; + $cache[$theme]['favicon'] = $favicon_path . $query_string_separator . $query_string; + } } } } diff --git a/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php index 9a13acb..bafcd9b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php @@ -49,31 +49,39 @@ function testThemeSettings() { $file_relative = strtr($file->uri, array('public:/' => PublicStream::basePath())); $default_theme_path = 'core/themes/stark'; + // Logos and favicons receive a query string. + try { + $query_string = \Drupal::state()->get('system.css_js_query_string') ?: '0'; + } + catch(Exception $e) { + $query_string = '0'; + } + $supported_paths = array( // Raw stream wrapper URI. $file->uri => array( 'form' => file_uri_target($file->uri), - 'src' => file_create_url($file->uri), + 'src' => file_create_url($file->uri) . '?' . $query_string, ), // 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_create_url($file->uri) . '?' . $query_string, ), // Relative path to a public file. $file_relative => array( 'form' => $file_relative, - 'src' => file_create_url($file->uri), + 'src' => file_create_url($file->uri) . '?' . $query_string, ), // 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' => $GLOBALS['base_url'] . '/' . 'core/misc/druplicon.png' . '?' . $query_string, ), // Relative path to a file in a theme. $default_theme_path . '/logo.png' => array( 'form' => $default_theme_path . '/logo.png', - 'src' => $GLOBALS['base_url'] . '/' . $default_theme_path . '/logo.png', + 'src' => $GLOBALS['base_url'] . '/' . $default_theme_path . '/logo.png' . '?' . $query_string, ), ); foreach ($supported_paths as $input => $expected) { @@ -171,7 +179,7 @@ function testThemeSettings() { ':rel' => 'home', ) ); - $this->assertEqual($elements[0]['src'], file_create_url($uploaded_filename)); + $this->assertEqual($elements[0]['src'], file_create_url($uploaded_filename) . '?' . $query_string); } /**