You are here

term_authoring_info.module in Taxonomy Term Authoring Information 7

Provide authoring information for taxonomy term.

File

term_authoring_info.module
View source
<?php

/**
 * @file
 * Provide authoring information for taxonomy term.
 */

/**
 * Module installation path.
 */
define('TERM_AUTHORING_INFO_PATH', drupal_get_path('module', 'term_authoring_info'));

/**
 * Implements hook_views_api().
 */
function term_authoring_info_views_api() {
  return array(
    'api' => 3,
    'path' => TERM_AUTHORING_INFO_PATH . '/views',
  );
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Add authoring information configuration field to native vocabulary editing.
 */
function term_authoring_info_form_taxonomy_form_vocabulary_alter(&$form, &$form_state, $form_id) {

  // Skip the authoring information fields in vocabulary delete confirm page.
  if (isset($form_state['confirm_delete'])) {
    return;
  }
  $form['term_authoring_info'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display authoring information'),
    '#default_value' => variable_get('term_authoring_info_vocab_' . $form['#vocabulary']->machine_name . '_showfield', 0),
    '#description' => t('Author username and publish date fields will be displayed.'),
    '#weight' => 1,
  );
  $form['#submit'][] = 'term_authoring_info_vocabulary_form_submit';
}

/**
 * Submit handler for the authoring information configuration.
 */
function term_authoring_info_vocabulary_form_submit($form, &$form_state) {
  $show_field = $form_state['values']['term_authoring_info'] ? 1 : 0;
  variable_set('term_authoring_info_vocab_' . $form_state['values']['machine_name'] . '_showfield', $show_field);

  // Clear the field cache.
  $cid = "field_info:bundle_extra:taxonomy_term:{$form_state['values']['machine_name']}";
  cache_clear_all($cid, 'cache_field', TRUE);
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Add authoring information fields to native term add/edit form.
 */
function term_authoring_info_form_taxonomy_form_term_alter(&$form, &$form_state, $form_id) {

  // Skip the authoring information fields in vocabulary delete confirm page.
  if (isset($form_state['confirm_delete'])) {
    return;
  }

  // Check the term's vocab has the show field enabled.
  if (variable_get('term_authoring_info_vocab_' . $form['#vocabulary']->machine_name . '_showfield', 0)) {
    $term = $form_state['term'];

    // If this is a new term, fill in the default values.
    $created = !empty($term->created) ? $term->created : NULL;
    if (empty($term->tid)) {
      global $user;
      $term->author = $user->name;
      $term->created = REQUEST_TIME;
    }
    else {
      $term->created = !empty($term->created) ? $term->created : REQUEST_TIME;
      if (isset($term->uid)) {
        $user = user_load($term->uid);
        $term->author = $user->name;
      }
    }
    $form['authoring_info'] = array(
      '#type' => 'fieldset',
      '#title' => t('Authoring Information'),
      '#access' => user_access('administer taxonomy'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#attributes' => array(
        'class' => array(
          'term-form-author',
        ),
      ),
      '#weight' => 15,
    );
    $form['authoring_info']['author'] = array(
      '#type' => 'textfield',
      '#title' => t('Authored by'),
      '#maxlength' => 60,
      '#autocomplete_path' => 'user/autocomplete',
      '#default_value' => !empty($term->author) ? $term->author : '',
      '#weight' => -1,
      '#description' => t('Leave blank for %anonymous.', array(
        '%anonymous' => variable_get('anonymous', t('Anonymous')),
      )),
    );
    $form['authoring_info']['created'] = array(
      '#type' => 'textfield',
      '#title' => t('Authored on'),
      '#maxlength' => 25,
      '#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array(
        '%time' => format_date($term->created, 'custom', 'Y-m-d H:i:s O'),
        '%timezone' => format_date($term->created, 'custom', 'O'),
      )),
      '#default_value' => !empty($created) ? format_date($created, 'custom', 'Y-m-d H:i:s O') : '',
    );
    $form['#validate'][] = 'term_authoring_info_validate';

    // Add a submit handler to run prior to the term being saved.
    $form += array(
      '#submit' => array(),
    );
    array_unshift($form['#submit'], 'term_authoring_info_submit');
  }
}

/**
 * Form validation handler for authoring information fields.
 *
 * @see term_authoring_info_form_taxonomy_form_term_alter()
 */
function term_authoring_info_validate($form, &$form_state) {
  $values = $form_state['values'];

  // Validate the "authored by" field.
  if (!empty($values['author']) && !($account = user_load_by_name($values['author']))) {

    // The use of empty() is mandatory in the context of usernames
    // as the empty string denotes the anonymous user. In case we
    // are dealing with an anonymous user we set the user ID to 0.
    form_set_error('author', t('The username %name does not exist.', array(
      '%name' => $values['author'],
    )));
  }

  // Validate the "authored on" field.
  if (!empty($values['created']) && strtotime($values['created']) === FALSE) {
    form_set_error('created', t('You have to specify a valid date.'));
  }
}

/**
 * Form submit handler for authoring information fields.
 */
function term_authoring_info_submit($form, &$form_state) {
  $form_state['values']['created'] = strtotime($form_state['values']['created']);
}

/**
 * Implements hook_taxonomy_term_load().
 */
function term_authoring_info_taxonomy_term_load($terms) {

  // Fetch authoring information from database and assign it to term.
  $result = db_query('SELECT tid, uid, created, changed FROM {term_authoring_info} WHERE tid IN (:tids)', array(
    ':tids' => array_keys($terms),
  ));
  foreach ($result as $record) {
    $terms[$record->tid]->uid = $record->uid;
    $terms[$record->tid]->created = $record->created;
    $terms[$record->tid]->changed = $record->changed;
  }
}

/**
 * Implements hook_taxonomy_term_update().
 */
function term_authoring_info_taxonomy_term_update($term) {
  term_authoring_info_save($term);
}

/**
 * Implements hook_taxonomy_term_delete().
 */
function term_authoring_info_taxonomy_term_delete($term) {
  db_delete('term_authoring_info')
    ->condition('tid', $term->tid)
    ->execute();
}

/**
 * Implements hook_taxonomy_term_insert().
 */
function term_authoring_info_taxonomy_term_insert($term) {
  term_authoring_info_save($term);
}

/**
 * Saves changes to authoring information or adds new authoring information.
 *
 * @param object $term
 *   The $term object to be saved.
 */
function term_authoring_info_save($term) {
  if (variable_get('term_authoring_info_vocab_' . $term->vocabulary_machine_name . '_showfield', 0)) {

    // A user might assign the term author by entering a user name in the term
    // form, which we then need to translate to a user ID.
    if (isset($term->author)) {
      if ($account = user_load_by_name($term->author)) {
        $term->uid = $account->uid;
      }
    }

    // Determine if the user ID still hasn't been defined.
    if (!isset($term->uid)) {
      global $user;
      $term->uid = $user->uid;
    }

    // The created timestamp.
    $term->created = !empty($term->created) ? $term->created : REQUEST_TIME;

    // The changed timestamp.
    $term->changed = REQUEST_TIME;

    // Let modules modify the authoring info before it is saved to the database.
    module_invoke_all('term_authoring_info_presave', $term);
    db_merge('term_authoring_info')
      ->key(array(
      'tid' => $term->tid,
    ))
      ->fields(array(
      'uid' => $term->uid,
      // For some reason, the 'created' date sometimes gets lost during this merge (such
      // as when the term form is embedded as an Inline Entity Form). Leaving 'created'
      // blank returns errors; so use the 'changed' date instead, which never gets lost.
      'created' => !empty($term->created) ? $term->created : $term->changed,
      'changed' => $term->changed,
    ))
      ->execute();
  }
}

/**
 * Implements hook_taxonomy_vocabulary_update().
 */
function term_authoring_info_taxonomy_vocabulary_update($vocabulary) {

  // Handle a vocabulary rename.
  if ($vocabulary->machine_name != $vocabulary->old_machine_name) {

    // Load the old variable setting for authoring information.
    $temp = variable_get('term_authoring_info_vocab_' . $vocabulary->old_machine_name . '_showfield', 0);
    if ($temp) {
      variable_set('term_authoring_info_vocab_' . $vocabulary->machine_name . '_showfield', $temp);
    }
    variable_del('term_authoring_info_vocab_' . $vocabulary->old_machine_name . '_showfield');
  }
}

/**
 * Implements hook_taxonomy_vocabulary_delete().
 */
function term_authoring_info_taxonomy_vocabulary_delete($vocabulary) {
  variable_del('term_authoring_info_vocab_' . $vocabulary->machine_name . '_showfield', $temp);
}

/**
 * Implements hook_field_extra_fields().
 */
function term_authoring_info_field_extra_fields() {
  $return = array();
  $info = entity_get_info('taxonomy_term');
  foreach (array_keys($info['bundles']) as $bundle) {
    if (variable_get('term_authoring_info_vocab_' . $bundle . '_showfield', 0)) {
      $return['taxonomy_term'][$bundle]['display']['authoring_information'] = array(
        'label' => t('Authoring Information'),
        'description' => t('Term created'),
        'weight' => 0,
      );
    }
  }
  return $return;
}

/**
 * Implements hook_taxonomy_term_view().
 */
function term_authoring_info_taxonomy_term_view($term, $view_mode, $langcode) {
  if (variable_get('term_authoring_info_vocab_' . $term->vocabulary_machine_name . '_showfield', 0) && isset($term->uid)) {
    $created = !empty($term->created) ? format_date($term->created) : NULL;
    $changed = !empty($term->changed) ? format_date($term->changed) : NULL;
    $username = theme('username', array(
      'account' => user_load($term->uid),
    ));
    $term->content['authoring_information'] = array(
      '#prefix' => '<div class="taxonomy-term-authoring-information">',
      '#markup' => t('Submitted by !username on !created<span class="changed">, last updated on !changed</span>', array(
        '!username' => $username,
        '!created' => $created,
        '!changed' => $changed,
      )),
      '#suffix' => '</div>',
    );
  }
}