[SparksInteractive] This is a task covered by the tile allotted to me by my employer. Discussion and patches are welcomed.

User roles don't currently have the ability to unpublish content (as they don't have administer nodes) - we should try using http://drupal.org/project/override_node_options to give the publish checkbox back to selected roles, which should hopefully do the trick - just need to check on the effects for the workflow status if users can manually publish. Otherwise we might need another workflow state to unpublish.

I'm suspecting that the override_node_options will give the users too much ability to also publish nodes regardless of state. I'm currently thinking that the unpublish workflow state will be the way to go.

Comments

eugenmayer’s picture

We should discuss this more widely. The need of a draft mode is on thing, the need of "re-drafting" a node until its "polished" again is something else needs to be covered. We need a proper view on those things, covering at least the most needed cases.

gold’s picture

Agreed. Just a note though; I'm on a time budget so if we can push the discussion forward that would be appreciated.

The usecase we're seeing:
We have 3 states (none, review, live).
We have 2 main roles that can change state;
Editor : live -> none, none -> review, review -> none
Web Coordinator : All CM perms

Content can come from many contributors and arrives with state 'none'.
Editors can;

  • approve content for review
  • take content down

Web Coordinators can;

  • change all content from any state to any state

Neither web coordinators, nor editors have the Administer Roles perms so they don't have access to Publish checkbox. We could use something like override_node_options to give them access to it but that would introduce an extra step into the workflow that would effectively be outside the workflow. i.e. You have just taken the live revision to a non-live state in order to take it offline and then you have to edit the node to actually achieve what you just requested content moderation to do.

Current behavior: There's no way for this to be achieved via the content moderation workflow. Actually, testing it again now, there's no way to take something from live to any other state. It appears that this can only be achieved if there is another revision and then only by making that live.

Desired behavior: Those with live -> * should be able to change the state of the node. This state change can result in a number of options.

  • We handle the unpublishing in the module
  • We don't handle the unpublishing and leave it to the site builder to handle through rules or some other mechanism

Suggested approach: Currently I'm leaning towards handling it via rules. This has 2 benefits that I see.

  1. Easier for us to do and less for us to maintain
  2. Opens up the options to the site builder to do more than just unpublish the node (e.g. e-mail someone to inform them of the change, write logs, tweet about it, etc)

This would mean all we need to do is add the edit state link to the Live revision exposing the state change form to the user and allowing for live -> * transitions to be used.

Thoughts?

gold’s picture

Update;
From http://drupal.org/node/1152404#comment-4447966 Eugen has pointed out that the default, out of the box behavior of drupal is to block access to anyone but the owner of an unpublished node.'

With this in mind we need to approach this from a slightly different angle.

We need someway of preventing a Jane Average web user from viewing the node if there is no revision with a live state. This should probably be a separate issue but it's close enough to this one that I think it counts.

Easiest way of doing this would be throwing a 404 if no live revision is found.

Do people agree? +/- votes?

gold’s picture

Status: Active » Needs review
StatusFileSize
new708 bytes

Dealing with the small matter of pages still being visible when no live state is present was simple enough. Eugen, if you're okay with this I'll push it to your repo.

gold’s picture

Status: Needs review » Needs work

dman has just pointed out that this is a single case thing. We still need to handle views, taxonomy, search results etc.

He recommends working on this though is_published. I'll come up with a hook_access() based approach shortly. Ignore the patch above.

edit: ...and hook_access only works for nodes that the module creates. :/ Hmm... I'm starting to see why this has been an issue for so long.

gold’s picture

Status: Needs work » Needs review

Okay... This has been doing my head in all day. There's so much that hangs on this sort of stuff that no matter where I touch the code the result is a cascade of other updates to take other areas of the system into account that our budget just wouldn't allow for that path.

At this point I'm going to suggest that we go with the small patch above that returns a 404 on a non-live page if the viewer doesn't have the appropriate rights.

It's a bandage on a gaping wound but it'll do for the moment. If someone wants to revisit this and submit a patch (likely a very large patch) that does this properly I'd love you forever, give you my first born male child and offer free beer for a year.

Eugen, for the small task the patch does, can you please review and let me know if it's working the way I think.

gold’s picture

Eugen, I've pushed this to my repo. Grab it from there to test if you like.
https://github.com/Unifex/content_moderation

eugenmayer’s picture

Well a lot of work here :)

This whole thing isnt to easy to get a good concept out. We need it configureable, consistent and as few code as possible:
1. Make it configureable if [non-authors, non A("i can set from live-1 to live") can see a node with no live version
2. having 1 activated, deals with the "unpublish thing" if the user adds a live->X transition

1.
You can deal with 1. using the access-api easily, but be sure to sue the node_access api to deal with all of them, not only the page-callback ( views, search .. ).
One big issue is A, as this is not trivial to determine yet ( due to loops as it is a directed graph ) ... can have more then one transition for X->live, even none->live (and we need to find those the user has access too in this content type.
Cant see how rules will help you dealing with the access issue, actually this will end up having the same code, hooking up somewhere else

2. Should be build in already

gold’s picture

Status: Needs review » Active

Having looked over yesterdays efforts I'm discarding that approach. The plaster on the gaping wound is not the way to go.

I've just had a rather long talk with Jan (the boss guy) about how to tackle this and he's pushing for using the $node->status and actually publishing/unpublishing the node. He raises a good argument for it too. No code required.

The theory I'm about to test:

Using http://drupal.org/project/override_node_options we can expose the publish checkbox for some users and regardless of workflow there will be some users that may have access to this. So, the idea is a two tined attack on the issue using rules.

The first case: Using content_moderation a user changes workflow state from live to anything else. Result: Rules unpublish the node.

This will involve #1154656: Change state from live to * being resolved. This could be ignored in favor of using the second case as the preferred method of doing this.

The second case: Using the publish checkbox a user unpublishes the node. Result: Rules updates the workflow state to none.

The advantage here is that there is no code and the issue of non-live pages being visible is dealt with. To this end the only modification to code would be for the suggestion that the default state be published.

More notes soon.

gold’s picture

StatusFileSize
new1.91 KB
new413 bytes

I've implemented the second case here.

Eugen, this is accomplished with a couple (well one, but I've added the opposite case also) of extra actions to set the state to none. I'll also write up documentation on how to implement it thought the already existing rules system.

mv content_moderation.actions.{txt,inc}
gold’s picture

Status: Active » Needs review

Actually, I'm going to push this to my repo. Eugen, have you got my repo setup anywhere you can test it from? Being able to update quickly and test may help out quite a bit.

This is going to be something of an attempt to document a method of using content_moderation also. It'll be a work in progress while we're still working on getting things deployed also.

instructions for implimenting this solution:

  1. From a clean install content_moderation from https://github.com/Unifex/content_moderation
  2. Install http://drupal.org/project/override_node_options
  3. Install http://drupal.org/project/rules
  4. Enable content_moderation, override_node_options and rules
  5. Hit admin/settings/content_moderation/general and ensure Force publishing on new nodes is unticked.
  6. For this test create 2 roles. One as an author and one as an editor.
  • author should be able to go from none to anything apart from live
  • editor should be able to for from anything to anything
  • Create 2 users and apply one of these roles to each.
  • Hit admin/user/permissions and set the appropriate permissions. For these instructions I'm going to assume you've applied moderation to the page content type.
    • Things to note: you'll want to touch permissions in content_moderation and override_node_options (will probably want to flesh this out a bit but give it a go and see what makes sense.)
  • Hit Administer » Rules » Import / Export » Import (admin/rules/ie/import) and import the following trigger;
    array (
      'rules' => 
      array (
        'rules_moderate_none_on_unpublish' => 
        array (
          '#type' => 'rule',
          '#set' => 'event_node_update',
          '#label' => 'Moderate(none) on unpublish',
          '#active' => 1,
          '#weight' => '0',
          '#categories' => 
          array (
            0 => 'moderation',
          ),
          '#status' => 'custom',
          '#conditions' => 
          array (
            0 => 
            array (
              '#info' => 
              array (
                'label' => 'Content has been unpublished',
                'label callback' => false,
                'arguments' => 
                array (
                  'boolean' => 
                  array (
                    'type' => 'boolean',
                    'label' => 'Truth value',
                  ),
                ),
                'module' => 'Rules',
              ),
              '#name' => 'rules_condition_check_boolean',
              '#settings' => 
              array (
                'boolean' => '<?php if ($node->status != 1 && $node_unchanged->status == 1) {echo 1;} else {echo 0;}  ?>',
                '#eval input' => 
                array (
                  'rules_input_evaluator_php' => 
                  array (
                    'boolean' => 
                    array (
                      0 => 'node',
                      1 => 'node_unchanged',
                    ),
                  ),
                ),
              ),
              '#type' => 'condition',
              '#weight' => 0,
            ),
          ),
          '#actions' => 
          array (
            0 => 
            array (
              '#weight' => 0,
              '#info' => 
              array (
                'module' => 'Node',
                'arguments' => 
                array (
                  'node' => 
                  array (
                    'label' => 'Content',
                    'type' => 'node',
                  ),
                ),
                'label' => 'Set Content Moderation to none',
                'base' => 'rules_core_action_execute',
                'action_name' => 'content_moderation_unpublish_action',
                'configurable' => false,
              ),
              '#name' => 'rules_core_content_moderation_unpublish_action',
              '#settings' => 
              array (
                'auto_save' => 1,
                '#argument map' => 
                array (
                  'node' => 'node',
                ),
              ),
              '#type' => 'action',
            ),
          ),
          '#version' => 6003,
        ),
      ),
    )
    

    I'm not sure if this auto enables or not but ensure that it's setup. In Rules > Triggered Rules you should stt Moderate(none) on unpublish under the Active Rules section.

  • Log in as the author user and create a page.
  • Log in as the editor user and moderate it to live
  • Check as other users that you can see it.
  • Log in as the editor user and edit the node. Untick the publish checkbox and submit.
  • Check as other users (anonymous is a good one) that you can't see it.
  • At the end of this the node should be unpublished and the moderation state should be none. It still has some polishing off to do. The last live revision still appears in the Live box for example. Not sure of how/why yet.