YII2 create function doesn't send data to database

257 views Asked by At

after my last question I've been working on an invoice in yii2 and came accross a new problem. after you fill in the form and click create it doesn't really do anything except refreshing the page and clearing the product fields, however the personal info like company name and date ect is after the refresh still filled in... also when i check the database nothing happened. could you please take a look at the code below?

the invoice form

    <?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
use kartik\datecontrol\Module;
use kartik\datecontrol\DateControl;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use app\models\Companies;
use app\models\Spokepersons;



/* @var $this yii\web\View */
/* @var $model app\models\Facturen */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="facturen-form">

    <?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>

    <?= $form->field($model, 'company_name')->widget(Select2::classname(), [
    'data' => ArrayHelper::map(Companies::find()->all(), 'company_id', 'company_name'),
    'language' => 'nl',
    'options' => ['placeholder' => 'Selecteer een bedrijf'],
    'pluginOptions' => [
        'allowClear' => true
    ],
])?>

    <?= $form->field($model, 'spokes_person')->widget(Select2::classname(), [
    'data' => ArrayHelper::map(Spokepersons::find()->all(), 'person_id', 'first_name'),
    'language' => 'nl',
    'options' => ['placeholder' => 'Selecteer een contactpersoon'],
    'pluginOptions' => [
        'allowClear' => true
    ],
])?>

    <?= $form->field($model, 'date')->widget(DateControl::classname(), [
    'type' => 'date',
    'ajaxConversion' => true,
    'autoWidget' => true,
    'widgetClass' => '',
    'displayFormat' => 'php:d-F-Y',
    'saveFormat' => 'php:Y-m-d',
    'saveTimezone' => 'UTC',
    'displayTimezone' => 'Europe/Amsterdam',
    'saveOptions' => [
        //'label' => 'Input saved as: ',
       // 'type' => 'text',
        'readonly' => true,
        'class' => 'hint-input text-muted'
    ],
    'widgetOptions' => [
        'pluginOptions' => [
            'autoclose' => true,
            'format' => 'php:d-F-Y'
        ]
    ],
    'language' => 'nl'
]) ?>

    <div class="row"> 
        <div class="panel-body">
             <?php DynamicFormWidget::begin([
                'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
                'widgetBody' => '.container-items', // required: css class selector
                'widgetItem' => '.item', // required: css class
                'limit' => 999, // the maximum times, an element can be cloned (default 999)
                'min' => 1, // 0 or 1 (default 1)
                'insertButton' => '.add-item', // css class
                'deleteButton' => '.remove-item', // css class
                'model' => $modelProducten[0],
                'formId' => 'dynamic-form',
                'formFields' => [
                    'product_id',
                    'product_name',
                    'amount',
                    'price',
                ],
            ]); ?>

            <div class="container-items"><!-- widgetContainer -->
            <?php foreach ($modelProducten as $i => $modelProduct): ?>
                <div class="item panel panel-default"><!-- widgetBody -->
                    <div class="panel-heading">
                        <label class="panel-title pull-left">Product</label>
                        <div class="pull-right">
                            <button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
                            <button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
                        </div>
                        <div class="clearfix"></div>
                    </div>
                    <div class="panel-body">
                        <?php
                            // necessary for update action.
                            if (! $modelProduct->isNewRecord) {
                                echo Html::activeHiddenInput($modelProduct, "[{$i}]id");
                            }
                        ?>
                        <div class="row">
                            <div class="col-sm-3">
                        <?= $form->field($modelProduct, "[{$i}]product_id")->textInput(['maxlength' => true]) ?>
                            </div>
                            <div class="col-sm-3">
                                <?= $form->field($modelProduct, "[{$i}]product_name")->textInput(['maxlength' => true]) ?>
                            </div>
                            <div class="col-sm-3">
                                <?= $form->field($modelProduct, "[{$i}]amount")->textInput(['maxlength' => true]) ?>
                            </div>
                            <div class="col-sm-3">
                                <?= $form->field($modelProduct, "[{$i}]price")->textInput(['maxlength' => true]) ?>
                            </div>
                        </div><!-- .row -->
                    </div>
                </div>
            <?php endforeach; ?>
            </div>
            <?php DynamicFormWidget::end(); ?>
        </div>

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => 'btn btn-primary']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>
</div>

i figured this wasn't the problem because the form works but still it might be handy.

the create function

public function actionCreate()
    {
        $model = new Facturen();
        $modelProducten = [new Producten];
        if ($model->load(Yii::$app->request->post()) && $model->save()) 
        {
            $modelProducten = Model::createMultiple(Producten::classname());
            Model::loadMultiple($modelProducten, Yii::$app->request->post());

            // validate all models
            $valid = $model->validate();
            $valid = Model::validateMultiple($modelProducten) && $valid;

            if ($valid) {
                $transaction = \Yii::$app->db->beginTransaction();
                try {
                    if ($flag = $model->save(false)) {
                        foreach ($modelProducten as $modelProduct) 
                        {
                            $modelProduct->factuur_id = $model->id;
                            if (! ($flag = $modelProduct->save(false))) {
                                $transaction->rollBack();
                                break;
                            }
                        }
                    }
                    if ($flag) {
                        $transaction->commit();
                        return $this->redirect(['view', 'id' => $model->id]);
                    }
                } catch (Exception $e) {
                    $transaction->rollBack();
                }
            }
        } 
        else {
            return $this->render('create', [
                'model' => $model,
                'modelProducten' => (empty($modelProducten)) ? [new Producten] : $modelProducten
            ]);
        }
    }

and finally the Model.php

<?php

namespace app\models;
use Yii;
use yii\helpers\ArrayHelper;

class Model extends \yii\base\Model
{
    /**
     * Creates and populates a set of models.
     *
     * @param string $modelClass
     * @param array $multipleModels
     * @return array
     */
    public static function createMultiple($modelClass, $multipleModels = [])
    {
        $model    = new $modelClass;
        $formName = $model->formName();
        $post     = Yii::$app->request->post($formName);
        $models   = [];

        if (! empty($multipleModels)) {
            $keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
            $multipleModels = array_combine($keys, $multipleModels);
        }

        if ($post && is_array($post)) {
            foreach ($post as $i => $item) {
                if (isset($item['id']) && !empty($item['id']) && isset($multipleModels[$item['id']])) {
                    $models[] = $multipleModels[$item['id']];
                } else {
                    $models[] = new $modelClass;
                }
            }
        }

        unset($model, $formName, $post);

        return $models;
    }
}

I hope you guys can spot the probelm in my code, and please tell me what I did wrong when you find a probelem. I'm trying to learn this framework and don't really want to give up

1

There are 1 answers

4
Kalu On

you are calling $model->save() for the same model twice. the Second instance: if ($flag = $model->save(false)) will return 0 since the second update does not affect any row in the table.
use if ( $model->save(false)!==false) to check if the update was successful instead.