2

On my site we have enquiries (nodes) and price offers (comments). So if there's at least one price offered (a comment submitted) the enquiry details (node) shouldn't be changed. Is there any way to do that?

1
  • Please don't fundamentally change questions that have already been answered. Thanks!
    – Clive
    Jun 21, 2016 at 9:56

3 Answers 3

3

If coding this is an option, you should look at hook_node_prepare. As mentioned there on the first line:

Act on a node object about to be shown on the add/edit form.

A code snippet idea that could do this for you:

function SOME_MODULE_node_prepare($node) {
  if (isset($node->nid) && $node->type == 'YOUR_CONTENT_TYPE' && $node->comment_count> 0) {
    drupal_set_message('You cannot alter this node anymore', 'warning');
    drupal_goto('node/' . $node->nid);
  }
}

Good luck!

5
  • Could you post your current code please? Jun 8, 2016 at 10:46
  • @ Stefanos Petrakis It restricted access to editing all nodes - commented and also uncommented. Pls revert Jun 8, 2016 at 10:47
  • @ Stefanos Petrakis i took yr code snippet and added my module name and my content type. Didn't add anything else. Jun 8, 2016 at 10:48
  • U r right, updated the condition in my code Jun 8, 2016 at 10:52
  • yes,that works fine now Jun 8, 2016 at 12:39
1

If you don't want to write custom code, you can use the Rules and Flag module for this, as described below.

Step 1: flag nodes with comments

Use the Flag module to create a (global) flag with a label of something like "Has price offers".

Step 2: register comment submission

Use Rules to create a custom rule with Rules Event "After saving a new comment.".

This rule should perform a Rules Action "Flag node" (using the flag created in step 1).

Step 3: disallow edits for nodes that have price offers

Use Rules to create a custom rule to disallowing 'edit' for nodes that have price offers (= were flagged). This rule is a variation of the rule I included (in export format) in my answer to the question about How to restrict access to a node via node/12 and allow access via a path like content/sometitle?

These are the changes to that rule to make it work this case also:

  • The paths containing node should be extended by adding /edit at the end (I'm assuming that's how the URL for your edit link looks like).
  • Add a Rules Condition to check if the node was flagged (with the flag from step 1).
  • Change the "Message" in the Rules Action to something to indicate that the edit is not allowed because it already has price offers.
  • Modify the Rules Action to fit your own requirements, e.g. to issue a redirect to some 'help page' with more details about this.

If you've problems adding the appropriate Rules Conditions (to find the relevant data selector), it might be because of what's mentioned in the Rules UI when you're adding a "data comparison" condition: somewhere it says "The data selector helps you drill down into the data available to Rules. To make entity fields appear in the data selector, you may have to use the condition 'entity has field' (or 'content is of type')".

Remark: this will block edits from anybody. Should you only want to block that for the node author, then (in step 3) add an extra Rules Condition to verify if the currently logged on user matches the node author. Variation of this could be that you want to allow such edits anyhow for some selected roles (by adding an appropriate Rules Condition to verify the role of the current user).

5
  • @TimurKutuev Thanks for the update of your question (and notifying me). Your 1st rule seems ok, but the Rules event you're using in your 2nd rule MUST (repeat: must) be "Drupal is initializing", otherwise you're "too late" to have rules intercept the start of an edit session. And I'm about sure you must also add a Rules action BEFORE the redirect action you already have to set a Drupal message of type "error". Check the rule I included in my linked answer for an illustration of both. Please let me know if this helps, ok? Jun 2, 2016 at 18:55
  • Editing rule 2 i made the following: added "ON" : { "init" : [] }, as you advised. Then i tried adding condition "node is flagged" that allowed me to check my global flag "has_price_offers" from the list. But there is also data selector that didn't offer me any relevant path to my flag, and i'm not sure what to put in this data selector. Scratching my head on this now. Jun 4, 2016 at 10:26
  • @TimurKutuev : check the paragraph I added (before the "remark"-paragraph). Jun 4, 2016 at 10:42
  • You advised to Add a Rules Condition to check if the node was flagged (with the flag from step 1). That's exactly what i'm doing. After choosing condition " node is flagged" and my flag i have to choose something else in data selector "Data types: Select data of the type Node". These are the tokens that are available: "site:current-user:roles: " (no further path is offered) and "site:current-page: " (also no further path is offered). Neither of them is satisfactory and i get message "Data selector node: "whatever" for parameter Node is invalid." Jun 4, 2016 at 12:02
  • @TimurKutuev : Rules can be tricky sometimes, and really tough to debug without seeing your (updated) rule. Regarding the extra Rules condition I suggested via my latest answer update (see my prior comment): if you did add some condition like that, can you confirm you added that as the FIRST condition (important!). Also, can you also add your updated (2nd) rule to your question (even though it doesn't work yet). That might help to pinpoint your remaining issue (I think you're close). Jun 4, 2016 at 12:45
0

I'd propose to not even show the edit link anymore if the user is not allowed to edit it. It is bad user experience to have a user click a button and then tell him he is not supposed to be there.

Drupal has an excellent content control system which you can use. It does involve some coding (< 20 lines), but I guess the result will be better than the other answers here.

You will have to create a custom module (a small one). Read that tutorial for information on creating a mymodule.info file.

Also create a mymodule.module file and implement hook_node_access:

function mymodule_node_access($node, $op, $account) {
  // If this user is the node author and he wants to edit a node?
  if ($account->uid == $node->uid && $op == 'update') {
    // Get comment count
    $comment_count = db_query('SELECT COUNT(cid) AS count FROM {comment} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
    // If there is 1 comment or more
    if ($comment_count > 0) {
      // Deny the user access (and hide the edit link).
      return NODE_ACCESS_DENY;
    }
  }
  return NODE_ACCESS_IGNORE;
}

That is all you need to put in this file. It allows admins and other privileged user to still edit the node (remove the $account->uid == $node->uid && part if you want to block those as well).

So you need only two files and a folder and this is in my opinion more user friendly than giving the user the impression he can edit something and then tell him he cannot.

An optional addition can be to show a message that the user can no longer edit the node during the viewing. Add this to the module file:

function mymodule_node_view($node, $view_mode, $langcode) {
  // Fetch the current user.
  global $user;

  // Compare
  if ($user->uid == $node->uid) {
    // Get comment count
    $comment_count = db_query('SELECT COUNT(cid) AS count FROM {comment} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
    // If there is 1 comment or more
    if ($comment_count > 0) {
      // Show the message
      drupal_set_message(t('This enquiry has received at least one price offer an can no longer be edited.'), 'warning');
    }
  }
}
10
  • Couldn't make it work. I created a module and info file, put it in new folder at sites/all/modules and enabled. Got "Fatal error: Call to undefined function db_result() in /var/www/u0177528/data/www/betonmap.ru/sites/all/modules/restrict_edits/restrict_edits.module on line 7" I'm using Panels so i tried also adding dependencies panels:panels but that also didn't work. Jun 5, 2016 at 16:08
  • Answer has been updated. I accidentally posted some Drupal 6 code. Jun 5, 2016 at 18:47
  • Tried yr updated code - error gone but still no luck - editing is open for commented node author Jun 8, 2016 at 10:45
  • I always forget node_access does not use TRUE and FALSE... does it work if you return NODE_ACCESS_DENY in the first snippet? Jun 8, 2016 at 11:01
  • Neograph734 Tried first snippet with NODE_ACCESS_DENY and NODE_ACCESS_DENY. It did nothing. I also changed {comments} to {comment} in db_query. Still no success. I'm not getting any error messages now but still have editing allowed to commented node author. Jun 8, 2016 at 11:48

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.