It would be nice instead of having to do:

$value = variable_get('myvariable');
if (isset($value)) {
  variable_set('mynewvariable', $value);
}
variable_del('myvariable);

We could just do:

variable_rename('myvariable', 'mynewvariable');

Comments

timhilliard’s picture

Hi Dave, I think this is a really great idea. I am willing to write this piece of code however I'm wondering how this works as there is currently no 8.x-dev branch as far as I can see. Does this need to happen before we can start writing in new features?

timhilliard’s picture

StatusFileSize
new1.93 KB

Heres my attempt at variable_rename. I created a diff against HEAD of d7 so not sure how this gets rolled later on.

Cheers,
Tim

dave reid’s picture

Status: Active » Needs work
+++ includes/bootstrap.inc	2 Feb 2011 15:42:12 -0000
@@ -776,6 +776,7 @@ function variable_initialize($conf = arr
+ * @see variable_update()
  */
 function variable_get($name, $default = NULL) {
   global $conf;
@@ -798,6 +799,7 @@ function variable_get($name, $default = 

@@ -798,6 +799,7 @@ function variable_get($name, $default = 
  *
  * @see variable_del()
  * @see variable_get()
+ * @see variable_update()
  */
 function variable_set($name, $value) {
   global $conf;
@@ -821,6 +823,7 @@ function variable_set($name, $value) {

@@ -821,6 +823,7 @@ function variable_set($name, $value) {
  *
  * @see variable_get()
  * @see variable_set()

Should be @see variable_rename()

+++ includes/bootstrap.inc	2 Feb 2011 15:42:12 -0000
@@ -834,6 +837,40 @@ function variable_del($name) {
+ * Renames a persistent variable.
+ *
+ * Case-sensitivity of the variable_* functions depends on the database
+ * collation used. To avoid problems, always use lower case for persistent
+ * variable names.
+ *
+ * @param $current_name
+ *   The current name of the variable to change.
+ * @param $new_name
+ *   The new name of the variable to change.
+ *
+ * @see variable_get()
+ * @see variable_set()
+ * @see variable_del()
+ */
+function variable_rename($current_name, $new_name) {
+  global $conf;
+  ¶
+  if (isset($conf[$current_name])) {
+
+    db_update('variable')
+      ->fields(array(
+        'name' => $new_name,
+      ))
+      ->condition('name', $current_name)
+      ->execute();
+    cache_clear_all('variables', 'cache_bootstrap');
+  ¶
+    $conf[$new_name] = $conf[$current_name];
+    unset($conf[$current_name]);
+  }

Bikeshedding, but for consistency let's name the parameters $name and $new_name.

I'm not sure yet about checking if (isset($conf[...])). We don't do this with variable_del() so I'm not sure why we'd want to add this here. Ahh I realize now since this would throw a warning on $conf[$new_name] = $conf[$current_name]. Hrm.

Powered by Dreditor.

timhilliard’s picture

StatusFileSize
new1.88 KB

You're correct it does throw a warning but I think it's also good that it doesn't set the variable in $conf if it doesn't exist already. It also means the query doesn't needlessly need to run.

The reason it was variable_update in the comments was because thats what I originally called the function before I realised that it was the wrong name and changed it, I just forgot to update the comments as well.

I have now re-rolled patch with recommended changes.

Cheers,
Tim

catch’s picture

Please put this in common.inc rather than bootstrap.inc

timhilliard’s picture

StatusFileSize
new1.21 KB

Re-rolled per catch's direction. I assume this is so the function doesn't get loaded on bootstrap as it will only be needed at a later stage of loading?

dave reid’s picture

Status: Needs work » Needs review
StatusFileSize
new1.78 KB

Re-rolled patch with Git and updaed docs.

dave reid’s picture

StatusFileSize
new2.15 KB

Using format-patch.

timhilliard’s picture

Status: Needs review » Reviewed & tested by the community

Looks great Dave.

catch’s picture

Status: Reviewed & tested by the community » Needs work

This will break in the case a variable is set in settings.php but not in the database. It should probably do select, delete, insert instead of update. If a variable is renamed but was set in settings.php I'm not sure what the behaviour should be, maybe check conf as well as the return from the direct query. To be honest I'm not convinced of the usefulness of this, how often does variable renaming happen? Additionally the convention is now not to use api functions in update hooks, so adding an api function that will rarely be used outside of those goes against this.

dave reid’s picture

Doesn't variable_set(), variable_del() etc also break in that way?

I cannot count the number of times I've renamed variables in my modules, so yes. Most of its usefulness is to contrib authors. And I found about 5 update hooks in D7 core that could have used this.

dave reid’s picture

Status: Needs work » Reviewed & tested by the community
catch’s picture

Status: Reviewed & tested by the community » Needs work

Those two functions do not try to update a row that doesn't exist.

dave reid’s picture

If I have a $conf['my_variable'] in my settings.php, I cannot use variable_del() with it - it breaks and calls db_delete() on a row that does not exist.

catch’s picture

$foo = variable_get('foo'); variable_set('bar', $foo); works though, the equivalent situation is broken in this patch.

catch’s picture

Also in your example deleting the variable won't remove it from $conf, but it does successfully delete it from the database, so the only cruft is a hopefully unused variable in settings.php. If the variable isn't in the db variable_del() doesn't care whether it's in conf or not in practice.

catch’s picture

OK I'm back on computer now, shouldn't review patches from iphone....

The issue is that the current pattern for renaming a variable works:

$foo = variable_get('foo');
if (isset($foo)) {
  variable_set('bar', $foo);
}
variable_del('foo');

That example works for both variables that are set in $conf, and variables that aren't.

The current patch would fail to set the old value to the new variable name, if the variable was only set in $conf.

Update hooks in D7 core should not be using API functions, arguably this includes variable_get()/variable_set()/variable_del() - so if they are we need to consider adding _update_variable_get_7000() equivalents to be consistent with the examples elsewhere.

timhilliard’s picture

Catch, when I created the function I used the exact pattern above as my guide and expanded the functions out and then re-factored it, so I believe that any problem that there is with the new function also exists with the pattern listed above.

I question whether you would want this function to rename a variable that is only set in $conf as that variable would be persistent even after attempting the rename. The only thing this function or pattern would do is unset the variable from $conf until the page was reloaded again.

As far as using API functions in update hooks that's not an argument that I'm going to weight into except only to say that I see variable_get()/variable_set()/variable_del() in update hooks all the time.

dawehner’s picture

Component: base system » configuration entity system
Issue summary: View changes

.

berdir’s picture

Status: Needs work » Closed (won't fix)

I think we can close this. An 8.x solution would be completely different and I doubt this would be added to 7.x.