Answer the question
In order to leave comments, you need to log in
Data from the form does not fall into the fields of the class instance?
Happy New Year, dear programmers . I'll
try to briefly describe the problem:
I'm writing a website where people can buy tickets for various events.
I am making a page in which tickets are purchased for the selected event, it looks like this
Which corresponds to the view code
Several models come from the controller to this view
The first two AR models that display information about the event and the types of tickets for this event from the database
The third model is the form that is needed for the user to purchase a ticket
<?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'));
}
}
<?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;
}
}
}
}
Answer the question
In order to leave comments, you need to log in
See the documentation for $model->load()
When model attributes are filled in this way, only those for which validation rules are set will be inserted rules
. You have no rules specified in the BuyTicketForm model, for example, for the cost field. That. the value passed through post will come, validation $model->validate()
will pass, but for example it $model->save()
will cause an error if this is a required field in the database.
I did not go into business logic, perhaps some fields should be calculated automatically (then do it in beforeValidate / beforeSave ). But for all passed fields, create appropriate validation rules.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question