Обновления данных при загрузке страницы.

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Обновления данных при загрузке страницы.

Сообщение Artikk »

Здравтсвуйте, как обновить данные без кнопки, т.е. при загрузке страницы?
Контроллер:

Код: Выделить всё

$model = Buy::findOne(['email_code' => $id]);
	if ($model->load(Yii::$app->request->post())) {
		if ($model->save()) {
			return $this->refresh();
		}
	}
Вид:

Код: Выделить всё

<?php $form = ActiveForm::begin([
		'id' => 'contact-form', 
		'options' => ['class' => 'form-horizontal'], 
	]); ?>
	<?echo $form->field($model, 'status_hash')->hiddenInput(['value' => '1'])->label(false); ?>
<?php ActiveForm::end(); ?>
Последний раз редактировалось Artikk 2017.07.16, 14:22, всего редактировалось 2 раза.
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Обновления данных при загрузке страницы.

Сообщение Artikk »

принцип активация регистрации по ссылке через почту.
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Обновления данных при загрузке страницы.

Сообщение Artikk »

оказалось намного проще))
$param = Buy::findOne(['email_code' => $id]);
Yii::$app->db->createCommand('UPDATE buy SET status_hash = 1 WHERE id='.$param->id.' ')->execute();
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Обновления данных при загрузке страницы.

Сообщение ElisDN »

Код: Выделить всё

$param = Buy::findOne(['email_code' => $id]);
$param->updateAttributes(['status_hash' => 1]);
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

Artikk писал(а): 2017.07.16, 13:42 принцип активация регистрации по ссылке через почту.
Решение мне понятно. Но я не понял саму задачу. Проясните, где вам это необходимо? Для чего вы делаете это?
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Обновления данных при загрузке страницы.

Сообщение ElisDN »

girmate писал(а): 2017.07.16, 22:53 Но я не понял саму задачу. Проясните, где вам это необходимо? Для чего вы делаете это?
Подтверждение регистрации по почте. Находим юзера по токену из письма и переключам статус с "Ожидает" на "Активен".
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

ElisDN писал(а): 2017.07.16, 23:25
girmate писал(а): 2017.07.16, 22:53 Но я не понял саму задачу. Проясните, где вам это необходимо? Для чего вы делаете это?
Подтверждение регистрации по почте. Находим юзера по токену из письма и переключам статус с "Ожидает" на "Активен".
Как раз вчера этим занимался. И чтобы далеко не ходить то можно я вопрос, Дмитрий?

Форма регистрации. Юзер заполнил отправил. Если валидна, я делаю:
1) Меняю статус в БД на STATUS_CONFIRM_EMAIL
2) Отправляю юзеру на почту токен

Дмитрий, а чтобы были либо два действия, либо ни одно, то я так понимаю нужны транзакции. Но не пойму что во что заворачивать? То есть если почта не отправилась - то ситуация опасная, юзер не получит токен, а в БД уже запись, что фиг ты с такой же почтой зарегаешься снова. Ну и если БД не обновилась, то нефиг почту слать с токеном, а то зря радоваться будет. Можно кратенький пример?
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Обновления данных при загрузке страницы.

Сообщение ElisDN »

girmate писал(а): 2017.07.16, 23:29 что заворачивать?
Свои операции с проверками if (!$model->save()) и if (!$mail->send()), где бросать throw new \RuntimeException('Ошибка сохранения.'). Так как сам фреймворк исключениями пользоваться не умеет, хотя при этом постоянно лукавит, что он как бы не при делах и никакой персональной архитектуры он разработчику не навязывает.
girmate писал(а): 2017.07.16, 23:29 во что заворачивать?
В:

Код: Выделить всё

Yii::$app->db->transaction(function() {
   ...
});
или вручную в:

Код: Выделить всё

$transaction = Yii::$app->db->beginTtransaction();
try {
    ...
    $transaction->commit();
} catch (\Exception $e) {
    $transaction->rolllback();
    throw $e;
}
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

Но в настоящее время моя моделька в $mail->send() возвращает true или false. Значит мне либо проверять, если false, то кидать исключение, либо генерировать исключение в методе $mail->send()?
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Обновления данных при загрузке страницы.

Сообщение ElisDN »

girmate писал(а): 2017.07.17, 13:00 Но в настоящее время моя моделька в $mail->send() возвращает true или false.
Это я про письмо Yii::$app->mailer->compose()->setTo(...)->send()

Отвыкайте от return true/false и переходите к исключениям, чтобы не было ни куч if-ов снаружи, ни проблем с логами и транзакциями.
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

ElisDN писал(а): 2017.07.17, 13:29
girmate писал(а): 2017.07.17, 13:00 Но в настоящее время моя моделька в $mail->send() возвращает true или false.
Это я про письмо Yii::$app->mailer->compose()->setTo(...)->send()

Отвыкайте от return true/false и переходите к исключениям, чтобы не было ни куч if-ов снаружи, ни проблем с логами и транзакциями.
Я и говорю, что в моей модельке $model-send() идет отправка письма. Вы же рекомендуете бросать исключение.
Значит
girmate писал(а): 2017.07.17, 13:00 ... генерировать исключение в методе $mail->send()?
я правильно понял?
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

Дмитрий, ну вот у меня так в модельке получилось:

Код: Выделить всё

 /**
     * @return User
     * @throws \Exception
     */
    public function signup()
    {

        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();

        $user->status = $user::STATUS_CONFIRM_EMAIL;
        $user->generateEmailConfirmToken();

        $transaction = Yii::$app->db->beginTransaction();
        try {
            $user->save();
            $this->sendEmail($user);
            $transaction->commit();
            return $user;
        } catch (\Exception $e) {
            $transaction->rollback();
            throw $e;
        }
    }


    /**
     * @param User $user
     * @return bool
     */
    private function sendEmail($user)
    {
        if (!Yii::$app
            ->mailer
            ->compose(
                ['html' => 'emailConfirmToken-html', 'text' => 'emailConfirmToken-text'],
                ['user' => $user]
            )
            ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
            ->setTo($this->email)
            ->setSubject('E-mail confirm for ' . Yii::$app->name)
            ->send()
        ) {
            throw new \RuntimeException('Ошибка отправки почты с ключом активации аккаунта.');
        }
        return true;
    }
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

а в контроллере сделал так:

Код: Выделить всё

 public function actionSignup()
    {
        $model = new SignupForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            try {
                if ($user = $model->signup()) {
                    return $this->render('successSignUp', [
                        'model' => $model,
                    ]);
                }
            } catch (\Exception $e) {
              throw $e;
            }
        }
        return $this->render('signup', ['model' => $model,]);
    }
А как передать в вид описание самой ошибки? А не "произошла ошибка сервера".

(добавил позже)
Хотя я понял. Этот зависит от константы YII_DEBUG.
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Обновления данных при загрузке страницы.

Сообщение ElisDN »

girmate писал(а): 2017.07.17, 15:54 А как передать в вид описание самой ошибки? А не "произошла ошибка сервера".

Код: Выделить всё

class SignupForm extends Model
{
    // ...

    public function signup()
    {
        $user = User::requestSignup(
            $this->username,
            $this->email,
            $this->password
        );

        Yii::$app->db->transaction(function () use ($user) {
            $this->saveUser($user);
            $this->sendEmail($user);
        });
    }

    private function saveUser(User $user)
    {
        if (!$user->save()) {
            throw new \RuntimeException('User saving error');
        }
    }

    private function sendEmail(User $user)
    {
        if (!Yii::$app
            ->mailer
            ->compose(
                ['html' => 'emailConfirmToken-html', 'text' => 'emailConfirmToken-text'],
                ['user' => $user]
            )
            ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
            ->setTo($this->email)
            ->setSubject('E-mail confirm for ' . Yii::$app->name)
            ->send()
        ) {
            throw new \RuntimeException('Email sending error.');
        }
    }
}

Код: Выделить всё

class SignupController extends Controller
{
    public function actionSignup()
    {
        $form = new SignupForm();
        if ($form->load(Yii::$app->request->post()) && $form->validate()) {
            try {
                $form->signup();
                Yii::$app->session->setFlash('success', 'Подтвердите Email.');
                return $this->goHome();
            } catch (\Exception $e) {
                throw new ServerErrorHttpException('Ошибка регистрации.', 0, $e);
            }
        }
        return $this->render('signup', [
            'model' => $form,
        ]);
    }
}
Последний раз редактировалось ElisDN 2017.07.17, 19:56, всего редактировалось 1 раз.
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

Дмитрий, здОрово получилось! Только вот это поясните немного:

Код: Выделить всё

$user = User::requestSignup(
            $this->username,
            $this->email,
            $this->password
        );
То есть вы предлагаете создать статический метод requestSignup(), который будет возвращать модель с заполненными атрибутами?
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Обновления данных при загрузке страницы.

Сообщение ElisDN »

girmate писал(а): 2017.07.17, 17:24 То есть вы предлагаете создать статический метод requestSignup(), который будет возвращать модель с заполненными атрибутами?
Да.
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

Ну и последний вопрос, несложный, просто проясните.

1. Если будет выброшено любое из исключений RuntimeException(), то пользователь все равно увидит просто "Ошибка регистрации". Но в логах я увидеть конкретную причину. Это верно?

2. И почему в BadRequestHttpException('Ошибка регистрации.', 0, $e) в параметре 0?, а не 500, например?
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
girmate
Сообщения: 1534
Зарегистрирован: 2015.10.27, 12:52

Re: Обновления данных при загрузке страницы.

Сообщение girmate »

И метод requestSignup таким должен быть?

в модели User:

Код: Выделить всё

public static function requestSignup($username, $email, $password){

        $user = new static();
        $user->username = $username;
        $user->email = $email;
        $user->setPassword($password);
        $user->generateAuthKey();
        $user->status = self::STATUS_CONFIRM_EMAIL;
        $user->generateEmailConfirmToken();

        return $user;

    }
это работает, но может вы не это имели в виду?
Последний раз редактировалось girmate 2017.07.17, 19:58, всего редактировалось 1 раз.
Осторожно! Вы общаетесь с новичком ;)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Обновления данных при загрузке страницы.

Сообщение ElisDN »

girmate писал(а): 2017.07.17, 18:06 Но в логах я увидеть конкретную причину. Это верно?
Да.
girmate писал(а): 2017.07.17, 18:06 И почему...
Поменял на ServerErrorHttpException.
Ответить