You are here

auditfiles.module in Audit Files 7.3

Implements various Drupal hooks.

This is the main module file that includes the various Drupal hook implementations, along with any additional helper functions. Most for the code for the reports is included in separate files.

File

auditfiles.module
View source
<?php

/**
 * @file
 * Implements various Drupal hooks.
 *
 * This is the main module file that includes the various Drupal hook
 * implementations, along with any additional helper functions.
 * Most for the code for the reports is included in separate files.
 */

/**
 * Implements hook_help().
 */
function auditfiles_help($path, $arg) {
  $output = '';

  // If on a confirmation form, then suppress the help message.
  if (array_key_exists('files', $_POST) && array_key_exists('op', $_POST) && (substr($_POST['op'], 0, 4) == 'Add ' || substr($_POST['op'], 0, 7) == 'Delete ')) {
    return $output;
  }
  switch ($path) {

    // Main module help for this module.
    case 'admin/help#auditfiles':
      $files_link = l(t('files'), 'admin/config/media/file-system');
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>';
      $output .= t('The Audit Files module allows for comparing and correcting files and file references in the "!files_link" directory, in the database, and in content.', array(
        '!files_link' => $files_link,
      ));
      $output .= '<h3>' . t('Uses') . '</h3>';
      $output .= '<dl>';
      $reports_link = l(t("Audit Files' reports page"), 'admin/reports/auditfiles');
      $output .= '<dt>' . t('Comparing and correcting file references') . '</dt>';
      $output .= '<dd>' . t('To compare and correct the various file references and usages, visit the !reports_link.', array(
        '!reports_link' => $reports_link,
      )) . '</dd>';
      $reports_link = l(t("Audit Files' Merge file references report page"), 'admin/reports/auditfiles/merge-file-references');
      $output .= '<dt>' . t('Merging duplicate file references') . '</dt>';
      $output .= '<dd>' . t('To merge duplicate file references, visit the !reports_link.', array(
        '!reports_link' => $reports_link,
      )) . '</dd>';
      $output .= '</dl>';

      // Include the INSTALL.txt file.
      $filepath = dirname(__FILE__) . '/INSTALL.txt';
      if (file_exists($filepath)) {
        $readme = file_get_contents($filepath);
      }
      if (isset($readme)) {
        $output .= '<h3>' . t('The contents of the INSTALL.txt file') . '</h3>';
        $output .= '<p><pre>' . $readme . '</pre></p>';
      }

      // Include the README.txt file.
      $filepath = dirname(__FILE__) . '/README.txt';
      if (file_exists($filepath)) {
        $readme = file_get_contents($filepath);
      }
      if (isset($readme)) {
        $output .= '<h3>' . t('The contents of the README.txt file') . '</h3>';
        $output .= '<p><pre>' . $readme . '</pre></p>';
      }
      break;
    case 'admin/config/system/auditfiles':
      $output .= '<p>';
      $output .= t('Configure the administrative settings for this module.');
      $output .= '</p>';
      break;
    case 'admin/reports/auditfiles':
      $output .= '<p>';
      $output .= t('The various reports provided for by this module.');
      $output .= '</p>';
      break;
    case 'admin/reports/auditfiles/notindatabase':
      $files_link = l(t('file system path'), 'admin/config/system/auditfiles');
      $output .= '<p>';
      $output .= t('This report lists the files that are in the admin specified !files_link directory, but are not in the file_managed database table.', array(
        '!files_link' => $files_link,
      ));
      $output .= '</p>';
      break;
    case 'admin/reports/auditfiles/notonserver':
      $files_link = l(t('file system path'), 'admin/config/system/auditfiles');
      $output .= '<p>';
      $output .= t('This report lists the files that are in the file_managed database table, but are not in the admin specified !files_link directory.', array(
        '!files_link' => $files_link,
      ));
      $output .= '</p>';
      break;
    case 'admin/reports/auditfiles/managednotused':
      $output .= '<p>';
      $output .= t('This report lists the files that are in the file_managed database table, but are not in the file_usage table.');
      $output .= '</p>';
      break;
    case 'admin/reports/auditfiles/usednotmanaged':
      $output .= '<p>';
      $output .= t('This report lists the files that are in the file_usage database table, but are not in the file_managed table.');
      $output .= '</p>';
      break;
    case 'admin/reports/auditfiles/usednotreferenced':
      $output .= '<p>';
      $output .= t('This report lists the files that are in the file_usage database table, but are not in any content.');
      $output .= '</p>';
      break;
    case 'admin/reports/auditfiles/referencednotused':
      $output .= '<p>';
      $output .= t('This report lists the files that are referenced in content, but are not in the file_usage database table.');
      $output .= '</p>';
      break;
  }
  return $output;
}

/**
 * Implements hook_permission().
 */
function auditfiles_permission() {
  return array(
    'access audit files reports' => array(
      'title' => t("Access Audit Files' reports"),
      'description' => t('Allow access to the reports generated by the Audit Files module.'),
    ),
    'administer audit files' => array(
      'title' => t('Administer Audit Files'),
      'description' => t('Configure the administration settings for the Audit Files module.'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function auditfiles_menu() {
  $items = array();

  // Configure the settings for this module.
  $items['admin/config/system/auditfiles'] = array(
    'title' => 'Audit Files',
    'description' => 'Set file, extension and path exclusions for file audits.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_admin_settings',
    ),
    'access arguments' => array(
      'administer audit files',
    ),
    'file' => 'auditfiles.admin.inc',
  );

  // The various reports.
  $items['admin/reports/auditfiles'] = array(
    'title' => 'Audit Files',
    'description' => 'Allows for comparing and correcting files and file references in the "files" directory, in the database, and in content.',
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'system.admin.inc',
    'file path' => drupal_get_path('module', 'system'),
  );
  $items['admin/reports/auditfiles/notindatabase'] = array(
    'title' => 'Not in database',
    'description' => 'Lists files that are in the "files" directory, but not in the database.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_not_in_database_form',
    ),
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'auditfiles.notindatabase.inc',
    'weight' => 0,
  );
  $items['admin/reports/auditfiles/notonserver'] = array(
    'title' => 'Not on server',
    'description' => 'Lists files that are in the database, but not in the "files" directory.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_not_on_server_form',
    ),
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'auditfiles.notonserver.inc',
    'weight' => 1,
  );
  $items['admin/reports/auditfiles/managednotused'] = array(
    'title' => 'Managed not used',
    'description' => 'Lists files that are in the file_managed table, but not in the file_usage table.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_managed_not_used_form',
    ),
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'auditfiles.managednotused.inc',
    'weight' => 2,
  );
  $items['admin/reports/auditfiles/usednotmanaged'] = array(
    'title' => 'Used not managed',
    'description' => 'Lists files that are in the file_usage table, but not in the file_managed table.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_used_not_managed_form',
    ),
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'auditfiles.usednotmanaged.inc',
    'weight' => 3,
  );
  $items['admin/reports/auditfiles/usednotreferenced'] = array(
    'title' => 'Used not referenced',
    'description' => 'List files that are in the file_usage table, but not referenced in content.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_used_not_referenced_form',
    ),
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'auditfiles.usednotreferenced.inc',
    'weight' => 4,
  );
  $items['admin/reports/auditfiles/referencednotused'] = array(
    'title' => 'Referenced not used',
    'description' => 'List files referenced in content, but not in the file_usage table.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_referenced_not_used_form',
    ),
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'auditfiles.referencednotused.inc',
    'weight' => 5,
  );
  $items['admin/reports/auditfiles/mergefilereferences'] = array(
    'title' => 'Merge file references',
    'description' => 'Lists potential duplicate files in the file_managed table, and allows for merging them into a single file.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'auditfiles_merge_file_references_form',
    ),
    'access arguments' => array(
      'access audit files reports',
    ),
    'file' => 'auditfiles.mergefilereferences.inc',
    'weight' => 6,
  );
  return $items;
}

/**
 * Implements hook_views_api().
 */
function auditfiles_views_api() {
  return array(
    'api' => 3.0,
  );
}

/**
 * Implements hook_action_info().
 */
function auditfiles_action_info() {
  return array(
    'auditfiles_merge_files' => array(
      'type' => 'file',
      'label' => t('Merge file references'),
      'configurable' => TRUE,
      'triggers' => array(
        'any',
      ),
      'vbo_configurable' => FALSE,
      'aggregate' => TRUE,
      'permissions' => array(
        'administer files',
      ),
    ),
  );
}

/**
 * The form definition for allowing the user to choose which file to keep.
 */
function auditfiles_merge_files_form($settings, &$form_state) {
  $form = array();
  foreach ($form_state['selection'] as $file_id) {
    $file = file_load($file_id);

    // Create the options array for display in the form.
    $files[$file_id] = t('File ID: !fileid; Name: !filename; URI: !fileuri; MIME: !filemime; Size: !filesize; Time uploaded: !timestamp (!formatted)', array(
      '!fileid' => $file_id,
      '!filename' => $file->filename,
      '!fileuri' => $file->uri,
      '!filemime' => $file->filemime,
      '!filesize' => $file->filesize,
      '!timestamp' => $file->timestamp,
      '!formatted' => date('r', $file->timestamp),
    ));
  }

  // Default to sorting by file ID.
  natsort($files);
  $form['file_being_kept'] = array(
    '#type' => 'radios',
    '#title' => t('Which file will be the one the others are merged into'),
    '#default_value' => key($files),
    '#options' => $files,
  );
  return $form;
}

/**
 * The submit handler for the auditfiles_merge_files_form() function.
 */
function auditfiles_merge_files_submit($form, $form_state) {
  $ret_val = array();
  $ret_val['file_being_kept'] = $form_state['values']['file_being_kept'];
  return $ret_val;
}

/**
 * Merges selected files.
 *
 * This function takes all files given it and changes all their usages to point
 * to the initial file, then removes their reference for all but the first file
 * from the file managed table and then also removes the files from the file
 * system.
 *
 * This function does not verify that the files are actually duplicates. The
 * assumption is made that the user has already done that.
 *
 * @param array $files
 *   An array of file objects, keyed by file ID.
 * @param array $context
 *   The context the action is executed in.
 */
function auditfiles_merge_files(array &$files, array $context) {

  // Make sure that more than one file was selected.
  if (count($files) > 1) {

    // Remove the file being kept from the array of files, so it is not deleted.
    $kept_file = $files[$context['file_being_kept']];
    unset($files[$context['file_being_kept']]);

    // Get the data for the record being kept.
    $results = db_select('file_usage', 'fu')
      ->fields('fu', array(
      'id',
      'count',
    ))
      ->condition('fid', $kept_file->fid)
      ->execute()
      ->fetchAll();
    if (empty($results)) {
      $message = t('There was no file usage data found for the file you choose to keep. No changes were made.');
      drupal_set_message($message, 'warning');
      return;
    }
    $kept_file_data = reset($results);

    // Iterate through the rest of the files in the array.
    foreach ($files as $file) {

      // Get the file data of the file being compared.
      $results = db_select('file_usage', 'fu')
        ->fields('fu', array(
        'id',
        'count',
      ))
        ->condition('fid', $file->fid)
        ->execute()
        ->fetchAll();
      if (empty($results)) {
        $message = t('There was an error retrieving the file usage data from the database for file ID !fid. Please check the files in one of the other reports. No changes were made for this file.', array(
          '!fid' => $file->fid,
        ));
        drupal_set_message($message, 'warning');
        continue;
      }
      $compared_file_data = reset($results);

      // Compare it with the kept file.
      if ($kept_file_data->id == $compared_file_data->id) {

        // If it matches, update the kept file and delete the one being
        // compared.
        $kept_file_data->count += $compared_file_data->count;

        // Delete the unnecessary entry from the file_usage table.
        db_delete('file_usage')
          ->condition('fid', $file->fid)
          ->execute();
      }
      else {

        // If it does not match, update the one being compared.
        // Make the file usages point to the fid of the file being kept.
        db_update('file_usage')
          ->fields(array(
          'fid' => $kept_file->fid,
        ))
          ->condition('fid', $file->fid)
          ->execute();
      }

      // Delete the unnecessary entries from the file_managed table.
      db_delete('file_managed')
        ->condition('fid', $file->fid)
        ->execute();

      // Delete the duplicate file.
      file_unmanaged_delete($file->uri);
    }
  }
  else {
    $message = t('More than one file must be selected in order to merge them. No changes were made.');
    drupal_set_message($message, 'warning');
  }
}

Functions

Namesort descending Description
auditfiles_action_info Implements hook_action_info().
auditfiles_help Implements hook_help().
auditfiles_menu Implements hook_menu().
auditfiles_merge_files Merges selected files.
auditfiles_merge_files_form The form definition for allowing the user to choose which file to keep.
auditfiles_merge_files_submit The submit handler for the auditfiles_merge_files_form() function.
auditfiles_permission Implements hook_permission().
auditfiles_views_api Implements hook_views_api().