Commit 40cc21c8 authored by sun's avatar sun Committed by gdd

Fixed Image module tests. Added many critical todos:

- Config values are not casted to strings (despite promised).
- Config keys are not casted to strings (although promised, too).
- XML can be invalid and not parse-able for many reasons.
- Config keys are not validated/sanitized.
- config()->clear() should really be ->unset().
- Configuration must not be additionally cached by a module in any way (static cache / database cache).
- Some modules invoke drupal_alter() on configuration (e.g., image styles).
- Need a way to list config object names/suffixes _after_ a specified prefix.
- Need a way to determine whether a config object exists.
- Some modules might have a valid use-case for retrieving/listing config objects using a wildcard within the name (instead of only searching by prefix).
- The key of a retrieved value is unknown; since you only get the value.  Configuration values (or sub-values) may be passed forward to another function/callback, and thus, that function no longer knows about the key of the value. (unless the key is contained in the value, which is a very very wonky duplication)
- Config keys must not contain periods (within a specific key).
parent d74f856c
......@@ -188,7 +188,7 @@ function config_xml_to_array($data) {
}
foreach ($xmlObject as $index => $content) {
if (is_object($content)) {
$out[$index] = config_xml2array($content);
$out[$index] = config_xml_to_array($content);
}
}
......@@ -219,6 +219,8 @@ function config_encode($data) {
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml_object->asXML());
// @todo The loaded XML can be invalid; throwing plenty of PHP warnings but no
// catchable error.
return $dom->saveXML();
}
......@@ -246,7 +248,9 @@ function config_array_to_xml($array, &$xml_object) {
}
}
else {
$xml_object->addChild("$key", "$value");
// @todo Cast to string must happen in DrupalConfig::set() already. But
// over there, $value may also be an array, so the result is "Array".
$xml_object->addChild($key, (string) $value);
}
}
}
......@@ -5,4 +5,4 @@
/**
* @todo
*/
class ConfigException extends Exception {}
class ConfigException extends \Exception {}
......@@ -3,6 +3,7 @@
namespace Drupal\Core\Config;
use Drupal\Core\Config\DrupalConfigVerifiedStorageInterface;
use Drupal\Core\Config\ConfigException;
/**
* Represents the default configuration storage object.
......@@ -105,6 +106,13 @@ public function get($key = '') {
* @todo
*/
public function set($key, $value) {
// Remove all non-alphanumeric characters from the key.
// @todo Reverse this and throw an exception when encountering a key with
// invalid name. The identical validation also needs to happen in get().
// Furthermore, the dot/period is a reserved character; it may appear
// between keys, but not within keys.
$key = preg_replace('@[^a-zA-Z0-9_.-]@', '', $key);
$parts = explode('.', $key);
if (count($parts) == 1) {
$this->data[$key] = $value;
......@@ -119,6 +127,8 @@ public function set($key, $value) {
*
* @param $key
* @todo
*
* @todo Rename into unset().
*/
public function clear($key) {
$parts = explode('.', $key);
......
......@@ -22,87 +22,6 @@ function image_uninstall() {
file_unmanaged_delete_recursive(file_default_scheme() . '://styles');
}
/**
* Implements hook_schema().
*/
function image_schema() {
$schema = array();
$schema['image_styles'] = array(
'description' => 'Stores configuration options for image styles.',
'fields' => array(
'isid' => array(
'description' => 'The primary identifier for an image style.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'name' => array(
'description' => 'The style name.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
),
'primary key' => array('isid'),
'unique keys' => array(
'name' => array('name'),
),
);
$schema['image_effects'] = array(
'description' => 'Stores configuration options for image effects.',
'fields' => array(
'ieid' => array(
'description' => 'The primary identifier for an image effect.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'isid' => array(
'description' => 'The {image_styles}.isid for an image style.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'weight' => array(
'description' => 'The weight of the effect in the style.',
'type' => 'int',
'unsigned' => FALSE,
'not null' => TRUE,
'default' => 0,
),
'name' => array(
'description' => 'The unique name of the effect to be executed.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
'data' => array(
'description' => 'The configuration data for the effect.',
'type' => 'blob',
'not null' => TRUE,
'size' => 'big',
'serialize' => TRUE,
),
),
'primary key' => array('ieid'),
'indexes' => array(
'isid' => array('isid'),
'weight' => array('weight'),
),
'foreign keys' => array(
'image_style' => array(
'table' => 'image_styles',
'columns' => array('isid' => 'isid'),
),
),
);
return $schema;
}
/**
* Implements hook_field_schema().
*/
......
......@@ -435,33 +435,30 @@ function image_path_flush($path) {
* @see image_style_load()
*/
function image_styles() {
$styles = &drupal_static(__FUNCTION__);
// Grab from cache or build the array.
if (!isset($styles)) {
if ($cache = cache()->get('image_styles')) {
$styles = $cache->data;
}
else {
// @todo Configuration must not be statically cached nor cache-system cached.
// However, there's a drupal_alter() involved here.
// $styles = &drupal_static(__FUNCTION__);
//
// // Grab from cache or build the array.
// if (!isset($styles)) {
// if ($cache = cache()->get('image_styles')) {
// $styles = $cache->data;
// }
// else {
$styles = array();
// Select the styles we have configured.
foreach (config_get_signed_file_storage_names_with_prefix('image.styles') as $config_name) {
$style = array();
$config = config($config_name);
$style['name'] = $config->get('name');
$style['effects'] = array();
foreach ($config->get('effects') as $key => $effect) {
$definition = image_effect_definition_load($effect['name']);
$effect = array_merge($definition, $effect);
$style['effects'][$key] = $effect;
}
$configured_styles = config_get_verified_storage_names_with_prefix('image.styles');
foreach ($configured_styles as $config_name) {
// @todo Allow to retrieve the name without prefix only.
$style = image_style_load(str_replace('image.styles.', '', $config_name));
$styles[$style['name']] = $style;
}
drupal_alter('image_styles', $styles);
cache()->set('image_styles', $styles);
}
}
// cache()->set('image_styles', $styles);
// }
// }
return $styles;
}
......@@ -478,16 +475,24 @@ function image_styles() {
* If the image style name is not valid, an empty array is returned.
* @see image_effect_load()
*/
function image_style_load($name = NULL) {
$styles = image_styles();
function image_style_load($name) {
$style = config('image.styles.' . $name)->get();
// If retrieving by name.
if (isset($name) && isset($styles[$name])) {
return $styles[$name];
// @todo Requires a more reliable + generic method to check for whether the
// configuration object exists.
if (!isset($style['name'])) {
return FALSE;
}
// Otherwise the style was not found.
return FALSE;
foreach ($style['effects'] as $ieid => $effect) {
$definition = image_effect_definition_load($effect['name']);
$effect = array_merge($definition, $effect);
$style['effects'][$ieid] = $effect;
}
// Sort effects by weight.
uasort($style['effects'], 'drupal_sort_weight');
return $style;
}
/**
......@@ -508,6 +513,8 @@ function image_style_save($style) {
$config->set('effects', array());
}
$config->save();
// @todo is_new must only be set when the configuration object did not exist
// yet.
$style['is_new'] = TRUE;
// Let other modules update as necessary on save.
......@@ -554,8 +561,7 @@ function image_style_delete($style, $replacement_style_name = '') {
* format array('isid' => array()), or an empty array if the specified style
* has no effects.
*
* @todo I think this function can be deprecated since we automatically
* load all effects with a style now.
* @todo Remove this function; it's entirely obsolete.
*/
function image_style_effects($style) {
return $style['effects'];
......@@ -754,11 +760,11 @@ function image_style_flush($style) {
// Let other modules update as necessary on flush.
module_invoke_all('image_style_flush', $style);
// Clear image style and effect caches.
cache()->delete('image_styles');
cache()->deletePrefix('image_effects:');
drupal_static_reset('image_styles');
drupal_static_reset('image_effects');
// // Clear image style and effect caches.
// cache()->delete('image_styles');
// cache()->deletePrefix('image_effects:');
// drupal_static_reset('image_styles');
// drupal_static_reset('image_effects');
// Clear field caches so that formatters may be added for this style.
field_info_cache_clear();
......@@ -899,6 +905,8 @@ function image_effect_definition_load($effect) {
* @return
* An array of all image effects.
* @see image_effect_load()
*
* @todo Remove after moving/resolving the todo.
*/
function image_effects() {
$effects = &drupal_static(__FUNCTION__);
......@@ -907,6 +915,9 @@ function image_effects() {
$effects = array();
// Add database image effects.
// @todo Strictly speaking, this is obsolete. However, it demonstrates a
// use-case for retrieving/listing configuration objects using a wildcard
// within the name (instead of only the suffix).
$result = db_select('image_effects', NULL, array('fetch' => PDO::FETCH_ASSOC))
->fields('image_effects')
->orderBy('image_effects.weight', 'ASC')
......@@ -928,13 +939,11 @@ function image_effects() {
/**
* Load a single image effect.
*
* @param $name
* The image effect name.
* @param $ieid
* The image effect ID.
* @param $style_name
* The image style name.
* @param $include
* If set, this loader will restrict to a specific type of image style, may be
* one of the defined Image style storage constants.
*
* @return
* An image effect array, consisting of the following keys:
* - "ieid": The unique image effect ID.
......@@ -947,9 +956,20 @@ function image_effects() {
* @see image_style_load()
* @see image_effect_definition_load()
*/
function image_effect_load($name, $style_name) {
if (($style = image_style_load($style_name)) && isset($style['effects'][$name])) {
return $style['effects'][$name];
function image_effect_load($ieid, $style_name) {
if (($style = image_style_load($style_name)) && isset($style['effects'][$ieid])) {
$effect = $style['effects'][$ieid];
$definition = image_effect_definition_load($effect['name']);
$effect = array_merge($definition, $effect);
// @todo The effect's key name within the style is unknown. It *should* be
// identical to the ieid, but that is in no way guaranteed. And of course,
// the ieid key *within* the effect is senseless duplication in the first
// place. This problem can be eliminated in many places, but especially
// for loaded menu arguments like %image_effect, the actual router
// callbacks don't have access to 'ieid' anymore (unless resorting to
// dirty %index and %map tricks).
$effect['ieid'] = $ieid;
return $effect;
}
return FALSE;
}
......@@ -979,15 +999,18 @@ function image_effect_save($style_name, $effect) {
// The machine name is all the elements of the data array concatenated
// together, delimited by underscores.
$machine_name = $effect['name'];
foreach ($effect['data'] as $key => $value) {
$machine_name .= '_' . $value;
}
// @todo The machine name must not use any special non-alphanumeric
// characters, and may also not contain dots/periods, as that is the
// config system's nested key syntax.
$machine_name = preg_replace('@[^a-zA-Z0-9_-]@', '', $machine_name);
$effect['ieid'] = $machine_name;
$config->set('effects.' . $machine_name, $effect);
}
$config->save();
$style = image_style_load(NULL, $style_name);
$style = image_style_load($style_name);
image_style_flush($style);
return $effect;
}
......
......@@ -468,7 +468,7 @@ class ImageAdminStylesUnitTest extends ImageFieldTestCase {
// Load the style by the new name with the new weights.
drupal_static_reset('image_styles');
$style = image_style_load($style_name, NULL);
$style = image_style_load($style_name);
// Confirm the new style order was saved.
$effect_edits_order = array_reverse($effect_edits_order);
......
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