Tassos Marinos Developer of Joomla Extensions

How to create a custom Joomla User Registration Form

Published in Convert Forms
Updated 20 Sep, 2023

Convert Forms allows you to register your users through your forms using a PHP snippet until the official Joomla! Registration Addon is available.

How to create a Joomla User Account with Convert Forms

To be able to create a new user with your form, you will need to set a few fields required by Joomla! to register new users.

Step 1: Create a new form with registration fields

First, open your form through Components > Convert Forms > Forms and select your form. Once you are in your form, you will need to create the following fields:

Field LabelField TypeField Name
Username Textbox username
Name Textbox name
Password Password password
Email Email email

And lastly, add a submit button in order to be able to submit the form.

Step 2: Add Joomla User Registration PHP Script

If you require your users to activate their accounts manually, please skip this step and go to step 3.

Go to Behavior > PHP Scripts > After Form Submission and place the following PHP code into the After Form Submission field.

function addJoomlaUser($username, $name, $email, $password, $groups, $activate = false)
{
	jimport('joomla.user.helper');
    
	$groups = is_string($groups) ? explode(',', $groups) : (array) $groups;
    
	$data = [
        'name'   	 => $name,
        'username'	 => $username,
        'password'	 => $password,
        'password2'	 => $password,
        'email'		 => JStringPunycode::emailToPunycode($email),
        'groups'	 => $groups
	];
    
	if (!$activate)
	{
        $hash = JApplicationHelper::getHash(JUserHelper::genRandomPassword());
		$data['activation'] = $hash;
		$data['block'] = 1;
	}
    
	// Load the users plugin group.
	JPluginHelper::importPlugin('user');
	$user = new JUser;
	
	if (!$user->bind($data))
	{
        throw new Exception($user->getError());
	}
    
	if (!$user->save())
	{
        throw new Exception($user->getError());
    }
    
    return $user;
}

// Gather submitted data
$username = $submission->params['username'];
$name     = $submission->params['name'];
$password = $submission->params['password'];
$email    = $submission->params['email'];

// Create Joomla User Account
$new_user = addJoomlaUser($username, $name, $email, $password, '2');

After you have added the above PHP snippet you can Save your Form. Now your users will get registered once they fill your form but their accounts wont enabled and require to be enabled and activated by an admin.

Create a user and automatically activate the newly created account

To create a user and activate the account, replace the last line in the aforementioned code with this:

$new_user = addJoomlaUser($username, $name, $email, $password, '2', true);

Now your newly created users will be automatically registered and their accounts will be automatically activated.

Step 3: (Optional) Send an Email Notification to your users to manually activate their account

If you require your users to manually activate their account, you will need to create 2 new Hidden Fields in your form using the below field details:

Field TypeField Name
Hidden Field activation_url
Hidden Field activation_hash

Go to Behavior > PHP Scripts and place the following PHP code into the Form Process field.

jimport('joomla.user.helper');

$hash =  JApplicationHelper::getHash(JUserHelper::genRandomPassword());

$config = JFactory::getConfig();

$linkMode = $config->get('force_ssl', 0) == 2 ? 1 : 0;

$activation_url = \JRoute::link(
	'site',
	'index.php?option=com_users&task=registration.activate&token=' . $hash,
	false,
	$linkMode,
	true
);

$post['activation_url'] = ltrim($activation_url, '/');
$post['activation_hash'] = $hash;

Now go to Behavior > PHP Scripts and enter the following PHP code into the After Form Submission field.

function addJoomlaUser($username, $name, $email, $password, $groups, $activate = false, $hash = null) {
	jimport('joomla.user.helper');

	$groups = is_string($groups) ? explode(',', $groups) : (array) $groups;

	$data = [
        'name'   	 => $name,
        'username'	 => $username,
        'password'	 => $password,
        'password2'	 => $password,
        'email'		 => JStringPunycode::emailToPunycode($email),
        'groups'	 => $groups
	];

	if ($activate)
	{
		$data['activation'] = $hash;
		$data['block'] = 1;
	}

	// Load the users plugin group.
	JPluginHelper::importPlugin('user');
	
	$user = new JUser;
	
	if(!$user->bind($data))
	{
        throw new Exception($user->getError());
	}
	if (!$user->save())
	{
        throw new Exception($user->getError());
    }

    return $user;
}

// Create and register a new user immediately
$username = $submission->params['username'];
$name = $submission->params['name'];
$password = $submission->params['password'];
$email = $submission->params['email'];
$hash = $submission->params['activation_hash'];
$new_user = addJoomlaUser($username, $name, $email, $password, '2', true, $hash);

Now, you can setup an Email Notification for your newly registered users so they can click on the activation link and register to your site.

Add the following PHP Snippet at the end of Behavior > PHP Scripts > After Form Submission.

// Set the sender name
$from_name = '{site.name}';

// Set the subject
$subject = '{site.name} Activation Link';

// Set the email message
$message = 'Hello {field.name},
Thank you for registering!
To start using your account, please activate your account using the link below: {field.activation_url}
Regards,
{site.name}'; // Do not edit below // Set the sender email address $from_email = '{site.email}'; // The recipients' email address $recipient = '{field.email}'; // Set the email address the user will reply to, by default the user will reply to the sender $reply_to = ''; // Once you have set $reply_to, you can also set a name to appear alongside the email address $reply_to_name = ''; $options = [ 'from_email' => $from_email, 'from_name' => $from_name, 'recipient' => $recipient, 'subject' => $subject, 'body' => $message, 'reply_to' => $reply_to, 'reply_to_name' => $reply_to_name, ]; // Replace Smart Tags $email = \ConvertForms\SmartTags::replace($options, $submission); // Send email $emailer = new \NRFramework\Email($email); $emailer->send();

Set the sender name in $from_email, subject in $subject as well as the email message in $message. You may also set the sender email in $from_email and the recipients email in $recipient.

Your user will then receive the email with the activation url to activate their account.

Important: Go to Global Configuration > Users > User Options > Allow User Registration and set it to Yes as well as go to New User Account Activation and set it to Self. This ensures the activation link sent to your users will work as expected.

Note: The user will activate their account but if you have set the setting New User Account Activation on System > Global Configuration > Users to Administrator then your users will verify their email address and require an Administrator to activate their account.

Note 2: Your registered users' info will also be added as a submission to your form which will contain all data in your form (even the password in plain text which may be sensitive information). If you do not want to store the submissions on your registration form, you can remove the submissions stored in your Form using the FAQ: How to remove the newly registered user from my submissions?

How can I set the user profile data upon user creation?

When you create a Joomla User, you can only send data that has to do with the user such as username, email, password, etc... This means you cannot set user profile data such as city, address, phone, etc... You need a separate function to do so. Below you can find the function that you can call by passing a user ID as well as an array of data that you want to set for the particular user.

function setUserProfileData($user_id, $data)
{
    $db = JFactory::getDbo();
    $query = $db->getQuery(true)
                    ->delete($db->quoteName('#__user_profiles'))
                    ->where($db->quoteName('user_id') . ' = ' . (int) $user_id)
                    ->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('profile.%'));
    $db->setQuery($query);
    $db->execute();

    $tuples = array();
    $order = 1;
    foreach ($data as $k => $v)
    {
        $tuples[] = '(' . $user_id . ', ' . $db->quote('profile.' . $k) . ', ' . $db->quote(json_encode($v)) . ', ' . $order++ . ')';
    }

    $db->setQuery('INSERT INTO ' . $db->quoteName('#__user_profiles') . ' VALUES ' . implode(', ', $tuples));
    $db->execute();
}

// Set the user id and profile data below
$user_id = 960;
$data = [
	'city' => 'Kos',
	'country' => 'Greece',
	'website' => 'tassos.gr'
];
setUserProfileData($user_id, $data);

List of Joomla User Profile Fields that you can use:

  • address1 (Address 1)
  • address2 (Address 2)
  • city (City)
  • region (Region)
  • country (Country)
  • postal_code (Postal Code)
  • phone (Phone)
  • website (Website)
  • favoritebook (Favorite Book)
  • aboutme (About Me)
  • dob (Date of Birth, The date of birth entered should use the format Year-Month-Day, ie 0000-00-00)

How can I set the user custom fields upon user creation?

To set values for the custom fields created under Users > Fields you will need to place the following PHP snippet after you call addJoomlaUser in After Form Submission PHP Scripts Event.

// Previous code from step 2/3 ...

// retrieve the values of the custom fields from the form
$age = $submission->params['age'];
$height = $submission->params['height'];

// Set the custom fields to save to the user
$data = [
	[
        'name' => 'age',
        'value' => $age,
    ],
	[
        'name' => 'height',
        'value' => $height
    ],
];

// Do not edit below
function setUserCustomFields($user, $data)
{
    JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php');

    $fields = FieldsHelper::getFields('com_users.user', $user);

    // Loading the model
    if (defined('nrJ4'))
	{
		$model = JFactory::getApplication()->bootComponent('com_fields')->getMVCFactory()
			->createModel('Field', 'Administrator', ['ignore_request' => true]);
	}
	else
	{
		$model = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true));
	}

    foreach ($fields as $field)
    {
        foreach ($data as $key => $value)
        {
            if ($field->name == $value['name'])
            {
			    $model->setFieldValue($field->id, $user->id, $value['value']);
            }
        }
    }
}

setUserCustomFields($new_user, $data);

For each custom field that you have created, you need to navigate to each custom field(Users > Fields > Your Field) then go to Permissions tab > Edit Custom Field Value > Set it to "Allowed".

Frequently Asked Questions

Can I display the registration form in a popup?

Yes, you can transform your form into a popup using EngageBox. To learn how you can make that happen visit How to load Convert Forms through EngageBox guide.

How to remove the newly registered user from my submissions?

To remove the submission from your form (does not interfere with the registered user in Joomla!), navigate to your Form > Behavior > PHP Scripts > After Form Submission and add the following:

ConvertForms\Api::removeSubmission($submission->id);

How can I validate the password field based on Global Configuration > Users > Password Options?

To validate the password based on the configuration set under Global Configuration > Users > Password Options, go into your Form > Behavior > PHP Scripts > Form Process and at the top of this textarea, add the following PHP snippet:

$rule = \Joomla\CMS\Form\FormHelper::loadRuleType('Password');
$xml = new \SimpleXMLElement('<xml/>');
if (!$valid = $rule->test($xml, $post['password']))
{
	$queue = JFactory::getApplication()->getMessageQueue();
	if (count($queue))
	{
		$error = '';

		foreach ($queue as $msg)
		{
			$error .= '<p>' . $msg['message'] . '</p>';
		}

		throw new Exception($error);
	}
}

This will display an error message when the password does not meet the criteria set under Password Options.