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.

Comments

berdir’s picture

Version: 7.10 » 7.x-dev
Priority: Critical » Normal

Please 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

davidwbarratt’s picture

Status: Active » Needs review
StatusFileSize
new617 bytes

sweet! here's the patch! (I've never done this before!) :)

davidwbarratt’s picture

woot! the patch worked! submitted my first drupal patch. :) thanks for the encouragement!

davidwbarratt’s picture

Status: Needs review » Reviewed & tested by the community

After 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.

berdir’s picture

Status: Reviewed & tested by the community » Needs review

Marking your own patches as RTBC is not allowed, especially not without a single review.

plach’s picture

Version: 7.x-dev » 8.x-dev
StatusFileSize
new1.29 KB

@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?

arnoldbird’s picture

I 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.

plach’s picture

@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.

arnoldbird’s picture

@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

plach’s picture

Perhaps this bug isn't the same as the bug in the other thread after all?

Yes, this seems to indicate they are two different bugs after all.

andypost’s picture

#6: file_ajax-1404480-6.patch queued for re-testing.

andypost’s picture

Issue tags: +Needs tests
cweagans’s picture

Issue tags: +Needs backport to D7
klonos’s picture

klonos’s picture

Issue summary: View changes

Fixed a typo

Status: Needs review » Needs work

The last submitted patch, 6: file_ajax-1404480-6.patch, failed testing.

estoyausente’s picture

Status: Needs work » Needs review

This function doesn't exist yet inside file module. I think that not need reroll, only close and discard this issue.

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

The code has moved to Drupal\file\Controller\FileWidgetAjaxController::upload(), but at a quick glance, it looks like this would still be an issue.

nlisgo’s picture

Issue tags: -Needs reroll
StatusFileSize
new1.26 KB

We still need clear steps to recreate the issue in D8. This is a reroll.

nlisgo’s picture

Status: Needs work » Needs review
jhedstrom’s picture

Status: Needs review » Needs work

Needs work for tests.

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.

joseph.olstad’s picture

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.

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

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Status: Needs work » Closed (outdated)
Issue tags: +Bug Smash Initiative

I 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