Problem/Motivation

The Field API Data Structures page describes the $field structure, but most functions which take such a parameter do not reference this page, and many of them describe the parameter as a "field array" or "field data" or even simply "field". These descriptions should be made consistent, and the functions taking such a parameter should reference the Field API Data Structures page.

Proposed resolution

A patch has been submitted which ensures that every relevant @param $field describes its parameter as a "field structure" and also links to the Field API Data Structures page.

Remaining tasks

  • The patch should be reviewed for correctness.
  • The term "field structure" is confusing to some. Core developers should choose a less confusing term.
  • As noted over two years ago, the field type documentation should specify which of the hooks listed in field.api.php are required to be implemented, and which are optional.

User interface changes

None; this is a documentation-only patch/fix.

API changes

None; this is a documentation-only patch/fix.

Original report

API page: http://api.drupal.org/api/drupal/modules--field--field.api.php/function/...

The documentation for the $field parameter gives absolutely no clue as to what is expected for this parameter.

Possibilities include:

  • A string containing the name of the field.
  • The field definition structure as returned from field_info_field()

Comments

jhodgdon’s picture

Title: Documentation for hook_field_is_empty needs type-hinting. » Documentation for hook_field_is_empty needs to describe what $field is

Do you know which is the actual value? Care to research and submit a patch?

pillarsdotnet’s picture

None of the hook_field_is_empty() implementations in core do anything with their $field parameter.

Searching through contrib now, but it will take a while, and I'm not sure that if I did find anything it would be useful as a standard.

When in doubt, do as the most popular contrib module does?

pillarsdotnet’s picture

Title: Update hook_field_is_empty() docs to describe expected parameter and return types, and to note that it is a required hook. » Documentation for hook_field_is_empty needs to describe what $field is
Status: Needs review » Active
StatusFileSize
new1.7 KB

Example hook_field_is_empty() implementations which do not ignore their $field parameter:

commerce_customer_field_is_empty()
/**
 * Implements hook_field_is_empty().
 */
function commerce_customer_field_is_empty($item, $field) {
  if ($field['type'] == 'commerce_customer_profile_reference') {
    // profile_id = 0 îs empty too, which is exactly what we want.
    return empty($item['profile_id']);
  }
}
computed_field_field_is_empty()
/**
 * Implements field hook_field_is_empty().
 */
function computed_field_field_is_empty($item, $field) {
  $data_type = $field['settings']['database']['data_type'];
  if ($data_type == 'int' || $data_type == 'float') {
    return !is_numeric($item['value']);
  }
  return empty($item['value']);
}
date_field_is_empty()
/**
 * Implements hook_field_is_empty().
 */
function date_field_is_empty($item, $field) {
  // Sometimes a $item is a date object.
  // Coming from repeating dates. Why?? 
  if (!is_array($item)) {
    return FALSE;
  }
  if (empty($item['value'])) {
    return TRUE;
  }
  elseif ($field['settings']['todate'] == 'required' && empty($item['value2'])) {
    return TRUE;
  }
  return FALSE;
}

Conclusion:

It would appear that $field is expected to be an array structure as returned from field_info_field().

Tentatively rolling a patch that describes the consensus implementation, even though there is considerable disagreement among these three examples:

  • The commerce_customer_field_is_empty() function returns NULL if $field is not the expected type.

    So commerce_customer_field_is_empty($item, NULL) would return NULL.

  • The date_field_is_empty() function always returns FALSE if $item is not an array.

    So date_field_is_empty(NULL, $field) would return FALSE.

  • The computed_field_field_is_empty() function returns TRUE if $item is not of the expected numeric field type.

    So computed_field_field_is_empty(NULL, $field) would return TRUE.

  • All other examples not shown implicitly assume that $item is an array of the expected field type, and many will produce PHP warnings if this assumption is violated.

    So hook_field_field_is_empty(NULL, $field) would (in most cases) produce a run-time warning.

None of the Field System hooks currently state whether or not they are required. I know that hook_field_is_empty() is required because of comment #517430-7 by bjaspan and also because of the code and comment in _field_filter_items(). I don't know which, if any, of the other field hooks are required. This documentation bug should be reported and addressed in a separate (meta?) issue, as bjaspan suggested over three years ago.

pillarsdotnet’s picture

Status: Active » Needs review
pillarsdotnet’s picture

Title: Documentation for hook_field_is_empty needs to describe what $field is » Update hook_field_is_empty() docs to describe expected parameter and return types, and to note that it is a required hook.
jhodgdon’s picture

Title: Documentation for hook_field_is_empty needs to describe what $field is » Update hook_field_is_empty() docs to describe expected parameter and return types, and to note that it is a required hook.
Status: Active » Needs work

A few things need fixing here:

a) The first line of a hook definition has a different verb requirement. Check http://drupal.org/node/1354 for standards.

b)

+ * @param array $item
+ *   A field instance that may or may not be empty.

I don't think this is actually a "field instance". That term has a special meaning in the field API. I think this is just the field data?

c)

+ * @param array $field
+ *   The field type as returned from field_info_field().

I'm not comfortable with calling this the "field type". Most things that in Drupal are called "type" are strings, such as "node type". Please use the term that is used in the rest of the field API... field definition array? not sure.

d)

  * @return
- *   TRUE if $field's type considers $item not to contain any data;
- *   FALSE otherwise.
+ *   TRUE if $item is an instance of type $field and empty of data;
+ *   FALSE if $item is an instance of type $field containing data;
+ *   undefined if $item is not an instance of type $field.

I'm not happy with saying "undefined" for the return value. We should not express our doubts about what to return, we should document what should be returned. Anyway, the field API is not so stupid that it will invoke this hook with $item not being an instance of type $field, so we don't really have to mention this case at all. So this can be quite simplified. Mention in @param $item that it is an instance of the field, and leave out the "is an instance of ..." in the @return.

Also, "empty of data" ... That's not actually accurate. $item could contain *some* data and still be considered empty (example: an image field that has alt text but no uploaded file). Which is why the old wording was "considers", which is accurate. Please fix this to be accurate; you can reword if you want, but it needs to be clear that the module can decide what "empty" means for this field. You can put it in the description if you want.

e) Also... is this hook actually required? In CCK at least, there was a default way to check if a field was empty, and modules just needed to implement the is_empty hook if they needed to override that. Isn't that possible for fields?

pillarsdotnet’s picture

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

@#6 by jhodgdon on October 6, 2011 at 3:48pm:

(a) through (d)

Corrected and re-rolled. Also:

Anyway, the field API is not so stupid that it will invoke this hook with $item not being an instance of type $field,

If these functions should never be called from userland, they should say so, and I need to remove the call to og_field_is_empty() from my contrib module. (Which, BTW, is what prompted me to file this issue in the first place.)

Also note the undocumented fact that field_info_field() may return NULL.

(e)

As previously stated:

I know that hook_field_is_empty() is required because of comment #517430-7 by bjaspan and also because of the code and comment in _field_filter_items().

Follow the links if you want; that's why I wrote them.

(Webchick thinks I should spend more time composing my comments, but do people even bother to read them, before replying?)

pillarsdotnet’s picture

StatusFileSize
new1.55 KB

BAH!!!!

That patch file name was completely wrong, even though the contents are (I believe) correct.

jhodgdon’s picture

Please, there is no need to be so snarky! It would be much nicer if you had just said "Actually, it is required" and provided the link politely. I obviously just reviewed your patch and didn't re-scan all the comments on this issue, or have them all in my head (I am involved in a lot of other issues obviously), or read all the other code in the Drupal code base.

So looking at that _field_is_empty function, it has a suspicious line that just says function_exists() but does nothing with the return value. Given that, I'm not sure what the intention is about whether the is_empty() hook should be required or not, but we should resolve that before we proceed to document that it's required. IMO the comment referenced on the other issue does not resolve the question, it merely says "if it's required, we should document it" and "if it's not required, we should test in the code and return". It doesn't answer the question of which is correct. And that issue was eventually closed as having been fixed elsewhere, so there is no answer.

One more thing, maybe "An array of field data that may or may not be considered empty." would be clearer as "Data for a single field value to test." or something like that? "An array of field data" makes it sound like it could be multiple field values together (it can only be one at a time), and "may or may not be considered" seems a bit redundant?

pillarsdotnet’s picture

Well, if hook_field_is_empty() is not required, then the following code from _field_filter_items() certainly needs to be changed:

    // Explicitly break if the function is undefined.
    if ($function($item, $field)) {

Note that the "suspicious call to function_exists()" was removed (today) by webchick.

See: #1300482: Remove cruft function_exists() from _field_filter_items() leftover from the (removed) function registry.

Sorry to be so "snarky", but if you are unwilling to read what I wrote the first time, and are unwilling to read what I wrote the second time, I'm not overly anxious to write it a third time.

I'm not sure what the intention is about whether the is_empty() hook should be required or not,

The people who developed the field API were crystal-clear that it should be required. If you're unwilling to read their testimony (linked above and quoted in #1300482) then go ask them yourself.

pillarsdotnet’s picture

StatusFileSize
new1.57 KB

One more thing, maybe "An array of field data that may or may not be considered empty." would be clearer as "Data for a single field value to test." or something like that? "An array of field data" makes it sound like it could be multiple field values together (it can only be one at a time), and "may or may not be considered" seems a bit redundant?

Revised as requested.

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

Looks good now. Thanks for the clarifications. Should be good for 8.x/7.x.

chx’s picture

Title: Update hook_field_is_empty() docs to describe expected parameter and return types, and to note that it is a required hook. » Unify @param $field explanation
Status: Reviewed & tested by the community » Needs work

An overwhelming majority of @param $field says "field structure". Just inside the field directory, there are 15 of "The field structure for the operation.", 5 simply is "A field structure." and 4 is "The field structure." However, 3 is "The field definition."

Not to mention that reading the doxygen field_info_field doesnt make you any wiser. You wanted http://api.drupal.org/api/drupal/modules--field--field.module/group/field/7 this. I do not know how to link to a group page from doxygen.

I am surprised by the opening post because there is absolutely no place in field API where such ambiguity exists undocumented. As far as I know only EFQ allows you to pass in both field names and field structures and that is clearly documented even if it says "Either a field name or a field array" and not "field structure", it's not ambigous.

I would recommend agreeing on "field structure" then go over all of the 15 mentions of "field array" in core and also the @params that do not mention the magic word structure.

pillarsdotnet’s picture

Status: Needs review » Needs work

@chx: Since you're basically asking me to review and/or rewrite the entire modules/field/field.api.php file, may I get (from you or someone else) a list of the field hooks which, like hook_field_is_empty(), are required of all field type implementations?

I do not know how to link to a group page from doxygen.

I figured it out. I just need to add the following to the end of the function header:

* @see @link field Field API data structures @endlink.
pillarsdotnet’s picture

Status: Needs work » Needs review
StatusFileSize
new41.12 KB

When I find exceptions to the general rule that @param $field refers to a field structure, should I submit a patch to rename the parameter?

lars toomre’s picture

Status: Needs work » Needs review

This is a perfect example of why we should be type hinting @param directives. Shouldn't this patch correct/modify each docblock touched for @param type hinting?

lars toomre’s picture

Also line '+ * @ingrou pfield' needs to be corrected. I believe you meant '@ingroup field'.

pillarsdotnet’s picture

@#16 by Lars Toomre on October 7, 2011 at 5:21am:

Shouldn't this patch correct/modify each docblock touched for @param type hinting?

No, the issue discussing type-hinting still lacks sufficient "core developer buy-in".

See #711918-69:

... But we do need buy-in from the core devs on all coding standards... and I'm not sure we're there yet on this idea.

pillarsdotnet’s picture

@#17 by Lars Toomre on October 7, 2011 at 5:26am:

Also line '+ * @ingrou pfield' needs to be corrected. I believe you meant '@ingroup field'.

Thanks. Corrected.

lars toomre’s picture

I see that there has been no progress on #711918: Documentation standard for @param and @return data types over the last four days. Maybe this patch should be postponed until that issue is settled one way or another? This really is an example that screams for type hinting.

pillarsdotnet’s picture

Status: Needs review » Postponed

@#20 by Lars Toomre on October 7, 2011 at 5:41am:

Maybe this patch should be postponed until that issue is settled one way or another?

Sure; why not. Updated issue summary.

salvis’s picture

I'm confused by the term "field structure" when used to describe an actual instance of field data. PHP has objects (classes) and arrays, but not structures, in the way that term is commonly used in other programming languages. Classes where all properties are public may be called "structures" in data structure terminology, but I don't think this is what we mean here. What we mean is keyed arrays with a certain defined set of keys, but they are still just "arrays", not "structures", because there is no language support for assuring the presence of those keys.

If we go for type hinting on @params (which I hope very much), it'll be just 'array', which, unfortunately, doesn't add a lot of information in this case.

pillarsdotnet’s picture

@#22 by salvis on October 7, 2011 at 7:31am:

I'm confused by the term "field structure" when used to describe an actual instance of field data.

Actually, "field structure" or $field refers to the definition of the field type.

A "field instance" or $instance describes the usage of that field type within a content type or "bundle".

A "field item" or $item refers to the data contained in a field within a particular node or entity object.

See the Field API page.

pillarsdotnet’s picture

Added a couple of missing end-of-sentence dots.

jhodgdon’s picture

Status: Postponed » Needs work

Param/return type hinting itself has already been adopted as a mostly optional standard. There is no reason to postpone this issue until it is decided -- as stated in a comment above, this seems like a good time to use it, to disambiguate some documentation, so please go ahead. :)

I agree with #22 - "structure" is an ambiguous term in PHP. It could say "field structure array", though, because "field array" would also be ambiguous (we need to get across the idea that it's the definition, not the data)... hmmm. maybe "field definition array" would be even better? thoughts?

pillarsdotnet’s picture

According to chx, there is absolutely no ambiguity in the term "field structure", especially when used with @param $field. Therefore, according to coding standards, type-hinting should not be used.

But since discussions about coding standards are a complete mis-use of time, energy, and focus, I'll wait until y'all decide what to do before I spend another two hours hand-editing code.

pillarsdotnet’s picture

Issue summary: View changes

Create issue summary for what is no longer a trivial issue.

pillarsdotnet’s picture

Issue summary: View changes

Updated status.

jhodgdon’s picture

I think chx is wrong about their being no ambiguity in the term "field structure", and so does salvis (see #22). If even a few people think it is confusing, couldn't we pick a better term that wouldn't confuse anyone?

pillarsdotnet’s picture

@#27 by jhodgdown on October 7, 2011 at 3:54pm:

... couldn't we pick a better term that wouldn't confuse anyone?

Please re-define the word we so that it does not include pillarsdotnet, or else magically unsubscribe me from this issue.

EDIT: updated summary so that "we" is defined as "Core developers".

salvis’s picture

I think my confusion comes from the ambiguity between
1) @param $field is of type "field structure" and
2) @param $field is of type array and contains the field structure
because I'm used to thinking "data type" when I see "structure".

Making it

@param array $field

would go a long way to clear this up for me.

pillarsdotnet’s picture

Status: Needs work » Postponed (maintainer needs more info)

Waiting for chx or another Field API maintainer to chime in on this one.

tim.plunkett’s picture

Status: Postponed (maintainer needs more info) » Needs work

Un-postponing for more visibility.

tim.plunkett’s picture

Issue summary: View changes

wordsmithing

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

quietone’s picture

Version: 8.9.x-dev » 7.x-dev
Issue summary: View changes
Issue tags: - +Bug Smash Initiative

This discussion and patch here are relevant for Drupal 7. IF there is a need for this documentation change in Drupal 9 new issues should be opened to discuss that.

Therefor moving to the Drupal 7 issue queue.

Status: Needs work » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.