Closed (fixed)
Project:
Scheduler
Version:
7.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
25 Apr 2013 at 09:31 UTC
Updated:
25 Dec 2013 at 08:20 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
pfrenssenHere is a reworked version that has been split off from the patch in #1966876: Allow other modules to alter the list of nodes to be published or unpublished. I incorporated the remarks from jonathan1055 in comment #17 of that issue, and renamed the function to
scheduler_is_allowed()and the hook tohook_scheduler_allow()to avoid confusion between "allowing" and "scheduling".Comment #2
pfrenssenHere is an example implementation of this hook. Only allow a node to be scheduled if it has been approved by a moderator.
This is from #1955938: Publish only "approved" nodes
Comment #3
pfrenssenFixed a bug in the patch:
Comment #4
jonathan1055 commentedHi,
I think you need to be clear exactly what the intention of this patch is. Originally in #14 of #1966876: Allow other modules to alter the list of nodes to be published or unpublished you just wanted to prevent the message 'This post is unpublished and will be published on date' because on sites which implement hook_scheduler_nid_list_alter() the content may be prevented from being published via scheduler. That was a good idea. But the changes you made in the patch in #16 on that issue actually prevent a node from being scheduled in the first place.
However, in the patch in #3 above, in scheduler_node_presave() the new function scheduler_is_allowed() is used to suppress the message but it does not alter whether the node can be scheduled or not.
Can you tell what the intended functionality is, then we can discuss how to achieve it.
Jonathan
Comment #5
rickmanelius commentedI'm a bit apprehensive about committing this patch. I feel like this use case would better be served by a combination of workbench moderation + revision scheduler (http://drupal.org/project/revision_scheduler). This way you can use the workbench logic to get the node to a stage where it's ready to publish, and THEN you can schedule that revision to be published.
Comment #6
pfrenssenWhat I want to achieve is that modules can prevent nodes from being published or unpublished. I first tried the approach in #1966876: Allow other modules to alter the list of nodes to be published or unpublished, by naively altering the list of nodes that are processed in
_scheduler_publish()and_scheduler_unpublish(). However this was not sufficient, sincescheduler_node_presave()also needs to know whether it should act on the node or not.The approach in #1966876: Allow other modules to alter the list of nodes to be published or unpublished only half meets the goal. It works well for reordering the node list, but since
scheduler_node_presave()still blindly acts on the node unexpected things may happen.At the moment the only unexpected thing is that an error message appears, but functionality might be added in the future that also needs to check if publishing of a particular node is allowed. One example is #1819074: Allow publish_on dates in the past. This patch allows nodes that have a scheduling date in the past to be published immediately. To make that work in combination with this issue it would need another call to
scheduler_is_allowed($node, 'publish').Comment #8
pfrenssen@jonathan1055, this patch does work in preventing the publishing and unpublishing, it is handled by these lines:
I have tests covering this in #1955938: Publish only "approved" nodes and in the distribution I'm working on: scheduling.test.
If you want I can add tests for this to Scheduler as well, it would require a small test module to be added that implements the hook.
Comment #9
medieval111 commentedThis works perfectly for me, in combination with #1955938: Publish only "approved" nodes .
Now "role1" can create a node and set the publish date. Role2 can approve the node, so the publish date will be honored. Otherwise it won't.
Can this please be committed?
Comment #10
pfrenssenThis needs tests in the Scheduler module itself before it can be committed.
Comment #11
pfrenssenStarted working on tests. Here is my work in progress. I created a test module that provides a node type with a field that needs to be checked by the CEO before a scheduled node may be published.
Comment #12
pfrenssenWorked some more on the test.
Comment #12.0
pfrenssenSpelling
Comment #13
jonathan1055 commentedHi Pieter,
I still do not fully understand the purpose of these changes - see my comment in #4. Specifically my concerns are:
So overall, the functionality in this patch can all be achieved by implementing existing hooks and form #validate functions. Atleast, that is how it appears to me. I'm happy to have a discussion about it, but as it stands I cannot pass this patch for committing.
Jonathan
Comment #14
pfrenssenThe intention is not to suppress the error message, but to prevent nodes from being published immediately. The confusion is probably because the patch was written before this functionality was added (in issue #1819074: Allow publish_on dates in the past), but it was already being worked on at the time. See my motivation in comment #6. In the meanwhile #1819074: Allow publish_on dates in the past got in but the patch still needs to be updated so it actually prevents the publication of the nodes.
I'm starting to think that the current approach taken in this issue might not be enough. We really need a hook firing during scheduler_node_presave() so we can have control over nodes that are being published and unpublished at this point in the cycle, but we might need to add an additional parameter indicating which part of the code is firing the hook, so we can differentiate between "regular" publication on cron, and "immediate" publication on node presave.
One potential use case is #1182450: i18n support - Synchronize scheduled dates in translated nodes. In this issue problems arise because the i18n_sync module is resaving nodes, firing hook_node_presave(), causing nodes to be published prematurely. The hook_scheduler_allow() that is being added in this issue should be able to solve this, but then we should be able to distinguish between this hook firing on cron or on presave. It should only prevent publishing on presave, not on cron.
Comment #15
pfrenssenHere's an updated patch, this should make it clearer. It now actively prevents the publication of nodes in scheduler_node_presave().
BTW I'm open for suggestions on how to solve this differently.
@Jonathan, I forgot to answer on your suggestion to use form validate handlers to prevent publication. This doesn't work because this will prevent the form from being submitted, which is undesirable if you have one user role that is responsible for scheduling, and another for publication approval. Also the form validate will only fire if the node form itself is used to create the nodes. This is not always the case, some sites use custom modules for creating nodes (eg admin dashboards, data importers, ...).
Setting this to "Needs review" to see if it does not break anything. This still needs work.
Comment #16
jonathan1055 commentedOK, I see your point that using an extra validate handler may not cover all cases, so a specific hook in scheduler_node_presave is required.
I've followed through your logic changes in presave, and if scheduler_is_allowed() returns false, that will prevent the immediate publishing if that option was on. But then the node gets scheduled anyway. It will then be down to the call to scheduler_is_allowed() in _scheduler_publish() to allow or still prevent publishing. This is ok, but I think you need to add a bit more of this explanation into the comment in presave, as it appeared odd when I first read what you were doing.
Some other points to consider:
Line 648: The correct use of the string is 'e.g.,' (with a comma after it). However, for clarity, consider changing 'e.g.' to 'for example,'// converting it into the node property (e.g. 'publish_on').Good work on the new test folder structure, thanks for starting that.
Jonathan
Comment #17
jonathan1055 commentedNow we need to do a second operation to change the status.
Comment #18
pfrenssenThe node not being published but remaining in a scheduled state even though its publication date may already have passed is by design. This is to cover the use case of having one "editor" user role that is responsible for writing and scheduling content, and a "chief editor" user role that is responsible for proofreading and approving content. They might not be able to approve the content in time. If the date has passed, they can then either approve the content and have it published immediately, or set a new scheduling date.
Me neither, I have broken my head several times already over the name of this hook. Now that I am implementing it for the test it bothers me again. Looking at how constraints are handled in D8 it seems to me that this concept fits better for this hook. Instead of the hook returning TRUE or FALSE it could return an array of violations (these could be strings containing error messages). If the array is empty there were no violations, and the (un)publication is allowed. What do you think of this? I like the last code example on Symfony's constraints documentation. We could adapt it to something like:
Fully agree.
Let's put it in a scheduler.api.php file, with some examples. There's already an issue about this: #1979462: Provide API documentation.
I'll address your remarks 4-5-6.
Comment #19
jonathan1055 commentedFor the function name, 'is_allowed' is the wrong part of speech. It is passive, I think it should be a verb, ie. hook_scheduler_allow_...()
Also we should avoid the word 'action', as this will cause confusion with actions that Scheduler (will soon) provide as part of the Rules integration.
So some suggestions are, in php to give a flavour of how they will look:
Alternatively, we could code it such that it does not use a second parameter, and the function name includes the action. Then modules would implement:
We need to make it easy for other modules to implement the hooks, so using the two functions makes the names simple to remember and to understand. If we did this, then the internal function could be called _scheduler_allow() and would look like:
Regarding the return value, I would say keep it simple as a boolean. In Scheduler we will not know whether the calling module has displayed those returned message(s) for the violations. If we just get back a boolean then it is clear to those who are writing their hook implementations that they need to display the messages.
Comment #20
pfrenssenI like this! Even though it means that module developers potentially have to implement two hooks, but this is a familiar pattern in D7 anyway.
What do you think of turning it around?
It's ok for me to return a boolean and handle the messages in the hook. Ideally the messages should only be shown when a form has been submitted, but showing them on node save is already the current behaviour.
Comment #21
jonathan1055 commentedYes I think turning it round is even better, as that matches why the developer is implementing the hook - specifically to stop publishing. The default behaviour with no hook is to allow publishing. Good idea!
I have a slight preference for
hook_scheduler_prevent_publishing()Comment #22
pfrenssenHere's an updated version of the patch containing my work in progress over the past couple of days. It is nearing completion.
I have adressed most of the remarks. Setting this to Needs review for the bot, but it still needs some work.
Remaining work:
Comment #23
pfrenssenI renamed the hooks to
hook_scheduler_prevent_(un)publishing(). Now it is maybe a bit weird to return FALSE if the (un)publication should be prevented, and TRUE if it is allowed. I left it like this because it is more common to use FALSE to deny something, but I would like a second opinion on this.Comment #24
jonathan1055 commentedAfter the previous discussion, I thought again, and came to exactly the same conclusion. Having a negative purpose (prevent/deny) in the function name is problematic when returning a TRUE/FALSE. I believe it will be clearer if we reverted to hook_scheduler_allow_publishing() and hook_scheduler_allow_unpublishing() returning TRUE if allowed and FALSE if denied.
The internal function could be called _scheduler_allow($node, $action) and the code is more or less the same as you currently have. I just changed the comments slightly:
In the calls to this function, in _scheduler_publish() and _scheduler_unpublish(), it could be
Everything else is great. If you agree with the names as above, then we are RTBC. If you want to get the majority of this committed now then that's ok with me, and you could finish off the tests later in the issue. It's up to you.
Jonathan
Comment #25
pfrenssenFinally found some time to work a bit on Scheduler :)
I have addressed the remarks from #24. I changed my mind on writing a whole new test to just check if the messages are displayed when the hooks are implemented. We are actually already testing that the hooks fire correctly, so let's just assume that drupal_set_message() works as intended :)
Unassigning myself, feel that my work is done here :)
Comment #27
jonathan1055 commentedI agree about the tests.
Good work. Excellent. RTBC :-)
It will be interesting, also, when you make this commit, to see if the -dev release gets updated. There are six commits which have been done since 18th Nov, and they are not showing yet on https://drupal.org/node/3292/commits
Comment #28
pfrenssenI'm curious about that too!
Committed to 7.x-1.x: commit 3940a805b.
Comment #29
eric_a commentedI deleted the 7.x-1.x branch test yesterday and today there's a new dev release! (Must be related to the d.o. upgrade.) Chances are that a next commit will fix the commit views display as well.
Comment #30
pfrenssenThanks for the info! The dev release was initiated manually today (ref. #2158069: Development release not packaged after commits to Scheduler). The issue about the commit view is tracked at #2125405: Not all commits showing up.
Comment #32
jonathan1055 commentedThis issue is an example of #2146913: Issue auto-closing logic does not consider comment activity. Pieter commented only 6 days ago but the last node change was 14 days ago, hence the auto-closure now.
I have written a patch to revert back to the required D6 behavior, but it's not been reviewed yet.
Jonathan