I've written some code in hook_nodeapi designed to unpublish a node if "save as draft" is checked, and publish it if "save as draft" is unchecked. This works the first time a node is inserted and updated. However, if you wish to again save the same node as a draft, it will not unpublish.

    case 'submit':
	  if (module_exists('save_as_draft')) {
            // Unpublish if save as draft is checked.
	    if ($node->save_as_draft == 1) {
	      $node->status = 0;
		}
	    // If save_as_draft is clicked off and the publish status is 0
        	// and this user does not have the 'administer nodes' permission,
		// then change publish status to 1
	    if ($node->save_as_draft == 0 && $node->status == 0 && (!user_access('administer nodes'))) {

	      $node->status = 1;
		}
	  }
      break;

I *think* my code isn't working because of this code in save_as_node_nodeapi:

      case 'submit':
        $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));
        $node->original_node = node_load($node->nid, $current_vid);
        break;
      case 'update':
        if (isset($node->original_node)) {
          // Update node table's vid to the original value.
          db_query("UPDATE {node} SET vid = %d, title = '%s', status = %d, moderate = %d WHERE nid = %d", $node->original_node->vid, $node->original_node->title, $node->original_node->status, $node->original_node->moderate, $node->nid);
          drupal_set_message(t('Your changes have been saved as a draft.'));
        }
        break;

The original node status (Published) is written, or something, but the node status isn't changed.

Question: Does anyone know if there's something I can do so that I can unpublish the nodes when "save_as_draft" is checked on in an update?

Or, is there a better way to allow a user who can't have the "administer nodes" permission to publish/unpublish his own nodes?

Thanks!

Comments

somebodysysop’s picture

OK, came up with my own solution:

/**
 * Implementation of hook_nodeapi().
 */
function lesspaper_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'submit':
	  if (module_exists('save_as_draft')) {
            // If save_as_draft is clicked on, then click off published
	    if ($node->save_as_draft == 1) {
	      $node->status = 0;
		}
	    // If save_as_draft is clicked off and the publish status is 0
		// and this user does not have the 'administer nodes' permission,
		// then change publish status to 1
	    if ($node->save_as_draft == 0 && $node->status == 0 && (!user_access('administer nodes'))) {

	      $node->status = 1;
		}
	  }
      break;

    case 'update':
      if (isset($node->original_node)) {
	    drupal_set_message('The original_node is set');
        // Update node table's vid to the original value.
		// But, do not update the $node->status to original value.  Use the new status instead.
        db_query("UPDATE {node} SET vid = %d, title = '%s', status = %d, moderate = %d WHERE nid = %d", $node->original_node->vid, $node->original_node->title, $node->status, $node->original_node->moderate, $node->nid);
        }
      break;
  }
}

I basically write the current status instead of the previous status. Not sure how this affects anything else, but it solves the problem I had. Would appreciate any comments on this approach.

ymmatt’s picture

Seems interesting, but without beating around the bush: What situation arose where this was necessary?

somebodysysop’s picture

I wanted users to be able to save "drafts" of their nodes without having to give them the "administer nodes" permission. By "draft", I mean submit an "unpublished" node that will not appear on any lists anywhere.

Do do this now requires the "administer nodes" permission, which gives you the "Publishing options" fieldset in the node submission form, in which you either check or uncheck the "Publish" option.

The save_as_drafts.module seemed to me like an end-around to the problem. Except, "saving as draft" as it is defined in this module, is NOT saving it as "unpublished". So, I wrote some code in my modules hook_nodeapi to handle that.

I finally solved the problem with this change:

    case 'update':
      if (isset($node->original_node)) {
        // Update node table's vid to the original value.
		// But, do not update the $node->status to original value.  Use the new status instead.
        db_query("UPDATE {node} SET vid = %d, title = '%s', status = %d, moderate = %d WHERE nid = %d", $node->original_node->vid, $node->original_node->title, $node->status, $node->original_node->moderate, $node->nid);
        }
      break;

Now, when I click on "save as draft", the node is saved as unpublished. When I unclick "save as draft", it is published -- unless the user has the "administer nodes" permission.

Anyway, it's exactly what I needed. And I accomplished it without having to touch the save_as_draft.module itself.

swortis’s picture

I think think this is a fabulous idea - really necessary for many production environments. However, I'm not seeing a "save as draft" button anywhere. Where should I be looking?

ymmatt’s picture

Status: Active » Fixed

Sounds like a decent work-around. However, your code would fit well in its own module independent of save as draft.

Swortis - Your comment belongs in another support request/issue, once this is posted I'll answer your question there. I'm trying to keep the issue cue relevant and clean.

Marking this as fixed

somebodysysop’s picture

Yes, just for the record, my recommended solution is to use or create separate module, and within hook_nodeapi of that module:

/**
* Implementation of hook_nodeapi().
*/
function lesspaper_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'submit':
      if (module_exists('save_as_draft')) {
            // If save_as_draft is clicked on, then click off published
        if ($node->save_as_draft == 1) {
          $node->status = 0;
        }
        // If save_as_draft is clicked off and the publish status is 0
        // and this user does not have the 'administer nodes' permission,
        // then change publish status to 1
        if ($node->save_as_draft == 0 && $node->status == 0 && (!user_access('administer nodes'))) {

          $node->status = 1;
        }
      }
      break;

    case 'update':
      if (isset($node->original_node)) {
        drupal_set_message('The original_node is set');
        // Update node table's vid to the original value.
        // But, do not update the $node->status to original value.  Use the new status instead.
        db_query("UPDATE {node} SET vid = %d, title = '%s', status = %d, moderate = %d WHERE nid = %d", $node->original_node->vid, $node->original_node->title, $node->status, $node->original_node->moderate, $node->nid);
        }
      break;
  }
}

So far, this is working great. No need to modify save_as_grant.module itself for this. But, obviously, save_as_grant.module is required for it to work.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.