I'm not sure if this is a bug (at least it's not documented this way), but #default_value isn't working with type 'text_format'. I changed to #value and now the next is properly shown in the text area.

Code that is used in admin settings form:

Broken:

  $site_map_message = variable_get('site_map_message', array('value' => '', 'format' => NULL));
  $form['site_map_message'] = array(
    '#type' => 'text_format',
    '#format' => isset($site_map_message['format']) ? $site_map_message['format'] : NULL,
    '#title' => t('Site map message'),
    '#default_value' => $site_map_message['value'],
    '#description' => t('Define a message to be displayed above the site map.'),
  );

Works:

  $site_map_message = variable_get('site_map_message', array('value' => '', 'format' => NULL));
  $form['site_map_message'] = array(
    '#type' => 'text_format',
    '#format' => isset($site_map_message['format']) ? $site_map_message['format'] : NULL,
    '#title' => t('Site map message'),
    '#value' => $site_map_message['value'],
    '#description' => t('Define a message to be displayed above the site map.'),
  );
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

hass’s picture

Damn it... it's not working with #value, too :-(. The textarea is populated with text saved in the database, but does not save it if #value is used and the text have changed.

hass’s picture

The current site_map D7 code has been committed to HEAD of http://drupal.org/project/site_map - if an easy repro case is required.

sun’s picture

Status: Active » Postponed (maintainer needs more info)

#default_value isn't working with type 'text_format'

"isn't working"? What's happening and what did you expect to happen?

hass’s picture

I do expect that the text that is fired into default value is shown in the user interface, but it isn't.

    '#default_value' => $site_map_message['value'],
hass’s picture

FileSize
52.6 KB

Only to make sure nobody need to guess anything... here is the code that can also be downloaded from CVS (site_map module) -> HEAD.

<?php
 
// Field to set site map message.
  // FIXME: Bug <a href="http://drupal.org/node/820816" rel="nofollow">http://drupal.org/node/820816</a>, '#default_value' should normally work, but currently doesn't.
 
$site_map_message = variable_get('site_map_message', array('value' => '', 'format' => NULL));
 
krumo($site_map_message);
 
$form['site_map_message'] = array(
   
'#type' => 'text_format',
   
'#format' => isset($site_map_message['format']) ? $site_map_message['format'] : NULL,
   
'#title' => t('Site map message'),
   
'#default_value' => $site_map_message['value'],
   
'#description' => t('Define a message to be displayed above the site map.'),
  );
?>

and here is the screenshot after pressing save - with the debug output. And you can also see the "site map message" text is not shown :-(. If pressing Save again, the message is deleted (expected result).

hass’s picture

I have opened a new bug for the htmlspecialchars() issue at #823362: htmlspecialchars() expects parameter 1 to be string, array given in check_plain().

sun’s picture

That htmlspecialchars() error message usually means that you are expecting to pass a string in a variable somewhere, but the variable actually is an array. Most likely, that's also the cause for this entire issue.

hass’s picture

I'm not doing this... This is only core fapi. :-)

sun’s picture

If that would be the case, don't you think that various places in Drupal core shouldn't be totally broken right now?

http://api.drupal.org/api/function/text_field_widget_form/7
http://api.drupal.org/api/function/user_account_form/7

Make sure that $site_map_message['value'] actually contains what it is supposed to contain.

Since I infrequently ran into this error since Drupal 5 and it was always caused by false assumptions on variable contents, I'm still speculating on a won't fix here. So please make absolutely sure that your variable data is correct. Otherwise, we need more debugging information here from you, since I suspect that no one else will be able to replicate this error.

sun’s picture

btw, is this a system_settings_form() ? If it is, then your variable does not contain what you expect. Your value is actually located in

$site_map_message['value']['value']

You need an additional form validation handler to shift the submitted form values around, prior to the submit handlers being called. #type 'text_format' is not really compatible with system_settings_form(). Perhaps we should document that. Probably a good idea, but not sure, where.

hass’s picture

Status: Active » Postponed (maintainer needs more info)

It sounds like you have not taken a look to the screenshots in #5 and http://drupal.org/node/823362#comment-3071368. Really annoying as it would have stopped you from wasting time. I'm sorry to say that you are simply wrong with $site_map_message['value']['value'], See krumo output in screenshot in #5. I made the debugging screenshots only for this reason.

I have also tested for verification purpose by hard coding text into the form fields and the sentence 'This is text that is not shown in the FORM field.' is NOT shown in the UI field. See below code example:

<?php
$form
['site_map_message'] = array(
   
'#type' => 'text_format',
   
'#format' => isset($site_map_message['format']) ? $site_map_message['format'] : NULL,
   
'#title' => t('Site map message'),
   
'#default_value' => 'This is text that is not shown in the FORM field.',
   
'#description' => t('Define a message to be displayed above the site map.'),
  );
?>

It would be much easier if you install site_map module and do a quick test. Should take only 5 minutes to figure out the new form field type is broken. If the text would be populated to the UI it would simply work. The #823362: htmlspecialchars() expects parameter 1 to be string, array given in check_plain() nailed out later. I have not implemented a special form handler and I see no reason why I need to do it as the data is correctly saved in the variables table - only the form field is broken and something in the deep background that cause #823362: htmlspecialchars() expects parameter 1 to be string, array given in check_plain() on form save what you can also see here:

hass’s picture

Status: Postponed (maintainer needs more info) » Active

*All* information is in the case.

Damien Tournoud’s picture

Category: bug » support
Status: Postponed (maintainer needs more info) » Active

Please read #10 and understand the new behavior of system_settings_form() when $automatic_defaults is true (which is the default).

hass’s picture

Category: support » bug

@Damien: Have you tried to repro? No idea why you change to support. Changing system_settings_form($form) to system_settings_form($form, FALSE) does not change anything. The form element need to work whatever need to be documented (or not), this form element is the only one that does not work like any other. This could be bad DX, it could be bad design, but it's not the way how it's expected to work and not the way how it seems to work. As said - all data is correctly saved in the variables table, but the populated static text fired into '#default_value' is not shown anywhere. Should I really expect this if all other form api fields work this way? I do not think so and I'm sorry I do not understand sun's comment why I need to shift anything around. All data is saved where it should be, but '#default_value' on form load do not work. An answer why - would be more than great.

Damien Tournoud’s picture

Category: bug » support

Trying to explain. Please follow carefully.

When $automatic_defaults is true, system_settings_form() uses the #name of the element as the variable name and the #default_value of the element as the default value of the variable, and automatically calls variable_get() for you.

This code assume that the automatic defaults loading is not enabled:

  $site_map_message = variable_get('site_map_message', array('value' => '', 'format' => NULL));
  $form['site_map_message'] = array(
    '#type' => 'text_format',
    '#format' => isset($site_map_message['format']) ? $site_map_message['format'] : NULL,
    '#title' => t('Site map message'),
    '#default_value' => $site_map_message['value'],
    '#description' => t('Define a message to be displayed above the site map.'),
  );

When automatic defaults loading is enabled, this will result in a call to variable_get('site_map_message', $site_map_message['value']), which will result in the #default_value being populated with an array. This is certainly not what you want.

You want either to disable the automatic defaults loading. Contrary to what you are saying, this will make it work, but you also need to populate the #format key.

hass’s picture

Title: Text not loaded with #default_value in textarea of type 'text_format' » system_settings_form() do not load the saved values if $automatic_defaults = TRUE

Not sure why this haven't worked while testing myslef. But now - it works, maybe the cache clear solved it. THX.

But now we are at the point we must clearly say - this is a bug! The http://api.drupal.org/api/function/_system_settings_form_automatic_defau... need to do something like if '#type' == 'text_format' read '#default_value' from variables table in $value['value'] and '#format' from $value['format']. It could be easy with is_array($value).

Than the new $automatic_defaults would work like a charm - also we the new 'text_format' form filed.

What do you think?

hass’s picture

Otherwise or additionally I strongly suggest to change the doc in http://api.drupal.org/api/function/system_settings_form/7 by adding some more detailed text that explains the new $automatic_defaults feature with a few more words. I'm sorry for having this missed as all other stuff worked as before nevertheless I do have '#default_value' with variable_get() calls in every form field array.

$automatic_defaults Automatically load the saved values for each field from the system variables (defaults to TRUE).

hass’s picture

Title: system_settings_form() do not load the saved values if $automatic_defaults = TRUE » system_settings_form() do not load the saved values if $automatic_defaults = TRUE in textarea of type 'text_format
hass’s picture

Title: #type text_format not compatible with system_settings_form($automatic_defaults = TRUE) » system_settings_form() do not load the saved values if $automatic_defaults = TRUE in textarea of type 'text_format

I'm assigning this to me and hope to get a patch ready that fixes above bugs. My plan is to get the following solved:

1. If '#default_value' is defined in the form array there is no default loaded in _system_settings_form_automatic_defaults(). We expect that a developer does something at it own. It will not -> // If the property (key) '#default_value' exists, replace it. as this will duplicate variable_get() calls.
2. Only load the value from variable table if there is no '#default_value' defined.
3. Make '#type' == 'text_format' work with system_settings_form() with $automatic_defaults.
4. Write better documentation for system_settings_form()'s $automatic_defaults.

sun’s picture

Title: system_settings_form() do not load the saved values if $automatic_defaults = TRUE in textarea of type 'text_format » #type text_format not compatible with system_settings_form($automatic_defaults = TRUE)
Assigned: Unassigned »
  1. Like chx, I'm not sure whether I like the new automatic defaults anyway.
  2. In case you missed it, an assigned #default_value is used and passed to variable_get([key], #default_value). Hence, the value of #default_value is purposively used, not mistakenly.
Damien Tournoud’s picture

This automatic defaults loading is basically a hack. I passionately hates it, but it is difficult to do better because current FAPI doesn't have a #element_submit option.

hass’s picture

Title: system_settings_form() do not load the saved values if $automatic_defaults = TRUE in textarea of type 'text_format » #type text_format not compatible with system_settings_form($automatic_defaults = TRUE)
Version: 7.0-alpha5 » 7.x-dev
Category: support » bug
Status: Active » Needs review
FileSize
1.12 KB

Ok, after looking more on this code I only fixed #3. See the attached patch, please.

I think the rest could also been solved by writing an update doc. I suggest something like the below, please review. If you know - where to add it on http://drupal.org/update/modules/6/7 it would be great.

system_settings_form() automatically populates form values

D6:

<?php
function system_site_information_settings() {
 
$form['site_name'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Site name'),
   
'#default_value' => variable_get('site_name', 'Drupal'),
   
'#required' => TRUE,
  );
  return
system_settings_form($form);
}
?>

D7 with autoloading of form value defaults:

<?php
function system_site_information_settings() {
 
$form['site_name'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Site name'),
   
'#default_value' => 'Drupal',
   
'#required' => TRUE,
  );
  return
system_settings_form($form);
}
?>

D7 with custom form value loading it's like it was in D6, but requires FALSE as second parameter in system_settings_form():

<?php
function system_site_information_settings() {
 
$form['site_name'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Site name'),
   
'#default_value' => variable_get('site_name', 'Drupal'),
   
'#required' => TRUE,
  );
  return
system_settings_form($form, FALSE);
}
?>
Damien Tournoud’s picture

Status: Needs review » Closed (duplicate)
sun’s picture

However, we should seriously consider to allow #type 'text_format' to accept an *array* as #default_value now. I.e., 'value' + 'format'.

That, to some extent, could also lead to the rollback of the rollback of automated settings, although I wouldn't necessarily support that.

#type 'date' similarly expands an array as #default_value into new-born child elements via #process. So, that would add some consistency of some sort.

Opinions?

slefevre1’s picture

Which issue is this a duplicate of? I'm running into this now and it seems to be a conflict with the current dev branch of the media module.

Anybody’s picture

Issue summary: View changes

@slefevre1 and all others running into this issue:

See #1761944: Using text_format field in settings forms : htmlspecialchars() expects parameter 1 to be string, the workaround in a system_settings_form seems to be to set
'#base_type' => 'textarea',
and use

 $form_description['value']

... still I think sun is right in#24 and this is still an issue after 7 years.