You are here

tft_archive.module in Taxonomy File Tree 7.2

Hook implementation and logic.

File

modules/tft_archive/tft_archive.module
View source
<?php

/**
 * @file
 * Hook implementation and logic.
 */
define('TFT_ARCHIVE_PERM__ARCHIVE_TERMS', 'tft archive child terms');

/**
 * Implements hook_menu().
 */
function tft_archive_menu() {
  $menu = array(
    'tft/term/archive/%' => array(
      'title' => "Archive a folder",
      'access callback' => 'tft_term_access',
      'access arguments' => array(
        3,
        NULL,
        'archive',
      ),
      'page callback' => 'drupal_get_form',
      'page arguments' => array(
        'tft_archive_term_form',
        3,
      ),
      'file' => 'includes/tft_archive.pages.inc',
      'type' => MENU_CALLBACK,
    ),
    'tft/file/archive/%' => array(
      'title' => "Archive a file",
      'access callback' => 'tft_archive_access',
      'access arguments' => array(
        3,
      ),
      'page callback' => 'drupal_get_form',
      'page arguments' => array(
        'tft_archive_file_form',
        3,
      ),
      'file' => 'includes/tft_archive.pages.inc',
      'type' => MENU_CALLBACK,
    ),
    'tft/term/restore/%' => array(
      'title' => "Restore a file",
      'access callback' => 'tft_term_access',
      'access arguments' => array(
        3,
        NULL,
        'archive',
      ),
      'page callback' => 'tft_archive_restore_element',
      'page arguments' => array(
        3,
        'term',
      ),
      'file' => 'includes/tft_archive.pages.inc',
      'type' => MENU_CALLBACK,
    ),
    'tft/file/restore/%' => array(
      'title' => "Restore a file",
      'access callback' => 'tft_archive_access',
      'access arguments' => array(
        3,
      ),
      'page callback' => 'tft_archive_restore_element',
      'page arguments' => array(
        3,
        'node',
      ),
      'file' => 'includes/tft_archive.pages.inc',
      'type' => MENU_CALLBACK,
    ),
  );
  return $menu;
}

/**
 * Implements hook_permission().
 */
function tft_archive_permission() {
  return array(
    TFT_ARCHIVE_PERM__ARCHIVE_TERMS => array(
      'title' => t("Archive terms and files"),
    ),
  );
}

/**
 * Implements hook_tft_term_access().
 */
function tft_archive_tft_term_access($tid, $account = NULL, $op = 'view') {
  if (!isset($account)) {
    global $user;
    $account = $user;
  }
  if ($op == 'archive') {
    return user_access(TFT_ARCHIVE_PERM__ARCHIVE_TERMS, $account);
  }
}

/**
 * Implements hook_tft_item_operation_links_alter().
 */
function tft_archive_tft_item_operation_links_alter(&$links, $type, $id, $parent_tid) {
  $query = isset($_SESSION['tft']['q']) ? $_SESSION['tft']['q'] : '';
  if ($type == 'folder') {
    if (tft_term_access($id, NULL, 'archive') && !tft_archive_is_archive_folder($id)) {
      if (tft_archive_element_is_archived($id, 'term')) {
        $links['restore'] = array(
          'title' => t("restore"),
          'href' => "tft/term/restore/{$id}",
          'attributes' => array(
            'class' => 'ops-link term-restore-link',
          ),
          'query' => array(
            'destination' => $query . (isset($parent_tid) ? "#tft/{$parent_tid}" : ''),
          ),
        );
      }
      else {
        $links['archive'] = array(
          'title' => t("archive"),
          'href' => "tft/term/archive/{$id}",
          'attributes' => array(
            'class' => 'ops-link term-archive-link',
          ),
          'query' => array(
            'destination' => $query . (isset($parent_tid) ? "#tft/{$parent_tid}" : ''),
          ),
        );
      }
    }
  }
  else {
    if (isset($links['edit']) && tft_term_access($parent_tid, NULL, 'archive')) {
      if (tft_archive_element_is_archived($id, 'node')) {
        $links['restore'] = array(
          'title' => t("restore"),
          'href' => "tft/file/restore/{$id}",
          'attributes' => array(
            'class' => 'ops-link term-restore-link',
          ),
          'query' => array(
            'destination' => $query . (isset($parent_tid) ? "#tft/{$parent_tid}" : ''),
          ),
        );
      }
      else {
        $links['archive'] = array(
          'title' => t("archive"),
          'href' => "tft/file/archive/{$id}",
          'attributes' => array(
            'class' => 'ops-link term-archive-link',
          ),
          'query' => array(
            'destination' => $query . (isset($parent_tid) ? "#tft/{$parent_tid}" : ''),
          ),
        );
      }
    }
  }
}

/**
 * Access callback: custom access callback when checking if a user
 * can archive files.
 *
 * @param int $file_nid
 * @param object $account = NULL
 *
 * @return bool
 */
function tft_archive_access($file_nid, $account = NULL) {
  $tid = db_query("SELECT DISTINCT(tn.tid) FROM {node_revision} v\n                        LEFT JOIN {node} n ON n.vid = v.vid\n                          LEFT JOIN {taxonomy_index} tn ON tn.nid = n.nid\n                      WHERE n.nid = :nid AND n.status = 1", array(
    ':nid' => $file_nid,
  ))
    ->fetchField();
  return tft_term_access($tid, $account, 'archive');
}

/**
 * Creates an archive folder under the passed folder.
 *
 * Returns the new term ID.
 *
 * @param int $parent_tid = 0
 *
 * @return int
 */
function tft_archive_create_archive_folder($parent_tid = 0) {
  $tid = tft_add_term(t("Archives"), $parent_tid);
  db_insert('tft_archive_tid')
    ->fields(array(
    'tid' => $tid,
    'is_archive' => 1,
  ))
    ->execute();
  return $tid;
}

/**
 * Helper function to get the closest archive folder.
 *
 * Recursively walks up the file tree and returns the first parent that is an archive folder.
 * If none are found, returns 0.
 *
 * @param int $tid
 *
 * @return int
 */
function tft_archive_get_closest_parent_archive_tid($tid) {
  while ($parent_tid = tft_get_parent_tid($tid)) {
    if (tft_archive_is_archive_folder($parent_tid)) {
      return $parent_tid;
    }
    else {

      // Are any of the siblings an archive folder ?
      $result = db_query("SELECT td.tid FROM {taxonomy_term_data} td\n                        LEFT JOIN {taxonomy_term_hierarchy} th ON th.tid = td.tid\n                      WHERE th.parent = :ptid AND td.vid = :vid ORDER BY td.name", array(
        ':ptid' => $parent_tid,
        ':vid' => variable_get('tft_vocabulary_vid', 0),
      ));
      foreach ($result as $term) {
        if (tft_archive_is_archive_folder($term->tid)) {
          return $term->tid;
        }
      }

      // No archive. Go up.
      $tid = $parent_tid;
    }
  }
  return 0;
}

/**
 * Stores the archived term or file so it can easily be restored.
 *
 * @param int $id
 * @param string $type
 *        The entity type being archived. Either 'term' or 'node'.
 * @param int $previous_parent_tid
 *        The previous parent folder tid.
 *
 */
function tft_archive_log($id, $type, $previous_parent_tid) {
  db_insert('tft_archive_restore')
    ->fields(array(
    'id' => $id,
    'type' => $type,
    'previous_parent_tid' => $previous_parent_tid,
  ))
    ->execute();
}

/**
 * Check if the element is currently archived.
 *
 * @param int $id
 * @param string $type
 *        The entity type being archived. Either 'term' or 'node'.
 *
 * @return bool
 */
function tft_archive_element_is_archived($id, $type) {
  $result = db_select('tft_archive_restore', 't')
    ->fields('t', array(
    'id',
  ))
    ->condition('id', $id)
    ->condition('type', $type)
    ->execute()
    ->fetchField();
  return !empty($result);
}

/**
 * Checks if the term is an "Archive" term.
 *
 * @param int $tid
 *
 * @return bool
 */
function tft_archive_is_archive_folder($tid) {
  $result = db_select('tft_archive_tid', 't')
    ->fields('t', array(
    'is_archive',
  ))
    ->condition('tid', $tid)
    ->execute()
    ->fetchField();
  return !empty($result);
}

/**
 * Restore the element to its previous position.
 *
 * If the previous place does not exist anymore, will be restored to the
 * root (or any other place, specified by a third-party module).
 *
 * @param int $id
 * @param string $type
 *        The type of entity. Either 'term' or 'node'.
 *
 * @return int
 */
function tft_archive_restore_archived_element($id, $type) {
  $log = db_query("SELECT * FROM {tft_archive_restore} WHERE type = :type AND id = :id", array(
    ':type' => $type,
    ':id' => $id,
  ))
    ->fetchAssoc();
  if (empty($log)) {
    $log = array(
      'id' => $id,
      'previous_parent_tid' => 0,
    );
  }
  drupal_alter('tft_archive_restore_element', $log, $id, $type);
  if ($type == 'node') {
    $node = node_load($log['id']);

    // @todo - currently supports only restoring to one single previous parent.
    $node->{"taxonomy_vocabulary_" . variable_get('tft_vocabulary_vid', 0)}[LANGUAGE_NONE][0]['tid'] = $log['previous_parent_tid'];
    node_save($node);
  }
  else {
    db_update('taxonomy_term_hierarchy')
      ->fields(array(
      'parent' => $log['previous_parent_tid'],
    ))
      ->condition('tid', $log['id'])
      ->execute();
  }
  db_delete('tft_archive_restore')
    ->condition('id', $id)
    ->condition('type', $type)
    ->execute();
  return $log['previous_parent_tid'];
}

Functions

Namesort descending Description
tft_archive_access Access callback: custom access callback when checking if a user can archive files.
tft_archive_create_archive_folder Creates an archive folder under the passed folder.
tft_archive_element_is_archived Check if the element is currently archived.
tft_archive_get_closest_parent_archive_tid Helper function to get the closest archive folder.
tft_archive_is_archive_folder Checks if the term is an "Archive" term.
tft_archive_log Stores the archived term or file so it can easily be restored.
tft_archive_menu Implements hook_menu().
tft_archive_permission Implements hook_permission().
tft_archive_restore_archived_element Restore the element to its previous position.
tft_archive_tft_item_operation_links_alter Implements hook_tft_item_operation_links_alter().
tft_archive_tft_term_access Implements hook_tft_term_access().

Constants

Namesort descending Description
TFT_ARCHIVE_PERM__ARCHIVE_TERMS @file Hook implementation and logic.