The handling for default values needs some work before this goes much further. Currently, CCK tracks a 'default_value' and a 'default_value_php' for each field as a widget setting. That's wrong for Fields in Core on a couple of counts.

First, a 'default value' is not a widget setting, it is an instance setting. If I have a field called 'State' and I want the default value to be 'Illinois', that has nothing to do with the widget I use to input it. The widget has the responsibility to insert that value into the widget in the right place, but that's all. So we need to have a system for handling a default value as an instance setting.

Second, the 'default_value_php' is way too specific for core, that's something that should be handled in contrib. Core should be either a hard-coded value, the name of a function that will return a value, or a hook that can be used to return a value. CCK, the contrib module, can do things like provide a way to input some PHP and store the snippet, and then return it in response to the default value hook.

I'm going to work on this and try to clean it up more before our patch hits core.

CommentFileSizeAuthor
#11 field_default_docs.patch1.35 KBmatt2000
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

KarenS’s picture

Status: Active » Fixed

This should be working right now. A general hook turned out to create too many problems because core field can contain no information to tell CCK whether it is handling the default value or whether some other module is. I ended up doing something very simple in core -- create an instance setting for the name of a function that will provide the default value and then use it to populate the default value in the form. There should be no reason for more than one function to be needed there or for one module to override another. And a module that creates a custom field via the API can insert its own function name, as can fields that want to handle their own default values. CCK then looks for fields with nothing in that setting and only provides default value handling for them.

CCK is now tracking some 'settings' that core doesn't care about, like the old 'default_value' hard-coded arrays and 'default_value_php' for the code snippets, so I created a simple table to store that information in. Then CCK acts on its default value function to look the information up and return the right value.

yched’s picture

a module that creates a custom field via the API can insert its own function name, as can fields that want to handle their own default values

I get the "module that creates a custom field via the API " part, but I'm not sure I get the other case - is that "field types that want to handle their own default values" ? If so, how would the they do that ? hook_field_create_instance() is currently called after _field_write_instance() , so modules cannot alter what gets written.

bjaspan’s picture

Status: Fixed » Needs work

This sounds great, but I have a few questions/to do items:

I ended up doing something very simple in core -- create an instance setting for the name of a function that will provide the default value and then use it to populate the default value in the form.

Since this is an instance setting, we should probably fill in the default value in field_attach_insert(), right? What about field_attach_update()? Currently, our hook_field_storage_write() does this for both:

    // Leave the field untouched if $object comes with no $field_name property.
    // Empty the field if $object->$field_name is NULL or an empty array.

I think those semantics are right for update, but for insert I think we should fill in the default value.

And a module that creates a custom field via the API can insert its own function name,

+1

... as can fields that want to handle their own default values.

How does a field specify the default value function for all instances of itself? Or do I not understand what you are saying here?

CCK then looks for fields with nothing in that setting and only provides default value handling for them.

This took me a couple reads to figure out, but I think you are saying: If an instance has a default value function that did not come from CCK, CCK provides no UI to change it (basically, it is locked). Instances without default value functions (or one they got from CCK) get a UI to edit it through CCK. Is that right?

One other topic. Should we worry about the module that implements the default value function being disabled? We can always wrap the call in a drupal_function_exists(), but if that happens the field is going to behave differently.

KarenS’s picture

My intention was that if there is no function or the function doesn't return anything (like for a disabled module) there would be no default value, and that having no default value would be the default behavior.

- So a module can create a field via an API and populate that value with the function it wants to use (that much should be working right).

- A field module, say 'Date' module (the example I am trying to work with) can set instance values for CCK's API via hook_field_instance_settings_form(). Which should take care of fields created by the UI that need their own default value handling.

- Any if that setting is empty, CCK will assume it is supposed to handle it. Which should take care of all other fields.

Maybe I've missed something, but I thought I had everything covered. I also thought I'd try to get the Date module ported to D7 so I can have an example of a module that is outside CCK which wants to handle some of its own values to test this more, but I may not get this done right away.

The concept needs to be examined since it's a new way of handling things. The real challenge when I dug into it was to come up with a way for CCK to know when to step in and when not to, since the core code, and the core field modules, don't know or care about CCK, so they won't provide any clues.

yched’s picture

Since this is an instance setting, we should probably fill in the default value in field_attach_insert(), right? What about field_attach_update()?

Since we now have a clean definition of default value as an instance / widget-agnostic property, then I think we're good to go with saving default values on insert. That includes programmatic entity_save(), and form submission where the current user is not allowed to edit the field (I changed that case recently so that the field is *not* included in the form, so this translates to field_attach_[insert|update] receiving no $entity->field_name entry, just like on an entity_save() )

I really think default_values don't belong in _update(). Default value has always been 'creation' only. Maybe some other behavior is possible, but I don't think we want to go there now...

If an instance has a default value function that did not come from CCK, CCK provides no UI to change it (basically, it is locked)
Right, that might be an issue. it means we have a locked property in the middle of $instance - which is supposed to be all changeable.
Pondering...

KarenS’s picture

Actually the next step I thought of was to add a textfield for the function name to the CCK UI. You could insert or remove a custom function as an alternative to providing an array or a PHP snippet. So there would be three ways to provide a default value via the UI. If you put a function name in there, CCK would just allow you to edit the function name, not do anything with it (no default value widget would be created).

Then if there is a function name used, that function will be called by Field, otherwise the CCK function will be used.

KarenS’s picture

Argh, except if the field provides a default value function, it would want it to be 'locked', so adding a place where it can be changed would break that.

Such a simple thing can get very complicated.

Anyway, go ahead and make changes if you have ideas.

KarenS’s picture

The 'Allowed values' code is handled in a similar way -- core has a setting for 'allowed_values' and 'allowed_values_function' and CCK provides a place to input PHP code and handling to return it in response to the core invocation. Most of that part was committed but I went ahead and committed everything else I had. Try both of these out and make suggestions on how to improve them. The issues for each will be the same:

- How will CCK know when to step in (currently by testing if the function setting is either empty or set to CCK.)
- How much of this belongs in core (possibly just the function name setting and nothing else, and core would do nothing but invoke that function if it exists).
- How do we allow other modules to set those values without creating problems for CCK?

Dave Reid’s picture

Status: Needs work » Active

No patch for review.

matt2000’s picture

Issue tags: +Needs documentation

Looks like this has been settled on?

http://api.drupal.org/api/function/field_get_default_value/7

Maybe just need to document it with field_create_instance?

matt2000’s picture

Status: Active » Needs review
FileSize
1.35 KB

How about this...

chx’s picture

Status: Needs review » Reviewed & tested by the community

Nice work.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

Status: Fixed » Closed (fixed)
Issue tags: -Needs documentation

Automatically closed -- issue fixed for 2 weeks with no activity.