How can I create a new Joomla user account from within a script?

妖精的绣舞 提交于 2019-11-27 07:00:35
GmonC

You should use Joomla internal classes, like JUser, since there a lot of internal logic such as password salting. Create a custom script that uses the values from the API request and saves the users in the database using methods from Joomla User Classes.

Two ways to add joomla users using your custom code is a wonderful tutorial. The approach works. I've used this approach in some projects.

If you have to access Joomla Framework outside Joomla, check this resource instead.

Based on the answer from waitinforatrain, which is not properly working for logged-in users (actually dangerous if you are using it in the back-end), I have modified it a bit and here it is, fully working for me. Please note that this is for Joomla 2.5.6, while this thread was originally for 1.5, hence the answers above:

 function addJoomlaUser($name, $username, $password, $email) {
    jimport('joomla.user.helper');

    $data = array(
        "name"=>$name,
        "username"=>$username,
        "password"=>$password,
        "password2"=>$password,
        "email"=>$email,
        "block"=>0,
        "groups"=>array("1","2")
    );

    $user = new JUser;
    //Write to database
    if(!$user->bind($data)) {
        throw new Exception("Could not bind data. Error: " . $user->getError());
    }
    if (!$user->save()) {
        throw new Exception("Could not save user. Error: " . $user->getError());
    }

    return $user->id;
 }
molo

Just go to documentation page: http://docs.joomla.org/JUser

Also competed sample of single page to register new users in Joomla:

<?php 

function register_user ($email, $password){ 

 $firstname = $email; // generate $firstname
 $lastname = ''; // generate $lastname
 $username = $email; // username is the same as email


 /*
 I handle this code as if it is a snippet of a method or function!!

 First set up some variables/objects     */

 // get the ACL
 $acl =& JFactory::getACL();

 /* get the com_user params */

 jimport('joomla.application.component.helper'); // include libraries/application/component/helper.php
 $usersParams = &JComponentHelper::getParams( 'com_users' ); // load the Params

 // "generate" a new JUser Object
 $user = JFactory::getUser(0); // it's important to set the "0" otherwise your admin user information will be loaded

 $data = array(); // array for all user settings

 // get the default usertype
 $usertype = $usersParams->get( 'new_usertype' );
 if (!$usertype) {
     $usertype = 'Registered';
 }

 // set up the "main" user information

 //original logic of name creation
 //$data['name'] = $firstname.' '.$lastname; // add first- and lastname
 $data['name'] = $firstname.$lastname; // add first- and lastname

 $data['username'] = $username; // add username
 $data['email'] = $email; // add email
 $data['gid'] = $acl->get_group_id( '', $usertype, 'ARO' );  // generate the gid from the usertype

 /* no need to add the usertype, it will be generated automaticaly from the gid */

 $data['password'] = $password; // set the password
 $data['password2'] = $password; // confirm the password
 $data['sendEmail'] = 1; // should the user receive system mails?

 /* Now we can decide, if the user will need an activation */

 $useractivation = $usersParams->get( 'useractivation' ); // in this example, we load the config-setting
 if ($useractivation == 1) { // yeah we want an activation

     jimport('joomla.user.helper'); // include libraries/user/helper.php
     $data['block'] = 1; // block the User
     $data['activation'] =JUtility::getHash( JUserHelper::genRandomPassword() ); // set activation hash (don't forget to send an activation email)

 }
 else { // no we need no activation

     $data['block'] = 1; // don't block the user

 }

 if (!$user->bind($data)) { // now bind the data to the JUser Object, if it not works....

     JError::raiseWarning('', JText::_( $user->getError())); // ...raise an Warning
     return false; // if you're in a method/function return false

 }

 if (!$user->save()) { // if the user is NOT saved...

     JError::raiseWarning('', JText::_( $user->getError())); // ...raise an Warning
     return false; // if you're in a method/function return false

 }

 return $user; // else return the new JUser object

 }

 $email = JRequest::getVar('email');
 $password = JRequest::getVar('password');

 //echo 'User registration...'.'<br/>';
 register_user($email, $password);
 //echo '<br/>'.'User registration is completed'.'<br/>';
?>

Please note that for registration used only email and password.

The sample of call: localhost/joomla/test-reg-user-php?email=test02@test.com&password=pass or just create simple form with appropriate parameters

faleev

http://joomlaportal.ru/content/view/1381/68/

INSERT INTO jos_users( `name`, `username`, `password`, `email`, `usertype`, `gid` )
VALUES( 'Иванов Иван', 'ivanov', md5('12345'), 'ivanov@mail.ru', 'Registered', 18 );

INSERT INTO jos_core_acl_aro( `section_value`, `value` )
VALUES ( 'users', LAST_INSERT_ID() );

INSERT INTO jos_core_acl_groups_aro_map( `group_id`, `aro_id` )
VALUES ( 18, LAST_INSERT_ID() );

Tested and working on 2.5.

function addJoomlaUser($name, $username, $password, $email) {
        $data = array(
            "name"=>$name, 
            "username"=>$username, 
            "password"=>$password,
            "password2"=>$password,
            "email"=>$email
        );

        $user = clone(JFactory::getUser());
        //Write to database
        if(!$user->bind($data)) {
            throw new Exception("Could not bind data. Error: " . $user->getError());
        }
        if (!$user->save()) {
            throw new Exception("Could not save user. Error: " . $user->getError());
        }

        return $user->id;
}

If you're outside the Joomla environment, you'll have to do this first, or if you're not writing a component, use the one in the link in @GMonC's answer.

<?php
if (! defined('_JEXEC'))
    define('_JEXEC', 1);
$DS=DIRECTORY_SEPARATOR;
define('DS', $DS);

//Get component path
preg_match("/\\{$DS}components\\{$DS}com_.*?\\{$DS}/", __FILE__, $matches, PREG_OFFSET_CAPTURE);
$component_path = substr(__FILE__, 0, strlen($matches[0][0]) + $matches[0][1]);
define('JPATH_COMPONENT', $component_path);

define('JPATH_BASE', substr(__FILE__, 0, strpos(__FILE__, DS.'components'.DS) ));
require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once JPATH_BASE .DS.'includes'.DS.'framework.php';
jimport( 'joomla.environment.request' );
$mainframe =& JFactory::getApplication('site');
$mainframe->initialise();

I use this for unit testing my component.

Update: oh I ddin't see you wanted 1.5 but you could do similar but wth the 1.5 API instead.

This is part of something I was usng for anther purpose but you would need to use the default group instead until an issue with using JUserHelper from the command line is fixed or make it a web application.

<?php
/**
 *
 * @copyright  Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

if (!defined('_JEXEC'))
{
    // Initialize Joomla framework
    define('_JEXEC', 1);
}

@ini_set('zend.ze1_compatibility_mode', '0');
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Load system defines
if (file_exists(dirname(__DIR__) . '/defines.php'))
{
    require_once dirname(__DIR__) . '/defines.php';
}

if (!defined('JPATH_BASE'))
{
    define('JPATH_BASE', dirname(__DIR__));
}

if (!defined('_JDEFINES'))
{
    require_once JPATH_BASE . '/includes/defines.php';
}

// Get the framework.
require_once JPATH_LIBRARIES . '/import.php';


/**
 * Add user
 *
 * @package  Joomla.Shell
 *
 * @since    1.0
 */
class Adduser extends JApplicationCli
{
    /**
     * Entry point for the script
     *
     * @return  void
     *
     * @since   1.0
     */
    public function doExecute()
    {
        // username, name, email, groups are required values.
        // password is optional
        // Groups is the array of groups

        // Long args
        $username = $this->input->get('username', null,'STRING');
        $name = $this->input->get('name');
        $email = $this->input->get('email', '', 'EMAIL');
        $groups = $this->input->get('groups', null, 'STRING');

        // Short args
        if (!$username)
        {
            $username = $this->input->get('u', null, 'STRING');
        }
        if (!$name)
        {
            $name = $this->input->get('n');
        }
        if (!$email)
        {
            $email = $this->input->get('e', null, 'EMAIL');
        }
        if (!$groups)
        {
            $groups = $this->input->get('g', null, 'STRING');
        }

        $user = new JUser();

        $array = array();
        $array['username'] = $username;
        $array['name'] = $name;
        $array['email'] = $email;

        $user->bind($array);
        $user->save();

        $grouparray = explode(',', $groups);
        JUserHelper::setUserGroups($user->id, $grouparray);
        foreach ($grouparray as $groupId)
        {
            JUserHelper::addUserToGroup($user->id, $groupId);
        }

        $this->out('User Created');

        $this->out();
    }

}

if (!defined('JSHELL'))
{
    JApplicationCli::getInstance('Adduser')->execute();
}

In my case (Joomla 3.4.3) the user was added to the session, so there was a buggy behaviour when trying to activate the account.

Just add this line, after $user->save():

JFactory::getSession()->clear('user', "default");

This will remove the newly created user from the session.

Another smart way would be to use the actual /component/com_users/models/registration.php class method called register since it will take care of everything really.

First you add these methods to your helper class

/**
*   Get any component's model
**/
public static function getModel($name, $path = JPATH_COMPONENT_ADMINISTRATOR, $component = 'yourcomponentname')
{
    // load some joomla helpers
    JLoader::import('joomla.application.component.model'); 
    // load the model file
    JLoader::import( $name, $path . '/models' );
    // return instance
    return JModelLegacy::getInstance( $name, $component.'Model' );
}   

/**
*   Random Key
*
*   @returns a string
**/
public static function randomkey($size)
{
    $bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ";
    $key = array();
    $bagsize = strlen($bag) - 1;
    for ($i = 0; $i < $size; $i++)
    {
        $get = rand(0, $bagsize);
        $key[] = $bag[$get];
    }
    return implode($key);
}  

Then you add the following user create method also to you component helper class

/**
* Greate user and update given table
*/
public static function createUser($new)
{
    // load the user component language files if there is an error
    $lang = JFactory::getLanguage();
    $extension = 'com_users';
    $base_dir = JPATH_SITE;
    $language_tag = 'en-GB';
    $reload = true;
    $lang->load($extension, $base_dir, $language_tag, $reload);
    // load the user regestration model
    $model = self::getModel('registration', JPATH_ROOT. '/components/com_users', 'Users');
    // set password
    $password = self::randomkey(8);
    // linup new user data
    $data = array(
        'username' => $new['username'],
        'name' => $new['name'],
        'email1' => $new['email'],
        'password1' => $password, // First password field
        'password2' => $password, // Confirm password field
        'block' => 0 );
    // register the new user
    $userId = $model->register($data);
    // if user is created
    if ($userId > 0)
    {
        return $userId;
    }
    return $model->getError();
}

Then anywhere in your component you can create a user like this

// setup new user array
$newUser = array(
    'username' => $validData['username'], 
    'name' => $validData['name'], 
    'email' => $validData['email']
    );
$userId = yourcomponentnameHelper::createUser($newUser); 
if (!is_int($userId))
{
    $this->setMessage($userId, 'error');
}

Doing it this way saves you all the trouble of handling the emails that needs to be send, since it automatically will use the system defaults. Hope this helps someone :)

there is one module called "login module" you can use that module and display it in one of the menu.. in which u will get one link like "new user?" or "create an account" just click on it you will get one registration page with validation..this is just 3-step process to use registration page...it may be helpful to get result faster!!..thanx

This won't work in joomla 1.6 as ACL are handled in another way... In the end is even simpler, you mandatory need to add an entry on the "jos_user_usergroup_map" table (further then the "jos_users" table) to declare at least one group for each user...

I have made an ajax call and then just passing the variables to this script and it worked for me.

define('_JEXEC', 1);
define('JPATH_BASE', __DIR__);
define('DS', DIRECTORY_SEPARATOR);

/* Required Files */
require_once(JPATH_BASE . DS . 'includes' . DS . 'defines.php');
require_once(JPATH_BASE . DS . 'includes' . DS . 'framework.php');
$app = JFactory::getApplication('site');
$app->initialise();

require_once(JPATH_BASE . DS . 'components' . DS . 'com_users' . DS . 'models' . DS . 'registration.php');

$model = new UsersModelRegistration();

jimport('joomla.mail.helper');
jimport('joomla.user.helper');
$language = JFactory::getLanguage();
$language->load('com_users', JPATH_SITE);
$type       = 0;
$username   = JRequest::getVar('username');
$password   = JRequest::getVar('password');
$name       = JRequest::getVar('name');
$mobile     = JRequest::getVar('mobile');
$email      = JRequest::getVar('email');
$alias      = strtr($name, array(' ' => '-'));
$sendEmail  = 1;
$activation = 0;

$data       = array('username'   => $username,
            'name'       => $name,
            'email1'     => $email,
            'password1'  => $password, // First password field
            'password2'  => $password, // Confirm password field
            'sendEmail'  => $sendEmail,
            'activation' => $activation,
            'block'      => "0", 
            'mobile'     => $mobile,
            'groups'     => array("2", "10"));
$response   = $model->register($data);

echo $data['name'] . " saved!";
$model->register($data);

Only user is not getting activated automatically. I am passing 'block' => "0" for activating user but it is not working :( But rest of the code works fine.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!