This simple test form triggers the following Fatal error on submit (make sure to upload a file...):
"Cannot use object of type stdClass as array in /var/www/drupal/includes/form.inc on line 1320"

Without the "#tree = true" it works fine.

function tst_form(&$form_state) {
  $form['#attributes']['enctype'] = 'multipart/form-data';
  $form['#tree'] = true; // remove me...

  $form['image'] = array(
    '#type'   => 'image_upload_element',
    '#title' => 'img',
    '#required' => true,
  );

  $form['submit'] = array(
   '#type' => 'submit',
   '#value' => 'Submit',
   );

  return $form;
}

Comments

alan d.’s picture

Priority: Critical » Normal

It looks like this is a possible issue with saving objects as element values in Drupal, which was the primary philosophy behind the module.

Casting the file object to an array bypasses this error in "form.inc", but breaks the module as it is expecting an object not an array.

If this is the case, then the module will have to be completely rewritten, a task that I simply do not have time to do at the moment.

I will update the intro to note this issue and leave this issue open in case some FAPI genius can come up with a simple workaround.

Otherwise it will have to wait till the next major release (6.x-2.0), as the changes will change the basic interface of the module. I am also planning multiple file support, so it is going to be a fairly major job for the next release.

edgar83’s picture

My solution is to put #tree = false on the upload element in my form. The form stays nested, except for this specific element.

Thanks for your great module btw :-)

alan d.’s picture

Version: 6.x-1.1 » 6.x-1.x-dev

Thanks for the feedback / workaround.

I'll leave this issue open for a future releases / versions.

Electronick’s picture

We can use simple (object)$array and (array)$object conversion. But don't know where.

alan d.’s picture

The solution is not as simple as this. Casting all of the objects into arrays cascaded into another series of bugs. This should be addressed later when things get refactored a bit.

jaypan’s picture

This is still an issue - I just dealt with it.

I believe that the problem in the way that the upload element renders the HTML ID attribute of the elements. When items are set to #tree, the ID gets square parentheses ([ and ]) inserted into ID. This is invalid HTML. I went in and changed upload_element.module myself and hardcoded an ID for testing purposes, and the element began to work again. Of course, this isn't something I want to depend on.

What I ended up doing was removing #tree, and instead naming my elements like this:

$form['element_' . $id] = array
(
  '#type' => 'image_upload_element',
  '#title' => t('Image'),
);

I had to add in a little regex on the processing end to deal with this however. This adds an extra load on the server, so it's by no means an optimal solution. However, this is the only way I could think to take care of the issue without having to alter the original module code.

madmanmax’s picture

You cannot set #tree = TRUE and use file_save_upload. See this thread: #83698: $source parameter in file_save_upload() not work as expected when field is in a fieldset with #tree set to TRUE
I had a hard time with this when making my own upload fields. Comment #6 is the only workaround I found so far. I'm not sure if you need regex for this though.

define('IMAGE_NO', 3); // How many image fields we need.

	$form['images'] = array(
	  '#title' 		=> t('Images fieldset'),
	  '#type' 		=> 'fieldset',
	
	for ($i = 1; $i <= IMAGE_NO; $i++) {
		$form['images']['image_' . $i] = array(
			'#title' => t('Upload picture @index', array('@index' => $i)),
			'#type' => 'image_upload_element',
			// ... Other form element properties
		);
	}
}

// In the validation or submit function we can just do this

$destination = file_directory_path() . 'some/custom/destination'/; // Where we want the images to be saved.
for ($i= 1; $i <= IMAGE_NO; $i++) {
	if (!empty($form_state['values']['upload_' . $i])
		  && is_object($form_state['values']['upload_' . $i])) {
		// Save the uploaded file.
		$file = $form_state['values']['upload_' . $i];
		$fid = upload_element_save(&$file, $destination, FILE_EXISTS_RENAME, 'imagecache_preset');
	}
}
alan d.’s picture

Issue summary: View changes
Status: Active » Closed (outdated)