@unclenoice
Учусь

Данные с формы не попадают в поля экземпляра класса?

С наступающим новым годом, уважаемые господа программисты
Попробую в кратце описать проблему:
Я пишу сайт, на котором люди могут покупать билеты на различные мероприятия.
Делаю страничку в которой осуществляется покупка билетов на выбранное мероприятие выглядит она так
5e0b5c2d8f127775697167.png
5e0b5c6808003984887265.png
Которой соответсвует код вьюшки
В эту вьюшку из контроллера приходят несколько моделей
Первые две модели AR которые выводят из базы данных инфу о мероприятии и о типах билетов на это мероприятие
Третья модель - форма которая нужна для того чтобы пользователь мог приобрести билет
<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
?>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script type="text/jаvascript">
        $(document).ready(function() {
            $('.minus').click(function () {
                var $input = $(this).parent().find('input');
                var count = parseInt($input.val()) - 1;
                count = count < 1 ? 1 : count;
                $input.val(count);
                $input.change();
                return false;
            });
            $('.plus').click(function () {
                var $input = $(this).parent().find('input');
                $input.val(parseInt($input.val()) + 1);
                $input.change();
                return false;
            });
        });


    </script>
</head>
<body>
<div class="container">
    <div class="row" style="margin-bottom: 3rem;">
        <div class="col-md-3" style="display: flex;flex-direction: column;justify-content: center;align-items: center">
            <h1><?= $event->title ?></h1>
            <div class="event-phohto"
                 style="background-color: #1a1a1a;width: 20rem;height: 14rem;color: white;display:flex;justify-content: center;align-items: center;margin-top: 1rem;margin-bottom: 1rem;">
                Нет фото
            </div>
            <div class="information">
                <?= $event->date ?>
                <?= $event->adress ?>
            </div>
        </div>
        <div class="col-md-6" style="margin-top: 3rem;">
            <p><?= $event->description ?></p>
        </div>
    </div>
    <div class="row">
        <div class="col-md-9">
            <h1>Доступные билеты</h1>
            <table class="table table-dark">
                <thead class="thead-dark">
                <tr>
                    <th>#</th>
                    <th>Тип билета</th>
                    <th>Осталось</th>
                    <th>Количесвто</th>
                    <th>Стоймость</th>
                    <th></th>
                </tr>
                </thead>
                <tbody>
                <? foreach ($events_tickets as $ticket): ?>
                    <? $form = ActiveForm::begin() ?>
                    <tr>
                        <th>
                            <?= $form->field($model, 'event_id')->hiddenInput(['value' => $event->id])->label('') ?>
                        </th>
                        <th>
                            <?php
                            $type = \app\models\TicketType::findOne($ticket->ticket_type_id);
                            echo $form->field($model, 'ticket_type_id')->hiddenInput(['value' => $type->id])->label('');
                            echo $type->type;
                            ?>
                        </th>
                        <th><?= $ticket->amount ?></th>
                        <th>
                            <div class="number">
                                <span class="minus">-</span>
                                <?= $form->field($model, 'amount')->textInput(['value' => 0, 'size' => 1])->label('') ?>
                                <span class="plus">+</span>
                            </div>
                        </th>
                        <th>
                            <?php
                            echo $ticket->cost;
                            echo $form->field($model, 'cost')->hiddenInput(['value' => $ticket->cost])->label('');
                            ?>
                        </th>
                        <th><?= Html::submitButton(
                                'Купить',
                                [//'data' => ['confirm' => 'Вы действительно хотите купить эти билеты?'],
                                    'class' => 'btn btn-success'
                                ])
                            ?>
                        </th>
                    </tr>
                    <? $form = ActiveForm::end() ?>
                <? endforeach; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>

Вот собственно код контроллера (Ничего особенного, все как я описал выше)
<?php

namespace app\controllers;

use app\models\BuyTicketForm;
use app\models\Event;
use Yii;
use yii\web\Controller;
use app\models\SignupForm;
use app\models\LoginForm;
use app\models\User;

class UserController extends Controller
{

    ...


    public function actionBuyTicket($id)
    {
        $event = Event::findOne($id);
        $events_tickets = $event->eventsTickets;
        $model = new BuyTicketForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            if ($model->buy()){
            $this->redirect(['/user/buy-ticket', 'id' => $id]);
        } else {
                die;
            }
        }
        return $this->render('buy-ticket', compact('model', 'event', 'events_tickets'));
    }
}

Форма работает вроде исправно, то есть в _POST'е есть данные которые заполняются в $model(Проходил дебагером)
Вот значит код модели-формы
И вся проблема в том что при вызове метода в модели buy() при обращении к полям модели через $this-> выдает null
Хотя до этого писал формы так же но там они заполнялись данными с формы
<?php

namespace app\models;

use yii\base\Model;
use Yii;


class BuyTicketForm extends Model
{
    public $event_id;
    public $ticket_type_id;
    public $amount;
    public $cost;

    public function rule()
    {
        return [
            [['event_id', 'ticket_type_id',], 'safe'],
            ['amount', 'string', 'max' => 1000000]
        ];
    }

    public function attributeLabels()
    {
        return [
            'amount' => 'Количесвто билетов',
        ];
    }

    public function buy()
    {
        $user_id = Yii::$app->user->id;
        if ($this->amount == 0) {
            return false;
        } else {
            $user = User::findOne($user_id);
            $total = $this->cost * $this->amount;
            if ($user->wallet < $total) {
                $this->addError('У вас не достаточно денег');
            } else {
                $user->wallet = $user->wallet - $total;
                $events_ticket = EventsTicket::findOne([
                    'event_id' => $this->event_id,
                    'ticket_type_id' => $this->ticket_type_id
                ]);
                $events_ticket->amount = $events_ticket->amount - $this->amount;
                for ($i = $this->amount; $i < 0; $this->amount--) {
                    $ticket = new Ticket();
                    $ticket->event_id = $this->event_id;
                    $ticket->ticket_type_id = $this->ticket_type_id;
                    $ticket->save();
                    $users_ticket = new UsersTicket();
                    $users_ticket->user_id = $this->user_id;
                    $users_ticket->ticket_id = $ticket->id;
                    $users_ticket->save();
                }
                return true;
            }
        }
    }
}

В чем баг, уважаемые программисты подскажите если не сложно, я новичок так что не сердчайте пожалуйста если ошибка элементарная
Заранее спасибо
  • Вопрос задан
  • 90 просмотров
Решения вопроса 1
Посмотрите документацию по $model->load()

Когда атрибуты модели заполняются таким образом, то вставятся лишь те, для которых заданы правила валидации rules. У вас в модели BuyTicketForm не указаны правила например для поля cost. Т.о. переданное через post значение придет, валидация $model->validate() пройдет, но например $model->save() вызовет ошибку, если в базе это обязательное поле.

Я не стал вдаваться в бизнес-логику, возможно какие-то поля должны вычисляться автоматически (тогда это делайте в beforeValidate/beforeSave). Но для всех передаваемых полей создавайте соответствующие правила валидации.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы