Upload Archives helps to maintain the orignal names of files uploaded to Drupal. Rather than append '_n' to the filename, Upload Archives creates a folder based on the filename and a timestamped subdirectory. All files with the same file name are organized in a shared folder, with each version stored in a unique timestamped folder with the original filename intact.

Project page

git clone --branch 7.x-1.x http://git.drupal.org/sandbox/jeffwylarsen/2383849.git upload_archives

Code review

Comments

PA robot’s picture

We are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and put yourself on the high priority list, then we will take a look at your project right away :-)

Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).

I'm a robot and this is an automated message from Project Applications Scraper.

jwylarsen’s picture

Issue summary: View changes
jwylarsen’s picture

Issue summary: View changes
sendinblue’s picture

Assigned: Unassigned » sendinblue

For review by me

sendinblue’s picture

Assigned: sendinblue » Unassigned
Status: Needs review » Needs work

Automated Review

Please check this: http://pareview.sh/pareview/httpgitdrupalorgsandboxjeffwylarsen2383849git
Coder Sniffer has found some issues with your code (please check the Drupal coding standards).

FILE: /var/www/drupal-7-pareview/pareview_temp/README.txt
--------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
--------------------------------------------------------------------------------
43 | ERROR | Files must end in a single new line character
--------------------------------------------------------------------------------

Please fix this error.

Manual Review

- All variables used in module should delete in hook_uninstall.

jwylarsen’s picture

Status: Needs work » Needs review

Thank you sendinblue. The issues noted have been addressed.

moravia’s picture

Status: Needs review » Needs work

Hello,

I tried your plugin and when I uploaded a file, it was saved successfully to the directory but I got this message:
Notice: Trying to get property of non-object in upload_archives_file_update() (line 42 of .../drupal/modules/upload_archives/upload_archives.module).
Continued with:

Uploaded file moved from public://1.jpg to .
File public://1.jpg removed.
Page file test has been updated.

Any idea why? Also at some point it somehow didnt delete removed file. Unfortunatelly I tried to do that again and for now I didnt succeed. Hope this will be helpful.

Also according to my opinion it would be useful, if you update your project page with some information from readme file (at least requirements are heplful :-)).

jwylarsen’s picture

Status: Needs work » Needs review

Moravia,

Thank you for your comments. I swapped a function for one that returned a string instead of a reference to a file object, resulting in the error you've noted. The mistake has been fixed, and I've also updated the project page.

Thanks again for your review.

moravia’s picture

Great! I didn't find any other bugs, hope it's ok now :)

jwylarsen’s picture

bump

jwylarsen’s picture

jwylarsen’s picture

Anyone willing to call this "RTBC"?

nileshlohar’s picture

Automated Review

Their are some issues at http://pareview.sh/pareview/httpgitdrupalorgsandboxjeffwylarsen2383849git

Manual Review

Individual user account
Yes: Follows the guidelines for individual user accounts.
No duplication
Yes: Does not cause module duplication and/or fragmentation.
Master Branch
Yes: Follows the guidelines for master branch.
Licensing
Yes: Follows the licensing requirements.
3rd party assets/code
Yes: Follows the guidelines for 3rd party assets/code.
README.txt/README.md
Yes: Follows the guidelines for in-project documentation and/or the README Template.
Code long/complex enough for review
No: Does not follow the guidelines for project length and complexity as their are only 4 functions.
Secure code
Yes: Meets the security requirements.
Coding style & Drupal API usage
    Not a Blockers but just a recommendations:
  1. When i change "Upload Archives directory name" it doesn't renames existing directory but creates new one.

The starred items (*) are fairly big issues and warrant going back to Needs Work. Items marked with a plus sign (+) are important and should be addressed before a stable project release. The rest of the comments in the code walkthrough are recommendations.

If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.

This review uses the Project Application Review Template.

valentine94’s picture

I think would be better to divide a upload_archives_file_update() to a next few functions(this will improve readability):
Old hook:

/**
 * Implements hook_file_update().
 */
function upload_archives_file_update($new_file) {

  $old_uri = $new_file->uri;
  // Clean up filename for directory name.
  $dir_name = preg_replace('/\./', '_', $new_file->filename);

  $user_folder = variable_get('upload_archives_foldername') ? variable_get('upload_archives_foldername') . '/' : NULL;

  $time_folder = variable_get('upload_archives_subfolder_format') ? $new_file->timestamp : date('Y\-m\-d\_H\h\-i\m\-s\s', $new_file->timestamp);

  $file_streamwrapper = file_uri_scheme($old_uri);

  $file_location = $file_streamwrapper . '://' . check_plain($user_folder) . $dir_name . '/' . $time_folder;
  $new_uri = $file_location . '/' . $new_file->filename;

  // file_move will trigger another call to hook_file_update, so we check to see
  // if the file has already been moved before trying to move it.
  if ($old_uri != $new_uri && file_exists($old_uri)) {

    file_prepare_directory($file_location, FILE_CREATE_DIRECTORY || FILE_MODIFY_PERMISSIONS);

    // file_move doesn't work with Private files, so we'll file_copy and then
    // file_delete.
    $moved_file = file_unmanaged_copy($old_uri, $new_uri, FILE_EXISTS_RENAME);

    if ($moved_file) {
      $new_file->uri = $moved_file;
      file_save($new_file);
      drupal_set_message(t('Uploaded file copied from <i>@old</i> to <i>@new</i>.', array('@old' => $old_uri, '@new' => $moved_file)));
      if (file_unmanaged_delete($old_uri, TRUE)) {
        drupal_set_message(t('File <i>@old</i> removed.', array('@old' => $old_uri)));
      }
    }
  }
}

New hook:

/**
 * Implements hook_file_update().
 */
function upload_archives_file_update($new_file) {
  $data = _upload_archives_prepare_update($new_file);
  // file_move will trigger another call to hook_file_update, so we check to see
  // if the file has already been moved before trying to move it.
  if ($data['old_uri'] != $data['new_uri'] && file_exists($data['old_uri'])) {
    file_prepare_directory($data['file_location'], FILE_CREATE_DIRECTORY || FILE_MODIFY_PERMISSIONS);
    // file_move doesn't work with Private files, so we'll file_copy and then
    // file_delete.
    $moved_file = file_unmanaged_copy($data['old_uri'], $data['new_uri'], FILE_EXISTS_RENAME);
    if ($moved_file) {
      $new_file->uri = $moved_file;
      file_save($new_file);
      drupal_set_message(t(
        'Uploaded file copied from <i>@old</i> to <i>@new</i>.',
        array(
          '@old' => $data['old_uri'],
          '@new' => $moved_file,
        )
      ));
      if (file_unmanaged_delete($data['old_uri'], TRUE)) {
        drupal_set_message(t(
          'File <i>@old</i> removed.',
          array(
            '@old' => $data['old_uri'],
          )
        ));
      }
    }
  }
}

/**
 * Helper function for prepare a required data.
 *
 * @param object $new_file
 *   New file object.
 *
 * @return array
 *   Prepared associative array with required data.
 */
function _upload_archives_prepare_update($new_file) {
  $data = array();
  $data['old_uri'] = $new_file->uri;
  // Clean up filename for directory name.
  $data['dir_name'] = preg_replace('/\./', '_', $new_file->filename);
  $data['user_folder'] = _upload_archives_get_user_folder();
  $data['time_folder'] = _upload_archives_get_time_folder($new_file->timestamp);
  $data['file_streamwrapper'] = file_uri_scheme($data['old_uri']);
  $data['file_location'] = _upload_archives_get_file_location($new_file->filename, $data);
  $data['new_uri'] = $data['file_location'] . '/' . $new_file->filename;
  return $data;
}

/**
 * Helper function for getting user folder.
 *
 * @return null|string
 *   User folder.
 */
function _upload_archives_get_user_folder() {
  $folder = variable_get('upload_archives_foldername');
  return $folder ? $folder . '/' : NULL;
}

/**
 * Helper function for getting time folder.
 *
 * @param int|string $timestamp
 *   UNIX timestamp.
 *
 * @return bool|string
 *   Time folder.
 */
function _upload_archives_get_time_folder($timestamp) {
  if (variable_get('upload_archives_subfolder_format')) {
    return $timestamp;
  }
  return date('Y\-m\-d\_H\h\-i\m\-s\s', $timestamp);
}

/**
 * Helper function for getting a file location.
 *
 * @param string $file_name
 *   File name.
 *
 * @param array $data
 *   Data array.
 *
 * @return string
 *   File location.
 */
function _upload_archives_get_file_location($file_name, $data) {
  $file_location = $data['file_streamwrapper'];
  $file_location .= '://' . check_plain($data['user_folder']);
  $file_location .= preg_replace('/\./', '_', $file_name);
  $file_location .= '/' . $data['time_folder'];
  return $file_location;
}
valentine94’s picture

Status: Needs review » Needs work
PA robot’s picture

Status: Needs work » Closed (won't fix)

Closing due to lack of activity. If you are still working on this application, you should fix all known problems and then set the status to "Needs review". (See also the project application workflow).

I'm a robot and this is an automated message from Project Applications Scraper.