The completion of this issue allowed us to replace an existing files entity file: #1123570: Replace file while retaining field metadata

Media module also handles offsite media content using modules such as media_youtube and media_vimeo. Since these aren't onsite files (using file entity) there doesn't seem to be a way to replace these without creating a completely new file entity.

Can someone confirm this is true? I'm assuming it is from what I see and I'm adding this as a feature request.

Comments

dave reid’s picture

Since the purpose of the functionality is to provide an updated version of the same file, the proper way to do that with remote files would be to provide and updated version on the remote providers themselves (upload a new version to YouTube, Vimeo, etc. directly).

Rob_Feature’s picture

Yeah, I see what you mean, but there are situations when you actually want a different url for the same video. In our case, for example, we're migrating all videos from bliptv to vimeo, so everything is the same for the file except the url.

Rob_Feature’s picture

Just a bump on this...anyone talked about this as media/file entity have matured?

What I think Dave's response doesn't consider is that, on a file entity, the file/offsite media field itself is just ONE field among (potentially) many (ie. this was the advance in D7 that is being forgotten, I think). Since we can add custom fields to a file, it's reasonable to assume that there's times when all the fields would remain the same EXCEPT the media field itself, which we'd want to 'replace' with new data (ie. changing our thinking from node-centric like in D6, to entity-centric beyond)

Since we can do this with files themselves (they can be replaced in this manner), it seems like a reasonable feature request to be able to do it with offsite media. In all other ways the module attempts to handle onsite files and offsite media in similar ways.

Any further thoughts?

amaisano’s picture

Component: File entity » Code
Issue summary: View changes

+1 for the ability to do this. I have several "offsite" media file entities that point to "http://www.website.com/file.mp3" for example, and those are attached to many nodes on the site. If for some reason that URL on the source server changes or breaks, to something like "http://www.new-website.com/file.mp3," I currently have no way of globally updating that reference on the Drupal site for that file entity. Instead of just updating/replacing the existing entity's URL, I would have to delete that file completely, create a new one, and then re-attach it to all the nodes on Drupal that referenced that file.

dman’s picture

See also #2541250

We have shifted to the abstraction of using file_entities as metadata wrappers on the promise that linking to the wrapper will be safer into the future than the filepath - so that client can safely replace the pdf in question without breaking incoming links.
And - this extends to them being able to link to offsite PDFs in the same way, and having the ability to redirect the target of that reference if the remote location moves, breaks, or is archived.
Without the ability to 'Replace URL' there, this doesn't seem to be possible.

This use-case is not a problem from within media or file_entity especially, as they are fine on their own.
So I guess it should be a fix provided from remote_file_wrappers that introduced the problem?

<?
// Add a 'replace this file' upload field if the file is writeable.
if (file_entity_file_is_writeable($file)) {
?>

A form_alter that goes if_file_url_is_remote() then add 'change this url' field...

dieuwe’s picture

Status: Active » Needs review

I've got a working code sample here, this needs a lot more thought and work, but it is functional.

I've made it specific to oEmbed (because it's what we're using 99% of the time).

If this were to be supported at the media level I think we would require some API changes that any internet sources providers would have to implement, so the best course of action might just be to close off this issue and shift the discussion to a specific provider.

/**
 * Implements hook_form_FORM_ID_alter().
 */
function drupalsouth_form_file_entity_edit_alter(&$form, &$form_state) {
  $file = $form_state['file'];

  // This is oEmbed specific.
  if (!isset($file->oembed['original_url'])) {
    return;
  }

  // Create a tabbed fieldset to get this out of the main form display.
  $form['uri'] = array(
    '#type' => 'fieldset',
    '#title' => 'Change file URI',
    '#description' => 'Do not touch this unless you know what you are doing.',
    '#group' => 'additional_settings',
  );

  // Copy 'embed code' field from 'add' form to this 'edit' form.
  $upload_form = drupal_get_form('media_internet_add_upload');
  $form['uri']['embed_code'] = $upload_form['embed_code'];
  $form['#providers'] = $upload_form['#providers'];
  $form['#validators'] = $upload_form['#validators'];

  // Provide the current URL as the default.
  $original_url = $file->oembed['original_url'];
  unset($form['uri']['embed_code']['#value']);
  $form['uri']['embed_code']['#default_value'] = $original_url;

  // Check with media that edited URL is valid.
  $form['actions']['submit']['#validate'][] = 'media_internet_add_validate';

  // Custom submit callback is specific to oEmbed, as you might expect
  // the one in media for 'add' will not work for an 'edit' form.
  $form['actions']['submit']['#submit'][] = 'drupalsouth_file_entity_edit_submit';
}

/**
 * Validation callback.
 */
function drupalsouth_file_entity_edit_validate($form, &$form_state) {
  // @todo We can't let the user change to a different file_entity type.
  // @todo We can't let the user change provider types.
}

/**
 * Submit callback.
 */
function drupalsouth_file_entity_edit_submit($form, &$form_state) {
  $embed_code = $form_state['values']['embed_code'];
  $file = file_load($form_state['file']->fid);
  $original_url = $file->oembed['original_url'];

  if ($embed_code !== $original_url) {
    $file->uri = 'oembed://' . drupal_encode_path($embed_code);
    $file->oembed = oembed_get_data($embed_code);
    file_save($file);
  }
}
dieuwe’s picture

I should add that I have just discovered that on the latest dev version, oEmbed has changed they the way it stores and accesses its data, so there are 4 places above where you'd need to replace $file->oembed with $file->metadata['oembed'].

phily’s picture

This would be a very helpfull feature to be able to update an existing offsite video url without the need to create a new one and relink all nodes where the older one is used/referenced.