publishcontent.module in Publish Content 6
Same filename and directory in other branches
Add button to publish or unpublish a node, with access control based on the node type
File
publishcontent.moduleView source
<?php
/**
* @file
* Add button to publish or unpublish a node,
* with access control based on the node type
*/
/**
* Implements of hook_menu().
*/
function publishcontent_menu() {
$items = array();
$items['admin/settings/publishcontent'] = array(
'title' => 'Publish content settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'publishcontent_config_form',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer site configuration',
),
'description' => 'Show/hide the publish/unpublish tabs on nodes.',
'file' => 'publishcontent.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['node/%publishcontent_tab/publish/%publishcontent_security_token'] = array(
'title' => 'Publish',
'page callback' => 'publishcontent_toggle_status',
'page arguments' => array(
1,
),
'access callback' => '_publishcontent_publish_access',
'access arguments' => array(
1,
3,
),
'weight' => 5,
'type' => MENU_LOCAL_TASK,
);
$items['node/%publishcontent_tab/unpublish/%publishcontent_security_token'] = array(
'title' => 'Unpublish',
'page callback' => 'publishcontent_toggle_status',
'page arguments' => array(
1,
),
'access callback' => '_publishcontent_unpublish_access',
'access arguments' => array(
1,
3,
),
'weight' => 5,
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Decide to show the (un)publish tab or not.
*/
function publishcontent_tab_load($nid) {
if (is_numeric($nid)) {
$node = node_load($nid);
if (variable_get('publishcontent_tabs', TRUE)) {
return $node;
}
}
return FALSE;
}
/**
* Used to append a security token to prevent XSS.
*
* @see Dynamic argument replacement (wildcard) for hook_menu at
* http://drupal.org/node/109153
*/
function publishcontent_security_token_to_arg($arg, $map, $index) {
return drupal_get_token();
}
/**
* DEPRECATED: This function will be going away. publish_content_menu_alter was
* using this function. Leaving in place to avoid fatal errors due to outdated
* menu cache.
*/
function _publishcontent_view_access($node) {
return user_access('un/publish ' . check_plain($node->type) . ' content') || user_access('un/publish *all* content') || node_access('view', $node);
}
/**
* Access callback for publish action. Only allow access based on permissions
* and current node status = unpublished
*/
function _publishcontent_publish_access($node, $token = FALSE) {
if ($token && !drupal_valid_token($token)) {
return FALSE;
}
if (!variable_get('publishcontent_' . $node->type, TRUE)) {
return FALSE;
}
global $user;
return !$node->status && (user_access('publish any content') || user_access('publish own content') && $user->uid == $node->uid || user_access('publish editable content') && node_access('update', $node) || user_access('publish own ' . check_plain($node->type) . ' content', $user) && $user->uid == $node->uid || user_access('publish any ' . check_plain($node->type) . ' content') || user_access('publish editable ' . check_plain($node->type) . ' content') && node_access('update', $node));
}
/**
* Access callback for unpublish action. Only allow access based on permissions
* and current node status = published
*/
function _publishcontent_unpublish_access($node, $token = FALSE) {
if ($token && !drupal_valid_token($token)) {
return FALSE;
}
if (!variable_get('publishcontent_' . $node->type, TRUE)) {
return FALSE;
}
global $user;
return $node->status && (user_access('unpublish any content') || user_access('unpublish own content') && $user->uid == $node->uid || user_access('unpublish editable content') && node_access('update', $node) || user_access('unpublish own ' . check_plain($node->type) . ' content', $user) && $user->uid == $node->uid || user_access('unpublish any ' . check_plain($node->type) . ' content') || user_access('unpublish editable ' . check_plain($node->type) . ' content') && node_access('update', $node));
}
/**
* Implements hook_perm().
*/
function publishcontent_perm() {
$perms = array(
'publish any content',
'unpublish any content',
'publish own content',
'unpublish own content',
'publish editable content',
'unpublish editable content',
);
foreach (node_get_types() as $type) {
if (isset($type->type)) {
$perms[] = 'publish any ' . check_plain($type->type) . ' content';
$perms[] = 'publish editable ' . check_plain($type->type) . ' content';
$perms[] = 'publish own ' . check_plain($type->type) . ' content';
$perms[] = 'unpublish any ' . check_plain($type->type) . ' content';
$perms[] = 'unpublish editable ' . check_plain($type->type) . ' content';
$perms[] = 'unpublish own ' . check_plain($type->type) . ' content';
}
}
return $perms;
}
/**
* Menu callback node/%/publish/% and node/%/unpublish/%
*
* @param $node a node object
*/
function publishcontent_toggle_status($node) {
// XOR the current status with 1 to get the opposite value.
$node->status = $node->status ^ 1;
// If this content type specifies that a new revision should be created on
// editing, then make sure to respect this option.
$node_options = variable_get('node_options_' . $node->type, array());
if (in_array('revision', $node_options)) {
$node->revision = 1;
}
node_save($node);
drupal_set_message(_publishcontent_get_message($node->nid, $node->title, $node->status));
drupal_goto('node/' . $node->nid);
}
/**
* Helper function to generate user feedback after status toggle.
*/
function _publishcontent_get_message($nid, $title, $status) {
$status = $status ? t('published') : t('unpublished');
return t('"@title" [@nid] has been !status', array(
'@title' => $title,
'@nid' => $nid,
'!status' => $status,
));
}
/**
* Implements of hook_form_alter().
*
* - Enable / Disable publishcontent for specific node types
* - Allow to use the 'Publishing options' on the edit/add page
*/
function publishcontent_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'node_type_form') {
$form['workflow']['publishcontent'] = array(
'#type' => 'checkbox',
'#title' => t('Enable publishcontent permissions for this node type.'),
'#default_value' => variable_get('publishcontent_' . $form['#node_type']->type, TRUE),
'#description' => t('Unchecking this option will disable publish and unpublish links for this node type.'),
);
}
elseif (user_access('administer nodes') || empty($form['type']['#value']) || empty($form['#node']) || $form['type']['#value'] . '_node_form' != $form_id || !_publishcontent_unpublish_access($form['#node']) && !_publishcontent_publish_access($form['#node'])) {
return;
}
$form['options']['status']['#access'] = TRUE;
if (!empty($form['options']['#access'])) {
return;
}
else {
$form['options']['#access'] = TRUE;
}
foreach (element_children($form['options']) as $key) {
// If another form has afforded access to a particular option, do not
// override that access. Otherwise, disable it.
$form['options'][$key]['#access'] = isset($form['options'][$key]['#access']) ? $form['options'][$key]['#access'] : FALSE;
}
}
/**
* Implements views_data_alter() to add items to the node table that are
* relevant to publishcontent.
*/
function publishcontent_views_data_alter(&$data) {
// new comments
$data['node']['publishcontent'] = array(
'title' => t('Publish link'),
'help' => t('Display a link to publish the node.'),
'field' => array(
'handler' => 'publishcontent_views_handler_field_node_link',
),
);
}
/**
* Implements hook_views_handlers().
*/
function publishcontent_views_handlers() {
return array(
'info' => array(
'path' => drupal_get_path('module', 'publishcontent'),
),
'handlers' => array(
// field handlers
'publishcontent_views_handler_field_node_link' => array(
'parent' => 'views_handler_field',
),
),
);
}
Functions
Name | Description |
---|---|
publishcontent_form_alter | Implements of hook_form_alter(). |
publishcontent_menu | Implements of hook_menu(). |
publishcontent_perm | Implements hook_perm(). |
publishcontent_security_token_to_arg | Used to append a security token to prevent XSS. |
publishcontent_tab_load | Decide to show the (un)publish tab or not. |
publishcontent_toggle_status | Menu callback node/%/publish/% and node/%/unpublish/% |
publishcontent_views_data_alter | Implements views_data_alter() to add items to the node table that are relevant to publishcontent. |
publishcontent_views_handlers | Implements hook_views_handlers(). |
_publishcontent_get_message | Helper function to generate user feedback after status toggle. |
_publishcontent_publish_access | Access callback for publish action. Only allow access based on permissions and current node status = unpublished |
_publishcontent_unpublish_access | Access callback for unpublish action. Only allow access based on permissions and current node status = published |
_publishcontent_view_access | DEPRECATED: This function will be going away. publish_content_menu_alter was using this function. Leaving in place to avoid fatal errors due to outdated menu cache. |