csm.module in Custom Submit Messages 7
Same filename and directory in other branches
The main module file for Custom Submit Messages.
File
csm.moduleView 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><none></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><none></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><none></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><none></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
Name![]() |
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 |