diff --git a/core/core.services.yml b/core/core.services.yml index ac24e17..ab1fce5 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -114,7 +114,7 @@ services: arguments: ['@service_container', '@settings'] keyvalue.database: class: Drupal\Core\KeyValueStore\KeyValueDatabaseFactory - arguments: ['@database'] + arguments: ['@serialization.phpserialize', '@database'] keyvalue.expirable: class: Drupal\Core\KeyValueStore\KeyValueExpirableFactory arguments: ['@service_container', '@settings'] @@ -123,6 +123,10 @@ services: tags: - { name: needs_destruction } arguments: ['@database'] + + serialization.phpserialize: + class: Drupal\Core\Serialization\PhpSerialize + settings: class: Drupal\Component\Utility\Settings factory_class: Drupal\Component\Utility\Settings diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php index b0791e2..bd6daae 100644 --- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php +++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php @@ -9,6 +9,7 @@ use Drupal\Core\Database\Query\Merge; use Drupal\Core\Database\Connection; +use Drupal\Core\Serialization\SerializationInterface; /** * Defines a default key/value store implementation. @@ -37,11 +38,13 @@ class DatabaseStorage extends StorageBase { * * @param string $collection * The name of the collection holding key and value pairs. + * @param \Drupal\Core\Serialization\SerializationInterface $format + * The serialization format to use. * @param string $table * The name of the SQL table to use, defaults to key_value. */ - public function __construct($collection, Connection $connection, $table = 'key_value') { - parent::__construct($collection); + public function __construct($collection, SerializationInterface $format, Connection $connection, $table = 'key_value') { + parent::__construct($collection, $format); $this->connection = $connection; $this->table = $table; } @@ -55,7 +58,7 @@ public function getMultiple(array $keys) { $result = $this->connection->query('SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE name IN (:keys) AND collection = :collection', array(':keys' => $keys, ':collection' => $this->collection))->fetchAllAssoc('name'); foreach ($keys as $key) { if (isset($result[$key])) { - $values[$key] = unserialize($result[$key]->value); + $values[$key] = $this->format->decode($result[$key]->value); } } } @@ -76,7 +79,7 @@ public function getAll() { foreach ($result as $item) { if ($item) { - $values[$item->name] = unserialize($item->value); + $values[$item->name] = $this->format->decode($item->value); } } return $values; @@ -91,7 +94,7 @@ public function set($key, $value) { 'name' => $key, 'collection' => $this->collection, )) - ->fields(array('value' => serialize($value))) + ->fields(array('value' => $this->format->encode($value))) ->execute(); } @@ -103,7 +106,7 @@ public function setIfNotExists($key, $value) { ->insertFields(array( 'collection' => $this->collection, 'name' => $key, - 'value' => serialize($value), + 'value' => $this->format->encode($value), )) ->condition('collection', $this->collection) ->condition('name', $key) diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php index 91e7752..540e9e1 100644 --- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php +++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php @@ -10,6 +10,7 @@ use Drupal\Core\DestructableInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Database\Query\Merge; +use Drupal\Core\Serialization\PhpSerialize; /** * Defines a default key/value store implementation for expiring items. @@ -20,13 +21,6 @@ class DatabaseStorageExpirable extends DatabaseStorage implements KeyValueStoreExpirableInterface, DestructableInterface { /** - * The connection object for this storage. - * - * @var \Drupal\Core\Database\Connection - */ - protected $connection; - - /** * Flag indicating whether garbage collection should be performed. * * When this flag is TRUE, garbage collection happens at the end of the @@ -53,7 +47,7 @@ class DatabaseStorageExpirable extends DatabaseStorage implements KeyValueStoreE * key_value_expire. */ public function __construct($collection, Connection $connection, $table = 'key_value_expire') { - parent::__construct($collection, $connection, $table); + parent::__construct($collection, new PhpSerialize(), $connection, $table); } /** @@ -67,7 +61,7 @@ public function getMultiple(array $keys) { ':keys' => $keys, ':collection' => $this->collection, ))->fetchAllKeyed(); - return array_map('unserialize', $values); + return array_map(array($this->format, 'decode'), $values); } /** @@ -80,7 +74,7 @@ public function getAll() { ':collection' => $this->collection, ':now' => REQUEST_TIME ))->fetchAllKeyed(); - return array_map('unserialize', $values); + return array_map(array($this->format, 'decode'), $values); } /** @@ -96,7 +90,7 @@ function setWithExpire($key, $value, $expire) { 'collection' => $this->collection, )) ->fields(array( - 'value' => serialize($value), + 'value' => $this->format->encode($value), 'expire' => REQUEST_TIME + $expire, )) ->execute(); @@ -113,7 +107,7 @@ function setWithExpireIfNotExists($key, $value, $expire) { ->insertFields(array( 'collection' => $this->collection, 'name' => $key, - 'value' => serialize($value), + 'value' => $this->format->encode($value), 'expire' => REQUEST_TIME + $expire, )) ->condition('collection', $this->collection) diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php index 1a840b3..22f4500 100644 --- a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php +++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php @@ -6,8 +6,10 @@ */ namespace Drupal\Core\KeyValueStore; + use Drupal\Core\Database\Connection; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\SerializationInterface; /** * Defines the key/value store factory for the database backend. @@ -15,13 +17,29 @@ class KeyValueDatabaseFactory implements KeyValueFactoryInterface { /** - * Constructs this factory object. + * The serialization format to use. + * + * @var \Drupal\Core\Serialization\SerializationInterface + */ + protected $format; + + /** + * The database connection to use. * + * @var \Drupal\Core\Database\Connection + */ + protected $connection; + + /** + * Constructs this factory object. * + * @param \Drupal\Core\Serialization\SerializationInterface $format + * The serialization format to use. * @param \Drupal\Core\Database\Connection $connection * The Connection object containing the key-value tables. */ - function __construct(Connection $connection) { + function __construct(SerializationInterface $format, Connection $connection) { + $this->format = $format; $this->connection = $connection; } @@ -29,6 +47,6 @@ function __construct(Connection $connection) { * {@inheritdoc} */ public function get($collection) { - return new DatabaseStorage($collection, $this->connection); + return new DatabaseStorage($collection, $this->format, $this->connection); } } diff --git a/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php index e6e07ef..fec8a1e 100644 --- a/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php +++ b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php @@ -20,6 +20,13 @@ class MemoryStorage extends StorageBase { protected $data = array(); /** + * Overrides \Drupal\Core\KeyValueStore\StorageBase::__construct(). + */ + public function __construct($collection) { + $this->collection = $collection; + } + + /** * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::get(). */ public function get($key, $default = NULL) { diff --git a/core/lib/Drupal/Core/KeyValueStore/StorageBase.php b/core/lib/Drupal/Core/KeyValueStore/StorageBase.php index 4c54271..b302896 100644 --- a/core/lib/Drupal/Core/KeyValueStore/StorageBase.php +++ b/core/lib/Drupal/Core/KeyValueStore/StorageBase.php @@ -7,6 +7,8 @@ namespace Drupal\Core\KeyValueStore; +use Drupal\Core\Serialization\SerializationInterface; + /** * Provides a base class for key/value storage implementations. */ @@ -20,10 +22,18 @@ protected $collection; /** + * The serialization format to use. + * + * @var \Drupal\Core\Serialization\SerializationInterface + */ + protected $format; + + /** * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::__construct(). */ - public function __construct($collection) { + public function __construct($collection, SerializationInterface $format) { $this->collection = $collection; + $this->format = $format; } /** diff --git a/core/lib/Drupal/Core/Serialization/Exception/InvalidDataTypeException.php b/core/lib/Drupal/Core/Serialization/Exception/InvalidDataTypeException.php new file mode 100644 index 0000000..e6b8ce6 --- /dev/null +++ b/core/lib/Drupal/Core/Serialization/Exception/InvalidDataTypeException.php @@ -0,0 +1,14 @@ +addArgument('default'); $this->container ->register('keyvalue.database', 'Drupal\Core\KeyValueStore\KeyValueDatabaseFactory') + ->addArgument(new Reference('serialization.phpserialize')) ->addArgument(new Reference('database')); + $this->container + ->register('serialization.phpserialize', 'Drupal\Core\Serialization\PhpSerialize'); $this->settingsSet('keyvalue_default', 'keyvalue.database'); }