As promised in http://drupal.org/node/276376#comment-4207316,
and in a newly created issue as Eric kindly asked,
here's a patch for the scheduler-7.x-1.x branch that adds scheduled promote/unpromote support.

Please test/review it if you can.

Comments

zilverdistel’s picture

Status: Active » Needs review
zilverdistel’s picture

StatusFileSize
new40.29 KB

Rerolled patch (removed a call to dpm(), and changed all occurances of Demote to Unpromote).

nancydru’s picture

"Demote" is more proper English than "unpromote," which would actually never be included in a good dictionary because of the negating double prefix.

nancydru’s picture

And now D6? Probably the biggest difference is the query construction.

nancydru’s picture

Minor technicality: 2 space indentation on forms.

Concatenation - spaces around dot.

jonathan1055’s picture

Thanks for doing the patch, but my initial impression is that it is a huge amount of changes [5 files changed, 525 insertions(+), 57 deletions(-) it says at the top] for essentially a simple operation. The problem is that the pacth duplicates so much of the existing code with only minor changes. I think Eric may have been designing another way to do it, also including other actions to be done on the node. At minimum we should parameterise and re-use current functions, as this change as it stands adds a large overhead to those who work on this module maintain and maintain it.

We definitely should consider options to promote/demote but I don't think the method suggested here is the correct approach in terms of making it extensible for future enhancements.

Jonathan
(sorry to be negative, thank you for your patch and for getting the idea started).

zilverdistel’s picture

@NancyDru: Concerning "demote" instead of "unpromote". I choose for unpromote, because I saw it being used in core (I don't remember where, maybe in some docblock in code).

@Jonathan: You're absolutely right about the code duplications. I needed this asap for a client ... Also, I think as a first step it's actually very usefull to duplicate the code, because it shows where further abstraction is needed... Concerning other possible actions, in my opinion, to keep this module simple (for the user) we should only provide scheduling for the publish/promote/sticky options, since these options are in core. More exotic options could then be handled by the rules module.

eric-alexander schaefer’s picture

The patch is indeed quite "comprehensive" (scheduler.module: 1027 lines, patch: 910 lines). Since I do not trust large patches, I "merge" them manually anyway (copy&paste section by section) to see what's going on. That way I can also refactor the patch as I go.

I agree with zilverdistel about limiting the scheduled actions to those core options. Everything else can be done with rules.

nancydru’s picture

@zilverdistel: I'm not so picky about internal documentation, but anything that is visible to the end user should be in good enough English as to be translatable.

@Eric: I tried applying it manually to 6.x and got thoroughly lost about half way through. I may try it again because I need this within the next two weeks, if not sooner.

Branndon’s picture

I tried to use this and promote something, and this was the resulting error. There were no errors during patching.

zilverdistel’s picture

@Branndon: seems a db column is missing. Did you run update.php after patching?

Branndon’s picture

I did. I haven't worked on this site for a while now, but I'll report back if the issue hasn't been fixed yet. Thanks.

jonathan1055’s picture

Status: Needs review » Postponed

Previously Eric has said

Promote and demote has to wait until the database normalization is done #1006766: Normalize and extend schema

jonathan1055’s picture

Issue summary: View changes
Parent issue: » #1006766: Normalize and extend schema
jonathan1055’s picture

Title: Scheduled promotion / unpromotion for Drupal 7 version » Scheduled promotion / demotion from Front page
Version: 7.x-1.x-dev » 8.x-1.x-dev
Status: Postponed » Active
Related issues: +#1982932: Drupal 8 Port of the Scheduler Module

Now that we are working on 8.x version of Scheduler we should discuss this, hence re-activating this issue. If the implementation is built into 8.x then we might back-port or we might not, but if it happens at all, it will be at 8.x first.

cybermache’s picture

I used Rules to create a temporary solution. Granted it's a universal solution but I can imagine someone could add to this to affect only certain content types or posts with certain taxonomy terms, of instance. The following Rules export is from Drupal 7.x but I think it's basic enough that can easily be recreated in 8.x. Hope people find this useful.

{ "rules_unpromote_republish" : {
    "LABEL" : "Unpromote\/republish",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "scheduler" ],
    "ON" : { "scheduler_node_has_been_unpublished_event" : [] },
    "IF" : [ { "node_is_promoted" : { "node" : [ "node" ] } } ],
    "DO" : [
      { "node_unpromote" : { "node" : [ "node" ] } },
      { "node_publish" : { "node" : [ "node" ] } }
    ]
  }
}
jonathan1055’s picture

Thanks cybermache for sharing that. As an alternative you can do this by implementing hook_scheduler_api if you don't want to use rules and need more control over the logic. I have just recently documented the hooks in scheduler.api.php.

In case others want to do this, here's the code for 7.x:

/**
 * Implements hook_scheduler_api().
 *
 * @param $node
 *   The node object
 * @param $action
 *   The action being performed, either 'pre_publish', 'publish',
 *   'publish_immediately', 'pre_unpublish' or 'unpublish'.
 */
function d7testing_scheduler_api($node, $action) {
  // When node is unpublished, unpromote from front page then republish. This
  // effectively alters Schedulers behaviour from unpublish to unpromote.
  // See https://www.drupal.org/node/1092934
  if (stristr($node->title, '1092934') && $action == 'unpublish') {
    dd(implode(' ', array('action', $action, 'node', $node->nid, "$node->title", 'unpromote and republish')));
    $node->promote = NODE_NOT_PROMOTED;
    $node->status = NODE_PUBLISHED;
    node_save($node);
  }
}

The above will do the work silently. Or if you wanted to use node actions, this also gives the full set of watchdog log messages:

    // Unpromote and keep published, using actions_do.
    $actions = array('node_unpromote_action', 'node_publish_action', 'node_save_action');
    actions_do($actions, $node, array('node' => $node), NULL, NULL);

The patches submitted in this thread above will not get implemented in 8.x or 7.x and I do not think we will be building in this functionality directly into the module. The existing hooks in 7.x allow plenty of scope for node manipulation, and they will also be available in 8.x via events - #2669164: Introduce event subscriber for the Scheduler hooks

Hope that helps.

pfrenssen’s picture

We should investigate how we could best do this. This calls for a plugin type, so the current two actions (publishing and unpublishing of nodes) would be two plugins, promotion and demotion would be two other plugins. We can then add more plugins for other actions that are great to perform on a schedule, such as sending of emails etc.

In theory the Action plugin system in core seems ideal for this. We should take a look at ConfigurableActionBase and some of its example implementations (e.g. UnpublishByKeywordNode). It is used for example to do bulk operations in the content overview, so it seems well suited. Each action is bound to a specific entity type, so we could support all existing node actions, and branch out to other entity types later (e.g. blocking of users). What is not so nice is that support for Actions in core seems quite minimal. We could also look at what Rules is doing in this respect.

This will require a rearchitecture of Scheduler though. It seems unlikely we can do this and maintain full backwards compatibility, so this will probably lead to Scheduler 2.x.