24

How do you set the value of a file field when using the entity_metadata_wrapper?

I've tried doing this in code:

$file = new stdClass();
$file->uid = 1;
$file->uri = $file_path;
$file->filename = basename($file_path);
$file->filemime = file_get_mimetype($file_path);
$file->filesize = filesize($file_path);
$file->status = FILE_STATUS_PERMANENT;
$file->display = '1';
file_save($file); // I also tried: $file = file_save($file);

$node = array(
  'type' => 'news_item',
  'uid' => 1,
  'status' => 1,
  'comment' => 0,
  'promote' => 0,
  'language' => 'en',
);

$entity = entity_create('node', $node);

$ewrapper = entity_metadata_wrapper('node', $entity);

$ewrapper->field_document->set((array) $file); // I also tried: $ewrapper->field_document->set($file);

$ewrapper->save(true);
entity_save('node', $entity);

But I get this exception:

EntityMetadataWrapperException: Invalid data value given. Be sure it matches the required data type and format. in EntityMetadataWrapper->set() (line 122 of C:\wamp\www\drupal\sites\all\modules\entity\includes\entity.wrapper.inc).

Any help is very mych appreciated.

5 Answers 5

14

Wrapping the file array in another array seems to do the trick for me:

$file = (array) $file;
$items = array($file);
$ewrapper->field_document->set($items);

But I haven't found out why yet...

3
  • That does indeed do the trick. Thanks alot for your help, appreciate it!
    – Smos
    Commented Apr 11, 2013 at 7:36
  • 5
    I believe it has something to do with the delta index of the field. If you don't assign a delta index to your field (i.e. $ewrapper->field_name->set(); ), you have to wrap another array around it. If you do assign a delta index to your field (i.e. $ewrapper->field_name[0]->set(); ), you can just use $file = (array) $file.
    – Smos
    Commented Apr 12, 2013 at 12:45
  • Yes that makes a lot of sense, thanks for following up
    – Clive
    Commented Apr 12, 2013 at 12:47
20

Well I just found out a simpler and less ugly looking way to set image.

$image_file = A FILE OBJECT; //Lot of choices here : new stdClass(), file_load, etc
$wrapper->FIELD_NAME->file->set($image_file);

Just as taxonomy or node/entity reference, the file field name point on a loaded object, thats how I find out.


:: EDIT a posteriori ::

Here how I would have do it with OP question.

// Get the file
$file = file_save_data(file_get_contents('/my_local_path/img1.jpg'), 'public://remote_name.jpg');

// Wrap' it like one of your French girls
$wrapper = entity_metadata_wrapper('node', $node);

// And set the photo
$wrapper->field_photo->file->set($file);

// And save the node
$wrapper->save();
5
  • Fatal error: Call to a member function set() on null... I'm able to add some text fields, but adding a file just doesn't work
    – PatrickS
    Commented Feb 7, 2015 at 11:21
  • @PatrickS You sure you created a file object ? Even the method from Clive didn't work ?
    – JudaPriest
    Commented Feb 13, 2015 at 13:17
  • I'm attempting to migrate some Joomla content into Drupal. The first time I migrate the files, it works. If I erase all the Products and attempt another migration, it doesn't work anymore. The only way I get it to work is from a fresh install. I have stored the Joomla data in a JSON file, which I use to create the entities. At the time I left the comment, I hadn't yet realised that only the first import was working & I was trying all sort of methods to create the entities. I had no idea what was going on since I was able to create all the fields, except the images!
    – PatrickS
    Commented Feb 15, 2015 at 6:35
  • 1
    The new stdClass() comment mislead me a little, assuming I could assign a newly created file object to a field directly. When using this, make sure the file has a fid assigned (i.e. it has been saved at least once), otherwise this will not work. Commented Dec 31, 2015 at 11:19
  • How would you apply this for multiple file field ? I think it should be something like $wrapper->field_photo[]->file->set($file) but I'm not sure. Have you ever faced this situation? Commented Jun 1, 2016 at 8:50
5

My node already existed and I had to set the following parameters:

$wrapper->field_pdf->set(array('fid'=>$fid, 'display'=>1, 'description'=>'This is a PDF'));

Different set-ups may require different parameters I suppose. If you look in your error logs (admin/reports/dblog) you can see what parameters are needed.

1
  • 1
    This worked for me. I could add the file field no problem, but it wouldn't show as display was 0 for some reason.
    – aross
    Commented Nov 13, 2014 at 17:12
1

Just in case anybody would find this helpful:

If you don't have an actual file handle and only know the fid you can use:

$wrapper->field_file->set( array( 'fid'=>1234 ) );

And (assuming a file with that fid exists) Drupal will attach the correct file upon $wrapper->save().

0

You have two ways to do it:

// By loading the file object in any way
$file_obj = file_load($fid);
$w_containing_node->field_attachment_content->file->set( $file_obj );


// By passing an array with the fid
$w_containing_node->field_attachment_content->set( array('fid' => $fid) );

Here is the source of the information: https://www.drupal.org/docs/7/api/entity-api/entity-metadata-wrappers#example-value-set-save

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.