When you visit the /admin/content page use the bulk operation feature to either publish or unpublish nodes that are under WBM, they do not do anything.

I think the best solution would be to replace the status column with the WBM state instead of just "publish/unpublish". Ideally we would add the state changes to the operation dropdown so you could use that. If this is not possible (because some nodes may have different states available than others, then we should remove the option to publish/unpublish from that dropdown as it appears to "work" but takes no affect on the actual node.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Bcwald created an issue. See original summary.

Crell’s picture

Replacing that view outright would depend on #2674520: Add current revision filter to views first. That's why we need that issue. :-)

Simply removing the publish/unpublish commands seems like the best way to handle that. Those commands are no longer useful in any context when an entity is moderated.

Patch welcome. :-)

Bcwald’s picture

Yeah, I think best is 2 step.

Remove OOTB publish/unpublish. Then once that patch hits, replace the status column with revision filter status, and update the operation dropdown to add those items.

That said, one confusing issue we will run into with adding the dropdown states from WBM is that each node type could potentially have its own states, so if you are viewing ALL content you will have an issue.

The only way I can imagine dealing with this is to only populate the dropdown with state actions IF you have filtered by content type first.

I can look into creating a patch for removing publish/unpublish as part of the first step.

Crell’s picture

Title: bulk operation publish/unpublished on /admin/content have no affect on WBM nodes » Remove published/unpublished operations when WBM is enabled, as they no longer apply

Retitling. If you can get a patch posted today it may get into beta2. If not, it can go into the next release (which I hope is an RC, but that depends on the Views integration).

Crell’s picture

Something like this. (HT to EclipseGc for the Plugin help.) I'm not quite sure of the best way to test this, though.

Dave Reid’s picture

Shouldn't these plugins be overriding the access() method to deny the action instead of overridding the execute() method?

Crell’s picture

Talked this through with Dave in IRC. Probably we should be checking in both methods, to be sure; however, using the access method also means that the error message you get becomes much more generic and thus less useful on the admin/content page, or anywhere that's using the Views BulkForm plugin. However, it means it will behave properly if someone calls access() on the plugin from anywhere else. So... I'm torn on the approach to take. Feedback welcome.

Bcwald’s picture

Issue summary: View changes
FileSize
48.51 KB

@Crell -- I tested out this patch.

2 things:

1) Based on your last comment, I agree with the method, but is there no way to override the error message?
I agree that this message:

No access to execute Unpublish content on the Content Test Article.

is not very meaningful to someone who doesnt understand the problem.

2) I still get a success message:

Unpublish content was applied to 1 item.

even though it didnt do that action.

Bcwald’s picture

Issue summary: View changes
Bcwald’s picture

In your code, you use: drupal_set_message($this->t('One or more entities were skipped as they are under moderation and may not be directly published or unpublished.')); which is a pretty good message.

Is that legacy code now that you are using access()?

Ideally, I think the message should be "(list the actual entities) were skipped ..." and still have the success message, that would say "(list of actual entities) were update..." I know this could potentially be a long list but if I am selecting actual items, I need to know what worked and what didn't.

One option to reduce clutter would be to say "Content Type: X entities were skipped because they are under moderation".

Dave Reid’s picture

@Bcwald: Unfortunately the messages you see are set by core, now that access() is used. I would argue that the error messages could be improved (displaying actual number of updated instead of blindly saying all were updated, even though access() returned FALSE).

Bcwald’s picture

I still think this issue of having mixed items that are available to publish/unpublish is confusing (even with good messaging). This solution operates well for the use-case of someone trying to access the plugin, but since /admin/content ships with core, we should be more assertive to making it usable.

One idea I have that is probably a lot of work with AJAX...

1) remove the "publish/unpublish" links from the bulk operation entirely on admin/content.
2) Add a toggle to filter moderated vs non-moderated nodes next to the bulk operation.
3) If the filter is applied to show non-moderated nodes, allow the publish/unpublish to work.
4) (once revisions are available in views) if the filter is applied to show moderated nodes, allow workbench states to populate the bulk operations.

Crell’s picture

Yeah, the messaging is pretty bad. Unfortunately, there's extremely little I can do from the plugin to fix it. Let me try and lay it out:

The plugin type has two methods: access() and execute(). The way you are *supposed* to use the actions is something to the effect of:

if ($action->access($entity)) {
  $action->execute($entity);
}

Which is, on the surface, a pretty common pattern in core now. However, actions are frequently going to be applied to multiple entities at once (as in the Views BulkForm case). What BulkForm does is essentially this (simplified from the actual code to emphasize the problem):

foreach ($entities as $entity) {
  if (!$action->access($entity)) {
    drupal_set_message("No access to {$entity->label}"));
    continue;
  }
  $real_entities[] = $entity;
  $count++;
}

foreach ($real_entities as $entity) {
  $action->execute($entity);
}

$count = count($entities);
drupal_set_message("Did stuff to {$count} entities.");

First off, there's a bug here in BulkForm because it keeps track of the number of entities for which access() passed, but then does nothing with it and uses the original entity count for the message. That's just flat out wrong and should be fixed in core.

Secondly, it means that if we use access(), there is *no way at all* to suppress the "No access to $entity" message. So implementing access() means that message appears. If we don't want that message to appear, we have to not use access().

But! Not using access() means that someone other than BulkForm that tries to use the action will end up trying to execute the action even when they shouldn't, thus execute() needs to have the opt-out logic. That's what I did originally. If we don't, then the entity will get saved, its moderation state field (which was unmodified) will result in the published property being overwritten with whatever WBM says it should be (which is then presumably the same as the previous state), and a new revision with no change gets resaved, seemingly "nothing happened".

Additionally, execute() is a single-item method. That means I have no way of counting the total number of times it was called, and thus no way to report "skipped X items". The only options are a static string (as the patch has now), for which drupal_set_message() helpfully removes duplicates (which is kind of cool), or a "skipped $entity->label()" message, which leads to one message per entity skipped.

Removing the publish/unpublish commands from the /admin/content form requires a hook_views_alter(), which is highly fragile magic. I really don't want to go there.

It would be quite easy to just kill the Publish/Unpublish actions entirely via an alter hook, but I don't know how well that view would handle its configured actions suddenly missing (would views handle that gracefully or explode in a fireball?), and it would also make those actions unavailable to any module anywhere, ever, which seems excessively draconian. Causing fatal errors for other modules is not a route I am comfortable taking.

So in the end, the options we have are:

1) Use the API "properly", get an unhelpful generic message from BulkForm, one per item skipped.

2) Filter in execute() instead, get a single static message.

3) Filter in execute() instead, get one message per item skipped.

4) Both 1 and 2.

5) Both 1 and 3.

None of those are good options, but those are the only options I see available without monkeypatching the BulkForm plugin, too, and I am not going there. :-)

Bcwald’s picture

Understood, thanks for the explanation. Given the restrictions id probably opt for 1 and 2.

In addition, removing those entirely (ideally providing a checkbox in WBM config settings) may not be entirely that bad, as they do expose the option to do that directly in Views UI. (See screenshot of that view)

Crell’s picture

Issue summary: View changes

Correct, the view could be modified to disable those actions, and honestly I'd recommend everyone using WBM do so. However, doing so programmatically from WBM is considerably trickier and opens up a whole host of questions (what if someone customized the view already, what if they replaced it, what if they don't want those options to go away, etc.) that I really would rather avoid, especially when I'm hoping for a 1.0 this week. :-)

Anyone else want to argue for option 5, instead of option 4?

Crell’s picture

One note: Options 4 and 5 mean that the message from execute will NOT get shown on the bulk page! That message will show ONLY in the case that someone other than BulkForm tries to call execute() without properly checking access() first.

Crell’s picture

Posted a patch to fix BulkForm's counting issues: #2705823: BulkForm reports incorrect count

Bcwald’s picture

In regards to the view, if we do not programmatically change it, I think we should add a section to the README file as a recommended install step.

Something like this:

** (OPTIONAL) Install steps **

Due to the nature of moderation on nodes, the core "publish content/unpublish content" view bulk operations, as found in the 'content' view ( /admin/content) will not operate as expected on moderated nodes. To avoid confusion, removing the actions is recommended.

1) Visit */admin/structure/views/view/content .
2) Configure: 'Content: Node operations bulk form' > change the Available actions to 'Only selected actions' > select all actions EXCEPT 'publish content' and 'unpublish content'.
3) Save view.

Crell’s picture

Oh yeah, I had a README file lying around in another branch that I'd started on but never finished. :-) Patch attached adds a README file, including the recommendation from #18. (No interdiff because nothing changes except that readme.)

I'm going to make an executive decision: You really ought to just disable those actions for that view entirely. The README now documents that you should do that. Therefore, follow the API "properly" (option 1) but also include the fail-safe in case someone doesn't call access() before calling execute() (option 2).

If the bot approves of this patch I will go ahead and merge it.

  • Crell committed 0f7a071 on 8.x-1.x
    Issue #2696829 by Crell, Bcwald: Remove published/unpublished operations...
Crell’s picture

Status: Needs review » Fixed

Merged. I also gave Bcwald some credit love for the readme text. :-) Thanks all!

balsama’s picture

Nice. It makes sense to do this by default in the Lightning distro: #2705931: Remove publish/unpublish actions from /admin/content view

Bcwald’s picture

Sounds good, thanks Crell. Should we open a different issue about adding the moderation state to that view?

Crell’s picture

That would be a separate README entry. That would again be a "don't want to go there" views alter to do automatically.

Status: Fixed » Closed (fixed)

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