Protecting Pages by Age

Let users in specific user groups see only pages of a certain age.


A MODX user wanted to create user groups who could only see pages of a certain age. The "Zero" User Group could see all pages. The "Sixty" User Group could only access pages that were more than 60 days old. The "Ninety" User Group could only see pages that were more than 90 days old.

It's possible to do this with Resource Group Access ACL entries, a cron job to put pages in the appropriate group as they age, and a plugin to put new pages into a separate protected Resource Group, but there's a much simpler and more reliable way.

The answer is a simple snippet in the page Template for all protected pages that checks the age of the page and the current User's User Group and acts accordingly.

Let's call the snippet "AgeCheck". Here is the tag for the Template:

[[!AgeCheck]]

Here is the code for the snippet:

/* AgeCheck snippet */
$currentUser = $modx->user;

/* make sure user is logged in */
if ($currentUser->hasSessionContext('web')) {
    /* get current timestamp */
    $now = time();
    /* get the page's birth date as a timestamp
       (we could use 'publishedon' or 'editedon' here) */
    $pageBirthday = strtotime($modx->resource->get('createdon'));

    /* Get page age in days */

    /* rounds up to nearest day */
    $pageAge = ceil(($now - $pageBirthday) / 86400);

    /* rounds down to nearest day */
    // $pageAge = floor(($now - $pageBirthday) / 86400);

    /* Check the user's User Group */
    if ($currentUser->isMember('Zero')){
        return '';
    }

    if ($currentUser->isMember('Sixty') && ($pageAge >= 60)) {
        return '';
    }

    if ($currentUser->isMember('Ninety') && ($pageAge >= 90)) {
        return '';
    }
}
/* User fails all tests, cannot see the current page */
        
return 'Sorry, you are not authorized to see this page';

// or 
        
$url = 'https://full/url/of/sorry/upgrade-your-subscription/page'; 
$modx->sendRedirect($url);

The return ''; line essentially does nothing and the user gets to see the page.

The strtotime() call is necessary because $modx->resource->get() returns a human-readable date/time when used with date fields like createdon, publishedon, and editedon. We have to use strtotime() to convert it into a timestamp, which is what is returned by time(). Because a timestamp is in seconds, we need to divide the difference between now and the page's birthday by 86400 to convert it to days (which we then round either up or down to the nearest day).

It's relatively easy to convert the code above to work with different page ages, and with a little work, you could send members of the "Sixty" or "Ninety" User Groups to a custom page that suggests upgrading to a User Group with access to newer pages and a subscription link that upgrades them.

There is one down side to using this method rather than using ACL entries. There's no easy way to hide pages in the menu that the user doesn't have access to. On the other hand, showing those pages provides an incentive for users to upgrade their memberships. It should be possible with a custom output modifier in one of the menu's Tpl chunks to make the menu entries for those pages be plain text rather than links, but that would keep the user from trying to access them and being sent to the upgrade page.



Comments (0)


Please login to comment.

  (Login)