Advanced: Automated Groups

In version 5.7 of Concrete CMS we introduced the concept of Automated Groups. Automated groups can be entered or exited by users automatically, based on a number of factors.

Automatic Group Expiration

Enabling an automated group is as easy as adding a group, and setting some custom properties. In this example, we're going to create a group named "Paid Members" and make it so that any user added to this group will automatically be removed in one year (since they're paying for a year membership.)

$members = \Group::add('Paid Members');
$members->setGroupExpirationByInterval(365, 0, 0, 'REMOVE');

The fourth argument is the action, which can be one of the following

  • REMOVE - Remove the user from the group
  • DEACTIVATE - Deactivate the user
  • REMOVE_DEACTIVATE - Do both

The user will have the corresponding action taken upon them 365 days from whenever they enter the group. If you'd like to set it so that the group has a fixed point for exiting, you can do that this way:

$members->setGroupExpirationByDateTime('2016-12-31 11:59:59', 'REMOVE');

To clear expiration options, call this method:

$members->removeGroupExpiration();

Automatic Group Entry

Automatic group entry is a little more complex. First, set the options on the group itself, programmatically. First, decide how you want to check for users to entry this group:

$checkOnRegister = true;
$checkOnLogin = true;
$checkOnJobRun = true;
$members->setAutomationOptions($checkOnRegister, $checkOnLogin, $checkOnJobRun);

In this example, we're checking to see whether users should be automatically added to this group every time a new user registers, every time a user logs in, as well as every time the "Check Automated Groups" jobs is run programmatically or through the Dashboard.

You can clear these automation options at any time by calling

$group->clearAutomationOptions();

Now that you've enabled automation on a group, you need to create a group automation controller, which is custom code that determines how to add users to this group, and when.

Creating an Automation Controller for Automatic Group Entry

You'll need to do this even if you enable automatic group entry from the Dashboard User Interface.

Non-Packaged Group

If this is a group you've created through the Dashboard, or if you've added the group programmatically but haven't assigned it to a package, then, typically this is where your group will live, and what its namespace will be:

application/src/User/Group/AutomatedGroup/YourGroupName.php with the namespace Application\Src\User\Group\AutomatedGroup

If you've set the config value app.provides_core_extension_autoloader_mapping to true, however (which is recommended), it should be found here

application/src/Concrete/User/Group/AutomatedGroup/YourGroupName.php with the namespace Application\User\Group\AutomatedGroup

Packaged Group

If this group has been added through a package's installation method, this is where the group will live, and what its namespace will be:

package/your_package/src/User/Group/AutomatedGroup/YourGroupName.php with the namespace Concrete\Package\YourPackage\Src\User\Group\AutomatedGroup

If, however, you've set the $pkgAutoloaderMapCoreExtensions variable to true in your Package controller (which is recommended), this is where you should put your group file:

package/your_package/src/Concrete/User/Group/AutomatedGroup/YourGroupName.php with the namespace Concrete\Package\YourPackage\User\Group\AutomatedGroup

Class Naming and Extension

Name the class based on the group, StudlyCapsed, with no spaces. If your group is named "Website Members" the class should be WebsiteMembers, within the appropriate namespace. The class must extend Concrete\Core\User\Group\GroupAutomationController.

Class Contents

Once you've created the appropriately named file, you simply need to implement a check(\Concrete\Core\User\User $user) method within the class. Return true if you wish the user to be added to the group, or false if not.

Example

Let's create a group for users who have created more than 10 pages on our site. We'll call this group "Esteemed Editors."

First, create the group:

$editors = \Group::add('Esteemed Editors');

Next, enable automation. We'll let a job handle this – we won't check on login or registration:

$editors->setAutomationOptions(false, false, true);

Next, create a class file. Since we haven't added this through a package, and we don't have any special configuration settings turned on, we'll create the file in the default application location, application/src/User/Group/AutomatedGroup/EsteemedEditors.php.

Finally, these are the contents of the group

<?php
namespace Application\Src\User\Group\AutomatedGroup;
use Concrete\Core\User\User;
use Concrete\Core\User\Group\GroupAutomationController;

class EsteemedEditors extends GroupAutomationController
{
    public function check(User $ux)
    {
        $db = \Database::connection();
        $num = $db->GetOne('select count(uID) from Pages where uID = ?', array($ux->getUserID()));
        if ($num > 9) {
            return true;
        }
        return false;
    }
}

That's it! Every time the job is run, our automated group will be cycled through, and users not in the group will be checked to see if they meet this criteria. If they do, they'll automatically be added to the group. Any badges or expiration settings applied to the group will also be applied.