You are here

signature_forum.module in Signatures for Forums 5

File

signature_forum.module
View source
<?php

/**
 * Do not display a signature when the content is under a certain length.
 */
define('MIN_CONTENT_ACTION_DO_NOT_DISPLAY', 0);

/**
 * Run the signature through an additional filter if the content is under a certain length.
 * Good for adding rel=nofollow to all links.
 */
define('MIN_CONTENT_ACTION_ADDITIONAL_FILTER', 1);

/**
 * Implementation of hook_help().
 */
function signature_forum_help($section = '') {
  switch ($section) {
    case 'admin/modules#description':
      return t('Tweaks signatures in ways inspired by other traditional forum software. Allows much longer signatures than the Drupal default; also users may be allowed to use different formats like BBCode (with the BBCode module downloadable from drupal.org) or HTML in their signatures.');
  }
}

/**
 * Implementation of hook_perm().
 */
function signature_forum_perm() {
  return array(
    'administer Signatures for Forums',
  );
}

/**
 * Implementation of hook_menu().
 */
function signature_forum_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/signature_forum',
      'title' => t('Signatures for Forums'),
      'description' => t('Manages users\' signatures.'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'signature_forum_admin_settings',
      ),
      'access' => user_access('administer Signatures for Forums'),
      'type' => MENU_NORMAL_ITEM,
    );
  }
  return $items;
}

/**
 * Admin settings form.
 */
function signature_forum_admin_settings() {
  $settings = variable_get('signature_forum_settings', signature_forum_defaults());
  $form['signature'] = array(
    '#type' => 'fieldset',
    '#description' => t('Show signatures with nodes and comments for:'),
  );
  foreach (node_get_types('names') as $type => $name) {
    $form['signature']['signature_forum_show_for_' . $type] = array(
      '#type' => 'checkbox',
      '#title' => $name,
      '#return_value' => 1,
      '#default_value' => $settings['signature_forum_show_for_' . $type],
    );
  }
  $form['template'] = array(
    '#type' => 'textarea',
    '#title' => t('Template for signatures'),
    '#default_value' => $settings['signature_forum_template'],
    '#description' => t('<strong>%s</strong> will be replaced with user\'s signature.'),
  );
  $form['filter'] = filter_form($settings['signature_forum_format'], NULL, array(
    'filter',
  ));
  $form['content_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Content options'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['content_settings']['min_content_length'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum content length'),
    '#size' => 3,
    '#maxlength' => 10,
    '#default_value' => $settings['signature_forum_min_content_length'],
    '#description' => t('The minimum number of characters in the content a signature is being attached to. 0 means no limit.'),
  );
  $form['content_settings']['min_content_length_action'] = array(
    '#type' => 'radios',
    '#title' => t('Minimum content action'),
    '#default_value' => $settings['signature_forum_min_content_length_action'],
    '#options' => array(
      MIN_CONTENT_ACTION_DO_NOT_DISPLAY => t('Do not display signature'),
      MIN_CONTENT_ACTION_ADDITIONAL_FILTER => t('Run through an additional filter'),
    ),
    '#description' => t('What to do if the content is under the minimum length. Set the filter below.'),
  );
  $form['content_settings']['min_content_length_filter'] = filter_form($settings['signature_forum_min_content_length_filter'], NULL, array(
    'min_content_length_filter',
  ));
  $form['content_settings']['min_content_length_filter']['#title'] = t('Minimum content additional filter format (if enabled)');

  // If admin has opted to run signature through additional filter when content too short,
  // expand the additional filter selection fieldset
  if ($settings['signature_forum_min_content_length_action'] == MIN_CONTENT_ACTION_ADDITIONAL_FILTER) {
    $form['content_settings']['min_content_length_filter']['#collapsed'] = 0;
  }
  if ($roles = user_roles()) {
    $form['content_settings']['roles'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Exempt roles'),
      '#default_value' => $settings['signature_forum_roles'],
      '#options' => $roles,
      '#description' => t('Members of these roles will be exempt from content length settings.'),
    );
  }
  $form['signature_other'] = array(
    '#type' => 'fieldset',
    '#title' => t('Other options'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['signature_other']['line_limit'] = array(
    '#type' => 'textfield',
    '#title' => t('Line limit'),
    '#size' => 3,
    '#maxlength' => 10,
    '#default_value' => $settings['signature_forum_line_limit'],
    '#description' => t('The maximum number of lines allowed in a signature. 0 means no limit. Note: existing signatures that are too long will not be changed.'),
  );
  $form['signature_other']['delete_signatures'] = array(
    '#type' => 'checkbox',
    '#title' => t('Delete embedded signatures'),
    '#description' => t('Deletes signatures that are embedded in existing comments (warning: cannot be undone!).'),
    '#default_value' => FALSE,
  );
  return system_settings_form($form);
}

/**
 * Default signature settings.
 */
function signature_forum_defaults() {
  return array(
    'signature_forum_template' => "__________________\n<p>%s</p>",
    'signature_forum_format' => FILTER_FORMAT_DEFAULT,
    'signature_forum_line_limit' => 0,
    'signature_forum_min_content_length' => 0,
    'signature_forum_min_content_length_action' => MIN_CONTENT_ACTION_DO_NOT_DISPLAY,
    'signature_forum_min_content_length_filter' => FILTER_FORMAT_DEFAULT,
  );
}

/**
 * Admin settings form submit.
 */
function signature_forum_admin_settings_submit($form_id, $form_values) {
  $settings = array();
  foreach ($form_values as $form_value_key => $form_value_value) {
    if (substr($form_value_key, 0, strlen('signature_forum_show_for_')) == 'signature_forum_show_for_') {
      $settings[$form_value_key] = $form_value_value;
    }
  }
  if ($form_values['delete_signatures']) {
    switch ($GLOBALS['db_type']) {
      case 'mysql':
      case 'mysqli':
        db_query("UPDATE {comments} c INNER JOIN {users_signature} u ON c.uid=u.uid\n          SET c.comment=left(c.comment, length(c.comment) - length(u.signature))\n          WHERE right(c.comment, length(u.signature)) LIKE u.signature;");
        break;
      case 'pgsql':
        db_query("UPDATE {comments} SET comment=substring({comments}.comment from 1 for length({comments}.comment)-length({users_signature}.signature))\n          FROM {users_signature}\n          WHERE {comments}.comment LIKE '%' || {users_signature}.signature");
        break;
    }
    cache_clear_all(NULL, 'cache_page');
    cache_clear_all(NULL, 'cache_filter');
    drupal_set_message(t('Signatures in comments deleted.'));
  }
  $settings['signature_forum_template'] = $form_values['template'];
  $settings['signature_forum_format'] = $form_values['filter'];
  $settings['signature_forum_line_limit'] = $form_values['line_limit'];
  $settings['signature_forum_min_content_length'] = $form_values['min_content_length'];
  $settings['signature_forum_min_content_length_action'] = $form_values['min_content_length_action'];
  $settings['signature_forum_min_content_length_filter'] = $form_values['min_content_length_filter'];
  $settings['signature_forum_roles'] = $form_values['roles'];
  variable_set('signature_forum_settings', $settings);
  drupal_set_message(t('The configuration options have been saved.'));
}

/**
 * Implementation of hook_user().
 */
function signature_forum_user($op, &$edit, &$account, $category = NULL) {

  // Re-route the user signature to this module's signature table
  switch ($op) {
    case 'submit':

      // If the user has a signature set update it, otherwise create a new entry
      if (db_result(db_query('SELECT uid FROM {users_signature} WHERE uid=%d', $account->uid)) != '') {
        db_query('UPDATE {users_signature} SET signature=\'%s\' WHERE uid=%d', array(
          $edit['signature'],
          $account->uid,
        ));
      }
      else {
        db_query('INSERT INTO {users_signature} (uid, signature) VALUES (%d, \'%s\')', array(
          $account->uid,
          $edit['signature'],
        ));
      }
      unset($edit['signature']);
      break;
    case 'load':
      $signature = db_result(db_query('SELECT signature FROM {users_signature} WHERE uid=%d', $account->uid));

      // Bug #190446 OG puts $account->signature into comments
      $account->signature_forum = $signature;
      break;
    case 'validate':
      $settings = variable_get('signature_forum_settings', signature_forum_defaults());

      // If the signature contains too many lines
      if ($settings['signature_forum_line_limit'] > 0 && substr_count($edit['signature'], "\n") > $settings['signature_forum_line_limit']) {
        form_set_error('signature', t('Maximum number of !max_lines lines allowed in signature exceeded.', array(
          '!max_lines' => $settings['signature_forum_line_limit'],
        )));
      }
      break;
  }
}

/**
 * Implementation of hook_form_alter().
 */
function signature_forum_form_alter($form_id, &$form) {
  $settings = variable_get('signature_forum_settings', signature_forum_defaults());

  // if signatures are disabled for all content types, hide signature field in user profile settings
  if ($form_id == 'user_edit') {
    $enabled = false;
    foreach (node_get_types('names') as $type => $name) {
      if ($settings['signature_forum_show_for_' . $type]) {
        $enabled = true;
        break;
      }
    }
    if (!$enabled) {
      unset($form['comment_settings']);
    }
    else {
      $account = $form['_account']['#value'];
      $form['comment_settings']['signature']['#default_value'] = $account->signature_forum;
    }
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function signature_forum_nodeapi(&$node, $op, $teaser, $page) {
  $settings = variable_get('signature_forum_settings', signature_forum_defaults());
  if (!$teaser && $settings['signature_forum_show_for_' . $node->type]) {
    switch ($op) {
      case 'view':

        // Bug #190446 OG put $account->signature into comments (changing this just in case)
        $node->signature_forum = db_result(db_query('SELECT signature FROM {users_signature} WHERE uid = %d', $node->uid));
        signature_forum_logic($node->signature_forum, $node->uid, strlen(strip_tags($node->content['body']['#value'])));
        $node->content['body']['#value'] = $node->content['body']['#value'] . theme('signature_forum', $node->signature_forum);
        break;
    }
  }
}

/**
 * Implementation of hook_comment().
 */
function signature_forum_comment(&$comment, $op) {
  static $node_type;
  $settings = variable_get('signature_forum_settings', signature_forum_defaults());
  if (!isset($node_type)) {
    $node_type = db_result(db_query('SELECT type FROM {node} WHERE nid = %d', $comment->nid));
  }
  if ($op == 'view' && $settings['signature_forum_show_for_' . $node_type]) {
    static $cache;
    if (!isset($cache)) {
      $result = db_query("SELECT u.uid, u.signature FROM {comments} c\n                            INNER JOIN {users_signature} u ON c.uid=u.uid\n                            WHERE c.nid=%d AND c.status=0 AND u.signature<>''\n                            GROUP BY u.uid, u.signature", $comment->nid);
      $cache = array();
      while ($row = db_fetch_object($result)) {
        $cache[$row->uid] = $row->signature;
      }
    }
    if (isset($cache[$comment->uid])) {

      // Make implicit copy of signature (signature_forum_logic() alters variable)
      $signature = (string) $cache[$comment->uid];
      signature_forum_logic($signature, $comment->uid, strlen(strip_tags($comment->comment)));
      $comment->comment .= theme('signature_forum', $signature);
    }
  }
}

/**
 * Find if uid is in min length exception list.
 *
 * @param $uid
 *   User ID.
 * @return
 *   TRUE if uid is in exception list. FALSE otherwise.
 */
function signature_forum_user_exception($uid = 0) {
  $settings = variable_get('signature_forum_settings', signature_forum_defaults());
  $result = db_query("SELECT r.rid FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d", $uid);
  while ($role = db_fetch_object($result)) {
    if ($settings['signature_forum_roles'][$role->rid] == $role->rid) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Signature logic, check content is long enough etc.
 *
 * @param &$signature
 *   Signature text.
 * @param $uid
 *   User ID.
 * @param $content_length.
 */
function signature_forum_logic(&$signature, $uid = 0, $content_length = 0) {
  $settings = variable_get('signature_forum_settings', signature_forum_defaults());

  // Content minimum length not set, is longer than minimum or the user has a role that is an exception
  if ($content_length >= $settings['signature_forum_min_content_length'] || signature_forum_user_exception($uid)) {
    $signature = check_markup($signature, $settings['signature_forum_format']);
    $signature = trim(sprintf("\n" . $settings['signature_forum_template'], $signature));
    return;
  }
  elseif ($settings['signature_forum_min_content_length_action'] == MIN_CONTENT_ACTION_DO_NOT_DISPLAY) {
    $signature = '';
    return;
  }
  else {
    $signature = check_markup($signature, $settings['signature_forum_format']);
    $signature = check_markup($signature, $settings['signature_forum_min_content_length_filter']);
    $signature = trim(sprintf("\n" . $settings['signature_forum_template'], $signature));
    return;
  }
}

/**
 * Format user signature.
 *
 * @ingroup themeable
 */
function theme_signature_forum($signature) {

  // Special case: signature is blank
  if ($signature == '') {
    return '';
  }
  return '<div class="signature">' . $signature . '</div>';
}

Functions

Namesort descending Description
signature_forum_admin_settings Admin settings form.
signature_forum_admin_settings_submit Admin settings form submit.
signature_forum_comment Implementation of hook_comment().
signature_forum_defaults Default signature settings.
signature_forum_form_alter Implementation of hook_form_alter().
signature_forum_help Implementation of hook_help().
signature_forum_logic Signature logic, check content is long enough etc.
signature_forum_menu Implementation of hook_menu().
signature_forum_nodeapi Implementation of hook_nodeapi().
signature_forum_perm Implementation of hook_perm().
signature_forum_user Implementation of hook_user().
signature_forum_user_exception Find if uid is in min length exception list.
theme_signature_forum Format user signature.

Constants

Namesort descending Description
MIN_CONTENT_ACTION_ADDITIONAL_FILTER Run the signature through an additional filter if the content is under a certain length. Good for adding rel=nofollow to all links.
MIN_CONTENT_ACTION_DO_NOT_DISPLAY Do not display a signature when the content is under a certain length.