php 如何从脚本中创建新的 Joomla 用户帐户?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1904809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:15:00  来源:igfitidea点击:

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

phpjoomlajoomla1.5

提问by user77413

We're creating an XML API for Joomla that allows partner sites to create new accounts for their users on our website.

我们正在为 Joomla 创建一个 XML API,它允许合作伙伴网站在我们的网站上为其用户创建新帐户。

We've created a standalone PHP script that processes and validates the API request, but now we need to actually create the new accounts. We were originally thinking about just doing a CURL call to submit the signup form, but we realized that there is an issue with the user token. Is there another clean way to create a user account without going into the guts of Joomla? If we do have to do some surgery, what is the best way to approach it?

我们已经创建了一个独立的 PHP 脚本来处理和验证 API 请求,但现在我们需要实际创建新帐户。我们最初只是想通过 CURL 调用来提交注册表单,但我们意识到用户令牌存在问题。有没有另一种干净的方法来创建用户帐户而不进入 Joomla 的内部?如果我们必须做一些手术,最好的方法是什么?

采纳答案by 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.

你应该使用 Joomla 内部类,比如 JUser,因为有很多内部逻辑,比如密码加盐。创建一个自定义脚本,该脚本使用来自 API 请求的值并使用来自 Joomla 用户类的方法将用户保存在数据库中。

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

使用自定义代码添加 joomla 用户的两种方法是一个很棒的教程。该方法有效。我在一些项目中使用了这种方法。

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

如果您必须在 Joomla之外访问 Joomla Framework ,请改为查看此资源

回答by mavrosxristoforos

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:

根据 waitinoratrain 的回答,它对登录用户无法正常工作(如果您在后端使用它实际上很危险),我对其进行了一些修改,现在它完全适合我。请注意,这是针对 Joomla 2.5.6,而该线程最初是针对 1.5 的,因此上面的答案:

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;
 }

回答by molo

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

只需转到文档页面:http: //docs.joomla.org/JUser

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

还竞争了单页样本以在 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/[email protected]&password=pass or just create simple form with appropriate parameters

调用示例:localhost/joomla/[email protected]&password=pass 或者只是创建带有适当参数的简单表单

回答by faleev

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

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

INSERT INTO jos_users( `name`, `username`, `password`, `email`, `usertype`, `gid` )
VALUES( 'Иванов Иван', 'ivanov', md5('12345'), '[email protected]', '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() );

回答by bcoughlan

Tested and working on 2.5.

已测试并在 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.

如果您在 Joomla 环境之外,则必须先执行此操作,或者如果您不编写组件,请使用@GMonC 答案中链接中的那个。

<?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.

我用它来对我的组件进行单元测试。

回答by Llewellyn

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.

另一种聪明的方法是使用名为 register 的实际 /component/com_users/models/registration.php 类方法,因为它会真正处理所有事情。

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 :)

这样做可以为您省去处理需要发送的电子邮件的所有麻烦,因为它会自动使用系统默认值。希望这对某人有所帮助:)

回答by Elin

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

更新:哦,我没有看到您想要 1.5,但您可以使用 1.5 API 做类似的事情。

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.

这是我用于另一个目的的一部分,但您需要改用默认组,直到从命令行使用 JUserHelper 的问题得到修复或使其成为 Web 应用程序。

<?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();
}

回答by Rob

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.

在我的情况下(Joomla 3.4.3)用户已添加到会话中,因此在尝试激活帐户时出现了错误行为。

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

只需在 $user->save() 之后添加这一行:

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

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

This will remove the newly created user from the session.

这将从会话中删除新创建的用户。

回答by Denish

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

有一个名为“登录模块”的模块,您可以使用该模块并将其显示在其中一个菜单中……您将在其中获得一个链接,例如“新用户?” 或“创建一个帐户”只需单击它,您将获得一个带有验证的注册页面..这只是使用注册页面的 3 个步骤过程......它可能有助于更快地获得结果!!..thanx

回答by luciomonter

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...

这在 joomla 1.6 中不起作用,因为 ACL 以另一种方式处理......最后更简单,您必须在“jos_user_usergroup_map”表(然后是“jos_users”表)上添加一个条目来声明每个用户至少一组...