I received the following error whenever I was creating a custom audio field.
Notice: Undefined index: in file_ajax_upload() (line 258 of modules/file/file.module).
Here is the code that the error is referring too:
// Get the current element and count the number of files.
$current_element = $form;
foreach ($form_parents as $parent) {
$current_element = $current_element[$parent];
}
$current_file_count = isset($current_element['#file_upload_delta']) ? $current_element['#file_upload_delta'] : 0;
Here is the code to reproduce the error:
audio.install
<?php
/**
* Implements hook_field_schema().
*/
function audio_field_schema($field) {
return array(
'columns' => array(
'fid' => array(
'description' => 'The mp3 {file_managed}.fid being referenced in this field.',
'type' => 'int',
'not null' => FALSE,
'unsigned' => TRUE,
),
'ogg_fid' => array(
'description' => 'The ogg {file_managed}.fid being referenced in this field.',
'type' => 'int',
'not null' => FALSE,
'unsigned' => TRUE,
),
'uid' => array(
'description' => "The {users}.uid being referenced in this field.",
'type' => 'int',
'not null' => FALSE,
'unsigned' => TRUE,
),
'title' => array(
'description' => "Audio title text",
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'desc' => array(
'description' => "Audio description text",
'type' => 'text',
'size' => 'big',
'not null' => FALSE,
),
'length' => array(
'description' => 'The length of the audio in seconds.',
'type' => 'int',
'unsigned' => TRUE,
),
),
'indexes' => array(
'fid' => array('fid', 'ogg_fid'),
'uid' => array('uid'),
),
'foreign keys' => array(
'fid' => array(
'table' => 'file_managed',
'columns' => array('fid' => 'fid', 'ogg_fid' => 'fid'),
),
'uid' => array(
'table' => 'users',
'columns' => array('uid' => 'uid'),
),
),
);
}
audio.module
<?php
/**
* Implements hook_field_info().
*/
function audio_field_info() {
return array(
'audio' => array(
'label' => t('Audio'),
'description' => t('This field handles HTML5 Audio'),
'default_widget' => 'audio_simple',
'default_formatter' => 'audio_player',
'settings' => array(
'uri_scheme' => 'private',
),
'instance_settings' => array(
'file_extensions' => 'mp3',
'file_directory' => 'audio/mp3',
),
),
);
}
/**
* Implements hook_field_is_empty().
*/
function audio_field_is_empty($item, $field) {
if ($field['type'] == 'audio') {
return file_field_is_empty($item, $field);
}
return FALSE;
}
/**
* Implements hook_field_widget_info().
*/
function audio_field_widget_info() {
return array(
'audio_simple' => array(
'label' => t('Audio'),
'description' => t('Add audio by file type.'),
'field types' => array('audio'),
'settings' => array(
'progress_indicator' => 'throbber',
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
'default value' => FIELD_BEHAVIOR_DEFAULT,
),
),
);
}
/**
* Implements hook_field_widget_form().
*/
function audio_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
if ($instance['widget']['type'] == 'audio_simple') {
// Add display_field setting to field because file_field_widget_form() assumes it is set.
$field['settings']['display_field'] = 0;
$elements = file_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
foreach (element_children($elements) as $delta) {
// Add all extra functionality provided by the image widget.
$elements[$delta]['#process'][] = 'audio_field_widget_process';
}
if ($field['cardinality'] == 1) {
// If there's only one field, return it as delta 0.
if (empty($elements[0]['#default_value']['fid'])) {
$elements[0]['#description'] = theme('file_upload_help', array('description' => $instance['description'], 'upload_validators' => $elements[0]['#upload_validators']));
}
} else {
$elements['#file_upload_description'] = theme('file_upload_help', array('upload_validators' => $elements[0]['#upload_validators']));
}
$elements = $elements[0];
unset($elements[0]);
}
return $elements;
}
/**
* An element #process callback for the audio field type.
*
* Expands the audio type to include the title, description, and ogg file fields.
*/
function audio_field_widget_process($element, &$form_state, $form) {
$item = $element['#value'];
$item['fid'] = $element['fid']['#value'];
$instance = field_widget_instance($element, $form_state);
$upload_validators = $element['#upload_validators'];
$upload_validators['file_validate_extensions'] = array('ogg');
$element['ogg_fid'] = array(
'#name' => 'blah',
'#type' => 'managed_file',
'#title' => t('ogg'),
'#upload_location' => 'private://audio/ogg',
'#upload_validators' => array(
'file_validate_extensions' => array('ogg'),
),
'#default_value' => !empty($item['ogg_fid']) ? $item['ogg_fid'] : '',
'#access' => (bool) $item['fid'],
'#description' => empty($item['ogg_fid']) ? theme('file_upload_help', array('description' => $instance['description'], 'upload_validators' => $upload_validators)) : null,
);
$element['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => isset($item['title']) ? $item['title'] : null,
'#access' => (bool) $item['fid'],
);
return $element;
}
/**
* Implements hook_field_presave().
*/
function audio_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
foreach ($items as $item) {
$fids = array(
$item['fid'],
$item['ogg_fid'],
);
foreach ($fids as $fid) {
if (!empty($fid)) {
$file = file_load($fid);
if (!empty($file->status)) {
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
}
if (!empty($file) && !empty($entity_type) && !empty($id)) {
file_usage_add($file, 'audio', $entity_type, $id);
}
}
}
}
}
If you enable the module, then create an "Audio" field on a node, then you will need to upload an mp3 file (which works fine), after that you will get the ogg_fid field, upload the ogg file and you will receive the error. However, even with the error, the field will save properly.
I noticed that for some reason all of the "ogg_fid" data is being saved with a child of "fid", (look at the name of the form element in the HTML), however, I couldn't find a way to remove this child (which I assume is what is causing the error).
I'm assuming the code could be changed to something like this:
// Get the current element and count the number of files.
$current_element = $form;
foreach ($form_parents as $parent) {
if (!empty($current_element[$parent])) {
$current_element = $current_element[$parent];
}
}
$current_file_count = isset($current_element['#file_upload_delta']) ? $current_element['#file_upload_delta'] : 0;
However, I do not have enough experience with file.module to know if it will break something or not.
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | notice_undefined-1404480-19.patch | 1.26 KB | nlisgo |
| #6 | file_ajax-1404480-6.patch | 1.29 KB | plach |
| #2 | 1404480-file-upload-php-notice.patch | 617 bytes | davidwbarratt |
Comments
Comment #1
berdirPlease provide a patch for your change, then the testbot will run and and we'll see what happens.
I don't think this classifies as critical, it might actually as well be a bug in the contrib modules you're using. Have a look at the Priority documentation page to see which priority to select: http://drupal.org/node/45111
Comment #2
davidwbarratt commentedsweet! here's the patch! (I've never done this before!) :)
Comment #3
davidwbarratt commentedwoot! the patch worked! submitted my first drupal patch. :) thanks for the encouragement!
Comment #4
davidwbarratt commentedAfter several weeks of testing, and noting that this edit only modifies two lines of code, I am moving the status of this patch to reviewed & tested.
Comment #5
berdirMarking your own patches as RTBC is not allowed, especially not without a single review.
Comment #6
plach@davidwbarratt:
Bugs are first fixed in the dev version and then backported.
Actually I stumbled upon what appears to be the same issue. From my investigations it seems the problem is that the file form element is retrieved before processing the form. In my case merging the two loops before and after form processing does the trick. Posting a 8.x patch with my fix to see if the bot complains. The patch should apply cleanly to the 7.x branch with -p2.
Would you please check if this patch fixes your issue?
Comment #7
arnoldbird commentedI may be jumping the gun on testing in D7, but the code in patch #6 gives...
Notice: Undefined index: #suffix in file_ajax_upload() (line 283 of /var/www/hiusa/public_html/modules/file/file.module).That's in 7.12.
Comment #8
plach@arnoldbird:
Are you running automated tests? Is it a plain 7.12 installation? If not you might be experiencing the same issue reported in #1336212: "Notice: Undefined index: field_xxx in file_ajax_upload()" and "Undefined index: #suffix in file_ajax_upload", which might not be related to this one.
I run the file widget automated test on a patched 7.x plain installation and I get all green.
Comment #9
arnoldbird commented@plach:
If I apply the patch to a clean 7.12 install, I don't get the #suffix error I mentioned above. The patch applies cleanly. However, the patch doesn't fix the bug for me. I'm still able to repro the bug according to the instructions I posted in the other thread at http://drupal.org/node/1336212#comment-5802090
I can repro the bug in both the bartik and seven themes.
Perhaps this bug isn't the same as the bug in the other thread after all?
Thanks
Comment #10
plachYes, this seems to indicate they are two different bugs after all.
Comment #11
andypost#6: file_ajax-1404480-6.patch queued for re-testing.
Comment #12
andypost@plach There's a similar issue #1067470: PHP notice on AJAX upload for file_managed fields added during element #process callback
Not sure which one is preferable
Comment #13
cweagansUpdating tags per http://drupal.org/node/1517250
Comment #14
klonos...coming from #1067470: PHP notice on AJAX upload for file_managed fields added during element #process callback
Comment #14.0
klonosFixed a typo
Comment #17
estoyausenteThis function doesn't exist yet inside file module. I think that not need reroll, only close and discard this issue.
Comment #18
jhedstromThe code has moved to
Drupal\file\Controller\FileWidgetAjaxController::upload(), but at a quick glance, it looks like this would still be an issue.Comment #19
nlisgo commentedWe still need clear steps to recreate the issue in D8. This is a reroll.
Comment #20
nlisgo commentedComment #21
jhedstromNeeds work for tests.
Comment #24
joseph.olstadThis issue was created in 2012 and is a duplicate of another created in 2011
Here is the original issue:
#1067470: PHP notice on AJAX upload for file_managed fields added during element #process callback
Comment #36
quietone commentedI think this is outdated due to #2500527: Rewrite \Drupal\file\Controller\FileWidgetAjaxController::upload() to not rely on form cache
If that is incorrect re-open this issue and add a comment.
Thanks