Creating a Module

Applies to: Jamroom 7.0+ Last verified: 2026-10-24
  • What we'll build

    A module that emails the site's admins when a new member activates their account. It shows the core of most modules: an include.php file, an event listener, and an email template.

    You need a test site with Run in Developer Mode on (see Developer Guide).

  • Finding the event

    With Developer Mode on, open ACP > Modules > Users > Users > Info. It lists the events the Users module fires. The one we want is:

    signup_activated: Fired when a user successfully validates their account

  • The smallest module

    A module is a folder in modules/ with an include.php file that has a _meta() and an _init() function. Our module is xxSignupNotify (xx is the prefix for your own modules; see Module Naming).

    Create modules/xxSignupNotify/include.php:

    <?php
    /**
     * xxSignupNotify - email admins when a new user activates
     */
    
    // make sure we are not being called directly
    defined('APP_DIR') or exit();
    
    /**
     * meta
     */
    function xxSignupNotify_meta()
    {
        return array(
            'name'        => 'Signup Notify',
            'url'         => 'signupnotify',
            'version'     => '1.0.0',
            'developer'   => 'Your Name, ©' . date('Y'),
            'description' => 'Email the site admins when a new user activates their account',
            'category'    => 'users',
            'license'     => 'mpl'
        );
    }
    
    /**
     * init
     */
    function xxSignupNotify_init()
    {
        jrCore_register_event_listener('jrUser', 'signup_activated', 'xxSignupNotify_signup_activated_listener');
        return true;
    }
  • Every PHP file in a module starts with defined('APP_DIR') or exit();, so it can't be run directly.

  • The listener

    A listener gets the event's data, can change it, and must return it. Add to include.php:

    /**
     * Email admins when a user activates their account
     * @param array $_data User being activated
     * @param array $_user Current user
     * @param array $_conf Global config
     * @param array $_args Extra event arguments
     * @param string $event Event name
     * @return array
     */
    function xxSignupNotify_signup_activated_listener($_data, $_user, $_conf, $_args, $event)
    {
        if ($_ids = jrUser_get_admin_user_ids()) {
            $_rp = array(
                'system_name' => $_conf['jrCore_system_name'],
                'user_name'   => $_data['user_name'],
                'user_email'  => $_data['user_email']
            );
            list($sub, $msg) = jrCore_parse_email_templates('xxSignupNotify', 'new_user', $_rp);
            foreach ($_ids as $uid) {
                $_us = jrCore_db_get_item('jrUser', $uid, true);
                if ($_us && jrCore_checktype($_us['user_email'], 'email')) {
                    jrCore_send_email($_us['user_email'], $sub, $msg);
                }
            }
        }
        return $_data;
    }
  • Always return $_data from a listener. Other modules listen for the same event, and the module that fired it uses what comes back.

  • The email templates

    jrCore_parse_email_templates('xxSignupNotify', 'new_user', $_rp) reads two templates from the module's templates folder, with the values in $_rp as variables.

    templates/email_new_user_subject.tpl:

    [{$system_name}] New user: {$user_name}
  • templates/email_new_user_message.tpl:

    A new user has activated their account on {$system_name}:
    
    User name: {$user_name}
    Email: {$user_email}
  • Installing it

    1. Copy the folder to modules/ on your test site.
    2. Go to ACP > Modules. The new module is in the Users category, inactive. Open it, check Active on its Info tab, and save.
    3. Sign up as a new user and activate the account. The admins get the email.
  • Seeing the data

    To see what a listener receives, write it to the Debug Log with fdebug():

    fdebug($_data);
  • Open ACP > Dashboard > Activity Log > Debug Log. Remove the call when you're done. A debugger shows the same with breakpoints: see Setting Up a Debugging Environment.

  • Next

Tags