Issue #3136041 by jweowu: drupal_static() edge case bug and inconsistent comments
parent
7ea52649ec
commit
d070ec1d3f
|
@ -429,36 +429,41 @@ function drupal_maintenance_theme() {
|
|||
* @see drupal_static_reset()
|
||||
*/
|
||||
function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
|
||||
static $data = [], $default = [];
|
||||
// First check if dealing with a previously defined static variable.
|
||||
if (isset($data[$name]) || array_key_exists($name, $data)) {
|
||||
// Non-NULL $name and both $data[$name] and $default[$name] statics exist.
|
||||
if ($reset) {
|
||||
// Reset pre-existing static variable to its default value.
|
||||
$data[$name] = $default[$name];
|
||||
}
|
||||
return $data[$name];
|
||||
}
|
||||
// Neither $data[$name] nor $default[$name] static variables exist.
|
||||
static $data = [], $defaults = [];
|
||||
if (isset($name)) {
|
||||
if ($reset) {
|
||||
// Reset was called before a default is set and yet a variable must be
|
||||
// returned.
|
||||
return $data;
|
||||
// Check if we're dealing with a previously defined static variable.
|
||||
if (\array_key_exists($name, $data)) {
|
||||
// Both $data[$name] and (implicitly) $defaults[$name] statics exist.
|
||||
if ($reset) {
|
||||
// Reset pre-existing static variable to its default value.
|
||||
$data[$name] = $defaults[$name];
|
||||
}
|
||||
}
|
||||
// First call with new non-NULL $name. Initialize a new static variable.
|
||||
$default[$name] = $data[$name] = $default_value;
|
||||
else {
|
||||
// Neither $data[$name] nor $defaults[$name] static variables exist.
|
||||
if ($reset) {
|
||||
// Reset was called before any value for $name was set, so we should
|
||||
// not set anything ($default_value is not reliable in this case). As
|
||||
// the function returns a reference, we must still return a variable.
|
||||
// (Code using $reset does not use the return value).
|
||||
return $data;
|
||||
}
|
||||
// First call with new non-NULL $name. Initialize a new static variable.
|
||||
$defaults[$name] = $data[$name] = $default_value;
|
||||
}
|
||||
// Return a reference to the named variable.
|
||||
return $data[$name];
|
||||
}
|
||||
// Reset all: ($name == NULL). This needs to be done one at a time so that
|
||||
// references returned by earlier invocations of drupal_static() also get
|
||||
// reset.
|
||||
foreach ($default as $name => $value) {
|
||||
$data[$name] = $value;
|
||||
else {
|
||||
// Reset all: ($name == NULL). This needs to be done one at a time so that
|
||||
// references returned by earlier invocations of drupal_static() also get
|
||||
// reset.
|
||||
foreach ($defaults as $name => $value) {
|
||||
$data[$name] = $value;
|
||||
}
|
||||
// As the function returns a reference, we must still return a variable.
|
||||
return $data;
|
||||
}
|
||||
// As the function returns a reference, the return should always be a
|
||||
// variable.
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,25 @@ class ResettableStaticTest extends KernelTestBase {
|
|||
$var = 'bar';
|
||||
drupal_static_reset();
|
||||
$this->assertEquals('foo', $var, 'Variable was reset after second invocation of global reset.');
|
||||
|
||||
// Test calling drupal_static() with no arguments (empty string).
|
||||
$name1 = __CLASS__ . '_' . __METHOD__ . '1';
|
||||
$name2 = '';
|
||||
$var1 = &drupal_static($name1, 'initial1');
|
||||
$var2 = &drupal_static($name2, 'initial2');
|
||||
$this->assertEquals('initial1', $var1, 'Variable 1 returned by drupal_static() was set to its default.');
|
||||
$this->assertEquals('initial2', $var2, 'Variable 2 returned by drupal_static() was set to its default.');
|
||||
$var1 = 'modified1';
|
||||
$var2 = 'modified2';
|
||||
drupal_static_reset($name1);
|
||||
drupal_static_reset($name2);
|
||||
$this->assertEquals('initial1', $var1, 'Variable 1 was reset after invocation of name-specific reset.');
|
||||
$this->assertEquals('initial2', $var2, 'Variable 2 was reset after invocation of name-specific reset.');
|
||||
$var1 = 'modified1';
|
||||
$var2 = 'modified2';
|
||||
drupal_static_reset();
|
||||
$this->assertEquals('initial1', $var1, 'Variable 1 was reset after invocation of global reset.');
|
||||
$this->assertEquals('initial2', $var2, 'Variable 2 was reset after invocation of global reset.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue