Commit 76f7a155 authored by TravisCarden's avatar TravisCarden

Issue #2944103 by quiron, TravisCarden: Use State API instead of Configuration...

Issue #2944103 by quiron, TravisCarden: Use State API instead of Configuration API to store checklist progress.
parent 1ac1b191
......@@ -35,6 +35,9 @@
* - #menu_name: (optional) The machine name of a menu to place the checklist
* into (e.g., "main-menu" or "navigation"). If this is omitted, Drupal will
* try to infer the correct menu placement from the specified path.
* - #storage: (optional) The storage backend for saving checklist progress.
* Allowed values are "config" and "state" for the Configuration and State
* systems respectively.
* - #weight: (optional) A floating point number used to sort the list of
* checklists before being output. Lower numbers appear before higher
* numbers.
......
......@@ -3,3 +3,9 @@ services:
class: Drupal\checklistapi\Access\ChecklistapiAccessCheck
tags:
- { name: access_check, applies_to: _checklistapi_access }
checklistapi_storage.config:
class: Drupal\checklistapi\Storage\ConfigStorage
arguments: ['@config.factory']
checklistapi_storage.state:
class: Drupal\checklistapi\Storage\StateStorage
arguments: ['@state']
......@@ -9,7 +9,29 @@
* Implements hook_uninstall().
*/
function checklistapiexample_uninstall() {
\Drupal::configFactory()
->getEditable("checklistapi.progress.example_checklist")
->delete();
/** @var \Drupal\checklistapi\Storage\StateStorage $storage */
$storage = \Drupal::service('checklistapi_storage.state');
$storage->setChecklistId('example_checklist')->deleteSavedProgress();
}
/**
* Move saved progress from old config storage to new state storage.
*/
function checklistapiexample_update_8101() {
$checklist_id = 'example_checklist';
// Get saved progress from old config storage.
/** @var \Drupal\checklistapi\Storage\ConfigStorage $old_config_storage */
$old_config_storage = \Drupal::service('checklistapi_storage.config');
$saved_progress = $old_config_storage->setChecklistId($checklist_id)
->getSavedProgress();
// Copy saved progress to new state storage.
/** @var \Drupal\checklistapi\Storage\StateStorage $new_state_storage */
$new_state_storage = \Drupal::service('checklistapi_storage.state');
$new_state_storage->setChecklistId($checklist_id)
->setSavedProgress($saved_progress);
// Delete old config storage.
$old_config_storage->deleteSavedProgress();
}
......@@ -22,6 +22,7 @@ function checklistapiexample_checklistapi_checklist_info() {
'#callback' => 'checklistapiexample_checklistapi_checklist_items',
'#description' => t('An example implementation of the Checklist API.'),
'#help' => t('<p>This checklist based on <a href="http://buytaert.net/drupal-learning-curve">Dries Buytaert\'s Drupal learning curve</a> is an example implementation of the <a href="http://drupal.org/project/checklistapi">Checklist API</a>.</p>'),
'#storage' => 'state',
];
return $definitions;
}
......
......@@ -14,6 +14,8 @@ class ChecklistapiChecklist {
/**
* The configuration key for saved progress.
*
* @deprecated since version 8.x-1.9, to be removed in 8.x-2.0.
*/
const PROGRESS_CONFIG_KEY = 'progress';
......@@ -59,6 +61,13 @@ class ChecklistapiChecklist {
*/
public $menuName;
/**
* The storage backend for saved progress.
*
* @var \Drupal\checklistapi\Storage\StorageInterface
*/
private $storage;
/**
* The checklist weight.
*
......@@ -91,6 +100,8 @@ class ChecklistapiChecklist {
* The configuration object for saving progress.
*
* @var \Drupal\Core\Config\Config
*
* @deprecated since version 8.x-1.9, to be removed in 8.x-2.0.
*/
public $config;
......@@ -107,22 +118,31 @@ class ChecklistapiChecklist {
unset($definition[$group_key]);
}
foreach ($definition as $property_key => $value) {
if ($property_key === '#storage') {
continue;
}
$property_name = checklistapi_strtolowercamel(Unicode::substr($property_key, 1));
$this->$property_name = $value;
}
$this->config = \Drupal::configFactory()->getEditable("checklistapi.progress.{$this->id}");
$this->savedProgress = $this->config->get($this::PROGRESS_CONFIG_KEY);
$storage = 'config';
$allowed_storage_values = ['config', 'state'];
if (isset($definition['#storage']) && in_array($definition['#storage'], $allowed_storage_values)) {
$storage = $definition['#storage'];
}
$this->storage = \Drupal::service("checklistapi_storage.{$storage}")
->setChecklistId($this->id);
$this->savedProgress = $this->storage->getSavedProgress();
}
/**
* Clears the saved progress for the checklist.
*
* Deletes the Drupal configuration object containing the checklist's saved
* progress.
* Deletes the storage object containing the checklist's saved progress.
*/
public function clearSavedProgress() {
$this->config->delete();
$this->storage->deleteSavedProgress();
drupal_set_message(t('%title saved progress has been cleared.', [
'%title' => $this->title,
......@@ -217,7 +237,7 @@ class ChecklistapiChecklist {
* TRUE if the checklist has saved progress, or FALSE if it doesn't.
*/
public function hasSavedProgress() {
return (bool) $this->config->get($this::PROGRESS_CONFIG_KEY);
return (bool) $this->storage->getSavedProgress();
}
/**
......@@ -287,7 +307,7 @@ class ChecklistapiChecklist {
// configuration files.
ksort($progress);
$this->config->set($this::PROGRESS_CONFIG_KEY, $progress)->save();
$this->storage->setSavedProgress($progress);
drupal_set_message(\Drupal::translation()->formatPlural(
$num_changed_items,
'%title progress has been saved. 1 item changed.',
......
<?php
namespace Drupal\checklistapi\Storage;
use Drupal\Core\Config\ConfigFactoryInterface;
/**
* Provides config-based checklist progress storage.
*/
class ConfigStorage extends StorageBase {
/**
* The configuration key for saved progress.
*/
const CONFIG_KEY = 'progress';
/**
* The config object.
*
* @var \Drupal\Core\Config\Config|null
*/
private $config;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
private $configFactory;
/**
* Constructs a class instance.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
*/
public function __construct(ConfigFactoryInterface $config_factory) {
$this->configFactory = $config_factory;
}
/**
* {@inheritdoc}
*/
public function getSavedProgress() {
return $this->getConfig()->get(self::CONFIG_KEY);
}
/**
* {@inheritdoc}
*/
public function setSavedProgress(array $progress) {
$this->getConfig()->set(self::CONFIG_KEY, $progress)->save();
}
/**
* {@inheritdoc}
*/
public function deleteSavedProgress() {
$this->getConfig()->delete();
}
/**
* Gets the config object.
*
* @return \Drupal\Core\Config\Config
* Returns the config object.
*/
private function getConfig() {
if (empty($this->config)) {
$this->config = $this->configFactory
->getEditable("checklistapi.progress.{$this->getChecklistId()}");
}
return $this->config;
}
}
<?php
namespace Drupal\checklistapi\Storage;
use Drupal\Core\State\StateInterface;
/**
* Provides state-based checklist progress storage.
*/
class StateStorage extends StorageBase {
/**
* The state service.
*
* @var \Drupal\Core\State\StateInterface
*/
private $state;
/**
* Constructs a class instance.
*
* @param \Drupal\Core\State\StateInterface $state
* The state service.
*/
public function __construct(StateInterface $state) {
$this->state = $state;
}
/**
* {@inheritdoc}
*/
public function getSavedProgress() {
return $this->state->get($this->stateKey());
}
/**
* {@inheritdoc}
*/
public function setSavedProgress(array $progress) {
$this->state->set($this->stateKey(), $progress);
}
/**
* {@inheritdoc}
*/
public function deleteSavedProgress() {
$this->state->delete($this->stateKey());
}
/**
* Returns the state key.
*
* @return string
* The state key.
*/
private function stateKey() {
return 'checklistapi.progress.' . $this->getChecklistId();
}
}
<?php
namespace Drupal\checklistapi\Storage;
/**
* Provides a base storage implementation for others to extend.
*/
abstract class StorageBase implements StorageInterface {
/**
* The checklist ID.
*
* @var string
*/
private $checklistId;
/**
* Sets the checklist ID.
*
* @param string $id
* The checklist ID.
*
* @return self
* The storage object.
*/
public function setChecklistId($id) {
if (!is_string($id)) {
throw new \InvalidArgumentException('A checklist ID must be a string.');
}
$this->checklistId = $id;
return $this;
}
/**
* Gets the checklist ID.
*
* @return string
* Returns the checklist ID.
*/
protected function getChecklistId() {
if (empty($this->checklistId)) {
throw new \LogicException('You must set the checklist ID before accessing saved progress.');
}
return $this->checklistId;
}
}
<?php
namespace Drupal\checklistapi\Storage;
/**
* Provides an interface for checklist storage.
*/
interface StorageInterface {
/**
* Sets the checklist ID.
*
* @param string $id
* The checklist ID.
*/
public function setChecklistId($id);
/**
* Gets the saved checklist progress.
*
* @return mixed
* The stored value, or NULL if no value exists.
*/
public function getSavedProgress();
/**
* Sets the saved checklist progress.
*
* @param array $progress
* An array of checklist progress data as built by ChecklistapiChecklist.
*/
public function setSavedProgress(array $progress);
/**
* Deletes the saved checklist progress.
*/
public function deleteSavedProgress();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment