1. Приветствуем Вас на неофициальном форуме технической поддержки XenForo на русском языке. XenForo - новый и перспективный форумный движок от бывших создателей vBulletin.

1.1.3 Регистрация через сторонний скрипт

Тема в разделе "Вопросы и ответы по XenForo Framework", создана пользователем DoctorBooooom, 15 окт 2012.

Загрузка
  1. DoctorBooooom

    DoctorBooooom Новичок

    Регистрация:
    14.10.12
    Сообщения:
    7
    Симпатии:
    0
    Версия XF:
    1.1.3
    Делаем свой клиент по типу Origin и Steam. Требуется авторизация/регистрация/восстановление пароля через xenForo (База юзеров). Авторизацию смогли написать, используя стандартные классы xf. Однако с регистрацией и восстановлением пароля никак не идет. Вроде нашел 2 класса отвечающие за это:

    Регистрация (library/XenForo/ControllerPublic/Register.php):
    Код:
        /**
        * Registers a new user.
        *
        * @return XenForo_ControllerResponse_Abstract
        */
        public function actionRegister()
        {
            $this->_assertPostOnly();
            $this->_assertRegistrationActive();
     
            $errors = array();
     
            if (!XenForo_Captcha_Abstract::validateDefault($this->_input))
            {
                $errors[] = new XenForo_Phrase('did_not_complete_the_captcha_verification_properly');
            }
     
            $data = $this->_input->filter(array(
                'username'  => XenForo_Input::STRING,
                'email'      => XenForo_Input::STRING,
                'timezone'  => XenForo_Input::STRING,
                'gender'    => XenForo_Input::STRING,
                'dob_day'    => XenForo_Input::UINT,
                'dob_month'  => XenForo_Input::UINT,
                'dob_year'  => XenForo_Input::UINT,
            ));
            $passwords = $this->_input->filter(array(
                'password' => XenForo_Input::STRING,
                'password_confirm' => XenForo_Input::STRING,
            ));
     
            if (XenForo_Dependencies_Public::getTosUrl() && !$this->_input->filterSingle('agree', XenForo_Input::UINT))
            {
                $errors[] = new XenForo_Phrase('you_must_agree_to_terms_of_service');
            }
     
            $options = XenForo_Application::get('options');
     
            $writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
            if ($options->registrationDefaults)
            {
                $writer->bulkSet($options->registrationDefaults, array('ignoreInvalidFields' => true));
            }
            $writer->bulkSet($data);
            $writer->setPassword($passwords['password'], $passwords['password_confirm']);
     
            // if the email corresponds to an existing Gravatar, use it
            if ($options->gravatarEnable && XenForo_Model_Avatar::gravatarExists($data['email']))
            {
                $writer->set('gravatar', $data['email']);
            }
     
            $writer->set('user_group_id', XenForo_Model_User::$defaultRegisteredGroupId);
            $writer->set('language_id', XenForo_Visitor::getInstance()->get('language_id'));
     
            $customFields = $this->_input->filterSingle('custom_fields', XenForo_Input::ARRAY_SIMPLE);
            $customFieldsShown = $this->_input->filterSingle('custom_fields_shown', XenForo_Input::STRING, array('array' => true));
            $writer->setCustomFields($customFields, $customFieldsShown);
     
            $writer->advanceRegistrationUserState();
            $writer->preSave();
     
            if ($options->get('registrationSetup', 'requireDob'))
            {
                // dob required
                if (!$data['dob_day'] || !$data['dob_month'] || !$data['dob_year'])
                {
                    $writer->error(new XenForo_Phrase('please_enter_valid_date_of_birth'), 'dob');
                }
                else
                {
                    $userAge = $this->_getUserProfileModel()->getUserAge($writer->getMergedData(), true);
                    if ($userAge < 1)
                    {
                        $writer->error(new XenForo_Phrase('please_enter_valid_date_of_birth'), 'dob');
                    }
                    else if ($userAge < intval($options->get('registrationSetup', 'minimumAge')))
                    {
                        // TODO: set a cookie to prevent re-registration attempts
                        $errors[] = new XenForo_Phrase('sorry_you_too_young_to_create_an_account');
                    }
                }
            }
     
            $errors = array_merge($errors, $writer->getErrors());
     
            if ($errors)
            {
                $fields = $data;
                $fields['tos'] = $this->_input->filterSingle('agree', XenForo_Input::UINT);
                $fields['custom_fields'] = $customFields;
                return $this->_getRegisterFormResponse($fields, $errors);
            }
     
            $writer->save();
     
            $user = $writer->getMergedData();
     
            // log the ip of the user registering
            XenForo_Model_Ip::log($user['user_id'], 'user', $user['user_id'], 'register');
     
            if ($user['user_state'] == 'email_confirm')
            {
                $this->_getUserConfirmationModel()->sendEmailConfirmation($user);
            }
     
            XenForo_Application::get('session')->changeUserId($user['user_id']);
            XenForo_Visitor::setup($user['user_id']);
     
            $viewParams = array(
                'user' => $user
            );
     
            return $this->responseView(
                'XenForo_ViewPublic_Register_Process',
                'register_process',
                $viewParams,
                $this->_getRegistrationContainerParams()
            );
        }
    Восстановление пароля (library/XenForo/ControllerPublic/LostPassword.php):
    Код:
        /**
        * Submits a lost password reset request.
        *
        * @return XenForo_ControllerResponse_Abstract
        */
        public function actionLost()
        {
            if (XenForo_Visitor::getUserId())
            {
                return $this->responseRedirect(
                    XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL,
                    XenForo_Link::buildPublicLink('index')
                );
            }
     
            $this->_assertPostOnly();
     
            $options = XenForo_Application::get('options');
     
            if ($options->lostPasswordCaptcha)
            {
                if (!XenForo_Captcha_Abstract::validateDefault($this->_input))
                {
                    return $this->responseError(new XenForo_Phrase('did_not_complete_the_captcha_verification_properly'));
                }
            }
     
            $usernameOrEmail = $this->_input->filterSingle('username_email', XenForo_Input::STRING);
            $user = $this->_getUserModel()->getUserByNameOrEmail($usernameOrEmail);
            if (!$user)
            {
                return $this->responseError(new XenForo_Phrase('requested_member_not_found'), 404);
            }
     
            $confirmationModel = $this->_getUserConfirmationModel();
     
            if ($options->lostPasswordTimeLimit)
            {
                if ($confirmation = $confirmationModel->getUserConfirmationRecord($user['user_id'], 'password'))
                {
                    $timeDiff = XenForo_Application::$time - $confirmation['confirmation_date'];
     
                    if ($options->lostPasswordTimeLimit > $timeDiff)
                    {
                        $wait = $options->lostPasswordTimeLimit - $timeDiff;
     
                        return $this->responseError(new XenForo_Phrase('must_wait_x_seconds_before_performing_this_action', array('count' => $wait)));
                    }
                }
            }
     
            $confirmationModel->sendPasswordResetRequest($user);
     
            return $this->responseMessage(new XenForo_Phrase('password_reset_request_has_been_emailed_to_you'));
        }
     
        /**
        * Confirms a lost password reset request and resets the password.
        *
        * @return XenForo_ControllerResponse_Abstract
        */
        public function actionConfirm()
        {
            $userId = $this->_input->filterSingle('user_id', XenForo_Input::UINT);
            if (!$userId)
            {
                return $this->responseError(new XenForo_Phrase('no_account_specified'));
            }
     
            $confirmationModel = $this->_getUserConfirmationModel();
     
            $confirmation = $confirmationModel->getUserConfirmationRecord($userId, 'password');
            if (!$confirmation)
            {
                if (XenForo_Visitor::getUserId())
                {
                    // probably already been reset
                    return $this->responseRedirect(
                        XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL,
                        XenForo_Link::buildPublicLink('index')
                    );
                }
                else
                {
                    return $this->responseError(new XenForo_Phrase('your_password_could_not_be_reset'));
                }
            }
     
            $confirmationKey = $this->_input->filterSingle('c', XenForo_Input::STRING);
            if ($confirmationKey)
            {
                $accountConfirmed = $confirmationModel->validateUserConfirmationRecord($confirmationKey, $confirmation);
            }
            else
            {
                $accountConfirmed = false;
            }
     
            if ($accountConfirmed)
            {
                $confirmationModel->resetPassword($userId);
                $confirmationModel->deleteUserConfirmationRecord($userId, 'password');
                XenForo_Visitor::setup(0);
     
                return $this->responseMessage(new XenForo_Phrase('your_password_has_been_reset'));
            }
            else
            {
                return $this->responseError(new XenForo_Phrase('your_password_could_not_be_reset'));
            }
        }
    Можно сделать, конечно, напрямую вставлять в базу пользователей, однако этот вариант хуже (у нас к xf прикручены разные плюшки в виде проверки мультиаккаунтов и т.д.)

    Может кто помочь?
     
  2. Pepelac

    Pepelac Продам луц в бутылках Команда форума

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.348
    Так а в чем проблема-то?
     
  3. DoctorBooooom

    DoctorBooooom Новичок

    Регистрация:
    14.10.12
    Сообщения:
    7
    Симпатии:
    0
    Версия XF:
    1.1.3
    Смотри идею: Я из программы POST запросом отправляю на свой скрипт например
    login="admin"
    pwd="awdawd"
    email="admin@admin.ru"
    ну и другие необходимые данные.

    Дальше мой скрипт должен зарегистрировать пользователя через встроенные классы. Вот как его заставить обращаться к нужным классам? как им передать параметры?

    При авторизации хотя бы была функция (library/XenForo/Authencation/Core.php)
    Код:
    public function authenticate($userId, $password)
        {
            if (!is_string($password) || $password === '' || empty($this->_data))
            {
                return false;
            }
     
            $userHash = $this->_createHash($this->_createHash($password) . $this->_data['salt']);
            return ($userHash === $this->_data['hash']);
        }
    В которую я мог передать данные. А тут куда как и что передавать?
     
  4. Pepelac

    Pepelac Продам луц в бутылках Команда форума

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.348
    Точно так же, как вы через POST запрос отправляете данные из программы вашему скрипту, отправьте данные POST запросом из вашего скрипта на форум (домен/register/register/).

    Или подключите необходимые классы из XF к вашему скрипту и напишите свою регистрацию по образу и подобию метода actionRegister из файла library/XenForo/ControllerPublic/Register.php
     
    DoctorBooooom нравится это.
  5. DoctorBooooom

    DoctorBooooom Новичок

    Регистрация:
    14.10.12
    Сообщения:
    7
    Симпатии:
    0
    Версия XF:
    1.1.3
    А капчу обойди можно?
     
  6. Pepelac

    Pepelac Продам луц в бутылках Команда форума

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.348
    Если пойдете по второму пути — можно
     
  7. DoctorBooooom

    DoctorBooooom Новичок

    Регистрация:
    14.10.12
    Сообщения:
    7
    Симпатии:
    0
    Версия XF:
    1.1.3
    А если по первому? то как можно ее отправит? или отключить проверку например...

    И как определить что регистрация прошла успешно? пользователю ведь не будет показана страница...
     
  8. Pepelac

    Pepelac Продам луц в бутылках Команда форума

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.348
    Немного в сторону вопрос - скажите, какой у вас опыт программирования?

    А так - можно сделать свой хак, который будет предоставлять модифицированную обработку POST запроса. И делать он это будет либо через перегрузку родного метода actionRegister, тогда вы сможете передавать в запросе какой-нибудь параметр, по которому будете определять, откуда пользователь регистрируется. Либо это может быть новый метод actionMyRegister, о котором будете знать только вы и работать будете только с ним. В обоих случаях вы сможете возвращать модифицированный результат выполнения запроса. К примеру - JSON.

    Еще вы можете поднять SOAP службу, которая будет заниматься тем же самым. Все зависит от вашей фантазии, познаний и опыта.
     
    DoctorBooooom нравится это.
  9. DoctorBooooom

    DoctorBooooom Новичок

    Регистрация:
    14.10.12
    Сообщения:
    7
    Симпатии:
    0
    Версия XF:
    1.1.3
    Смотря на чем. В delphi - лет 5 в C++ и PHP/mysql/JS около года

    Спасибо за идею. Вроде понял как сделать.
     
  10. Pepelac

    Pepelac Продам луц в бутылках Команда форума

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.348
    Тогда, я думаю, у вас получится во всем разобраться.
    Я бы на вашем месте выбрал варинт создания SOAP службы — в будущем, если соберетесь добавить чего — будет проще.
     
  11. DoctorBooooom

    DoctorBooooom Новичок

    Регистрация:
    14.10.12
    Сообщения:
    7
    Симпатии:
    0
    Версия XF:
    1.1.3
    Я не знаю что такое SOAP... Пойду гуглить...
     

Поделиться этой страницей