diff --git a/core/core.services.yml b/core/core.services.yml index 1b0d520..f8c5b36 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -619,6 +619,7 @@ services: scope: request asset.css.collection_renderer: class: Drupal\Core\Asset\CssCollectionRenderer + arguments: [ '@state' ] asset.css.collection_optimizer: class: Drupal\Core\Asset\CssCollectionOptimizer arguments: [ '@asset.css.collection_grouper', '@asset.css.optimizer', '@asset.css.dumper', '@state' ] @@ -630,6 +631,7 @@ services: class: Drupal\Core\Asset\AssetDumper asset.js.collection_renderer: class: Drupal\Core\Asset\JsCollectionRenderer + arguments: [ '@state' ] asset.js.collection_optimizer: class: Drupal\Core\Asset\JsCollectionOptimizer arguments: [ '@asset.js.collection_grouper', '@asset.js.optimizer', '@asset.js.dumper', '@state' ] diff --git a/core/includes/common.inc b/core/includes/common.inc index df552ed..2048ab4 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -4845,7 +4845,7 @@ function drupal_flush_all_caches() { */ function _drupal_flush_css_js() { // The timestamp is converted to base 36 in order to make it more compact. - variable_set('css_js_query_string', base_convert(REQUEST_TIME, 10, 36)); + Drupal::state()->set('system.css_js_query_string', base_convert(REQUEST_TIME, 10, 36)); } /** diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 91a241f..644ec57 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -423,6 +423,13 @@ function install_begin_request(&$install_state) { )) ->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)')); + $container->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory') + ->addArgument(new Reference('service_container')); + $container->register('keyvalue.memory', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory'); + // Override the default keyvalue storage to use memory as the database is + // not available. + $conf['keyvalue_default'] = 'keyvalue.memory'; + // Register the expirable key value store used by form cache. $container ->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueExpirableFactory') @@ -431,6 +438,11 @@ function install_begin_request(&$install_state) { ->register('keyvalue.expirable.null', 'Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory'); $conf['keyvalue_expirable_default'] = 'keyvalue.expirable.null'; + $container->register('state', 'Drupal\Core\KeyValueStore\KeyValueStoreInterface') + ->setFactoryService(new Reference('keyvalue')) + ->setFactoryMethod('get') + ->addArgument('state'); + // Register Twig template engine for use during install. CoreServiceProvider::registerTwig($container); @@ -440,8 +452,10 @@ function install_begin_request(&$install_state) { CoreServiceProvider::registerUuid($container); // Register the CSS and JavaScript asset collection renderers. - $container->register('asset.css.collection_renderer', 'Drupal\Core\Asset\CssCollectionRenderer'); - $container->register('asset.js.collection_renderer', 'Drupal\Core\Asset\JsCollectionRenderer'); + $container->register('asset.css.collection_renderer', 'Drupal\Core\Asset\CssCollectionRenderer') + ->addArgument(new Reference('state')); + $container->register('asset.js.collection_renderer', 'Drupal\Core\Asset\JsCollectionRenderer') + ->addArgument(new Reference('state')); } // Set the request in the kernel to the new created Request above @@ -1205,7 +1219,7 @@ function install_database_errors($database, $settings_file) { * @see install_settings_form_validate() */ function install_settings_form_submit($form, &$form_state) { - global $install_state; + global $install_state, $conf; // Update global settings array and save. $settings = array(); @@ -1251,6 +1265,10 @@ function install_settings_form_submit($form, &$form_state) { // Add the config directories to settings.php. drupal_install_config_directories(); + // The container is about to be rebuilt so we need to unset the keyvalue + // storage override that the installer is using. + unset($conf['keyvalue_default']); + // Indicate that the settings file has been verified, and check the database // for the last completed task, now that we have a valid connection. This // last step is important since we want to trigger an error if the new diff --git a/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php b/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php index 6d36ede..09846c1 100644 --- a/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php +++ b/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Asset; use Drupal\Core\Asset\AssetCollectionRendererInterface; +use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Component\Utility\String; /** @@ -15,6 +16,23 @@ class CssCollectionRenderer implements AssetCollectionRendererInterface { /** + * The state key/value store. + * + * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface + */ + protected $state; + + /** + * Constructs a CssCollectionRenderer. + * + * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface + * The state key/value store. + */ + public function __construct(KeyValueStoreInterface $state) { + $this->state = $state; + } + + /** * {@inheritdoc} */ public function render(array $css_assets) { @@ -24,7 +42,7 @@ public function render(array $css_assets) { // 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. - $query_string = variable_get('css_js_query_string', '0'); + $query_string = $this->state->get('system.css_js_query_string') ?: '0'; // Defaults for LINK and STYLE elements. $link_element_defaults = array( diff --git a/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php b/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php index b9f6582..e739d1c 100644 --- a/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php +++ b/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Asset; use Drupal\Core\Asset\AssetCollectionRendererInterface; +use Drupal\Core\KeyValueStore\KeyValueStoreInterface; /** * Renders JavaScript assets. @@ -14,6 +15,23 @@ class JsCollectionRenderer implements AssetCollectionRendererInterface { /** + * The state key/value store. + * + * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface + */ + protected $state; + + /** + * Constructs a CssCollectionRenderer. + * + * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface + * The state key/value store. + */ + public function __construct(KeyValueStoreInterface $state) { + $this->state = $state; + } + + /** * {@inheritdoc} */ public function render(array $js_assets) { @@ -25,7 +43,7 @@ public function render(array $js_assets) { // URL changed. Files that should not be cached (see drupal_add_js()) // get REQUEST_TIME as query-string instead, to enforce reload on every // page request. - $default_query_string = variable_get('css_js_query_string', '0'); + $default_query_string = $this->state->get('system.css_js_query_string') ?: '0'; // For inline JavaScript to validate as XHTML, all JavaScript containing // XHTML needs to be wrapped in CDATA. To make that backwards compatible diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php index 54abcba..052ea57 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php @@ -78,7 +78,7 @@ function testRenderFile() { $styles = drupal_get_css(); $this->assertTrue(strpos($styles, $css) > 0, 'Rendered CSS includes the added stylesheet.'); // Verify that newlines are properly added inside style tags. - $query_string = variable_get('css_js_query_string', '0'); + $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; $css_processed = ''; $this->assertEqual(trim($styles), $css_processed, 'Rendered CSS includes newlines inside style tags for JavaScript use.'); } @@ -184,7 +184,7 @@ function testAddCssFileWithQueryString() { drupal_add_css($css_with_query_string); $styles = drupal_get_css(); - $query_string = variable_get('css_js_query_string', '0'); + $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; $this->assertTrue(strpos($styles, $css_without_query_string . '?' . $query_string), 'Query string was appended correctly to css.'); $this->assertTrue(strpos($styles, str_replace('&', '&', $css_with_query_string)), 'Query string not escaped on a URI.'); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php index 7c47046..2d3d87b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php @@ -101,7 +101,7 @@ function testAddExternal() { * Tests adding JavaScript files with additional attributes. */ function testAttributes() { - $default_query_string = variable_get('css_js_query_string', '0'); + $default_query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; drupal_add_library('system', 'drupal'); drupal_add_js('http://example.com/script.js', array('attributes' => array('defer' => 'defer'))); @@ -122,7 +122,7 @@ function testAggregatedAttributes() { // Enable aggregation. \Drupal::config('system.performance')->set('js.preprocess', 1)->save(); - $default_query_string = variable_get('css_js_query_string', '0'); + $default_query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; drupal_add_library('system', 'drupal'); drupal_add_js('http://example.com/script.js', array('attributes' => array('defer' => 'defer'))); @@ -275,7 +275,7 @@ function testDifferentWeight() { * @see drupal_pre_render_conditional_comments() */ function testBrowserConditionalComments() { - $default_query_string = variable_get('css_js_query_string', '0'); + $default_query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; drupal_add_library('system', 'drupal'); drupal_add_js('core/misc/collapse.js', array('browsers' => array('IE' => 'lte IE 8', '!IE' => FALSE))); @@ -304,7 +304,7 @@ function testVersionQueryString() { * Tests JavaScript grouping and aggregation. */ function testAggregation() { - $default_query_string = variable_get('css_js_query_string', '0'); + $default_query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; // To optimize aggregation, items with the 'every_page' option are ordered // ahead of ones without. The order of JavaScript execution must be the @@ -563,7 +563,7 @@ function testAddJsFileWithQueryString() { $js = drupal_get_path('module', 'node') . '/node.js'; drupal_add_js($js); - $query_string = variable_get('css_js_query_string', '0'); + $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; $scripts = drupal_get_js(); $this->assertTrue(strpos($scripts, $js . '?' . $query_string), 'Query string was appended correctly to JS.'); } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 596122b..3742dde 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1749,12 +1749,13 @@ function system_update_8031() { } /** - * Remove the drupal_js_cache_files variable. + * Remove the drupal_js_cache_files and css_js_query_string variables. * * @ingroup config_upgrade */ function system_update_8032() { update_variable_del('drupal_js_cache_files'); + update_variable_del('css_js_query_string'); } /** diff --git a/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php b/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php index 6fcb055..d8e3a32 100644 --- a/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php @@ -25,14 +25,6 @@ function file_create_url($uri) { } -if (!function_exists('variable_get')) { - - function variable_get($variable, $default) { - return $default; - } - -} - } @@ -71,6 +63,13 @@ class CssCollectionRendererUnitTest extends UnitTestCase { */ protected $inline_css_group; + /** + * The state mock class. + * + * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $state; + public static function getInfo() { return array( 'name' => 'CSS asset collection renderer functionality', @@ -82,7 +81,9 @@ public static function getInfo() { function setUp() { parent::setUp(); - $this->renderer = new CssCollectionRenderer(); + $this->state = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreInterface'); + + $this->renderer = new CssCollectionRenderer($this->state); $this->file_css_group = array( 'group' => -100, 'every_page' => TRUE, @@ -540,6 +541,10 @@ function testRenderProvider() { * @dataProvider testRenderProvider */ function testRender(array $css_assets, array $render_elements) { + $this->state->expects($this->once()) + ->method('get') + ->with('system.css_js_query_string') + ->will($this->returnValue(NULL)); $this->assertSame($render_elements, $this->renderer->render($css_assets)); } @@ -547,6 +552,10 @@ function testRender(array $css_assets, array $render_elements) { * Tests a CSS asset group with the invalid 'type' => 'internal'. */ function testRenderInvalidType() { + $this->state->expects($this->once()) + ->method('get') + ->with('system.css_js_query_string') + ->will($this->returnValue(NULL)); $this->setExpectedException('Exception', 'Invalid CSS asset type.'); $css_group = array(