Timed publishing and unpublishing of pages

Does anyone know of a way of getting pages to automatically publish and unpublish pages?

I want to have a members area that is only available a specific times to the members.

Does anyone know of an Extra that does this?

I assume you’re aware of the “Publish Date” and “Unpublish Date” settings under the resource Settings tab? If you’re looking for a way to do this dynamically based on user input or some other data point it would be a very simple thing to create a snippet for this purpose. I think we’ll need a clearer understanding of what you’re wanting to accomplish.

Thanks @claytonk I wasn’t aware, but it looks like that just does it once or not.
I run online events and I want to stop people from accessing those page(s) outside the time when an event is being run.
They are already user controlled pages.
If for example I have an event Monday evening and Wednesday evening the pages should automatically become available about an hour before hand and an hour after the finishing time.

Does that help, or make sense?

If I’m understanding you correctly, then the “Publish Date” and “Unpublish Date” settings are exactly what you need. You can set a page to publish at any future date and time and to unpublish at a later date and time, MODX will automatically set the page’s “published” setting accordingly when that date and time arrives. So, for instance, if you have an event running from June 7 – June 9, you can set the Publish Date to June 7 at any time you want the page to become available and set the Unpublish Date to June 9 at any time you want the page to cease being available.

Just be sure you check your server’s timezone setting to ensure the times you’re using match the times the server will be using.

@claytonk, that would do it once, bit I am looking at doing this for the same pages every few days. Does the publish and unpublish dates allow for this?

No, if you want to preset a whole series of publish/unpublish dates you would need to do that a different way. You’re correct, the settings will only publish and unpublish your resource once. However, these settings are accessible via snippet, so you could set up a simple snippet that resets these settings on a specific schedule. Are you familiar with writing snippets?

If I’m understanding you, it sounds like a custom snippet or plugin that checks the current date and time and forwards the user to some other page if the current page shouldn’t be available would do it.

If you used NewsPublisher in the front end, a snippet at the top of the NewsPublisher page would do it.

If you want it to occur in the MODX Manager, I think it would have to be a plugin, and that would be more complicated.

That was my thinking, thanks for your help

@bobray That is what I thought. Didn’t know about NewsPublisher, does that have the snippet I would need?

If I need to write my own, is there any good place to start learning how to do this?
I work better with video training, but happy to look at anything that would help me.

Thanks

NewsPublisher doesn’t have the snippet. It just allows users to create and edit resources in the front end, without logging in to the Manager.

It would take a custom snippet, but the only difficult part would be the date and time arithmetic.

What are the exact restrictions you want on when the page is available?

The page is only available to members, and I have already done this using Modx’s users and user groups.

The arithmatic shouldn’t be too bad as it will be repeating at the same times most days, but not all.

It would need to be updated, but currently it would be something like Mon, Tue, Wed, Thur (20:00 to 21:00) and Sat 18:00 - 22:00)

Here is some code for a plugin that may or may not work:

  • The plugin runs on the event OnLoadWebDocument. (Check the checkbox for this event when creating the plugin).
  • This blocks access only in the frontend (and NOT in the manager).
  • Change the IDs in the array $blocked_resource_ids = [98,99]; to the resource IDs you want to block access to.
  • Test it thoroughly before using it and make sure you understand the code.
<?php
$eventName = $modx->event->name;
switch($eventName) {
    case 'OnLoadWebDocument':
        $blocked_resource_ids = [98,99]; //IDs of resources to block access to
        $current_resource_id = $modx->resource->get('id');
        
        if (in_array($current_resource_id, $blocked_resource_ids)){
            $day = (int)date('w'); //A numeric representation of the day (0 for Sunday, 6 for Saturday)
            $hour = (int)date('G'); //24-hour format of an hour (0 to 23)
            
            $block_access = false;
            //Mon, Tue, Wed, Thur (20:00 to 20:59:59) 
            if (in_array($day,[1,2,3,4]) && $hour == 20){
                $block_access = true;
            }
            //Sat 18:00 - 21:59:59
            if ($day == 6 && $hour >= 18 && $hour < 22){
                $block_access = true;
            }
                
            if ($block_access) {
                $modx->log(modX::LOG_LEVEL_ERROR,'Access blocked to resource ' . $current_resource_id); //Write message to error log
                $redirect_id = $modx->getOption('site_unavailable_page',null,1); //read system setting 'site_unavailable_page'
                $modx->sendForward($redirect_id);
            }
        }
        break;
}
1 Like

Thanks so much for this, i will have a play with it and let you know if it workds as expected

I think in halftrainedharry’s code, $block_access should be true in the first case and false in the other two.

I think this would do it in the front end:

$block_access = true;

/* This won't be necessary if PHP's time is correct for your timezone */
date_default_timezone_set('America/Chicago'); 

$day = (int) date('w'); /* 0-6 (0 = sunday) */

$allowedDays = array(
   1 => 'Monday',
   2 => 'Tuesday',
   3 => 'Wednesday',
   5 => 'Friday',
   6 => 'Saturday',
);

if (isset($allowedDays[$day])) {
    $hour = (int) date("G"); /* 0 - 23, 0 is 12:00 to 1:00 am) */
    if ($day === 6) { /* Saturday */
        if ($hour > 17 && $hour < 22)
            $block_access = false;
    } else { /* other days */
        if ($hour == 20) {
            $block_access = false;
        }
    }
}

if ($block_access) {
    $modx->sendRedirect('https://some/other/full/url');
}

return '';

I created the array for two reasons. First, to make it a little easier to edit. Second, to allow the use of isset() which is a little faster than in_array().

Also, the hour isn’t pulled if it’s not an available day.

I assume the redirect page would contain an apology and a reminder of the available days and times.

The snippet tag would go at the top of the NewsPublisher page.

1 Like

You are right. I misread that.

@halftrainedharry @bobray Hi I have tried the code as given and amended, and I am now getting

This page isn’t working

modx.forequizzes.co.uk redirected you too many times.

ERR_TOO_MANY_REDIRECTS

I am using this code:

<?php $eventName = $modx->event->name; switch($eventName) { case 'OnLoadWebDocument': $blocked_resource_ids = [33,34]; //IDs of resources to block access to $current_resource_id = $modx->resource->get('id'); $block_access = true; /* This won't be necessary if PHP's time is correct for your timezone */ date_default_timezone_set('Europe/London'); $day = (int) date('w'); /* 0-6 (0 = sunday) */ $allowedDays = array( 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 5 => 'Friday', 6 => 'Saturday', ); if (isset($allowedDays[$day])) { $hour = (int) date("G"); /* 0 - 23, 0 is 12:00 to 1:00 am) */ if ($day === 6) { /* Saturday */ if ($hour > 17 && $hour < 22) $block_access = false; } else { /* other days */ if ($hour == 19) { $block_access = false; } } } if ($block_access) { $modx->sendRedirect('https://modx.forequizzes.co.uk/noquiz.html'); } return ''; }

The problem is probably this line

 $modx->sendRedirect('https://modx.forequizzes.co.uk/noquiz.html');

Make sure the url 'https://modx.forequizzes.co.uk/noquiz.html' is always accessible and NOT one of the blocked resource-ids ([33,34]).


Btw: When you post code here, please put lines with three back-ticks at the start and at the end of your code to make it more readable.

```//line with 3 back-ticks at the beginning
//your code here
```//line with 3 back-ticks at the end

Thanks.
It isn’t it is 36.

Thanks for the help with the code, I was wondering how to do this.

The code is below, but in better format

<?php
$eventName = $modx->event->name;
switch($eventName) {
    case 'OnLoadWebDocument':
        $blocked_resource_ids = [33,34]; //IDs of resources to block access to
        $current_resource_id = $modx->resource->get('id');
        
        $block_access = true;

/* This won't be necessary if PHP's time is correct for your timezone */
date_default_timezone_set('Europe/London'); 

$day = (int) date('w'); /* 0-6 (0 = sunday) */

$allowedDays = array(
   1 => 'Monday',
   2 => 'Tuesday',
   3 => 'Wednesday',
   5 => 'Friday',
   6 => 'Saturday',
);

if (isset($allowedDays[$day])) {
    $hour = (int) date("G"); /* 0 - 23, 0 is 12:00 to 1:00 am) */
    if ($day === 6) { /* Saturday */
        if ($hour > 17 && $hour < 22)
            $block_access = false;
    } else { /* other days */
        if ($hour == 19) {
            $block_access = false;
        }
    }
}

if ($block_access) {
    $modx->sendRedirect('https://modx.forequizzes.co.uk/noquiz.html');
}

return '';
}

You deleted the part where it checks the resource id, therefore it blocks all pages!

if (in_array($current_resource_id, $blocked_resource_ids)){ ... }

In Bobs example this isn’t necessary, because he provided a snippet code, that you would only put in the resources where it should run.