Download & Extend

Parameter 1 to upload_replace_file_update() expected to be a reference, value given in module_invoke_all()

Project:Upload File Replace (for filefield CCK)
Version:7.x-1.x-dev
Component:Miscellaneous
Category:bug report
Priority:normal
Assigned:Unassigned
Status:reviewed & tested by the community

Issue Summary

I get this warning, when I upload a existing file: Warning: Parameter 1 to upload_replace_file_update() expected to be a reference, value given in module_invoke_all() (line 817 of /var/www/drupal/includes/module.inc).

This also causes, that the module don't do it's job. The newest file still gets _x behind file name.

Comments

#1

Same problem

#2

I also have the same problem

#3

I'm also getting this message.

#4

+1 on this. I too am receiving this warning. Also getting it for upload_replace_file_delete() as well.

#5

Likewise, though I'm in D6

#6

I'm pretty sure this is because hook_file_update and hook_file_delete are not supposed to take a referenced argument. The & needs to be removed from the function definition of these hook implementations.

#7

+1

#8

Version:7.x-1.x-dev» 6.x-1.2

I get this same problem on D6, but only when using the workflow module to publish the most current pending revision. If I don't use the workflow module, and just click "Publish This" in the Revisions tab it works as it is suppose to and I don't get the trailing _0. It would be nice to be able to use the workflow module with this module.

#9

For Drupal 7 you have to change the access to the file object and also the database requests:

<?php
/**
* @file
* A module file for providing functionality to replace files on upload
* Typical Drupal behavior is to rename files on upload to <filename>_0.<ext>
* This module modifies that behavior.
*
* 1.0 - Behavior is as follows: when a user is replacing a file (remove and save).
*   if the file to be removed is <filename>.<ext> and the file to be saved is
*   <filename>_<[0-9]+>.<ext> then the file will be removed and the new file will
*   be renamed to <filename>.<ext>
*/


/**
* Implementation of hook_file_update()
*/
function upload_replace_file_update($new_file) {
  if (!
$new_file->fid) {
   
//Nothing to do if no fileid
   
return;
  }
 
$desired_destination = preg_replace('/_[0-9]+\.(.*)$/', '.$1', $new_file->uri);
 
$db_path = db_select('file_managed', 'f')
    ->
fields('f', array('uri'))
    ->
condition('fid', $new_file->fid)
    ->
execute()
    ->
fetchAssoc();
  if (
$db_path['uri'] != $new_file->uri) {
   
//this happens when a reversion is being reverted
   
$next_good_uri = file_destination($desired_destination, FILE_EXISTS_RENAME);
   
db_update('file_managed')
      ->
fields(array('uri' => $next_good_uri))
      ->
condition('fid', $new_file->fid)
      ->
execute();
   
$new_file->uri = $desired_destination;
  }
  else {
   
//If the filename has be modified by adding a _0 value, or
    //on certain situations the uri will not match the uri in the db, such as
    //when reverting a revision.  When reverting a revision change the filename as well
   
if (!strpos($new_file->uri, $new_file->filename)) {
     
//the filename is not in the uri, so drupal must have added a "_0" before the extension
      //find the file that is blocking this file from keeping the correct path
     
$result = db_select('file_managed', 'f')
        ->
fields('f')
        ->
condition('uri', $desired_destination)
        ->
execute();
     
//@todo only one result is handled, should allow for multiple results
     
foreach ($result as $file) {
       
$is_blocked = TRUE;
       
$blocking_file = $file;
       
$tmp_destination = file_directory_temp()."/test_-".$blocking_file->fid."_-".$blocking_file->filename."";
      }

     
$old_destination = $db_path['uri'];
     
//Swap the files
     
if ($is_blocked) {
       
//move the blocking file to a temparary location
       
if (!file_unmanaged_move($desired_destination, $tmp_destination)) {
         
drupal_set_message(t('The file %old could not be moved to %new', array('%old' => $desired_destination, '%new' => $tmp_destination)), 'error');
          return;
        }
       
//DRUPAL 7 no longer changes the source uri during move
        //move blocking file was successful, update the DB
       
db_update('file_managed')
          ->
fields(array('uri' => $tmp_destination))
          ->
condition('fid', $blocking_file->fid)
          ->
execute();
      }


     
//move the newfile to the prefered location
     
if (!file_unmanaged_move($old_destination, $desired_destination)) {
       
drupal_set_message(t('The file %old could not be moved to %new', array('%old' => $old_destination, '%new' => $desired_destination)), 'error');
        return;
      }
     
//move newfile was successful, update the DB
     
db_update('file_managed')
        ->
fields(array('uri' => $desired_destination))
        ->
condition('fid', $new_file->fid)
        ->
execute();
     
$new_file->uri = $desired_destination;//set the newfile's path to the correct path


     
if ($is_blocked) {
       
//move the older file from temp to the new _0 location
       
if (!file_unmanaged_move($tmp_destination, $old_destination)) {
         
drupal_set_message(t('The file %old could not be moved to %new', array('%old' => $tmp_destination, '%new' => $old_destination)), 'error');
          return;
        }
       
//move blocking file was successful, update the DB with the actual location after file copy, so we use tmp_destination as it was updated during the move
       
db_update('file_managed')
          ->
fields(array('uri' => $old_destination))
          ->
condition('fid', $blocking_file->fid)
          ->
execute();
      }
    }
  }
 
//Have to clear the cache because the revision data is cached somewhere
  /*
   * Find the nids where this file is used
  $query = "SELECT DISTINCT id FROM {file_usage} WHERE fid=%d";
  $result = db_query($query, $new_file->fid);
  while($data = db_fetch_object($result)) {
    cache_clear_all("node:$data->id");
  }
  */
  //This is inefficent, but how can we determine what nodes use this file?
// cache_clear_all('*', 'cache_content', TRUE);
}

/**
* HOOK_file_delete, update the uri in the file object before deleting as we may have altered it above
* @param object $new_file
*/
/*
function upload_replace_file_delete($file) {
  $file->uri = db_result(db_query("SELECT uri FROM {file_managed} WHERE fid = %d", $file->fid));
}
*/
?>

#10

Version:6.x-1.2» 7.x-1.0-beta1

I'm confused: Is the revised code in #9 proposed as a patch? Is anyone with commit privs planning to commit it? Thanks.

#11

Version:7.x-1.0-beta1» 7.x-1.x-dev

Just replace the code in the file "sites/all/modules/upload_replace/upload_replace.module" with this new code.
(-> I think the original code was made for Drupal 6 - and just copied.)

#12

replaced the .module file with the code from #9...works fine.

#13

Status:active» reviewed & tested by the community

Code from #9 works for me. Here it is in a patch. I think this can go in.

AttachmentSize
upload_replace_error-1115484-13.patch 4.53 KB

#14

So, does #8/#13 work in v6 and/or will it be rolled in to an beta or updated version?