enforce_revlog.module in Enforce revision log message 6
Same filename and directory in other branches
Allows enforcing unpriviledged users to enter a log message every time a node revision is created or reverted
File
enforce_revlog.moduleView source
<?php
/**
* @file
* Allows enforcing unpriviledged users to enter a log message every time
* a node revision is created or reverted
*/
/**
* TODO:
* - Make comments follow more closely the Doxygen format
*/
/**
* Implementation of hook_perm().
*
* Adding permission for skipping the check.
*/
function enforce_revlog_perm() {
return array(
'skip revision log message',
);
}
/**
* Implementation of hook_menu().
*
* Administration page and JS callback
*/
function enforce_revlog_menu() {
$items = array();
$items['admin/settings/enforce_revlog'] = array(
'title' => 'Enforce revlog',
'description' => 'Enforce users to enter a log message for every revision.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'enforce_revlog_settings',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer site configuration',
),
);
$items['enforce_revlog/js'] = array(
'page callback' => 'enforce_revlog_js',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Settings page
*/
function enforce_revlog_settings() {
$form['info_msg'] = array(
'#type' => 'markup',
// not necessary (default value), added for exhaustivity
'#value' => t('Do not forget to <a href="@setperms">set permissions</a> for roles that will be able to skip entering a log message', array(
'@setperms' => url('admin/user/permissions', array(
'fragment' => 'module-enforce_revlog',
)),
)),
// use placeholder and url() as it's best practice for these translatable strings
'#prefix' => '<p><em>',
'#suffix' => '</em></p>',
);
$form['enforce_revlog_revision_revert'] = array(
'#type' => 'checkbox',
'#title' => t('Enforce users to enter a log message when reverting a revision'),
'#default_value' => variable_get('enforce_revlog_revision_revert', 0),
);
$form['types'] = array(
'#type' => 'fieldset',
'#title' => t('Enforce users to enter a log message for every revision of these content types'),
'#description' => t('Each selected content type must have revisions enabled for this module to work'),
);
// Generate per content-type settings
foreach (node_get_types() as $type => $name) {
$form['types']['enforce_revlog_node_type_' . $type] = array(
'#type' => 'checkbox',
'#title' => $type,
'#default_value' => variable_get('enforce_revlog_node_type_' . $type, 0),
);
}
return system_settings_form($form);
}
/**
* Implementation of hook_nodeapi()
*
* Displays a message when the revision log is empty.
*/
function enforce_revlog_nodeapi(&$node, $op, $arg = 0) {
switch ($op) {
case 'prepare':
// We should enable enforce_revlog on this form if:
if ($node->nid && variable_get('enforce_revlog_node_type_' . $node->type, 0) && !user_access('skip revision log message')) {
$node->enforce_revlog = TRUE;
}
break;
case 'validate':
// A log message will only be required if:
if ($node->nid && $node->revision && $node->op == $node->submit && variable_get('enforce_revlog_node_type_' . $node->type, 0) && !user_access('skip revision log message') && empty($node->log)) {
// different message if user is a node administrator
$message = user_access('administer nodes') ? t('Please enter a revision log message or uncheck the revision checkbox.') : t('Please enter a revision log message.');
form_set_error('log', $message);
}
break;
case 'presave':
// Trigger only if we're reverting a revision
// Determined thanks to a custom property in the node object
if (!empty($node->enforce_revlog_revision_revert)) {
// Adding the custom log message to the standard one
$node->log = $node->enforce_revlog_log_message . ' (' . $node->log . ')';
// Deleting custom object properties, there aren't needed anymore
unset($node->enforce_revlog_log_message, $node->enforce_revlog_revision_revert);
}
break;
}
}
/**
* Implementation of hook_help()
*/
function enforce_revlog_help($path, $arg) {
switch ($path) {
case 'admin/help#enforce_revlog':
// Help page
return '<p>' . t('Enforce users to enter a log message for every revision.') . '</p>';
case 'admin/settings/enforce_revlog':
// Settings page header
return '<p>' . t('Settings for the Enforce revlog module.') . '</p>';
}
}
/**
* Implementation of hook_form_alter().
*
* Trying to identify all node forms to enable log message textarea as required
*/
function enforce_revlog_form_alter(&$form, $form_state, $form_id) {
switch ($form['#id']) {
case 'node-form':
if ($form['#node']->enforce_revlog) {
// Triggering AHAH handler on enabling / disabling creation of a new revision
$form['revision_information']['revision']['#ahah'] = array(
'event' => 'change',
// not necessary (default value), added for exhaustivity
'path' => 'enforce_revlog/js',
'wrapper' => 'edit-log-wrapper',
);
// Mark the log message as required if creation of a new revision is enabled
if (!empty($form['#node']->revision)) {
// Using a custom theme function here instead of setting the #required property
// to prevent validation issues we would encounter otherwise
$form['revision_information']['log']['#theme'] = 'enforce_revlog_log_message';
}
}
break;
case 'node-revision-revert-confirm':
// Add a log message textarea to the revision revert form - adapt the one from node.module
$form['log'] = array(
'#type' => 'textarea',
'#title' => t('Log message'),
'#default_value' => '',
'#rows' => 2,
'#description' => t('An explanation of your reasons for reverting the revision to help other authors understand your motivations.'),
'#required' => variable_get('enforce_revlog_revision_revert', 0) && !user_access('skip revision log message') ? TRUE : FALSE,
);
// Adding our own properties to the node object for future use
$form['#node_revision']->enforce_revlog_revision_revert = 1;
$form['#node_revision']->enforce_revlog_log_message = '';
// Custom validation function
$form['#validate'][] = 'enforce_revlog_revision_revert_validate';
break;
case 'node-type-form':
// Adding enforce_revlog setting on the content type editing form.
// Value will be automatically saved in the variable table.
// Content type name changes are handled automatically too.
$form['workflow']['enforce_revlog_node_type'] = array(
'#type' => 'radios',
'#title' => t('Enforce users to enter a log message for every revision'),
'#description' => t('Revisions must be enabled for this module to work'),
'#default_value' => variable_get('enforce_revlog_node_type_' . $form['#node_type']->type, 0),
'#options' => array(
t('Disabled'),
t('Enabled'),
),
);
break;
}
}
/**
* Validation function for the revision revert form
* Passing $form by reference to store changes to the object
*/
function enforce_revlog_revision_revert_validate(&$form, &$form_state) {
// Storing the custom log message in the node object
$form['#node_revision']->enforce_revlog_log_message = check_plain($form_state['values']['log']);
}
/**
* Helper AHAH function to change the required state of the log message textarea.
* Allows visual feedback by the user.
* This function is only triggered when the right conditions are met.
*/
function enforce_revlog_js() {
$form_state = array(
'submitted' => FALSE,
);
$form_build_id = $_POST['form_build_id'];
// Add the new element to the stored form. Without adding the element to the
// form, Drupal is not aware of this new element's existence and will not
// process it. We retreive the cached form, add the element, and resave.
$form = form_get_cache($form_build_id, $form_state);
// Switching theme function used to render the log message textarea. Will switch the "required" state.
// We cannot use the #required property due to validation issues otherwise
$form['revision_information']['log']['#theme'] = empty($form['revision_information']['log']['#theme']) ? 'enforce_revlog_log_message' : NULL;
form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
);
// Rebuild the form.
$form = form_builder($_POST['form_id'], $form, $form_state);
// Render the new output.
$new_form = $form['revision_information']['log'];
return drupal_json(array(
'status' => TRUE,
'data' => drupal_render($new_form),
));
}
/**
* Implementation of hook_node_type().
*
* Deleting associated variable when content type is deleted
* Avoiding issues with unused variables and hook_uninstall()
* Update is handled automatically
* @see enforce_revlog_uninstall().
*/
function enforce_revlog_node_type($op, $info) {
switch ($op) {
case 'delete':
variable_del('enforce_revlog_node_type_' . $info->type);
break;
}
}
/**
* Implementation of hook_theme()
* Enabling custom theme implementation
*/
function enforce_revlog_theme() {
return array(
'enforce_revlog_log_message' => array(
'arguments' => array(
'element' => NULL,
),
),
);
}
/**
* Custom theme function for the log message element
* Faking the #required property without triggering the automatic validation
*/
function theme_enforce_revlog_log_message($element) {
// Setting the #required property here as it won't affect the form - only the display
$element['#required'] = TRUE;
return theme('textarea', $element);
}
Functions
Name![]() |
Description |
---|---|
enforce_revlog_form_alter | Implementation of hook_form_alter(). |
enforce_revlog_help | Implementation of hook_help() |
enforce_revlog_js | Helper AHAH function to change the required state of the log message textarea. Allows visual feedback by the user. This function is only triggered when the right conditions are met. |
enforce_revlog_menu | Implementation of hook_menu(). |
enforce_revlog_nodeapi | Implementation of hook_nodeapi() |
enforce_revlog_node_type | Implementation of hook_node_type(). |
enforce_revlog_perm | Implementation of hook_perm(). |
enforce_revlog_revision_revert_validate | Validation function for the revision revert form Passing $form by reference to store changes to the object |
enforce_revlog_settings | Settings page |
enforce_revlog_theme | Implementation of hook_theme() Enabling custom theme implementation |
theme_enforce_revlog_log_message | Custom theme function for the log message element Faking the #required property without triggering the automatic validation |