how to limit/set duration of published state . i want to control the duration of published state

Comments

jonathan1055’s picture

Hi kaizerking,

Can you be a bit more specific? Do you mean that you want to make sure the content is unpublished within a certain date of it being published by scheduler? That is not something that Scheduler does at the moment. You can force the user to enter an 'unpublished on' date but currently there is no validation on how far in advance that date is.

If you have php skills, it may be possible to use form_alter() to add an extra validation function which could check that the 'unpublish on' date is within the range you require.

Jonathan

kaizerking’s picture

Hi jonathan,
Thanks for reply
My requirement is Admin should be able to control the duration of node published state.
Suppose if there is an advertisement content type there are different packages, a three months package would allow the advertisement to be in 'published' state for 3 months and after expiry of 3 months if user is not renewing then the advertisement should be unpublished.
A configurable duration field may just be sufficient at admin settings per content type. value 0 or similar . will allow the user to input the end date in the node creation. a rules support and token support will enhance the usability along with this.

Kaizerking

jonathan1055’s picture

Hi,
It sounds like your requirements are quite specific. But now that I have written support for Rules https://drupal.org/project/rules to allow other modules and/or custom rules to set the Scheduler Unpublish date, you should be able to cover what you need.

The Rules Integration issue is #773510: Integration with Rules module and you might also be interested in our support for View Bulk Operations #1026072: Ability to schedule nodes in bulk using Views Bulk Operations

Jonathan

jonathan1055’s picture

As part of my testing of the new rules integration code I wrote a rule which automatically sets the unpublish date to a specified time period from the when the node was created. Here is the exported rule definition, and you can import this into Rules to help you get started:

{ "rules_set_unpublish_on_date" : {
    "LABEL" : "Unpublish 30 days after edit\/save (when node title contains UNPUBLISH)",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "scheduler" ],
    "ON" : [ "node_insert", "node_update" ],
    "IF" : [
      { "data_is" : { "data" : [ "node:title" ], "value" : "set unpublish date" } },
      { "scheduler_condition_publish_enabled" : { "node" : [ "node" ] } }
    ],
    "DO" : [
      { "scheduler_set_unpublish_date_action" : {
          "node" : [ "node" ],
          "date" : { "select" : "node:changed", "date_offset" : { "value" : 2592000 } }
        }
      },
      { "drupal_message" : { "message" : "Unpublish-on date is set to [node:scheduler-unpublish], was [node-unchanged:scheduler-unpublish]. Change performed by rule \u0027set unpublish date\u0027" } }
    ]
  }
}

Go to #773510: Integration with Rules module to get the patch and test the above. Please let us know how you get on. Thanks.

Jonathan

jonathan1055’s picture

Status:Active» Closed (works as designed)

No response from Kaizerking for seven months, hence closing this request.

The scheduler enhancements integrating with Rules and Views Bulk Operations can provide the required customisation, and the example I gave showed exactly how to implement it.

jonathan1055’s picture

hwasem’s picture

Status:Closed (works as designed)» Active

Sorry if I should create a new issue, but I thought this need was very similar to the OP, so I reopened.

I had a similar requirement where I have an 'event' content type and I would like unpublish these events 7 days after their last ending occurrence (field-date-start). This seems pretty easy to do in theory, but it took quite a lot of reading to get this far.

In english:
If content_Type='event' && node=publish,
then unpublish_on = (variable for last event end date) + 7 days

Here is my rule export:

{ "rules_event_unpublish_7_days_after_last_occurance" : {
    "LABEL" : "Event: Unpublish 7 days after last occurance",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "TAGS" : [ "Scheduler" ],
    "REQUIRES" : [ "scheduler", "rules" ],
    "ON" : { "node_insert" : [], "node_update" : [] },
    "IF" : [
      { "scheduler_condition_unpublishing_is_enabled" : { "node" : [ "node" ] } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_date_start" } }
    ],
    "DO" : [
      { "scheduler_set_unpublish_date_action" : {
          "node" : [ "node" ],
          "date" : {
            "select" : "node:field-date-start:0:value2",
            "date_offset" : { "value" : 604800 }
          }
        }
      },
      { "drupal_message" : { "message" : "Unpublish-on date is set to [node:scheduler-unpublish], was [node-unchanged:scheduler-unpublish]. Change performed by rule \u0027set unpublish date\u0027" } }
    ]
  }
}

The only problem is that I have repeating events. Currently this is unpublishing after the first occurrence of the event, not the last repeating date. I have a few date options available in actions:

node:field-date-start:0:
node:field-date-start:1:
node:field-date-start:2:
node:field-date-start:3:

If I use node:field-date-start:3: , it sets unpublish based on the 4th instance of recurrence. But how do I set the rule to always pick the last date instance - whether it repeats 15 times or none? I'm on Rules 7.x-2.6+8-dev, in case that matters.

jonathan1055’s picture

Hello hwasem

Good to see you have a working example. Are you using the date-repeat functionality which comes with the Date module? If so, are there any extra fields supplied to either give the last date or the number of dates? The solution might be to have a php code snippet in Rules to return the last date, instead of just taking the value straight from the node. Do you have php programming skills? If not, let me know and I will set up a repeating date event content type like yours and try to get what you want. What version of Date are you using?

Jonathan

hwasem’s picture

I really appreciate your response. I am using the Date module version 7.x-2.7 with its repeating features. I have a little PHP experience, but am not sure where to start with this.

Looking through a node's var dump, I think the RRULE is the best thing to use. This is where my PHP experience, or lack of, makes it tough. The field that would show it is $field_date_start['0']['rrule']. The var dump of the first date instance:


field_date_start (Array, 76 elements)
    0 (Array, 6 elements)
        value (String, 19 characters ) 2013-01-22 10:00:00
        value2 (String, 19 characters ) 2013-01-22 11:00:00
        rrule (String, 68 characters ) RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU;UNTIL=201...
            RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU;UNTIL=20140702T065959Z;WKST=SU
        timezone (String, 19 characters ) America/Los_Angeles
        timezone_db (String, 19 characters ) America/Los_Angeles
        date_type (String, 8 characters ) datetime

for example.

So... IF there is an RRULE, I want to use the UNTIL date instead of the date in #7 above (20140702 in this case). While the until date is not necessarily the last occurrence, it is close enough for our purposes.

Thanks for any advice you have on this.
Heidi

jonathan1055’s picture

Hello Heidi,

I thought this would be fairly straight-forward in rules, but unfortunately I have not managed it yet either.

Your idea of using the RRULE might work in the cases where there is an end date, but when the repeats are specified by the number of dates, we get rrule (String, 44 characters ) RRULE:FREQ=WEEKLY;INTERVAL=1;COUNT=6;WKST=MO. Working out the end date is therefore harder. However, given that in both cases the actual dates are stored in an array, I thought the simplest way would be to take the date of thre last item. In PHP this is easy, and I tried it out using the action 'show a message on the site' and it works fine. The variable $node is available for use so the php code is:

<?php
$dates
= $node->field_event_date['und'];
dsm($dates);
var_dump($dates);
$number = sizeof($dates);
dsm($dates[$number-1]);
echo
'this event has ' . $number . ' dates. The last one is ' . $dates[$number-1]['value'];
?>

Now, when specifying a date value for an action (such as scheduler publish-on) we can define it using PHP but for some reason the $node variable is not available. The PHP input textarea is slightly different from what we get in the Message action. It seems that the only variable we can use is $value, which is the selected input value. This has to be a date type, so we cannot pass in the $node.

I also tried using the 'create a variable' action which does allow the full php input. This works but I cannot seem to access that variable in later actions. It shows up in the replacement tokens but no value is displayed.

Now that we've got this far I might ask someone from Rules to help.

Jonathan

hwasem’s picture

Jonathan,

You make a great point about the repeating until end date vs. number of events. I was able to use your code and found a slightly easier way to get at that end date (In my case the value2 "to-date").

 
<?php
        $dates
= $node->field_date_start['und'];
       
$repeat_length = count($dates);      \\gives total number of repeats
    $last_date
$dates[$repeat_length - 1]['value2'];
        print
'<p>' . $last_date. '</p>';
 
?>

It is currently reporting the last occurrence's ending date correctly in the Message action.

I learned how to create tokens yesterday. I was able to get the token to print correctly in the Message action, too. BUT, I couldn't use it as a field in my Action Set unpublish rule. I thought it was because I didn't specifically load it in the Conditions (i.e. Entity has field), but I couldn't figure out how to get at it there either.

So I'm now trying to create a new action rule now in my custom module. I learned how to do this yesterday, as well. We'll see how far that goes. Will update with results.

Heidi

hwasem’s picture

I created a custom action in my own module. The action works, but doesn't use the Rule's offset of +1 day. So I'm kind at the same place I was above.

What is the format the date is expecting in the Set Unpublishing Rule? Unix? Y-m-d? I think that may be my problem.

jonathan1055’s picture

Hello Heidi,
If you have your own module then it is easier to do. You do not need to create a custom rule but can set the unpublish_on date directly in your own hook_node_presave. Here is a working example:

<?php
   
// Set to automatically unpublish 5 days after final repeating date.
    // https://drupal.org/node/1880748
   
if ($node->type == 'simpletest_example' && module_exists('scheduler') && variable_get('scheduler_unpublish_enable_' . $node->type, 0)) {
     
$dates = isset($node->field_event_date[LANGUAGE_NONE]) ? $node->field_event_date[LANGUAGE_NONE] : FALSE;
      if (
is_array($dates)) {
       
dd($dates, '$dates');
       
$number = sizeof($dates);
       
$last_date = $dates[$number-1]['value'];
       
dd($last_date, '$last_date');
       
$timestamp = strToTime($last_date . ' + 5 days');
       
dd($timestamp, '$timestamp');
       
$node->unpublish_on = $timestamp;
       
drupal_set_message(t('This @type has @dates and the last is @last. The content will be unpublished on @unpub_date', array(
         
'@type' => $node->type,
         
'@dates' => format_plural($number, '1 date', '@count dates'),
         
'@last' => $last_date,
         
'@unpub_date' => format_date($timestamp, 'medium'),
        )));
      }
    }
?>

You can change or remove the test for a specific content type, but I would leave in the check where we ensure that unpublishing is enabled for that type. Also I checked that the date field exists and is an array. You may want to also check that the date is actually entered. I have included devel debug output via the dd() function. If you do not have the devel module you can delete these.

Let me know how you get on or if you want any further explanation of the above code.

Thanks for mentioning your work on making a custom action, because it gave me the idea that we should make the Scheduler rules and action available for other modules to use, not simply for use within the Rules module itself. I will try that and if successful will raise it on a separate issue.

Jonathan

hwasem’s picture

Status:Active» Closed (fixed)

That's perfect! And much more simple. I like having the content type and expiration control easily accessible in the code - because you never know when the requirement could change. Thank you so much!

jonathan1055’s picture

Status:Closed (fixed)» Fixed

Glad you like the solution.

We need a slight fix to the code above. The unpublish_on date should not be set during a cron run, otherwise the moment the node is unpublished by scheduler and the date removed, it immediately be set to be unpublished again, on the same date, and thus continually appear in the page of scheduled nodes.

Luckily, I have recently added the function scheduler_cron_is_running() so that other modules can detect if the page request is currently being processed during a scheduler cron run and react accordingly. You will need to add && !scheduler_cron_is_running() into the test at the top of the block, so that it is only processed if not during a cron run. It can be added to the same IF test as module_exists('scheduler') providing that it is later in the row, so that if Scheduler is not present it does not try to execute the non-existent function.

Jonathan

jonathan1055’s picture

That link to the source code viewer currently has an internal server error. The code is:

<?php
/**
 * Return whether Scheduler cron is running.
 *
 * This function can be called from any Scheduler function, from any contrib
 * module or from custom PHP in a view or rule.
 *
 * @return bool
 *   TRUE if scheduler_cron is currently running. FALSE if not.
 */
function scheduler_cron_is_running() {
  return
drupal_static('scheduler_cron');
}
?>

However, this is only in the dev version, it was added in #2168861: Use drupal_static() to indicate when scheduler_cron is running on 28th Feb. If you want to stick with the proper release 7.x-1.2 then this does not help you.

hwasem’s picture

I am using the dev version from Feb 28 already, so I added that bit to the IF statement in my module.

Thanks,
Heidi

Status:Fixed» Closed (fixed)

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