The file module allows extending the file field by calling the callbacks listed in $element['#file_value_callbacks'] within file_managed_value().
However, the $form_state variable is missing from the call, so the callbacks are unable to find the field or widget settings.

The attached patch fixes it.

CommentFileSizeAuthor
#3 yh-1002396.patch624 bytesyhager
yh-missing-form-state.patch748 bytesyhager
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yched’s picture

Component: field system » file system
Status: Active » Reviewed & tested by the community

Recategorizing.

Sounds correct, though. $form_state holds a number of important information, including the $field and $instance definition against which a widget is being generated.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, yh-missing-form-state.patch, failed testing.

yhager’s picture

Version: 7.0-rc2 » 7.0-rc3
Status: Needs work » Reviewed & tested by the community
FileSize
624 bytes

Rerolling, and setting back the status as before.

Any chance this would go in for D7? it holds back successful completion of imagefield_crop D7 version.

Damien Tournoud’s picture

Version: 7.0-rc3 » 7.x-dev

+1 here.

And yes, this FAPI property is completely undocumented.

webchick’s picture

Component: file system » documentation
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs documentation

Committed to HEAD. Thanks!

Moving to the documentation queue to get this property documented.

jhodgdon’s picture

What are we documenting, and where does it need documenting -- update guide? docblocks for api.drupal.org? Is this an API change that needs to be announced?

A summary would be most helpful...

webchick’s picture

Hm. I can't help you out with a summary of what it does. But the #file_value_callbacks property is missing from http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....

jhodgdon’s picture

Issue tags: +FAPI reference

Thanks -- adding a tag for the FAPI reference...

So is this an API change that we should add to the 6/7 module update guide, and/or have rfay announce?

webchick’s picture

This isn't an API change, per se, it's a new capability. D6 and below didn't have a managed_file FAPI type.

jhodgdon’s picture

Right, duh! :)

So the only place this needs to be documented is in the FAPI reference?

webchick’s picture

I think so, yep!

jhodgdon’s picture

Project: Drupal core » Documentation
Version: 7.x-dev »
Component: documentation » API documentation files
Issue tags: -Needs documentation

FAPI reference file is in the Documentation project now.

jn2’s picture

Title: Missing $form_state in callback call in file_managed_file_value » Need documentation for #file_value_callbacks property; Missing $form_state in callback call in file_managed_file_value
Status: Needs work » Needs review

I've done some research to document this property and need some input. There's very little on d.o. or the web about it, so I've had to extrapolate from the one mention I could find in core and the related #value_callback. It looks like the value function should be about the same as for that property. Here's what I have so far:
________________________________________________
Used by: managed_file

Description: Lists the names of custom value functions that implement how user input is mapped to a managed_file element's #value property. The related #value_callback property only allows one function name, so this property fills the missing functionality to allow File fields to be extended through the Form API.

Values: A list of value function names called to set the #value property for the managed file element.

A value function for a managed_file element takes $element, $input and $form_state as parameters, and has the form:

function myelement_file_value($element, $input = FALSE, $form_state = array()) {
  if ($input === FALSE) {
    return isset($element['#default_value']) ? $element['#default_value'] : 0;
  }
}

----------------------------------------------------------------------------------
I'm not sure if the value function must include _file_ in its name.

You may notice that managed_file does not have default_value marked as available in the FAPI reference table. However, the managed_file usage example from core includes this property. So I'll also change that when I add the #file_value_callbacks property.

I couldn't find any usage examples for #file_value_callbacks. It's not necessary to have one, but if someone wants to contribute one, I'll include it.

sven.lauer’s picture

Status: Needs review » Needs work

#13 is a good start, but note that, unlike #value_callback callbacks, the file module does NOT assign the return value to the #value property. Indeed, it assumes that nothing is returned by the callback (and hence, I guess, that the $element property is modified in place.

carstenG’s picture

Assigned: Unassigned » carstenG

#14 editing the referenced elements doesn't work....

here is the code snipped from file_managed_file_value() in file.module:

// Process any input and save new uploads.
  if ($input !== FALSE) {
    $return = $input;

    // Uploads take priority over all other values.
    if ($file = file_managed_file_save_upload($element)) {
      $fid = $file->fid;
    }
    else {
      // Check for #filefield_value_callback values.
      // Because FAPI does not allow multiple #value_callback values like it
      // does for #element_validate and #process, this fills the missing
      // functionality to allow File fields to be extended through FAPI.
      if (isset($element['#file_value_callbacks'])) {
        foreach ($element['#file_value_callbacks'] as $callback) {
          $callback($element, $input, $form_state);
        }
      }
      // Load file if the FID has changed to confirm it exists.
      if (isset($input['fid']) && $file = file_load($input['fid'])) {
        $fid = $file->fid;
      }
    }
  }

 ......
  $return['fid'] = $fid;
  return $return;

The import part is the return value. The #file_value_callbacks can only work (return or edit values) if element or input in the following part are merged into $return array. So in my point of view...at the moment this callback is almost useless... you can do only some additional calculations but u can't edit the element array.

foreach ($element['#file_value_callbacks'] as $callback) {
          $callback($element, $input, $form_state);
}
sven.lauer’s picture

Re: #15

That is not quite true. If the callback takes $input by reference, it can manipulate it, and thus, e.g., set $input['fid'] to some (new) value. This would be picked up in

   // Load file if the FID has changed to confirm it exists.
      if (isset($input['fid']) && $file = file_load($input['fid'])) {
        $fid = $file->fid;
      }

and then later merged into $return with

 $return['fid'] = $fid;

The documentation for this property should probably indicate that $input['fid'] is the thing to manipulate.

carstenG’s picture

yep. I know...but I cannot add some other keys.....

sven.lauer’s picture

@lordgil: That's true. For now, let's document the current behavior, though. Then we might post a follow-up issue to the forms component asking for better behavior in 8.x.

jhodgdon’s picture

Issue tags: +valid issue

Tagging so #1421874: [meta] Documentation Issue Queue Cleanup doesn't have to look at API docs issues.

carstenG’s picture

Assigned: carstenG » Unassigned
Issue summary: View changes