SilverStripe Membership Module Tutorial

This SilverStripe Membership Module by ajshort is one of the most useful and solid modules I've used on a SilverStripe install.

Strangely this module is not listed on SilverStripe.org's collection of modules, I stumbled upon it after performing a search for "SilverStripe Membership Module" and coming across a forum post where the github repository for the module was linked to.

How to install the Membership module

  • Grab the code from the github repository, if you have git installed its a matter of cloning the repo with: git clone http://github.com/ajshort/silverstripe-memberprofiles.git
  • Rename the folder to 'memberprofiles' otherwise the little membership icon will not be found for the admin area. Make sure the memberprofiles folder is in the root of your SilverStripe install.
  • Run a /dev/build/
  • Create a new 'Member Profile Page' in the CMS.

The membership module should now be installed but to make life a bit easier go to the Security tab of the CMS and add a new group that will be used for new memberships - call it what you want, such as 'members'.

Now go to the 'Administrators' security group and edit your admin account, add yourself to the new group you just created. Navigate back to the 'Pages' section of the CMS, edit the new membership profile page and on the Behaviour tab check the option to:
Allow members with member creation permissions to add members via this page

So you will now be able to log in as a member using your admin account and additionally add new memberships. I still found it handy to test signing up as a new member in another browser profile however.

What the Membership Module will do

Straight off the bat the module takes care of everything for basic memberships:

  • Registering new members
  • Editing member profiles
  • Forgotten passwords
  • Email confirmation as a requirement before signing up
  • Post registration and login redirection
  • Members can choose which groups they want to belong to

And all of the above is very customisable, you can...

  • choose not to send out any emails, just send a notification email confirming membership or send a validation email with confirmation link to ensure new members have a valid email address.
  • force new members to be assigned to certain groups and allow members to pick which groups they want to belong to.
  • customise registration and post registration page content and whether to redirect a new member to another page, with full control over which page to redirect to.
  • drag and drop to reorder the registration form fields, manage validation requirements, error messages, field titles and show only certain form fields on registration.
  • add more form fields by decorating / extending the member class (see below).

All memberships can be managed from the Security tab of the CMS, so the existing functionality for managing admin users etc. is used.

Extending the Member class

Its very easy to add some custom data to your memberships.

Create a new class to extend the existing member class in /mysite/code. If you are signing up members that are a certain type name the class after that type, in the example I'll assume you are signing up pianists:

<?php
//mysite/code/Pianist.php
class Pianist extends DataObjectDecorator{
    function extraStatics(){
        return array(
            'db' => array(
                'PostalAddress' => 'Varchar(255)',
                    'HeardFrom' => "Enum('Word of mouth,Email,Website link,Facebook,Search Engine,Other','Word of mouth')",
                    'Status' => "Enum('Active,Disabled','Disabled')",
                    'AcceptTerms' => 'Boolean'
            ),
            'defaults' => array(
                 'Status' => 'Disabled'
            )
        );
    }
}

The pianist class adds some db data in order to record new members' postal address, how the new member heard about the website and whether the new member has accepted the terms and conditions.

We are also setting the default status of this member to Disabled because we want to screen all new members before giving them access to parts of the site.

To instantiate this DataObjectDecorator you need to include a line to add the extension in the config file:

//Decorate/extend the member class
Object::add_extension('Member', 'Pianist');

After running a /dev/build you should be able to see the new fields in your members table in the database. You should also see the new fields populated on the Membership Profile page in the CMS, you can edit to make the AcceptTerms field required and only shown when a user registers, and similarly for the other fields - directly from the CMS.

One of the things I love about this module, and SilverStripe, is the ability to add functionality using the DataObjectDecorator without hacking about in the core of the module, its very erm modular.

Checking if active members are logged in

Above we added a field to the member table using the Pianist DataObjectDecorator which sets the status of a member to 'Disabled' by default. The nice thing about this is admin users can search through members in the Security area of the CMS and edit the member so that their status is either Active or Disabled, this way you can have control over what members can do and view on your site.

Some useful functions to help with this are:

<?php
//mysite/code/Page.php
class Page_Controller extends ContentController {
 
    public static $allowed_actions = array (
    );
 
    public function init() {
        parent::init();
        Requirements::block(SAPPHIRE_DIR . "/javascript/ConfirmedPasswordField.js");
    }
 
    public function getLoggedIn() {
 
        //This should return false but is returning null when user is not logged in
        if (!Member::currentUser()) {
            return false;
        }
        return true;
    }
 
    public function getMemberActive() {
        $member = Member::currentUser();
        if (!$member) {
            return false;
        }
        $status = $member->getField('Status');
        if ($status == 'Active') {
            return true;
        }
        return false;
    }
 
    public function logout() {
        Security::logout(false);
        Director::redirect("home/");
    }
}

Emailing the site owner when new members join

Another nice addition is emailing the site owner when a new member signs up. Its quite easy to do so using the DataObjectDecorator again:

<?php
//mysite/code/Pianist.php
class Pianist extends DataObjectDecorator{
 
    //Other code from above here
 
    function onBeforeWrite() {
 
        if (!$this->owner->exists()) {
            $email = new Email();
            $data = $this->owner->getAllFields();
 
            $toAddress = Email::getAdminEmail();
            $email->setTo($toAddress);
 
            $email->setSubject('New Pianist has just registered');
            $email->setFrom($data['Email']);
 
            $email->setTemplate('NewPianistEmail');
            $email->populateTemplate($data);
 
            $email->send();
        }
    }
 
}

The above code checks if a new Pianist is registering then sends an email to the site admin if so. You will need to add an admin email address in config in order for Email::getAdminEmail() to retrieve something useful:

//mysite/_config.php
Email::setAdminEmail('admin@example.com');

Issues

One issue I had with the module was the double up of the password confirm field labels for some reason. Someone else had this issue as well, this hack works:

//memberprofiles/code/MemberProfilePage.php line ~750 in MemberProfilePage_Controller::getProfileFields()

//Changed to remove duplicate password labels on register form
if (!$field instanceof ConfirmedPasswordField) {
    $field->setTitle($profileField->Title);
}

I also had an issue with the ConfirmedPasswordField not hiding by default, this is not an issue related to the module I don't believe. Applying this hack fixed it for me.

Notes

The membership module scores very highly for me and should be included in SilverStripe's module directory. Many thanks to Andrew Short for this awesome piece of work! The membership profiles github repository is a great place to start for documentation etc.