Esempio n. 1
0
/**
 * This function inserts the default data on new installs
 */
function createuser($username, $password, $email)
{
    if (!class_exists('Users_Constant')) {
        require_once 'system/Users/Constants.php';
    }
    $connection = Doctrine_Manager::connection();
    // get the database connection
    ModUtil::dbInfoLoad('Users', 'Users');
    ModUtil::dbInfoLoad('Extensions', 'Extensions');
    $dbtables = DBUtil::getTables();
    // create the password hash
    $password = UserUtil::getHashedPassword($password);
    // prepare the data
    $username = mb_strtolower(DataUtil::formatForStore($username));
    $password = DataUtil::formatForStore($password);
    $email = mb_strtolower(DataUtil::formatForStore($email));
    $nowUTC = new DateTime(null, new DateTimeZone('UTC'));
    $nowUTCStr = $nowUTC->format(Users_Constant::DATETIME_FORMAT);
    // create the admin user
    $sql = "UPDATE {$dbtables['users']}\n            SET   uname        = '{$username}',\n                  email        = '{$email}',\n                  pass         = '******',\n                  activated    = 1,\n                  user_regdate = '{$nowUTCStr}',\n                  lastlogin    = '******'\n            WHERE uid   = 2";
    $result = DBUtil::executeSQL($sql);
    return $result ? true : false;
}
Esempio n. 2
0
 public function processRecoveryPassword()
 {
     // get variables
     $username = $this->INPUT['zuname'];
     $password1 = $this->INPUT['zpass1'];
     $password2 = $this->INPUT['zpass2'];
     // check that username is not empty
     if (empty($username)) {
         $this->setError(__('Username cannot be empty'));
         return false;
     }
     // check that password is not empty
     if (empty($password1)) {
         $this->setError(__('Password cannot be empty'));
         return false;
     }
     // check that passwords match
     if ($password1 != $password2) {
         $this->setError(__('Passwords do not match'));
         return false;
     }
     // check that username is not the anonymous one
     $anonymous = ModUtil::getVar('Users', 'anonymous');
     if ($username == $anonymous || $username == strtolower($anonymous)) {
         $this->setError(__('You cannot change the password for the anonymous user. Please provide the username of a valid user'));
         return false;
     }
     $table = DBUtil::getTables();
     $userstable = $table['users'];
     $userscolumn = $table['users_column'];
     // check that username exists
     $uid = DBUtil::selectField('users', 'uid', $userscolumn['uname'] . "='" . $username . "'");
     if (!$uid) {
         $this->setError(__('The username you supplied is not valid'));
         return false;
     }
     // hash the password and check if it is valid
     $password = UserUtil::getHashedPassword($password1);
     if (!$password) {
         $this->setError(__('The password you supplied is not valid'));
         return false;
     }
     // update the password
     // create the object
     $obj = array('uid' => $uid, 'pass' => $password);
     // perform update
     if (!DBUtil::updateObject($obj, 'users', '', 'uid')) {
         $this->setError(__('Error resetting the password'));
         return false;
     }
     // Set a status message.
     $this->setStatus(__('The password was successfully reset'));
     // Recovery successful.
     return true;
 }
Esempio n. 3
0
    /**
     * Creates, saves and sends a registration e-mail address verification code.
     *
     * Parameters passed in the $args array:
     * -------------------------------------
     * array   $args['reginfo']      An array containing a valid registration record; optional; if not set, then $args['uid'] must
     *                                      be set and point to a valid registration record.
     * numeric $args['uid']          The uid of a valid registration record; optional; if not set, then $args['reginfo'] must be set and valid.
     * boolean $args['force']        Indicates that a verification code should be sent, even if the Users module configuration is
     *                                      set not to verify e-mail addresses; optional; only has an effect if the current user is
     *                                      an administrator.
     * array   $args['rendererArgs'] Optional arguments to send to the Zikula_View instance while rendering the e-mail message.
     *
     * @param array $args All parameters passed to this function.
     *
     * @return bool True on success; otherwise false.
     *
     * @throws Zikula_Exception_Forbidden Thrown if the user is not logged in and does not have read access, or if the user is logged in
     *                                      and does not have moderate access.
     */
    public function sendVerificationCode($args)
    {
        // In the future, it is possible we will add a feature to allow a newly registered user to resend
        // a new verification code to himself after doing a login-like process with information from  his
        // registration record, so allow not-logged-in plus READ, as well as moderator.
        if ((!UserUtil::isLoggedIn() && !SecurityUtil::checkPermission('Users::', '::', ACCESS_READ))
                || (UserUtil::isLoggedIn() && !SecurityUtil::checkPermission('Users::', '::', ACCESS_MODERATE))) {
            throw new Zikula_Exception_Forbidden();
        }

        if (isset($args['reginfo'])) {
            // Got a full reginfo record
            if (!is_array($args['reginfo'])) {
                $this->registerError(LogUtil::getErrorMsgArgs());

                return false;
            }
            $reginfo = $args['reginfo'];
            if (!$reginfo || !is_array($reginfo) || !isset($reginfo['uid']) || !is_numeric($reginfo['uid'])) {
                $this->registerError(LogUtil::getErrorMsgArgs());

                return false;
            }
        } elseif (!isset($args['uid']) || !is_numeric($args['uid']) || ((int)$args['uid'] != $args['uid'])) {
            $this->registerError(LogUtil::getErrorMsgArgs());

            return false;
        } else {
            // Got just a uid.
            $reginfo = UserUtil::getVars($args['uid'], false, 'uid', true);
            if (!$reginfo || empty($reginfo)) {
                $this->registerError($this->__f('Error! Unable to retrieve registration record with uid \'%1$s\'', $uid));

                return false;
            }
            if (!isset($reginfo['email'])) {
                $this->registerError($this->__f('Error! The registration record with uid \'%1$s\' does not contain an e-mail address.', $uid));

                return false;
            }
        }

        if ($this->currentUserIsAdmin() && isset($args['force']) && $args['force']) {
            $forceVerification = true;
        } else {
            $forceVerification = false;
        }

        if (isset($args['rendererArgs']) && is_array($args['rendererArgs'])) {
            $rendererArgs = $args['rendererArgs'];
        } else {
            $rendererArgs = array();
        }

        $approvalOrder = $this->getVar('moderation_order', Users_Constant::APPROVAL_BEFORE);

        // Set the verification code
        if (isset($reginfo['isverified']) && $reginfo['isverified']) {
            $this->registerError($this->__f('Error! A verification code cannot be sent for the registration record for \'%1$s\'. It is already verified.', $reginfo['uname']));

            return false;
        } elseif (!$forceVerification && ($approvalOrder == Users_Constant::APPROVAL_BEFORE) && isset($reginfo['approvedby']) && !empty($reginfo['approved_by'])) {
            $this->registerError($this->__f('Error! A verification code cannot be sent for the registration record for \'%1$s\'. It must first be approved.', $reginfo['uname']));

            return false;
        }

        $nowUTC = new DateTime(null, new DateTimeZone('UTC'));
        $verificationCode = UserUtil::generatePassword();

        ModUtil::apiFunc($this->name, 'user', 'resetVerifyChgFor', array(
            'uid'       => $reginfo['uid'],
            'changetype'=> Users_Constant::VERIFYCHGTYPE_REGEMAIL,
        ));

        $verifyChgObj = array(
            'changetype'=> Users_Constant::VERIFYCHGTYPE_REGEMAIL,
            'uid'       => $reginfo['uid'],
            'newemail'  => $reginfo['email'],
            'verifycode'=> UserUtil::getHashedPassword($verificationCode),
            'created_dt'=> $nowUTC->format(Users_Constant::DATETIME_FORMAT),
        );
        $verifyChgObj = DBUtil::insertObject($verifyChgObj, 'users_verifychg');

        if (!$verifyChgObj) {
            $this->registerError($this->__f('Error! Unable to save the verification code for the registration for \'%1$s\'.', $reginfo['uname']));

            return false;
        }

        if (empty($rendererArgs)) {
            $siteurl   = System::getBaseUrl();

            $rendererArgs = array();
            $rendererArgs['sitename'] = System::getVar('sitename');
            $rendererArgs['siteurl'] = substr($siteurl, 0, strlen($siteurl)-1);
        }
        $rendererArgs['reginfo'] = $reginfo;
        $rendererArgs['verifycode'] = $verificationCode;
        $rendererArgs['approvalorder'] = $approvalOrder;

        $codeSent = ModUtil::apiFunc($this->name, 'user', 'sendNotification', array(
            'toAddress'         => $reginfo['email'],
            'notificationType'  => 'regverifyemail',
            'templateArgs'      => $rendererArgs,
        ));

        if ($codeSent) {
            return $verifyChgObj['created_dt'];
        } else {
            DBUtil::deleteObject($verifyChgObj, 'users_verifychg');

            return false;
        }
    }
Esempio n. 4
0
    /**
     * Save the preliminary user e-mail until user's confirmation.
     *
     * Parameters passed in the $args array:
     * -------------------------------------
     * string $args['newemail'] The new e-mail address to store pending confirmation.
     *
     * @param array $args All parameters passed to this function.
     *
     * @return bool True if success and false otherwise.
     *
     * @throws Zikula_Exception_Forbidden Thrown if the current user is logged in.
     */
    public function savePreEmail($args)
    {
        if (!UserUtil::isLoggedIn()) {
            throw new Zikula_Exception_Forbidden();
        }

        $dbinfo = DBUtil::getTables();
        $verifychgColumn = $dbinfo['users_verifychg_column'];

        $nowUTC = new DateTime(null, new DateTimeZone('UTC'));

        $uid = UserUtil::getVar('uid');
        $uname = UserUtil::getVar('uname');

        // generate a randomize value of 7 characters needed to confirm the e-mail change
        $confirmCode = UserUtil::generatePassword();
        $confirmCodeHash = UserUtil::getHashedPassword($confirmCode);

        $obj = array(
            'changetype'    => Users_Constant::VERIFYCHGTYPE_EMAIL,
            'uid'           => $uid,
            'newemail'      => DataUtil::formatForStore($args['newemail']),
            'verifycode'    => $confirmCodeHash,
            'created_dt'    => $nowUTC->format(Users_Constant::DATETIME_FORMAT),
        );

        DBUtil::deleteWhere('users_verifychg',
            "({$verifychgColumn['uid']} = {$uid}) AND ({$verifychgColumn['changetype']} = " . Users_Constant::VERIFYCHGTYPE_EMAIL . ")");
        $obj = DBUtil::insertObject($obj, 'users_verifychg', 'id');

        if (!$obj) {
            return false;
        }

        // send confirmation e-mail to user with the changing code
        $subject = $this->__f('Confirmation change of e-mail for %s', $uname);

        $view = Zikula_View::getInstance($this->name, false);
        $viewArgs = array(
            'uname'     => $uname,
            'email'     => UserUtil::getVar('email'),
            'newemail'  => $args['newemail'],
            'sitename'  => System::getVar('sitename'),
            'url'       =>  ModUtil::url($this->name, 'user', 'confirmChEmail', array('confirmcode' => $confirmCode), null, null, true),
        );
        $view->assign($viewArgs);

        $message = $view->fetch('users_email_userverifyemail_html.tpl');
        $sent = ModUtil::apiFunc('Mailer', 'user', 'sendMessage', array(
            'toaddress' => $args['newemail'],
            'subject'   => $subject,
            'body'      => $message,
            'html'      => true
        ));

        if (!$sent) {
            return false;
        }

        return true;
    }
Esempio n. 5
0
 /**
  * This function inserts the admin's user data
  */
 private function updateAdmin()
 {
     $em = $this->container->get('doctrine.entitymanager');
     $params = $this->decodeParameters($this->yamlManager->getParameters());
     // create the password hash
     $password = \UserUtil::getHashedPassword($params['password'], \UserUtil::getPasswordHashMethodCode(UsersConstant::DEFAULT_HASH_METHOD));
     // prepare the data
     $username = mb_strtolower($params['username']);
     $nowUTC = new \DateTime(null, new \DateTimeZone('UTC'));
     $nowUTCStr = $nowUTC->format(UsersConstant::DATETIME_FORMAT);
     /** @var \Zikula\Module\UsersModule\Entity\UserEntity $entity */
     $entity = $em->find('ZikulaUsersModule:UserEntity', 2);
     $entity->setUname($username);
     $entity->setEmail($params['email']);
     $entity->setPass($password);
     $entity->setActivated(1);
     $entity->setUser_Regdate($nowUTCStr);
     $entity->setLastlogin($nowUTCStr);
     $em->persist($entity);
     $em->flush();
     return true;
 }
Esempio n. 6
0
    /**
     * Render and process a registration e-mail verification code.
     *
     * This function will render and display to the user a form allowing him to enter
     * a verification code sent to him as part of the registration process. If the user's
     * registration does not have a password set (e.g., if an admin created the registration),
     * then he is prompted for it at this time. This function also processes the results of
     * that form, setting the registration record to verified (if appropriate), saving the password
     * (if provided) and if the registration record is also approved (or does not require it)
     * then a new user account is created.
     *
     * Parameters passed via GET:
     * --------------------------
     * string uname      The user name of the user who is verifying his e-mail address for registration.
     * string verifycode The code sent to the user in order to verify his e-mail address.
     *
     * Parameters passed via POST:
     * ---------------------------
     * string uname           The user name of the user who is verifying his e-mail address for registration.
     * string verifycode      The code sent to the user in order to verify his e-mail address.
     * string newpass         If the user needs to set his password (the admin created the account record and did not create a password
     *                              at that time), then this contains the user's new password.
     * string newpassagain    The new password repeated for verification.
     * string newpassreminder The new password reminder.
     *
     * Parameters passed via SESSION:
     * ------------------------------
     * None.
     *
     * @return string|bool The rendered template; true on redirect; false on error.
     */
    public function verifyRegistration()
    {
        if (UserUtil::isLoggedIn()) {
            $this->registerError($this->__('Sorry! An account cannot be verified while you are logged in.'))
                    ->redirect(ModUtil::url($this->name, 'user', 'main'));
        }

        if ($this->request->isGet()) {
            $uname      = $this->request->query->get('uname', '');
            $verifycode = $this->request->query->get('verifycode', '');
        } elseif ($this->request->isPost()) {
            $this->checkCsrfToken();
            $uname          = $this->request->request->get('uname', '');
            $verifycode     = $this->request->request->get('verifycode', '');
            $newpass        = $this->request->request->get('newpass', '');
            $newpassagain   = $this->request->request->get('newpassagain', '');
            $newpassreminder= $this->request->request->get('newpassreminder', '');
        } else {
            throw new Zikula_Exception_Forbidden();
        }

        if ($uname) {
            $uname = mb_strtolower($uname);
        }
        $setPass = false;

        if ($uname && $verifycode) {
            // Both a user name and verification code were submitted

            $reginfo = ModUtil::apiFunc($this->name, 'registration', 'get', array('uname' => $uname));

            if ($reginfo) {
                if (!isset($reginfo['pass']) || empty($reginfo['pass'])) {
                    $setPass = true;

                    if ($this->request->isPost()) {
                        $passwordErrors = ModUtil::apiFunc($this->name, 'registration', 'getPasswordErrors', array(
                            'uname'         => $uname,
                            'pass'          => $newpass,
                            'passagain'     => $newpassagain,
                            'passreminder'  => $newpassreminder,
                        ));

                        if (empty($passwordErrors)) {
                            $newpassHash = UserUtil::getHashedPassword($newpass);;
                            $passSaved = UserUtil::setVar('pass', $newpassHash, $reginfo['uid']);
                            if (!$passSaved) {
                                $this->registerError($this->__('Sorry! There was an error while trying to save your new password and reminder.'));
                            } else {
                                $reginfo['pass'] = $newpassHash;
                            }

                            $passReminderSaved = UserUtil::setVar('passreminder', $newpassreminder, $reginfo['uid']);
                            if (!$passReminderSaved) {
                                $this->registerError($this->__('Sorry! There was an error while trying to save your new password and reminder.'));
                            } else {
                                $reginfo['passreminder'] = $newpassreminder;
                            }
                        }
                    }
                }

                if ($verifycode && $reginfo && isset($reginfo['pass']) && !empty($reginfo['pass'])) {
                    $verifyChg = ModUtil::apiFunc($this->name, 'registration', 'getVerificationCode', array(
                        'uid'   => $reginfo['uid'],
                    ));

                    if ($verifyChg) {
                        $codesMatch = UserUtil::passwordsMatch($verifycode, $verifyChg['verifycode']);

                        if ($codesMatch) {
                            $verified = ModUtil::apiFunc($this->name, 'registration', 'verify', array('reginfo' => $reginfo));

                            if ($verified) {

                                if (isset($verified['regErrors']) && count($verified['regErrors']) > 0) {
                                    $regErrorsMessage = $this->__('There were some problems detected during the verification process. Please contact the site administrator regarding the status of your verification.');
                                    $this->view->assign('regErrors', $verified['regErrors']);
                                }

                                switch ($verified['activated']) {
                                    case Users_Constant::ACTIVATED_PENDING_REG:
                                        if (empty($verified['approved_by'])) {
                                            $message = $this->__('Done! Your account has been verified, and is awaiting administrator approval.');
                                        } else {
                                            $message = $this->__('Done! Your account has been verified. Your registration request is still pending completion. Please contact the site administrator for more information.');
                                        }
                                        $this->registerStatus($message);
                                        if (isset($verified['regErrors']) && count($verified['regErrors']) > 0) {
                                            $this->registerStatus($regErrorsMessage);
                                        }

                                        return $this->view->fetch('users_user_displaystatusmsg.tpl');
                                        break;
                                    case Users_Constant::ACTIVATED_ACTIVE:
                                        $this->registerStatus($this->__('Done! Your account has been verified. You may now log in with your user name and password.'));
                                        if (isset($verified['regErrors']) && count($verified['regErrors']) > 0) {
                                            $this->registerStatus($regErrorsMessage);

                                            return $this->view->fetch('users_user_displaystatusmsg.tpl');
                                        } else {
                                            $this->redirect(ModUtil::url($this->name, 'user', 'login'));
                                        }
                                        break;
                                    default:
                                        $this->registerStatus($this->__('Done! Your account has been verified.'));
                                        $this->registerStatus($this->__('Your new account is not active yet. Please contact the site administrator for more information.'));
                                        if (isset($verified['regErrors']) && count($verified['regErrors']) > 0) {
                                            $this->registerStatus($regErrorsMessage);
                                        }

                                        return $this->view->fetch('users_user_displaystatusmsg.tpl');
                                        break;
                                }
                            } else {
                                if (!$this->request->getSession()->hasMessages(Zikula_Session::MESSAGE_ERROR)) {
                                    $this->registerError($this->__('Sorry! There was an error while marking your registration as verifed. Please contact an administrator.'))
                                            ->redirect(ModUtil::url($this->name, 'user', 'main'));
                                } else {
                                    $this->redirect(ModUtil::url($this->name, 'user', 'main'));
                                }
                            }
                        } else {
                            $this->registerError($this->__('Sorry! The verification code you provided does not match our records. Please check the code, and also check your e-mail for a newer verification code that might have been sent.'));
                        }
                    } elseif ($verifyChg === false) {
                        $this->registerError($this->__('Error! There was a problem retrieving the verification code for comparison.'));

                        return false;
                    } else {
                        $this->registerError($this->__f('Error! There is no pending verification code for \'%1$s\'. Please contact the site administrator.', array($reginfo['uname'])));

                        return false;
                    }
                }
                // No code, or no password. Pass down through to the template rendering.
            } else {
                $this->registerError($this->__('Sorry! A registration does not exist for the user name you provided. Maybe your request has expired? Please check the user name, or contact an administrator.'));
            }
        }

        if (isset($passwordErrors) && !empty($passwordErrors)) {
            $errorInfo = ModUtil::apiFunc($this->name, 'user', 'processRegistrationErrorsForDisplay', array('registrationErrors' => $passwordErrors));
        } else {
            $errorInfo = array();
        }
        $rendererArgs = array(
            'verify_uname'      => $uname,
            'verifycode'        => $verifycode,
            'reginfo'           => isset($reginfo) ? $reginfo : array(),
            'setpass'           => $setPass,
            'newpass'           => isset($newpass) ? $newpass : '',
            'newpassreminder'   => isset($newpassreminder) ? $newpassreminder : '',
            'errormessages'     => (isset($errorInfo['errorMessages']) && !empty($errorInfo['errorMessages'])) ? $errorInfo['errorMessages'] : array(),
        );

        return $this->view->assign($rendererArgs)
                          ->fetch('users_user_verifyregistration.tpl');
    }
Esempio n. 7
0
    /**
     * Add new user accounts from the import process.
     *
     * Parameters passed in the $args array:
     * -------------------------------------
     * array $args['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.
     */
    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'] = Users_Constant::ACTIVATED_PENDING_REG;
            }
        }

        $importValuesDB = $importValues;
        foreach ($importValuesDB as $key => $value) {
            $importValuesDB[$key]['pass'] = UserUtil::getHashedPassword($importValuesDB[$key]['pass']);
        }

        // execute sql to create users
        $result = DBUtil::insertObjectArray($importValuesDB, 'users', 'uid');
        if (!$result) {
            return false;
        }

        // 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) {
            $this->registerError($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.'));

            return false;
        }

        // get available groups
        $allGroups = ModUtil::apiFunc('Groups', 'user', 'getAll');

        // create an array with the groups identities where the user can add other users
        $allGroupsArray = array();
        foreach ($allGroups as $group) {
            if (SecurityUtil::checkPermission('Groups::', $group['name'] . '::' . $group['gid'], ACCESS_EDIT)) {
                $allGroupsArray[] = $group['gid'];
            }
        }

        $groups = array();
        // construct a sql statement with all the inserts to reduce SQL queries
        foreach ($importValues as $value) {
            $groupsArray = explode('|', $value['groups']);
            foreach ($groupsArray as $group) {
                $groups[] = array('uid' => $usersInDB[$value['uname']]['uid'], 'gid' => $group);
            }
        }

        // execute sql to create users
        $result = DBUtil::insertObjectArray($groups, 'group_membership', 'gid', true);
        if (!$result) {
            $this->registerError($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.'));

            return false;
        }

        // check if module Mailer is active
        $modinfo = ModUtil::getInfoFromName('Mailer');
        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'] != Users_Constant::ACTIVATED_PENDING_REG) {
                    $createEvent = new Zikula_Event('user.account.create', $value);
                    $this->eventManager->notify($createEvent);
                } else {
                    $createEvent = new Zikula_Event('user.registration.create', $value);
                    $this->eventManager->notify($createEvent);
                }
                if ($value['activated'] && $value['sendmail']) {
                    $view->assign('email', $value['email']);
                    $view->assign('uname', $value['uname']);
                    $view->assign('pass', $value['pass']);
                    $message = $view->fetch('users_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('Mailer', 'user', 'sendMessage', $sendMessageArgs)) {
                        $this->registerError($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;
    }