コード例 #1
0
ファイル: RegistrationApi.php プロジェクト: Silwereth/core
 /**
  * Creates a new users table record.
  *
  * This is an internal function that creates a new user. External calls to create either a new
  * registration record or a new users record are made to Users_Api_Registration#registerNewUser(), which
  * dispatches either this function or createRegistration(). Users_Api_Registration#registerNewUser() should be the
  * primary and exclusive function used to create either a user record or a registraion, as it knows how to
  * decide which gets created based on the system configuration and the data provided.
  *
  * ATTENTION: This is the proper place to fire an item-created hook for the user account
  * record, even though the physical database record may have been saved previously as a pending
  * registration. See the note in createRegistration().
  *
  * @param array $reginfo                 Contains the data gathered about the user for the registration record.
  * @param bool  $userNotification        Whether the user should be notified of the new registration or not;
  *                                       however if the user's password was created for him, then he will
  *                                       receive at least that notification without regard to this setting.
  * @param bool $adminNotification        Whether the configured administrator notification e-mail address should
  *                                       be sent notification of the new registration.
  * @param string $passwordCreatedForUser The password that was created for the user either automatically or by
  *                                       an administrator (but not by the user himself).
  *
  * @return array|bool The user info, as saved in the users table; false on error.
  *
  * @throws \InvalidArgumentException Thrown if invalid parameters are received.
  * @throws AccessDeniedException Thrown if the current user does not have overview access.
  * @throws \RuntimeException Thrown if the user couldn't be added to the relevant user groups or
  *                                  if the registration couldn't be saved
  */
 protected function createUser(array $reginfo, $userNotification = true, $adminNotification = true, $passwordCreatedForUser = '')
 {
     $currentUserIsAdminOrSubadmin = $this->currentUserIsAdminOrSubAdmin();
     if (!isset($reginfo) || empty($reginfo)) {
         throw new \InvalidArgumentException(__('Invalid arguments array received'));
     }
     // It is only considered 'created by admin' if the reginfo has no id. If it has an id, then the
     // registration record was created by an admin, but this is being created after a verification
     $createdByAdminOrSubAdmin = $currentUserIsAdminOrSubadmin && !isset($reginfo['uid']);
     // Protected method (not callable from the api), so assume that the data has been validated in registerNewUser().
     // Just check some basic things we need directly in this function.
     if (!isset($reginfo['email']) || empty($reginfo['email'])) {
         throw new \InvalidArgumentException(__('Invalid arguments array received'));
     }
     // Check to see if we are getting a record directly from the registration request process, or one
     // from a later step in the registration process (e.g., approval or verification)
     if (!isset($reginfo['uid']) || empty($reginfo['uid'])) {
         // This is a record directly from the registration request process (never been saved before)
         // Protected method (not callable from the api), so assume that the data has been validated in registerNewUser().
         // Just check some basic things we need directly in this function.
         if (!isset($reginfo['isapproved']) || empty($reginfo['isapproved'])) {
             throw new \InvalidArgumentException(__('Invalid arguments array received'));
         }
         // Ensure that no user gets created without a password, and that the password is reasonable (no spaces, salted)
         // If the user is being registered with an authentication method other than one from the Users module, then the
         // password will be the unsalted, unhashed string stored in UsersConstant::PWD_NO_USERS_AUTHENTICATION.
         $hasPassword = isset($reginfo['pass']) && is_string($reginfo['pass']) && !empty($reginfo['pass']);
         if ($reginfo['pass'] === UsersConstant::PWD_NO_USERS_AUTHENTICATION) {
             $hasSaltedPassword = false;
             $hasNoUsersAuthenticationPassword = true;
         } else {
             $hasSaltedPassword = $hasPassword && strpos($reginfo['pass'], UsersConstant::SALT_DELIM) != strrpos($reginfo['pass'], UsersConstant::SALT_DELIM);
             $hasNoUsersAuthenticationPassword = false;
         }
         if (!$hasPassword || !$hasSaltedPassword && !$hasNoUsersAuthenticationPassword) {
             throw new \InvalidArgumentException(__('Invalid arguments array received'));
         }
         $reginfo['uname'] = mb_strtolower($reginfo['uname']);
         $reginfo['email'] = mb_strtolower($reginfo['email']);
         $nowUTC = new \DateTime(null, new \DateTimeZone('UTC'));
         $nowUTCStr = $nowUTC->format(UsersConstant::DATETIME_FORMAT);
         // Finally, save it, but first get rid of some pseudo-properties
         $userObj = $reginfo;
         // Remove some pseudo-properties
         if (isset($userObj['isapproved'])) {
             unset($userObj['isapproved']);
         }
         if (isset($userObj['isverified'])) {
             unset($userObj['isverified']);
         }
         if (isset($userObj['verificationsent'])) {
             unset($userObj['verificationsent']);
         }
         $userObj = $this->cleanFieldsToAttributes($userObj);
         if (isset($userObj['__ATTRIBUTES__']['_Users_isVerified'])) {
             unset($userObj['__ATTRIBUTES__']['_Users_isVerified']);
         }
         $userObj['user_regdate'] = $nowUTCStr;
         if ($createdByAdminOrSubAdmin) {
             // Current user is admin, so admin is creating this registration.
             // See below if moderation is off and user is self-approved
             $userObj['approved_by'] = UserUtil::getVar('uid');
         }
         // Approved date is set no matter what approved_by will become.
         $userObj['approved_date'] = $nowUTCStr;
         // Set activated state as pending registration for now to prevent firing of update hooks after the insert until the
         // activated state is set properly further below.
         $userObj['activated'] = UsersConstant::ACTIVATED_PENDING_REG;
         // store user's attributes to a variable.
         // we will persist them to the database after the user record is created
         $attributes = $userObj['__ATTRIBUTES__'];
         unset($userObj['__ATTRIBUTES__']);
         $user = new \Zikula\UsersModule\Entity\UserEntity();
         $user->merge($userObj);
         $this->entityManager->persist($user);
         $this->entityManager->flush();
         // store attributes also
         foreach ($attributes as $attr_key => $attr_value) {
             $user->setAttribute($attr_key, $attr_value);
         }
         // NOTE: See below for the firing of the item-create hook.
         $userObj = $user->toArray();
         if ($userObj) {
             if (!$createdByAdminOrSubAdmin) {
                 // Current user is not admin, so moderation is off and user "self-approved" through the registration process
                 // We couldn't do this above because we didn't know the uid.
                 $user['approved_by'] = $userObj['uid'];
                 $this->entityManager->flush();
             }
             $reginfo['uid'] = $userObj['uid'];
         }
     } else {
         // This is a record from intermediate step in the registration process (e.g. verification or approval)
         // Protected method (not callable from the api), so assume that the data has been validated in registerNewUser().
         // Just check some basic things we need directly in this function.
         if (!isset($reginfo['approved_by']) || empty($reginfo['approved_by'])) {
             throw new \InvalidArgumentException(__('Invalid arguments array received'));
         }
         $userObj = $reginfo;
         $reginfo['isapproved'] = true;
         // delete attribute from user without using UserUtil::delVar
         // so that we don't get an update event. (Create hasn't happened yet.);
         $user = $this->entityManager->find('ZikulaUsersModule:UserEntity', $reginfo['uid']);
         $user->delAttribute('_Users_isVerified');
         // NOTE: See below for the firing of the item-create hook.
     }
     if ($userObj) {
         // Set appropriate activated status. Again, use Doctrine so we don't get an update event. (Create hasn't happened yet.)
         // Need to do this here so that it happens for both the case where $reginfo is coming in new, and the case where
         // $reginfo was already in the database.
         $user = $this->entityManager->find('ZikulaUsersModule:UserEntity', $userObj['uid']);
         $user['activated'] = UsersConstant::ACTIVATED_ACTIVE;
         $userObj['activated'] = UsersConstant::ACTIVATED_ACTIVE;
         // Add user to default group
         $defaultGroup = ModUtil::getVar('ZikulaGroupsModule', 'defaultgroup', false);
         if (!$defaultGroup) {
             throw new \RuntimeException($this->__('Warning! The user account was created, but there was a problem adding the account to the default group.'));
         }
         $groupAdded = ModUtil::apiFunc('ZikulaGroupsModule', 'user', 'adduser', array('gid' => $defaultGroup, 'uid' => $userObj['uid']));
         if (!$groupAdded) {
             throw new \RuntimeException($this->__('Warning! The user account was created, but there was a problem adding the account to the default group.'));
         }
         // Force the reload of the user in the cache.
         $userObj = UserUtil::getVars($userObj['uid'], true);
         // ATTENTION: This is the proper place for the item-create hook, not when a pending
         // registration is created. It is not a "real" record until now, so it wasn't really
         // "created" until now. It is way down here so that the activated state can be properly
         // saved before the hook is fired.
         $createEvent = new GenericEvent($userObj);
         $this->getDispatcher()->dispatch('user.account.create', $createEvent);
         $regErrors = array();
         if ($adminNotification || $userNotification || !empty($passwordCreatedForUser)) {
             $sitename = System::getVar('sitename');
             $siteurl = System::getBaseUrl();
             $approvalOrder = $this->getVar('moderation_order', UsersConstant::APPROVAL_BEFORE);
             $rendererArgs = array();
             $rendererArgs['sitename'] = $sitename;
             $rendererArgs['siteurl'] = substr($siteurl, 0, strlen($siteurl) - 1);
             $rendererArgs['reginfo'] = $reginfo;
             $rendererArgs['createdpassword'] = $passwordCreatedForUser;
             $rendererArgs['admincreated'] = $createdByAdminOrSubAdmin;
             $rendererArgs['approvalorder'] = $approvalOrder;
             $rendererArgs['PWD_NO_USERS_AUTHENTICATION'] = UsersConstant::PWD_NO_USERS_AUTHENTICATION;
             if ($userNotification || !empty($passwordCreatedForUser)) {
                 $notificationSent = ModUtil::apiFunc($this->name, 'user', 'sendNotification', array('toAddress' => $userObj['email'], 'notificationType' => 'welcome', 'templateArgs' => $rendererArgs));
                 if (!$notificationSent) {
                     $loggedErrorMessages = $this->request->getSession()->getMessages(Zikula_Session::MESSAGE_ERROR);
                     $this->request->getSession()->clearMessages(Zikula_Session::MESSAGE_ERROR);
                     foreach ($loggedErrorMessages as $lem) {
                         if (!in_array($lem, $regErrors)) {
                             $regErrors[] = $lem;
                         }
                         $regErrors[] = $this->__('Warning! The welcoming email for the newly created user could not be sent.');
                     }
                 }
             }
             if ($adminNotification) {
                 // mail notify email to inform admin about registration
                 $notificationEmail = $this->getVar('reg_notifyemail', '');
                 if (!empty($notificationEmail)) {
                     $subject = $this->__f('New registration: %s', $userObj['uname']);
                     $notificationSent = ModUtil::apiFunc($this->name, 'user', 'sendNotification', array('toAddress' => $notificationEmail, 'notificationType' => 'regadminnotify', 'templateArgs' => $rendererArgs, 'subject' => $subject));
                     if (!$notificationSent) {
                         $loggedErrorMessages = $this->request->getSession()->getMessages(Zikula_Session::MESSAGE_ERROR);
                         $this->request->getSession()->clearMessages(Zikula_Session::MESSAGE_ERROR);
                         foreach ($loggedErrorMessages as $lem) {
                             if (!in_array($lem, $regErrors)) {
                                 $regErrors[] = $lem;
                             }
                             $regErrors[] = $this->__('Warning! The notification email for the newly created user could not be sent.');
                         }
                     }
                 }
             }
         }
         $userObj['regErrors'] = $regErrors;
         return $userObj;
     } else {
         throw new \RuntimeException($this->__('Unable to store the new user registration record.'));
     }
 }
コード例 #2
0
ファイル: AdminApi.php プロジェクト: Silwereth/core
 /**
  * Add new user accounts from the import process.
  *
  * @param array[] $args {
  *      @type array $importvalues An array of information used to create new user records. Each element of the
  *                                array should represent the minimum information to create a user record, including
  *                                'uname', 'email', 'pass', etc.
  *                      }
  *
  * @param array $args All parameters passed to this function.
  *
  * @return bool True on success; false otherwise.
  *
  * @throws \RuntimeException Thrown if the registration e-mail couldn't be sent or
  *                                  if the users, following addition to the database, couldn't be retrieved again or
  *                                  if the users couldn't be added to any groups
  */
 public function createImport($args)
 {
     // Need add access to call this function
     if (!SecurityUtil::checkPermission("{$this->name}::", '::', ACCESS_ADD)) {
         return false;
     }
     $importValues = $args['importvalues'];
     if (empty($importValues)) {
         return false;
     }
     // Prepare arrays.
     $usersArray = array();
     foreach ($importValues as $key => $value) {
         $usersArray[] = $value['uname'];
         if (!$value['activated']) {
             $importValues[$key]['activated'] = UsersConstant::ACTIVATED_PENDING_REG;
         }
     }
     $importValuesDB = $importValues;
     foreach ($importValuesDB as $key => $value) {
         $importValuesDB[$key]['pass'] = UserUtil::getHashedPassword($importValuesDB[$key]['pass']);
     }
     // create users
     foreach ($importValuesDB as $importValueDB) {
         $user = new \Zikula\UsersModule\Entity\UserEntity();
         $user->merge($importValueDB);
         $this->entityManager->persist($user);
     }
     $this->entityManager->flush();
     // get users. We need the users identities set them into their groups
     $usersInDB = ModUtil::apiFunc($this->name, 'admin', 'checkMultipleExistence', array('valuesarray' => $usersArray, 'key' => 'uname'));
     if (!$usersInDB) {
         throw new \RuntimeException($this->__('Error! The users have been created but something has failed trying to get them from the database. Now all these users do not have group.'));
     }
     // add user to groups
     $error_membership = false;
     foreach ($importValues as $value) {
         $groupsArray = explode('|', $value['groups']);
         foreach ($groupsArray as $group) {
             $adduser = ModUtil::apiFunc('ZikulaGroupsModule', 'user', 'adduser', array('gid' => $group, 'uid' => $usersInDB[$value['uname']]['uid'], 'verbose' => false));
             if (!$adduser) {
                 $error_membership = true;
             }
         }
     }
     if ($error_membership) {
         throw new \RuntimeException($this->__('Error! The users have been created but something has failed while trying to add the users to their groups. These users are not assigned to a group.'));
     }
     // check if module Mailer is active
     $modinfo = ModUtil::getInfoFromName('ZikulaMailerModule');
     if ($modinfo['state'] == ModUtil::TYPE_SYSTEM) {
         $sitename = System::getVar('sitename');
         $siteurl = System::getBaseUrl();
         $view = Zikula_View::getInstance($this->name, false);
         $view->assign('sitename', $sitename);
         $view->assign('siteurl', $siteurl);
         foreach ($importValues as $value) {
             if ($value['activated'] != UsersConstant::ACTIVATED_PENDING_REG) {
                 $createEvent = new GenericEvent($value);
                 $this->getDispatcher()->dispatch('user.account.create', $createEvent);
             } else {
                 $createEvent = new GenericEvent($value);
                 $this->getDispatcher()->dispatch('user.registration.create', $createEvent);
             }
             if ($value['activated'] && $value['sendmail']) {
                 $view->assign('email', $value['email']);
                 $view->assign('uname', $value['uname']);
                 $view->assign('pass', $value['pass']);
                 $message = $view->fetch('Email/importnotify_html.tpl');
                 $subject = $this->__f('Password for %1$s from %2$s', array($value['uname'], $sitename));
                 $sendMessageArgs = array('toaddress' => $value['email'], 'subject' => $subject, 'body' => $message, 'html' => true);
                 if (!ModUtil::apiFunc('ZikulaMailerModule', 'user', 'sendMessage', $sendMessageArgs)) {
                     throw new \RuntimeException($this->__f('Error! A problem has occurred while sending e-mail messages. The error happened trying to send a message to the user %s. After this error, no more messages were sent.', $value['uname']));
                     break;
                 }
             }
         }
     }
     return true;
 }