How to register a user in custom extensions in Joomla?

A

your-component/forms/import.xml

This XML manifest file will provide basic required fields for Joomla user registration.

B

your-component/admin/src/Controller/ImportController.php

It is MVC Controller. This is main code file that once user submit form, it will then handle all requested data, connecting with Model for register user function and finally redirect to Success or failure page.

C

your-component/src/Model/ImportModel.php

Model file contains functions, this will have user registration function, get xml form, set fields and its data, and finally send that output to view.

D

your-component/src/View/Import/HtmlView.php

It is MVC View interacting with model, take form fields that will be finally rendered in template file.

E

yout-component/tmpl/import/default.php

It is HTML/PHP template for display "user" fields.

 

File Details

import.xml

<?xml version="1.0" encoding="utf-8"?>
<form>

	<fieldset name="basic" label="Import Fields" addfieldprefix="Abdul\Component\componentname\Administrator\Field">
		<field
			name="name"
			type="text"
			label="Full Name"
			default="muftiismailtoru"
			filter="string"
			required="true"
			size="30"
		/>

		<field
			name="username"
			type="text"
			label="User Name"
			class=""
			filter="username"
			required="true"
			size="30"
			default="This email address is being protected from spambots. You need JavaScript enabled to view it."
			autocomplete="username"
		/>

		<field
			name="password1"
			type="password"
			label="Password"
			required="true"
			autocomplete="new-password"
			class="validate-password"
			field="password1"
			size="30"
			validate="password"
			strengthmeter="true"
			rules="true"
			force="on"
			filter="raw"
			default="password1234"
		/>

		<field
			name="password2"
			type="password"
			label="Confirm password"
			autocomplete="new-password"
			class="validate-password"
			field="password1"
			filter="raw"
			message="COM_USERS_PROFILE_PASSWORD1_MESSAGE"
			size="30"
			validate="equals"
			required="true"
			default="password1234"
		/>

		<field
			name="email1"
			type="email"
			default="This email address is being protected from spambots. You need JavaScript enabled to view it."
			label="Email"
			field="id"
			filter="string"
			required="true"
			size="30"
			unique="true"
			validate="email"
			validDomains="com_users.domains"
			autocomplete="email"
		/>
	</fieldset>
	
</form>

your-component/admin/src/Controller/ImportController.php

public function save($key = NULL, $urlVar = NULL)
    {
        // Check for request forgeries.
        $this->checkToken();
		$app   = $this->app;
		$db = Factory::getContainer()->get('DatabaseDriver');
		 // Get the user data.
               $requestData = $this->input->post->get('jform', array(), 'array');
// set default password		
		$requestData['password2']= $requestData['password1'];
		// Save the data in the session.
		$app->setUserState('com_component_name.signup.data', $requestData);
		
        $input  = $app->input;
	/*
	STEP: Register User in Joomla system
	*****************/
        // If registration is disabled - Redirect to login page.
        if (ComponentHelper::getParams('com_users')->get('allowUserRegistration') == 0) {
            $this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
            return false;
        }
        /** @var \Joomla\Component\Users\Site\Model\RegistrationModel $model */
        $model = $this->getModel('import', 'Administrator');

        // Validate the posted data.
        $form = $model->getForm();
        if (!$form) {
            throw new \Exception($model->getError(), 500);
        }
	$data = $model->validate($form, $requestData);
	// Check for validation errors.
			// IF user exists
			if ($data === false) {
				// Get the validation messages.
			   $errors = $model->getErrors();
	// Push up to three validation messages out to the user.
			   for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) {
					if ($errors[$i] instanceof \Exception) {
						$app->enqueueMessage($errors[$i]->getMessage(), 'error');
					} else {
						$app->enqueueMessage($errors[$i], 'error');
					}
				}
				// Save the data in the session.
		//        $app->setUserState('com_componentname.signup.data', $requestData);
				// Redirect back to the registration screen.
				$this->setRedirect(Route::_('index.php?option=com_ componentname &view=import', false));			   return false;
			}
			// Attempt to save the data.
			$user_id = $model->register($data); 
			/*
			USER is not saved
			------------------------------*/
			if($user _id == "save_error") {
			$app->setUserState('com_ componentname.import.data', $data);
				// Redirect back to the edit screen.
				$this->setMessage("Save error: ".$model->getError(), 'error');
				$this->setRedirect(Route::_('index.php?option=com_ componentname &view=imports', false));		return false;
			}
			else { /// USER SAVED SUCCESSFULLY
			
				$db = Factory::getDBO();
				$customFields=FieldsHelper::getFields('com_users.user',Factory::getUser($item_id), true); 
				
				foreach ($customFields as $field)
				{
					$q1="";
// use exact name of field as you set in backend Users: Fields					
if($field->name=='piecesgained') {
					$q1="Insert into tutor_fields_values(field_id,item_id,value)
					values(".$field->id.",'$item_id','$piecesGained')";
					}
					else 
					if($field->name=='totalpieces') {
					$q1="Insert into tutor_fields_values(field_id,item_id,value)
					values(".$field->id.",'$item_id','$totalPieces')";
					}
					if($q1!="") :
					$db->setQuery($q1);
					try {
						$result= $db->execute();
					} catch (\RuntimeException $e) {
						$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
					}
					endif;
				}
			}
		}

		$this->setRedirect( 'index.php?option=com_componentname&view=imports', "Operation Completed Successfully.");
	}

your-component/src/Model/ImportModel.php

Import UserHelper class into your code in very lines: 
use Joomla\CMS\User\UserHelper;
public function getData()
{

	if ($this->data === null) {

		$this->data = new \stdClass();

		$app = Factory::getApplication();

		$params = ComponentHelper::getParams('com_users');
		// Override the base user data with any data in the session.

		$temp = (array) $app->getUserState('com_componentname.import.data', array());



		// Don't load the data in this getForm call, or we'll call ourself

		$form = $this->getForm(array(), false);



		foreach ($temp as $k => $v) {

			// Here we could have a grouped field, let's check it

			if (is_array($v)) {

				$this->data->$k = new \stdClass();



				foreach ($v as $key => $val) {

					if ($form->getField($key, $k) !== false) {

						$this->data->$k->$key = $val;

					}

				}

			} elseif ($form->getField($k) !== false) {

				// Only merge the field if it exists in the form.

				$this->data->$k = $v;

			}

		}



		// Get the groups the user should be added to after registration.

		$this->data->groups = array();



		// Get the default new user group, guest or public group if not specified.

		$system = $params->get('new_usertype', $params->get('guest_usergroup', 1));



		$this->data->groups[] = $system;



		// Unset the passwords.

		unset($this->data->password1, $this->data->password2);



		// Get the dispatcher and load the users plugins.

		PluginHelper::importPlugin('user');



		// Trigger the data preparation event.

		Factory::getApplication()->triggerEvent('onContentPrepareData', array('com_users.registration', $this->data));

	}



	return $this->data;

}


/**
 * Method to get the record form.
 *
 * @param   array    $data      Data for the form.
 * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
 *
 * @return  Form|boolean  A Form object on success, false on failure
 *
 * @since   1.6
 */
public function getForm($data = array(), $loadData = true)
{
//		echo 'import Model';exit;
	// Get the form.
	$form = $this->loadForm('com_componentname.import', 'import', array('control' => 'jform', 'load_data' => $loadData));

	if (empty($form))
	{
		return false;
	}

	return $form;
}

/**
 * Method to get the data that should be injected in the form.
 *
 * @return  mixed  The data for the form.
 *
 * @since   1.6
 */
protected function loadFormData()
{
//	echo 'loadform';exit;
	// Check the session for previously entered form data.
	$app = Factory::getApplication();
	$data = $app->getUserState('com_componentname.edit.import.data', array());
//		echo 'import Model';exit;

	if (empty($data))
	{
		$data = $this->getItem();

		// Pre-select some filters (Status, Category, Language, Access) in edit form if those have been selected in Article Manager: Articles
	}

	$this->preprocessData('com_componentname.import', $data);

	return $data;
}

public function register($temp)
{
	$params = ComponentHelper::getParams('com_users');
	// Initialise the table with Joomla\CMS\User\User.

	$user = new User();
	$data = (array) $this->getData();

	// Merge in the registration data.

	foreach ($temp as $k => $v) {

		$data[$k] = $v;
	}

	// Prepare the data for the user object.

	$data['email'] = PunycodeHelper::emailToPunycode($data['email1']);
	$data['password'] = $data['password1'];
	$useractivation = $params->get('useractivation');
	$sendpassword = $params->get('sendpassword', 1);

	// Check if the user needs to activate their account.
	$data['activation'] = "";
	$data['block'] = 0;
	$data['requireReset'] = 1;

	/*
	Set Group for user(in my case it is registered id==2 in backend
	********************************/
	$data['groups'][0]=2;

	// Bind the data.
	if (!$user->bind($data)) {

		$this->setError($user->getError());
		return false;
	}
	// Load the users plugin group.

	PluginHelper::importPlugin('user');

	// Store the data.

	if (!$user->save()) {

		$this->setError(Text::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $user->getError()));

		return "save_error";

		//	return false;

	}

	else	// SUCCESS user save
	{
		return $user->id;
	}
}

your-component/src/View/Import/HtmlView.php

public function display($tpl = null)
	{
		$this->form  = $this->get('Form');
		if (count($errors = $this->get('Errors')))
		{
			throw new GenericDataException(implode("\n", $errors), 500);
		}
		$this->addToolbar();
		return parent::display($tpl);
	}

yout-component/tmpl/import/default.php

<?php
defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Factory;
HTMLHelper::_('behavior.formvalidator');
HTMLHelper::_('behavior.keepalive');
?>
<form action="<?php echo Route::_('index.php?option=com_componentname&view=import'); ?>"
	method="post" name="adminForm" id="import-form" class="form-validate" enctype="multipart/form-data">
	<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
		<?php $fields = $this->form->getFieldset($fieldset->name); ?>
        <?php if (count($fields)) : ?>
            <fieldset>
                <?php // If the fieldset has a label set, display it as the legend. ?>
                <?php if (isset($fieldset->label)) : ?>
                    <legend><?php echo Text::_($fieldset->label); ?></legend>
                <?php endif; ?>
                <?php echo $this->form->renderFieldset($fieldset->name); ?>
            </fieldset>
        <?php endif; ?>
    <?php endforeach; ?>	
	<input type="hidden" name="task" value="">
	<?php echo HTMLHelper::_('form.token'); ?>
</form>
4. your-component/src/View/Import/HtmlView.php
	public function display($tpl = null)
	{
		$this->form  = $this->get('Form');
		if (count($errors = $this->get('Errors')))
		{
			throw new GenericDataException(implode("\n", $errors), 500);
		}
		$this->addToolbar();
		return parent::display($tpl);
	}

So that is How to register a user in custom extensions in Joomla 4. If you like my efforts, don't forget to buy me a cup of coffee, check out link in bottom.