【问题标题】:How can I create a new Joomla user account from within a script?如何从脚本中创建新的 Joomla 用户帐户?
【发布时间】:2010-12-26 15:55:34
【问题描述】:

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

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

【问题讨论】:

    标签: php joomla joomla1.5


    【解决方案1】:

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

    Two ways to add joomla users using your custom code 是一个很棒的教程。该方法有效。我在一些项目中使用了这种方法。

    如果您必须在外部 Joomla 访问Joomla 框架,check this resource instead

    【讨论】:

    • 链接断开。这就是为什么你应该总是在这里发布代码...... :(
    【解决方案2】:

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

    【讨论】:

    • 感谢您发布此内容,我真的需要了解加密密码存储的最佳方法...并且懒得看 Joomla 核心代码...
    • 很好,但我遇到了一个错误,Αποτυχία ενημέρωσης επαφής: COM_CONTACT_WARNING_SAME_NAME, βοήθα ! :),我正在检查,用户之前不存在。
    • Themi,我不认为我可以用希腊语回复,因为网站规则,并考虑到这些 cmets 应该帮助其他读者的事实。虽然,我相信您面临的问题与联系人组件表有关,并且可能与别名有关。你用谷歌搜索过吗?也许您可以在我的网站上与我联系,以便我们更好地交谈。 (和我的用户名完全一样,加上一个 .com)
    • @mavrosxristoforos 你能解释一下函数中“$cpassword”的使用位置吗?
    • @wardha-Web 我会说它被用于某个秘密功能,但我不会说服任何人! :) 那里似乎不需要那部分,我把它转回数据数组中的 $password 。我可以确认它可以正常工作,但如果您删除第 3 到 5 行,它可能也可以工作。很好,谢谢!
    【解决方案3】:

    只需转到文档页面: 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 或者只是创建带有适当参数的简单表单

    【讨论】:

    • $data['block'] = 1; // 不阻塞用户,应该是 $data['block'] = 0;
    • @molo 我评论太晚了。这会发送 joomla 核心激活电子邮件吗?这也会像以前一样在保存后服从 joomla 用户插件挂钩吗?
    • 代码是如何工作的?您没有包括核心功能。
    【解决方案4】:

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

    【讨论】:

      【解决方案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;
      }
      

      如果您不在 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();
      • @Tom 我不记得我为什么那样做。 new JUser(); 有效吗?如果是这样,那将是一个更好的解决方案。
      【解决方案6】:

      另一种聪明的方法是使用名为 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');
      }
      

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

      【讨论】:

        【解决方案7】:

        我进行了 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' =&gt; "0" 激活用户,但它不起作用:( 但其余代码工作正常。

        【讨论】:

          【解决方案8】:

          更新:哦,我没有看到您想要 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();
          }
          

          【讨论】:

          • 感谢这对 2.5 有帮助。组代码对我不起作用,但我会继续尝试,我认为这是因为我的组的名称为“Foo Bar”,带有空格。我会继续玩它的。任何其他见解都会有所帮助。
          • 哦,你知道吗,我忘了我有一个拉取请求来修复创建组的错误。
          • 该拉取请求最近被合并,将在 3.1 中。
          • @Elin 我需要从 csv 文件中导入一组用户,并希望在此处使用您的代码。但是当我在 Joomla 3.3.6 中尝试时,我收到了类似“显示错误页面时出错:应用程序实例化错误:访问用户组无效”的错误。如果您可以更新您的代码以与 Joomla3.3.x 一起使用,我将不胜感激。谢谢艾琳。
          • 您确定要发送给他们的用户组存在吗?您是否能够运行其他 CLI 应用程序? (尝试在 cli 文件夹中收集垃圾)。我用谷歌搜索了您的错误消息,如果您安装了第三方用户插件,似乎会发生这种情况。你能检查一下吗?如果是这样,您可以暂时禁用它,或者修改我的代码以在 CLI 中禁用它。
          【解决方案9】:

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

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

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

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

          【讨论】:

            【解决方案10】:

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

            【讨论】:

              【解决方案11】:

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

              【讨论】:

              • 配置包括新用户的默认用户组。如果您想要不同的东西,这就是您应该使用或覆盖的内容。
              【解决方案12】:

              适用于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');
              
              • 这些是在 Joomla 中拥有“用户”所需的基本必要细节。请记住相应地更新相应的字段值
              • 此查询将使 CMS 要求用户在首次登录时更新密码,以便在盐和其他东西方面安全
              • 用户组设置为Super Administrator,您可以设置为您希望将用户注册到的任何内容。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2022-12-14
                • 1970-01-01
                • 2018-11-21
                • 1970-01-01
                • 1970-01-01
                • 2011-04-13
                • 1970-01-01
                相关资源
                最近更新 更多