【发布时间】:2010-12-26 15:55:34
【问题描述】:
我们正在为 Joomla 创建一个 XML API,它允许合作伙伴网站在我们的网站上为其用户创建新帐户。
我们已经创建了一个独立的 PHP 脚本来处理和验证 API 请求,但现在我们需要实际创建新帐户。我们最初只是想通过 CURL 调用来提交注册表单,但我们意识到用户令牌存在问题。是否有另一种干净的方法来创建用户帐户而无需进入 Joomla 的胆量?如果我们必须做一些手术,最好的方法是什么?
【问题讨论】:
我们正在为 Joomla 创建一个 XML API,它允许合作伙伴网站在我们的网站上为其用户创建新帐户。
我们已经创建了一个独立的 PHP 脚本来处理和验证 API 请求,但现在我们需要实际创建新帐户。我们最初只是想通过 CURL 调用来提交注册表单,但我们意识到用户令牌存在问题。是否有另一种干净的方法来创建用户帐户而无需进入 Joomla 的胆量?如果我们必须做一些手术,最好的方法是什么?
【问题讨论】:
你应该使用 Joomla 内部类,比如 JUser,因为有很多内部逻辑,比如密码加盐。创建一个自定义脚本,该脚本使用来自 API 请求的值,并使用 Joomla 用户类中的方法将用户保存在数据库中。
Two ways to add joomla users using your custom code 是一个很棒的教程。该方法有效。我在一些项目中使用了这种方法。
如果您必须在外部 Joomla 访问Joomla 框架,check this resource instead。
【讨论】:
根据 waitinfratrain 的回答,它不适用于已登录的用户(如果您在后端使用它实际上很危险),我对其进行了一些修改,现在它完全适合我.请注意,这是针对 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;
}
【讨论】:
只需转到文档页面: http://docs.joomla.org/JUser
还在 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/>';
?>
请注意,注册时仅使用电子邮件和密码。
调用示例: localhost/joomla/test-reg-user-php?email=test02@test.com&password=pass 或者只是创建带有适当参数的简单表单
【讨论】:
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() );
【讨论】:
经过测试并在 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;
}
如果您不在 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();
我用它来对我的组件进行单元测试。
【讨论】:
$user = clone(JFactory::getUser()); 而不仅仅是$user = new JUser();?
new JUser(); 有效吗?如果是这样,那将是一个更好的解决方案。
另一种聪明的方法是使用名为 register 的实际 /component/com_users/models/registration.php 类方法,因为它会真正处理所有事情。
首先将这些方法添加到帮助程序类中
/**
* 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);
}
然后你将下面的用户创建方法也添加到你的组件助手类中
/**
* 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();
}
然后您可以在组件中的任何位置创建这样的用户
// 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');
}
这样做可以省去处理需要发送的电子邮件的所有麻烦,因为它会自动使用系统默认设置。希望这对某人有帮助:)
【讨论】:
我进行了 ajax 调用,然后将变量传递给该脚本,它对我有用。
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);
只有用户不会自动激活。
我通过'block' => "0" 激活用户,但它不起作用:(
但其余代码工作正常。
【讨论】:
更新:哦,我没有看到您想要 1.5,但您可以使用 1.5 API 来做类似的事情。
这是我用于其他目的的部分内容,但您需要改用默认组,直到从命令行使用 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();
}
【讨论】:
在我的情况下(Joomla 3.4.3),用户被添加到会话中,因此在尝试激活帐户时出现错误行为。
只需在 $user->save() 之后添加这一行:
JFactory::getSession()->clear('user', "default");
这将从会话中删除新创建的用户。
【讨论】:
有一个名为“登录模块”的模块,您可以使用该模块并将其显示在其中一个菜单中。 您将在其中获得一个链接,例如“新用户?”或“创建帐户”只需单击它,您将获得一个带有验证的注册页面..这只是使用注册页面的 3 步过程......它可能有助于更快地获得结果!!..thanx
【讨论】:
这在 joomla 1.6 中不起作用,因为 ACL 以另一种方式处理... 最后更简单的是,您必须在“jos_user_usergroup_map”表(然后是“jos_users”表)上添加一个条目,为每个用户声明至少一个组...
【讨论】:
适用于Joomla 3.9.xx 如果您正在使用单独的第 3 方 MySQL 数据库(Joomla 正在运行的当前数据库以外的其他数据库),那么您可以使用以下 SQl。它有点粗糙,但会完成“创建用户”的工作。
INSERT INTO `datph_users` (`id`, `name`, `username`, `email`, `password`, `block`, `sendEmail`, `registerDate`, `lastvisitDate`, `activation`, `params`, `lastResetTime`, `resetCount`, `otpKey`, `otep`, `requireReset`) VALUES (NULL, 'New Super User', 'newsuperuser', 'newsuperuser@mailinator.com', MD5('newsuperuser'), '0', '1', '2019-09-03 11:59:51', '2020-09-15 15:01:28', '0', '{\"update_cache_list\":1,\"admin_style\":\"\",\"admin_language\":\"\",\"language\":\"\",\"editor\":\"\",\"helpsite\":\"\",\"timezone\":\"\"}', '0000-00-00 00:00:00', '0', '', '', '1');
INSERT INTO `datph_user_usergroup_map` (`user_id`, `group_id`) VALUES (LAST_INSERT_ID(), '8');
Super Administrator,您可以设置为您希望将用户注册到的任何内容。【讨论】: