diff -u b/core/includes/bootstrap.inc b/core/includes/bootstrap.inc --- b/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2514,6 +2514,12 @@ /** * Returns the state storage service. * + * Use this to store machine-generated data, local to a specific environment + * that does not need deploying and does not need human editing; for example, + * the last time cron was run. Data which needs to be edited by humans and + * needs to be the same across development, production, etc. environments + * (for example, the system maintenance message) should use config() instead. + * * @return Drupal\Core\KeyValueStore\KeyValueStoreInterface */ function state() { diff -u b/core/includes/menu.inc b/core/includes/menu.inc --- b/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -318,7 +318,7 @@ $ancestors = array(); $length = $number_parts - 1; $end = (1 << $number_parts) - 1; - $masks = variable_get('menu_masks'); + $masks = state()->get('menu_masks'); // If the optimized menu_masks array is not available use brute force to get // the correct $ancestors and $placeholders returned. Do not use this as the // default value of the menu_masks variable to avoid building such a big @@ -451,7 +451,7 @@ if (!isset($router_items[$path])) { // Rebuild if we know it's needed, or if the menu masks are missing which // occurs rarely, likely due to a race condition of multiple rebuilds. - if (state()->get('menu_rebuild_needed') || !variable_get('menu_masks', array())) { + if (state()->get('menu_rebuild_needed') || !state()->get('menu_masks', array())) { menu_router_rebuild(); } $original_map = arg(NULL, $path); @@ -3776,7 +3776,7 @@ // Insert any remaining records. $insert->execute(); // Store the masks. - variable_set('menu_masks', $masks); + state()->set('menu_masks', $masks); return $menu; } diff -u b/core/includes/update.inc b/core/includes/update.inc --- b/core/includes/update.inc +++ b/core/includes/update.inc @@ -130,19 +130,19 @@ update_extra_requirements($requirements); if ($has_required_schema) { - if (!db_table_exists('keyvalue')) { + if (!db_table_exists('key_value')) { $specs = array( - 'description' => 'Generic key-value storage table.', + 'description' => 'Generic key-value storage table. See state() for an example.', 'fields' => array( - 'name' => array( - 'description' => 'The key.', + 'collection' => array( + 'description' => 'A named collection of key and value pairs.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', ), - 'collection' => array( - 'description' => 'The collection of the variable.', + 'name' => array( + 'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, diff -u b/core/lib/Drupal/Core/KeyValueStore/AbstractStorage.php b/core/lib/Drupal/Core/KeyValueStore/AbstractStorage.php --- b/core/lib/Drupal/Core/KeyValueStore/AbstractStorage.php +++ b/core/lib/Drupal/Core/KeyValueStore/AbstractStorage.php @@ -10,6 +10,8 @@ abstract class AbstractStorage implements KeyValueStoreInterface { /** + * The name of the collection holding key and value pairs. + * * @var string */ protected $collection; diff -u b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php --- b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php +++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php @@ -17,31 +17,38 @@ /** * Overrides Drupal\Core\KeyValueStore\AbstractStorage::__construct(). + * + * @param string $collection + * The name of the collection holding key and value pairs. + * @param array $options + * An associative array of options for the key/value storage collection. + * Keys used: + * - table. The name of the SQL table to use, defaults to key_value. */ public function __construct($collection, array $options = array()) { parent::__construct($collection, $options); - $this->table = isset($options['table']) ? $options['table'] : 'keyvalue'; + $this->table = isset($options['table']) ? $options['table'] : 'key_value'; } /** * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::getMultiple(). */ public function getMultiple(array $keys) { + $values = array(); try { $result = db_query('SELECT name, value FROM {' . db_escape_table($this->table) . '} WHERE name IN (:keys) AND collection = :collection', array(':keys' => $keys, ':collection' => $this->collection))->fetchAllAssoc('name'); - $values = array(); foreach ($keys as $key) { if (isset($result[$key])) { - $values[$key] = unserialize($result[$key]->value); + $values[$key] = unserialize($result[$key]->value); } } - return $values; } catch (\Exception $e) { - // If the database is never going to be available, key/value requests should - // return FALSE in order to allow exception handling to occur. - return array(); + // @todo: Perhaps ff the database is never going to be available, + // key/value requests should return FALSE in order to allow exception + // handling to occur but for now, keep it an array, always. } + return $values; } /** diff -u b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php --- b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php +++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php @@ -16,7 +16,7 @@ * Constructs a new key/value collection. * * @param string $collection - * The collection for which the object is created. + * The name of the collection holding key and value pairs. * @param array $options * An associative array of options for the key/value storage collection. */ diff -u b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php --- b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php +++ b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php @@ -15,6 +15,8 @@ class MemoryStorage implements KeyValueStoreInterface { /** + * The actual storage of key-value pairs. + * * @var array */ protected $data = array(); diff -u b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php --- b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php @@ -12,6 +12,11 @@ */ class DatabaseStorageTest extends StorageTestBase { + /** + * The name of the class to test. + * + * The tests themselves are in StorageTestBase and use this class. + */ protected $storageClass = 'Drupal\Core\KeyValueStore\DatabaseStorage'; public static function getInfo() { diff -u b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/MemoryStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/MemoryStorageTest.php --- b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/MemoryStorageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/MemoryStorageTest.php @@ -12,6 +12,11 @@ */ class MemoryStorageTest extends StorageTestBase { + /** + * The name of the class to test. + * + * The tests themselves are in StorageTestBase and use this class. + */ protected $storageClass = 'Drupal\Core\KeyValueStore\MemoryStorage'; public static function getInfo() { diff -u b/core/modules/system/system.install b/core/modules/system/system.install --- b/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -866,18 +866,18 @@ ), ); - $schema['keyvalue'] = array( - 'description' => 'Generic key-value storage table.', + $schema['key_value'] = array( + 'description' => 'Generic key-value storage table. See state() for an example.', 'fields' => array( - 'name' => array( - 'description' => 'The key.', + 'collection' => array( + 'description' => 'A named collection of key and value pairs.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', ), - 'collection' => array( - 'description' => 'The collection of the variable.', + 'name' => array( + 'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE,