Search code examples
yii2yii2-advanced-appyii2-model

Yii2 Setting read-only property


Good day everyone

When I try to create a client,
I get an error: Setting read-only property: app\models\form\ClientForm::Clientclient

How can I fix this error?

This is my ClientClient(model)

class ClientClient extends \yii\db\ActiveRecord
{
/**
 * {@inheritdoc}
 */
public static function tableName()
{
    return 'client_client';
}
public $clientclients;
/**
 * {@inheritdoc}
 */
public function rules()
{
    return [
        [['age', 'client_id'], 'integer'],
        [['first_name', 'patronymic', 'last_name', 'clientclients'], 'string', 'max' => 255],
    ];
}

/**
 * {@inheritdoc}
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'first_name' => 'First Name',
        'patronymic' => 'Patronymic',
        'last_name' => 'Last Name',
        'age' => 'Age',
        'client_id' => 'Client Id',


    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getClient_id()
{
    return $this->hasOne(ClientPhone::class, ['client_id' => 'id']);
}

public function getPhone()
{
    return $this->hasOne(ClientPhone::class, ['phone_digital' => 'id']);
}
}

This is my ClientForm(model):

class ClientForm extends model
{
private $_client;
private $_phone;


public function rules()
{
    return [
        [['ClientClient'], 'required'],
        [['ClientPhone'], 'safe'],
    ];
}

public function afterValidate()
{
    $error = false;
    if (!$this->ClientClient->validate()) {
         $error = true;
    }
    if (!$this->ClientPhone->validate()) {
        $error = true;
    }
    if ($error) {
        $this->addError(null); // add an empty error to prevent saving
    }
    parent::afterValidate();
}
public function save()
{
    if (!$this->validate()) {
        return false;
    }
    $transaction = Yii::$app->db->beginTransaction();
    if (!$this->ClientClient->save()) {
        $transaction->rollBack();
        return false;
    }
    $this->ClientPhone->client_id = $this->ClientClient->id;
    if (!$this->phone->save(false)) {
        $transaction->rollBack();
        return false;
    }
    $transaction->commit();
    return true;
}

public function getClientclient()
{
    return $this->_client;
}

public function setClient($client)
{
    if ($client instanceof Client) {
        $this->_client = $client;
    } else if (is_array($client)) {
        $this->_client->setAttributes($client);
    }
}

public function getphone()
{
    if ($this->_phone === null) {
        if ($this->client->isNewRecord) {
            $this->_phone = new Phone();
            $this->_phone->loadDefaultValues();
        } else {
            $this->_phone = $this->client->phone;
        }
    }
    return $this->_phone;
}



public function setPhone($phone)
{
    if (is_array($phone)) {
        $this->phone->setAttributes($phone);
    } elseif ($phone instanceof Phone) {
        $this->_phone = $phone;
    }
}

public function errorSummary($form)
{
    $errorLists = [];
    foreach ($this->getAllModels() as $id => $model) {
        $errorList = $form->errorSummary($model, [
            'header' => '<p>Please fix the following errors for <b>' . $id . '</b></p>',
        ]);
        $errorList = str_replace('<li></li>', '', $errorList); // remove the empty error
        $errorLists[] = $errorList;
    }
    return implode('', $errorLists);
}

private function getAllModels()
{
    return [
        'Client' => $this->client,
        'Phone' => $this->phone,
    ];
}

}

_form

<div class="clientclient-form">

<?php $form = ActiveForm::begin(); ?>

<?= $form->field($clientForm->Clientclient, 'first_name')->textInput(['maxlength' => true]) ?>

<?= $form->field($clientForm->Clientclient, 'patronymic')->textInput(['maxlength' => true]) ?>

<?= $form->field($clientForm->clientphone, 'last_name')->textInput(['maxlength' => true]) ?>

<?= $form->field($clientForm->clientphone, 'phone_digital')->widget( MaskedInput::class, ['mask' => '9999999999'])?>

<?= $form->field($clientForm->Clientclient, 'age')->textInput() ?>

<div class="form-group">
    <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>

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

</div>

and Controller

public function actionCreate()
{
    $clientForm = new ClientForm();
    $clientForm->Clientclient = new ClientClient();
    $clientForm->setAttributes(Yii::$app->request->post());
    if (Yii::$app->request->post() && $clientForm->save()) {
        Yii::$app->getSession()->setFlash('success', 'Clientclient has been created.');
        return $this->redirect(['update', 'id' => $clientForm->Clientclient->id]);
    } elseif (!Yii::$app->request->isPost) {
        $clientForm->load(Yii::$app->request->get());
    }
    return $this->render('create', ['clientForm' => $clientForm]);
}

public function actionUpdate($id)
{
    $clientForm = new ClientForm();
    $clientForm->ClientClients = $this->findModel($id);
    $clientForm->setAttributes(Yii::$app->request->post());
    if (Yii::$app->request->post() && $clientForm->save()) {
        Yii::$app->getSession()->setFlash('success', 'clientClient has been created.');
        return $this->redirect(['update', 'id' => $clientForm->ClientClient->id]);
    } elseif (!Yii::$app->request->isPost) {
        $clientForm->load(Yii::$app->request->get());
    }
    return $this->render('create', ['clientForm' => $clientForm]);
}

Why is Clientclient::tags read-only? And whats the proper way to set a model relationship?


Solution

  • I get an error: Setting read-only property: app\models\form\ClientForm::Clientclient

    You are using Yii getter and setter class methods instead of public properties but only getter method is defined inside your ClientForm class. You need to also add the Setter method:

    public function setClientclient($value)
    {
        $this->_client = $value;
    }
    

    See Concept Properties in official documentation for more details.