You are here

csm.module in Custom Submit Messages 7

Same filename and directory in other branches
  1. 6 csm.module
  2. 7.x csm.module

The main module file for Custom Submit Messages.

File

csm.module
View source
<?php

/**
 * @file
 * The main module file for Custom Submit Messages.
 */

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function csm_form_node_type_form_alter(&$form, $form_state) {

  // We need to know the current site language in order to present the form with
  // appropriate sections expanded.
  global $language;
  $current_lang = $language->language;

  // Build the form section that allows the user to change the submit messsages.
  $form['csm'] = array(
    '#type' => 'fieldset',
    '#title' => t('Submit message settings'),
    //'#access' => user_access('change ' . $form['#node_type']->type . 'submit messages'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
    '#attached' => array(
      'js' => array(
        drupal_get_path('module', 'csm') . '/csm.js',
      ),
    ),
    //'#tree' => TRUE,
    '#weight' => 100,
    '#attributes' => array(
      'class' => array(
        'csm-form',
      ),
    ),
  );

  // Add submit message subsections for each language
  $enabled_languages = language_list('enabled');
  $enabled_languages = $enabled_languages['1'];

  // If this returns NULL then we don't have to deal with any per-role messages
  $csm_attributes = variable_get('csm_attributes', NULL);
  if ($csm_attributes !== NULL) {
    foreach ($csm_attributes as $rid => $settings) {
      $csm_attributes_sorted_by_weight[$settings['weight']] = array(
        'rid' => $rid,
        'checkbox' => $settings['checkbox'],
      );
    }
    ksort($csm_attributes_sorted_by_weight);
    foreach ($csm_attributes_sorted_by_weight as $weight => $settings) {
      if ($settings['checkbox'] == 1) {

        // Add create/update/delete fields for $settings['rid']
      }
    }
  }
  foreach ($enabled_languages as $lang => $details) {

    // Display the global fields
    $form['csm'][$lang] = array(
      '#type' => 'fieldset',
      '#title' => check_plain(t($enabled_languages[$lang]->name)),
    );
    $form['csm'][$lang]['global'] = _csm_lang_fieldsets($lang, $form['#node_type']->type, 'message', 'global');
    $form['csm'][$lang]['global']['#title'] = t("Default");
    if ($lang == $current_lang) {
      $form['csm'][$lang]['global']['#collapsed'] = FALSE;
    }
    if (isset($csm_attributes_sorted_by_weight)) {
      foreach ($csm_attributes_sorted_by_weight as $weight => $settings) {
        if ($settings['checkbox'] == 1) {
          $form['csm'][$lang]['some_text'] = array(
            '#markup' => '<p>' . t('If you have chosen to set custom messages for
                        specific user roles, you can set those messages below.
                        If a message is left blank for a specific role, users
                        with that role will revert to the global message, above.
                        If a user has multiple user roles for which role-specific
                        messages are set, the message closest to the top of this
                        list will be used. The order of this list (and the roles
                        it includes) can be set at ') . l('admin/config/csm/csm', 'admin/config/csm/csm') . '</p>',
          );
          break;
        }
      }

      // Loop through the specified roles and display fields for each
      foreach ($csm_attributes_sorted_by_weight as $weight => $settings) {
        if ($settings['checkbox'] == 1) {
          $form['csm'][$lang][$settings['rid']] = _csm_lang_fieldsets($lang, $form['#node_type']->type, 'message', $settings['rid']);
          $form['csm'][$lang][$settings['rid']]['#title'] = t(user_role_load($settings['rid'])->name);
        }
      }
    }
  }

  // Add token help section
  $form['csm']['view']['token_help'] = array(
    '#title' => t('Replacement patterns'),
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['csm']['view']['token_help']['help'] = array(
    '#theme' => 'token_tree',
    '#token_types' => array(
      'node',
    ),
    '#global_types' => TRUE,
    '#click_insert' => TRUE,
  );

  // Build the form section that allows the user to change the node creation
  // page title.
  $form['cnpt'] = array(
    '#type' => 'fieldset',
    '#title' => t('Node creation page title and status message'),
    '#access' => user_access('change ' . $form['#node_type']->type . ' creation page title'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
    '#attached' => array(
      'js' => array(
        drupal_get_path('module', 'csm') . '/csm.js',
      ),
    ),
    //'#tree' => TRUE,
    '#weight' => 101,
    '#attributes' => array(
      'class' => array(
        'csm-form',
      ),
    ),
  );

  // Add create form title subsections for each language
  foreach ($enabled_languages as $lang => $details) {
    $form['cnpt'][$lang] = _csm_lang_fieldsets($lang, $form['#node_type']->type, 'title', 'global');
    $form['cnpt'][$lang]['#title'] = t($details->name);
    if ($lang == $current_lang) {
      $form['cnpt'][$lang]['#collapsed'] = FALSE;
    }
    if (isset($csm_attributes_sorted_by_weight)) {
      foreach ($csm_attributes_sorted_by_weight as $weight => $settings) {
        if ($settings['checkbox'] == 1) {
          $form['cnpt'][$lang]['some_text'] = array(
            '#markup' => '<p>' . t('If you have chosen to set custom titles for
                          specific user roles, you can set those titles below.
                          If a title is left blank for a specific role, users
                          with that role will revert to the global title, above.
                          If a user has multiple user roles for which role-specific
                          title are set, the title closest to the top of this
                          list will be used. The order of this list (and the roles
                          it includes) can be set at ') . l('admin/config/csm/csm', 'admin/config/csm/csm') . '</p>',
          );
          break;
        }
      }

      // Loop through the specified roles and display fields for each
      foreach ($csm_attributes_sorted_by_weight as $weight => $settings) {
        if ($settings['checkbox'] == 1) {
          $form['cnpt'][$lang][$settings['rid']] = _csm_lang_fieldsets($lang, $form['#node_type']->type, 'title', $settings['rid']);
          $form['cnpt'][$lang][$settings['rid']]['#title'] = t(user_role_load($settings['rid'])->name);
        }
      }
    }
  }

  // Add token help section
  $form['cnpt']['view']['token_help'] = array(
    '#title' => t('Replacement patterns'),
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['cnpt']['view']['token_help']['help'] = array(
    '#theme' => 'token_tree',
    '#token_types' => array(
      'node',
    ),
    '#global_types' => TRUE,
    '#click_insert' => TRUE,
  );
}

/**
 * Implements hook_form_alter().
 */
function csm_form_alter(&$form, $form_state, $form_id) {

  // Need an if clause to stop errors occurring when a value isn't set
  if (!isset($form['type']['#value'])) {
    return;
  }

  // Need another if clause so that we exit if this isn't the sort of form we
  // care about
  if (!($form_id == $form['type']['#value'] . '_node_form' && $form['nid']['#value'] == NULL && empty($form_state['post']))) {
    return;
  }
  global $language;
  global $user;
  $relevant_roles = _csm_relevant_role_array($user);
  $csm_settings = variable_get('csm_attributes', NULL);

  // Is there a way of combining these two foreach loops?
  foreach ($relevant_roles as $key => $role) {

    // If the title is set for that role, use that title
    $title = variable_get('csm_form_title_' . $language->language . '_' . $role . '_' . $form['type']['#value'], '');
    if ($title && $title !== '') {
      if ($title == '<none>') {
        $title = '';
      }
      drupal_set_title(token_replace($title, array(
        'node' => $form['#node'],
      )));

      // Log a system message.
      watchdog('csm', '@type: node creation page title changed using Custom
                Submit Messages.', array(
        '@type' => $form['type']['#value'],
      ), WATCHDOG_NOTICE);
      break;
    }
  }
  reset($relevant_roles);
  foreach ($relevant_roles as $key => $role) {

    // If the message is set for that role, use that message
    $message = variable_get('csm_form_msg_msg_' . $language->language . '_' . $role . '_' . $form['type']['#value'], '');
    if ($message && $message !== '') {

      // The message is set
      $message_type = variable_get('csm_form_msg_type_' . $language->language . '_' . $role . '_' . $form['type']['#value'], 'status');
      if ($message_type == 'none') {

        // The message is set, but the message type is set to "none". We need to
        // keep looking for a message to set.
        continue;
      }
      else {
        drupal_set_message(check_plain(token_replace($message, array(
          'node' => $form['#node'],
        ))), $message_type);

        // Log a system message
        watchdog('csm', '@type: node creation page message set using Custom
               Submit Messages.', array(
          '@type' => $form['type']['#value'],
        ), WATCHDOG_NOTICE);
        break;
      }
    }
  }
  return;
}

/**
 * Implements hook_node_insert().
 */
function csm_node_insert($node) {
  _csm_node_ops($node, 'insert');
  return;
}

/**
 * Implements hook_node_update().
 */
function csm_node_update($node) {
  _csm_node_ops($node, 'update');
  return;
}

/**
 * Implements hook_node_delete().
 */
function csm_node_delete($node) {
  _csm_node_ops($node, 'delete');
  return;
}

/**
 * Implements hook_node_prepare().
 */
function csm_node_prepare($node) {
  if (!isset($node->nid)) {

    // Adding a new node. Store the node in the variable table so that it can be retrieved
    // by hook_form_alter and token substitutions can be done properly on the title of
    // the page.
    _csm_variable_set('csm_node_temp', $node);
  }
  return;
}

/**
 * Helper function for the various csm_node_op() functions.
 */
function _csm_node_ops($node, $op) {
  $node->op = $op;
  if (isset($_SESSION['csm']) && is_array($_SESSION['csm'])) {
    return;
  }
  else {
    $_SESSION['csm'][$node->nid] = $node->nid;
    _csm_variable_set('csm_node_temp_' . $node->nid, $node);
  }
}

/**
 * Implements hook_menu().
 */
function csm_menu() {
  $items['admin/config/csm'] = array(
    'title' => 'Custom Submit Messages',
    'description' => 'Custom submit message tools.',
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array(
      'access administration pages',
    ),
    'file' => 'system.admin.inc',
    'file path' => drupal_get_path('module', 'system'),
  );
  $items['admin/config/csm/csm'] = array(
    'title' => 'Custom submit messages',
    'description' => 'Configuration for custom submit messages',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'csm_form',
    ),
    'access arguments' => array(
      'access administration pages',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Page callback: CSM settings
 *
 * @see csm_menu()
 */
function csm_form($form, &$form_state) {

  // Load user_roles() (we'll need this names of each role for the form labels)
  // and load the saved settings for the form.
  $user_roles = user_roles();
  $form_defaults = variable_get('csm_attributes', NULL);

  // Re-index the $form_defaults by weight and then re-sort. Then, when we build
  // the form we can step through the array in weight order, and the form entries
  // will be displayed in weight order. If $form_defaults is not set yet (i.e.,
  // if the form has not been saved yet) then just index by rid.
  if ($form_defaults !== NULL) {
    foreach ($form_defaults as $rid => $defaults) {
      $form_defaults_sorted_by_weight[$defaults['weight']] = array(
        'rid' => $rid,
        'checkbox' => $defaults['checkbox'],
      );
    }
    ksort($form_defaults_sorted_by_weight);
  }
  else {
    foreach ($user_roles as $rid => $role) {
      $form_defaults_sorted_by_weight[$rid] = array(
        'rid' => $rid,
        'checkbox' => 0,
      );
    }
  }

  // Build the form
  $form['csm_attributes'] = array(
    '#prefix' => '<div id="curve-attributes">',
    '#suffix' => '</div>',
    '#tree' => TRUE,
    '#theme' => 'csm_components',
  );
  foreach ($form_defaults_sorted_by_weight as $weight => $values) {
    $form['csm_attributes'][$values['rid']]['label'] = array(
      '#type' => 'item',
      '#markup' => $user_roles[$values['rid']],
    );
    $form['csm_attributes'][$values['rid']]['checkbox'] = array(
      '#type' => 'checkbox',
      '#default_value' => $values['checkbox'],
    );
    $form['csm_attributes'][$values['rid']]['weight'] = array(
      '#type' => 'textfield',
      '#default_value' => $weight,
      '#size' => 3,
      '#attributes' => array(
        'class' => array(
          'item-row-weight',
        ),
      ),
    );
  }
  return system_settings_form($form);
}

/**
 * Implements hook_theme().
 */
function csm_theme($existing, $type, $theme, $path) {
  $themes = array(
    'csm_components' => array(
      'render element' => 'element',
    ),
  );
  return $themes;
}

// Custom theme output.
function theme_csm_components($vars) {
  $element = $vars['element'];
  drupal_add_tabledrag('sample_table', 'order', 'sibling', 'item-row-weight');
  $header = array(
    'label' => t('User role'),
    'checkbox' => t('Enable role-specific messages'),
    'weight' => t('Weight'),
  );
  $rows = array();
  foreach (element_children($element) as $key) {
    $row = array();
    $row['data'] = array();
    foreach ($header as $fieldname => $title) {
      $row['data'][] = drupal_render($element[$key][$fieldname]);
      $row['class'] = array(
        'draggable',
      );
    }
    $rows[] = $row;
  }
  return theme('table', array(
    'header' => $header,
    'rows' => $rows,
    'attributes' => array(
      'id' => 'sample_table',
    ),
  ));
}

/**
 * Implements hook_permission().
 */
function csm_permission() {

  // Add an option to change submit messages for each node type, and to change
  // the node creation page title for each node type.
  $node_types = node_type_get_types();
  foreach ($node_types as $key => $value) {
    $perm['change ' . $key . ' submit messages'] = array(
      'title' => t('change ' . $key . ' submit messages'),
    );
    $perm['change ' . $key . ' creation page title'] = array(
      'title' => t('change ' . $key . ' creation page title'),
    );
  }
  return $perm;
}

/**
 * Implements hook_help().
 */
function csm_help($path, $arg) {
  switch ($path) {
    case 'admin/config/csm/csm':
      return '<p>' . t('The Custom Submit Messages module allows you
                       to set different messages for different user
                       roles. If you would like to set a specific message
                       for a specific user role, please check the checkbox
                       next to that user role. If a user has two roles for
                       which specific messages are defined, the message
                       defined for the role nearest the top of this list will
                       be displayed. Please re-order this list to ensure
                       that the correct messages are displayed.') . '</p>';
  }
}

/**
 * Implements hook_message_alter().
 */
function csm_message_alter(&$messages) {

  // If $messages->messages['status'] doesn't exist then there are no status
  // messages and there's nothing to do
  if (!isset($messages->messages['status'])) {
    if (isset($_SESSION['csm'])) {
      unset($_SESSION['csm']);
    }
    return;
  }

  // Search for submit messages and change any that are found
  // First create arrays containing messages that may need to be changed.
  // Because the messages might not be in English, we need to load the node
  // first. We can then build its create, update, and delete messages in t()
  // and check the output against the message we are looking to change.
  if (!isset($_SESSION['csm'])) {
    return;
  }
  foreach ($_SESSION['csm'] as $key => $nid) {
    $node = variable_get('csm_node_temp_' . $nid, NULL);
    $args = array(
      '@type' => node_type_get_name($node),
      '%title' => $node->title,
    );
    $created = $messages
      ->contains(t('@type %title has been created.', $args), 'status');
    $updated = $messages
      ->contains(t('@type %title has been updated.', $args), 'status');
    $deleted = $messages
      ->contains(t('@type %title has been deleted.', $args), 'status');

    // Then parse through each array, double-checking for messages that need to be
    // changed and then changing them.
    // This code is no longer necessary because the matching technique (above) is
    // tighter, but it is retained so that $relevant_messages is created and can
    // be parsed later on. This could be rewritten so that $created, $updated, and
    // $deleted are parsed directly.
    $message_types_to_check = array(
      'created',
      'updated',
      'deleted',
    );
    foreach ($message_types_to_check as $delta => $type) {
      if (${$type} == FALSE) {
        continue;

        // There are no messages of type $$type so nothing to check
      }
      else {

        // Double check the messages
        foreach (${$type}['status'] as $delta_2 => $message_array) {
          $relevant_messages[] = $message_array['index'];
        }
      }
    }
    if (!isset($relevant_messages)) {

      // No relevant messages so nothing to change. There might be some stray data
      // left if the variable table, though, and also some non-visible messages,
      // so let's delete that.
      if (array_key_exists('csm', $_SESSION)) {
        unset($_SESSION['csm']);
      }
      return;
    }
  }

  // Change the messages:
  foreach ($relevant_messages as $delta => $index) {
    variable_del('csm_node_temp_' . $nid);

    // Check the active language and user then load the msg based on that.
    global $language;
    global $user;
    $relevant_roles = _csm_relevant_role_array($user);
    foreach ($relevant_roles as $key => $role) {
      $message = variable_get('csm_' . $node->op . '_msg_' . $language->language . '_' . $role . '_' . $node->type, '');
      if ($message == "") {

        // message hasn't been set for this rid, so check the next rid
        continue;
      }
      else {

        // message has been set for this rid, so we can stop searching for a
        // message
        break;
      }
    }
    if ($message) {
      if ($message == '<none>') {

        // kill the message
        unset($messages->messages['status'][$delta]);
        $messages->remove_used = TRUE;
        $messages
          ->clean();
      }
      else {
        $message = $message == '<none>' ? '' : token_replace($message, array(
          'node' => $node,
        ));
        $messages->messages['status'][$delta] = t($message);
      }
    }
    unset($message);

    // Log a system message.
    watchdog('csm', '@type: node @msg_type message changed using Custom Submit Messages.', array(
      '@type' => $node->type,
      '@msg_type' => $node->op,
    ), WATCHDOG_NOTICE);
    return;
  }
}
function _csm_variable_set($name, $value) {
  if (module_exists('nodecomment')) {
    if (variable_get($name, 'notset') !== 'notset') {

      // The variable has already been set so there's not need to set it again
      return;
    }
  }
  variable_set($name, $value);
  return;
}

/**
 * Provide the form sub-section fieldsets for a given (or NULL) language.
 */
function _csm_lang_fieldsets($lang = NULL, $form_type, $type = 'message', $role = NULL) {
  if ($lang == NULL) {
    global $language;
    $lang = $language->language;
  }
  $fields = array(
    '#type' => 'fieldset',
    '#title' => t($lang),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $variable_name_suffix = $lang . '_' . $role . '_' . $form_type;
  switch ($type) {
    case 'message':
      $fields['csm_insert_msg_' . $lang . '_' . $role] = array(
        '#type' => 'textfield',
        '#title' => t('Create message'),
        '#default_value' => t(variable_get('csm_insert_msg_' . $variable_name_suffix, '')),
        '#description' => t('Override the default message displayed when a user
                            creates a node of this type. Use <em>&lt;none&gt;</em>
                            to display no message, or leave blank to use the default
                            message ("[node:content-type:name] [node:title] has
                            been created.").'),
        '#size' => 60,
        '#maxlength' => 4096,
        '#required' => FALSE,
      );
      $fields['csm_update_msg_' . $lang . '_' . $role] = array(
        '#type' => 'textfield',
        '#title' => t('Update message'),
        '#default_value' => t(variable_get('csm_update_msg_' . $variable_name_suffix, '')),
        '#description' => t('Override the default message displayed when a user
                            updates a node of this type. Use <em>&lt;none&gt;</em>
                            to display no message, or leave blank to use the default
                            message ("[node:content-type:name] [node:title] has
                            been updated.").'),
        '#size' => 60,
        '#maxlength' => 4096,
        '#required' => FALSE,
      );
      $fields['csm_delete_msg_' . $lang . '_' . $role] = array(
        '#type' => 'textfield',
        '#title' => t('Delete message'),
        '#default_value' => t(variable_get('csm_delete_msg_' . $variable_name_suffix, '')),
        '#description' => t('Override the default message displayed when a user
                            deletes a node of this type. Use <em>&lt;none&gt;</em>
                            to display no message, or leave blank to use the default
                            message ("[node:content-type:name] [node:title] has
                            been deleted.").'),
        '#size' => 60,
        '#maxlength' => 4096,
        '#required' => FALSE,
      );
      return $fields;
      break;
    case 'title':
      $variable_name = 'csm_form_title_' . $variable_name_suffix;
      $fields['csm_form_title_' . $lang . '_' . $role] = array(
        '#type' => 'textfield',
        '#title' => t('Node creation page title'),
        '#default_value' => t(variable_get('csm_form_title_' . $variable_name_suffix, '')),
        '#description' => t('Override the default title for the node creation page.
                            Use <em>&lt;none&gt;</em> to display no title, or leave
                            blank to use the default title ("Create [node:content-type:name]").'),
        '#size' => 60,
        '#maxlength' => 4096,
        '#required' => FALSE,
      );
      $fields['csm_form_msg_msg_' . $lang . '_' . $role] = array(
        '#type' => 'textfield',
        '#title' => t('Node creation page message'),
        '#default_value' => t(variable_get('csm_form_msg_msg_' . $variable_name_suffix, '')),
        '#description' => t('Set a message to be displayed on node creation pages for this content type. Leave blank to display no message.'),
        '#size' => 60,
        '#maxlength' => 4096,
        '#required' => FALSE,
      );
      $fields['csm_form_msg_type_' . $lang . '_' . $role] = array(
        '#type' => 'select',
        '#title' => t('Node creation page message type'),
        '#default_value' => variable_get('csm_form_msg_type_' . $variable_name_suffix, 'status'),
        '#description' => t('Set the type of message to be displayed.'),
        '#options' => array(
          'none' => 'None',
          'status' => 'Status',
          'warning' => 'Warning',
          'error' => 'Error',
        ),
        '#description' => '',
      );
      return $fields;
      break;
  }
}
function _csm_relevant_role_array($user) {

  // The $user has more than one role (as they almost always will do) so we
  // need to work out which role is relevant for our purposes
  $csm_settings = variable_get('csm_attributes', NULL);
  if ($csm_settings == NULL) {
    $relevant_roles[] = 'global';
    return $relevant_roles;
  }
  else {
    foreach ($csm_settings as $rid => $settings) {
      if ($settings['checkbox'] == 1) {
        break;
      }
    }
    if ($settings['checkbox'] == 0) {

      // The csm_settings have been set, but none of the checkboxes are checked
      // so we only need to deal with language-specific messages (not role specific)
      $relevant_roles[] = 'global';
      return $relevant_roles;
    }
  }

  // Loop through each role and if checkbox is checked and user has role then
  // add that role to our array
  foreach ($user->roles as $rid => $role) {
    if (array_key_exists($rid, $csm_settings) && $csm_settings[$rid]['checkbox'] == 1) {
      $relevant_roles[] = $rid;
      $weights[] = $csm_settings[$rid]['weight'];
    }
  }
  array_multisort($weights, $relevant_roles);
  $relevant_roles[] = 'global';
  return $relevant_roles;
}

/**
 * Returns a list of all of the variables the module may have added to the
 * variable table. Used in csm.install when uninstalling the module to clear
 * the variables out of the variable table.
 */
function csm_variables() {
  $crud = array(
    'insert_msg',
    'delete_msg',
    'form_title',
    'update_msg',
  );
  $node_types = node_type_get_types();
  $user_roles = user_roles();
  $user_roles['global'] = 'global';
  if (module_exists('locale')) {
    $languages = locale_language_list();
  }
  else {
    $languages = array(
      'en' => 'en',
    );
  }
  foreach ($crud as $crud_key => $crud_value) {
    foreach ($node_types as $node_type_key => $node_type_value) {
      foreach ($languages as $language_key => $language_value) {
        foreach ($user_roles as $rid => $role) {
          $variables[] = 'csm_' . $crud_value . '_' . $language_key . '_' . $rid . '_' . $node_type_key;
        }
      }
    }
  }
  if ($csm_node_temp = variable_get('csm_node_temp', FALSE)) {
    $variables[] = 'csm_node_temp';
  }
  if ($csm_settings = variable_get('csm_attributes', FALSE)) {
    $variables[] = 'csm_attributes';
  }
  $sql = 'SELECT name FROM {variable} WHERE name LIKE :name';
  $args = array(
    ':name' => db_like('csm_node_temp_') . '%',
  );
  foreach (db_query($sql, $args) as $result) {
    $variables[] = $result->name;
  }
  return $variables;
}

Functions

Namesort descending Description
csm_form Page callback: CSM settings
csm_form_alter Implements hook_form_alter().
csm_form_node_type_form_alter Implements hook_form_BASE_FORM_ID_alter().
csm_help Implements hook_help().
csm_menu Implements hook_menu().
csm_message_alter Implements hook_message_alter().
csm_node_delete Implements hook_node_delete().
csm_node_insert Implements hook_node_insert().
csm_node_prepare Implements hook_node_prepare().
csm_node_update Implements hook_node_update().
csm_permission Implements hook_permission().
csm_theme Implements hook_theme().
csm_variables Returns a list of all of the variables the module may have added to the variable table. Used in csm.install when uninstalling the module to clear the variables out of the variable table.
theme_csm_components
_csm_lang_fieldsets Provide the form sub-section fieldsets for a given (or NULL) language.
_csm_node_ops Helper function for the various csm_node_op() functions.
_csm_relevant_role_array
_csm_variable_set