7

Scenario:

A user can create a node (content type "story"). All story nodes that are created are unpublished by default.

I have a boolean field called "publish my story". Once this has been checked and saved the node is published using rules.

Question:

Is it possible to revoke a users ability to edit published nodes by using rules as I do not want them to change the story afterwards.

2 Answers 2

8

Yes, you can define dynamic rules in a custom module. See hook_node_access

Here's a sample implementation:

/**
 * Implements hook_node_access().
 */
function MYMODULE_node_access($node, $op, $account) {
  if (
    // The $node argument can be either a $node object or a machine name of
    // node's content type. It is called multiple times during a page load
    // so it is enough if you perform the check once you get the object.
    is_object($node) && $node->type == 'story' &&
    // Operation on which you want to act: "create", "delete", "update", "view".
    $op == 'update'
  ) {
    // Check if the node is published.
    if ($node->field_published[LANGUAGE_NONE][0]['value'] == 1) {
      return NODE_ACCESS_DENY;
    }
  }
}
3
  • I was hoping to do it using rules, but this works great thanks!
    – Q10
    Oct 22, 2012 at 15:46
  • 3
    > if ($node->field_published[LANGUAGE_NONE][0]['value'] == 1) { could be better using field_get_item like > field_get_items('node', $node, 'field_published') to prevent language bugs Jun 17, 2015 at 9:43
  • @ClemensTolboom has a great idea. Just to make it clearer if ($node->field_published[LANGUAGE_NONE][0]['value'] == 1) could become if ($node->field_published->value == 1).
    – serverjohn
    Jul 7 at 13:01
1

Here are a complete module to perform the task, plus assigning a role to do that behavior with it:

saidbakr_tools.info:

name = SaidBakr Tools
description = Tools offered by Said Bakr [email protected]
core = 7.x 

configure = admin/config/administration/saidbakr_tools

saidbakr_tools.module:

<?php
/**
 * Implements hook_node_access().
 */
function saidbakr_tools_node_access($node, $op, $account) {
   global $user;
  if (
    // The $node argument can be either a $node object or a machine name of
    // node's content type. It is called multiple times during a page load
    // so it is enough if you perform the check once you get the object.
    is_object($node) && $node->type == 'article' &&
    // Operation on which you want to act: "create", "delete", "update", "view".
    $op == 'update'
  ) {
    // Check if the node is published.
  //  var_dump($node);
    if ($node->status == 1 && in_array(variable_get('saidbakr_tools_role','author'), $user->roles)) {
      return NODE_ACCESS_DENY;
    }
  }
}

/**
 * Implements hook_menu().
 */
function saidbakr_tools_menu() {
  $items = array();

  $items['admin/config/administration/saidbakr_tools'] = array(
    'title' => 'SaidBakr Tools',
    'description' => 'Settings for SaidBakr Tools!',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('saidbakr_tools_form'),
    'access arguments' => array('access administration pages'),
    'type' => MENU_NORMAL_ITEM,
  );

  return $items;
}

/**
 * Page callback: Current posts settings
 *
 * @see saidbakr_tools_menu()
 */
function saidbakr_tools_form($form, &$form_state) {
  $form['saidbakr_tools_role'] = array(
    '#type' => 'textfield',
    '#title' => t('The role name'),
    '#default_value' => variable_get('saidbakr_tools_role', 'author'),
    '#size' => 20,
    '#maxlength' => 24,
    '#description' => t('Enter the role name that its users should not be able to edit published contents.'),
    '#required' => TRUE,
  );

  return system_settings_form($form);
}

Create the above two files in a folder, name it saidbakr_tools and then upload it to your Drupal installation at sites/all/modules.

In this solution to test node publish status, I used $node->status

1
  • 1
    This is a nice clean solution that worked well for me, even in tandem with the 'Save Draft' module. Dec 6, 2018 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.