Model not updated due to validation error

Пытаюсь обновить поля status, но оно не обновляется debugger показывает yiidbActiveRecord::update Model not updated due to validation error. смотрю varDumper показывает что поля team_home и team_away должны быть строкой, хотя я их не обновляю и значения не меняются, В чем проблема ? может из-за того что поля являються внешними ключами ? (оба поля я вляються внешними ключами таблицы Team)

Ошибка при обновлений поля [Решено]

SSDD

Сообщения: 43
Зарегистрирован: 2013.11.06, 18:47

Ошибка при обновлений поля [Решено]

Пытаюсь обновить поля status, но оно не обновляется debugger показывает yiidbActiveRecord::update Model not updated due to validation error.
смотрю varDumper показывает что поля team_home и team_away должны быть строкой, хотя я их не обновляю и значения не меняются,
В чем проблема ? может из-за того что поля являються внешними ключами ? (оба поля я вляються внешними ключами таблицы Team)

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

       
$status = 2;
$value = Matches::findOne($id = 23);
$value->status = $status;
$value->update();
 

VarDumper показывает

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

commonmodulesfootballmodelsMatches#1
(
    [
    [yiidbBaseActiveRecord:_attributes] => [
        'id' => 23
        'team_home' => 11
        'team_away' => 16
        'date_time' => '16.08.2014 15:45'
        'status' => 2
        'referee_id' => null
        'season_id' => 4
        'tournament_id' => 1
        'tour_id' => 0
    ]
    [yiidbBaseActiveRecord:_oldAttributes] => [
        'id' => 23
        'team_home' => 11
        'team_away' => 16
        'date_time' => '16.08.2014 15:45'
        'status' => 0
        'referee_id' => null
        'season_id' => 4
        'tournament_id' => 1
        'tour_id' => 0
    ]
    [yiidbBaseActiveRecord:_related] => []
    [yiibaseModel:_errors] => [
        'team_home' => [
            0 => 'Значение «Команда хозяев» должно быть строкой.'
        ]
        'team_away' => [
            0 => 'Значение «Команда гостей» должно быть строкой.'
        ]
    ]
 

Ругаеться на

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

        'team_home' => [
            0 => 'Значение «Команда хозяев» должно быть строкой.'
        ]
        'team_away' => [
            0 => 'Значение «Команда гостей» должно быть строкой.'
        ]

Последний раз редактировалось SSDD 2014.09.12, 19:10, всего редактировалось 1 раз.

SSDD

Сообщения: 43
Зарегистрирован: 2013.11.06, 18:47

Re: Ошибка при обновлений поля

Сообщение

SSDD » 2014.09.12, 17:03

Модель Matches разные варианты пробовал не помогает

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

    public function rules()
    {
        return [
            //['status', 'default', 'value' => 1],
            [['tournament_id', 'team_home', 'team_away', 'date_time', 'tour_id'], 'required'],
            [['team_home', 'team_away', 'date_time'], 'unique', 'targetAttribute' => ['team_home', 'team_away', 'date_time']],
            [['referee_id', 'season_id', 'tournament_id', 'tour_id'], 'integer'],
            [['team_home', 'team_away', 'date_time', 'team_home', 'team_away'], 'string', 'max' => 45],
            ['status', 'in', 'range' => array_keys(self::getStatusArray())]
        ];
    }
 

SSDD

Сообщения: 43
Зарегистрирован: 2013.11.06, 18:47

Re: Ошибка при обновлений поля

Сообщение

SSDD » 2014.09.12, 19:09

Что называеться разул глаза бывает сорри, и спасибо за комент

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

[['team_home', 'team_away', 'date_time', 'team_home', 'team_away'], 'string', 'max' => 45], 

I have been fighting with an «invisible» error.
I am trying to do what I see as a simple update of a field, however the field never gets updated. Strangely, Yii2 doesn’t output any error except for the following log:

info yiidbActiveRecord::update Model not updated due to validation error.

Code in controler:

public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        $scenario = (Yii::$app->user->identity->technology == $id) ? "updateOwner" : "updateGuest";

        $model->scenario = $scenario;
        $function = $scenario."Technology";

        if ($model->load(Yii::$app->request->post()) && $model->validate() && Technology::$function($model)) {
            return  $this->render(['view', 'model' => $model->id]);
        } else {
            return $this->render($scenario, [
                'model' => $model,
            ]);
        }
    }

The function in model:

public function updateGuestTechnology($model){
        $transaction = Yii::$app->db->beginTransaction();
         try 
            {   
                $technology = Technology::findOne($model->id);
                $user = Yii::$app->user->identity;

                $technology->scenario = "updateGuest";
                $technology->bno_coins += $model->bno_coins;
                $technology->bots += $model->bots;
                $technology->save();

                //The user query works just fine.
                $user->scenario = "update";
                $user->bots -= $model->bots;
                $user->bno_coins -= $model->bno_coins;
                $user->save();

                $transaction->commit();
            }
            catch (Exception $e)
            {
                $transaction->rollBack();
                Yii::error("Error during technology update by owner transaction. UserID: {$buyer->id}");
                return false; //Transaction failed
            }
            Yii::info("Technology updated by non-owner! Technology ID: {$technology->id} . UserID: {$user->id}");
            return true;
    }

Scenario:

"updateGuest" => ["bno_coins", "bots"],

Rules for bno_coins and bots:

//bno_coins rules
["bno_coins", "required", "on" => ["create", "updateOwner", "updateGuest"]],
["bno_coins", "integer", "min" => 0, "max" => Yii::$app->user->identity->bno_coins, "on" => ["create", "updateOwner", "updateGuest"]],

//bots rules
["bots", "required", "on" => ["create", "updateOwner", "updateGuest"]],
["bots", "integer", "min" => 0, "max" => Yii::$app->user->identity->bots, "on" => ["create", "updateOwner", "updateGuest"]],

$model->errors; Doesn’t contain any data. It seems that the whole $model doesn’t contain any values (that would explain why the validation fails). However, according to Yii Debugger, the requests contain all necessary information.

using yii ver 2.1.0
unable to attache the file
pasting it here

<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yiidb;

use Yii;
use yiibaseInvalidConfigException;
use yiihelpersArrayHelper;
use yiihelpersInflector;
use yiihelpersStringHelper;

/*
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @author Carsten Brandt <mail@cebe.cc>
 * @since 2.0
 */
class ActiveRecord extends BaseActiveRecord
{
    const OP_INSERT = 0x01;
    const OP_UPDATE = 0x02;
    const OP_DELETE = 0x04;
    const OP_ALL = 0x07;
    public function loadDefaultValues($skipIfSet = true)
    {
        foreach ($this->getTableSchema()->columns as $column) {
            if ($column->defaultValue !== null && (!$skipIfSet || $this->{$column->name} === null)) {
                $this->{$column->name} = $column->defaultValue;
            }
        }
        return $this;
    }

    public static function getDb()
    {
        return Yii::$app->getDb();
    }

    public static function findBySql($sql, $params = [])
    {
        $query = static::find();
        $query->sql = $sql;

        return $query->params($params);
    }

    protected static function findByCondition($condition)
    {
        $query = static::find();

        if (!ArrayHelper::isAssociative($condition)) {
            // query by primary key
            $primaryKey = static::primaryKey();
            if (isset($primaryKey[0])) {
                $pk = $primaryKey[0];
                if (!empty($query->join) || !empty($query->joinWith)) {
                    $pk = static::tableName() . '.' . $pk;
                }
                $condition = [$pk => $condition];
            } else {
                throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
            }
        }

        return $query->andWhere($condition);
    }

    public static function updateAll($attributes, $condition = '', $params = [])
    {
        $command = static::getDb()->createCommand();
        $command->update(static::tableName(), $attributes, $condition, $params);

        return $command->execute();
    }

    public static function updateAllCounters($counters, $condition = '', $params = [])
    {
        $n = 0;
        foreach ($counters as $name => $value) {
            $counters[$name] = new Expression("[[$name]]+:bp{$n}", [":bp{$n}" => $value]);
            $n++;
        }
        $command = static::getDb()->createCommand();
        $command->update(static::tableName(), $counters, $condition, $params);

        return $command->execute();
    }

    public static function deleteAll($condition = '', $params = [])
    {
        $command = static::getDb()->createCommand();
        $command->delete(static::tableName(), $condition, $params);

        return $command->execute();
    }


    public static function find()
    {
        return Yii::createObject(ActiveQuery::className(), [get_called_class()]);
    }


    public static function tableName()
    {
        return '{{%' . Inflector::camel2id(StringHelper::basename(get_called_class()), '_') . '}}';
    }


    public static function getTableSchema()
    {
        $schema = static::getDb()->getSchema()->getTableSchema(static::tableName());
        if ($schema !== null) {
            return $schema;
        } else {
            throw new InvalidConfigException("The table does not exist: " . static::tableName());
        }
    }


    public static function primaryKey()
    {
        return static::getTableSchema()->primaryKey;
    }


    public function attributes()
    {
        return array_keys(static::getTableSchema()->columns);
    }

    public function transactions()
    {
        return [];
    }

    /**
     * @inheritdoc
     */
    public static function populateRecord($record, $row)
    {
        $columns = static::getTableSchema()->columns;
        foreach ($row as $name => $value) {
            if (isset($columns[$name])) {
                $row[$name] = $columns[$name]->phpTypecast($value);
            }
        }
        parent::populateRecord($record, $row);
    }


    public function insert($runValidation = true, $attributes = null)
    {
        if ($runValidation && !$this->validate($attributes)) {
            Yii::info('Model not inserted due to validation error.', __METHOD__);
            return false;
        }

        if (!$this->isTransactional(self::OP_INSERT)) {
            return $this->insertInternal($attributes);
        }

        $transaction = static::getDb()->beginTransaction();
        try {
            $result = $this->insertInternal($attributes);
            if ($result === false) {
                $transaction->rollBack();
            } else {
                $transaction->commit();
            }
            return $result;
        } catch (Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    protected function insertInternal($attributes = null)
    {
        if (!$this->beforeSave(true)) {
            return false;
        }
        $values = $this->getDirtyAttributes($attributes);
        $fdaddy = $attributes[$attributes];
        error_log("HERE HERE : " .  __METHOD__ . "attributes = " . $attributes, 0 );
        if (empty($values)) {
            foreach ($this->getPrimaryKey(true) as $key => $value) {
                $values[$key] = $value;
            }
        }
        if (($primaryKeys = static::getDb()->schema->insert($this->tableName(), $values)) === false) {
            return false;
        }
        foreach ($primaryKeys as $name => $value) {
            $id = $this->getTableSchema()->columns[$name]->phpTypecast($value);
            $this->setAttribute($name, $id);
            $values[$name] = $id;
        }

        $changedAttributes = array_fill_keys(array_keys($values), null);
        $this->setOldAttributes($values);
        $this->afterSave(true, $changedAttributes);

        return true;
    }


    public function update($runValidation = true, $attributeNames = null)
    {
        if ($runValidation && !$this->validate($attributeNames)) {
            Yii::info('Model not updated due to validation error.', __METHOD__);
            return false;
        }

        if (!$this->isTransactional(self::OP_UPDATE)) {
            return $this->updateInternal($attributeNames);
        }

        $transaction = static::getDb()->beginTransaction();
        try {
            $result = $this->updateInternal($attributeNames);
            if ($result === false) {
                $transaction->rollBack();
            } else {
                $transaction->commit();
            }
            return $result;
        } catch (Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    public function delete()
    {
        if (!$this->isTransactional(self::OP_DELETE)) {
            return $this->deleteInternal();
        }

        $transaction = static::getDb()->beginTransaction();
        try {
            $result = $this->deleteInternal();
            if ($result === false) {
                $transaction->rollBack();
            } else {
                $transaction->commit();
            }
            return $result;
        } catch (Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }


    protected function deleteInternal()
    {
        if (!$this->beforeDelete()) {
            return false;
        }

        // we do not check the return value of deleteAll() because it's possible
        // the record is already deleted in the database and thus the method will return 0
        $condition = $this->getOldPrimaryKey(true);
        $lock = $this->optimisticLock();
        if ($lock !== null) {
            $condition[$lock] = $this->$lock;
        }
        $result = $this->deleteAll($condition);
        if ($lock !== null && !$result) {
            throw new StaleObjectException('The object being deleted is outdated.');
        }
        $this->setOldAttributes(null);
        $this->afterDelete();

        return $result;
    }

     public function equals($record)
    {
        if ($this->isNewRecord || $record->isNewRecord) {
            return false;
        }

        return $this->tableName() === $record->tableName() && $this->getPrimaryKey() === $record->getPrimaryKey();
    }

     public function isTransactional($operation)
    {
        $scenario = $this->getScenario();
        $transactions = $this->transactions();

        return isset($transactions[$scenario]) && ($transactions[$scenario] & $operation);
    }
}

Организую загрузку картинок.

Модель:

class Image extends yiidbActiveRecord
{
    public $files;
     public function rules()
    {
        return [
            [[ 'id_actoutrs', 'id_category', 'id_pages', 'id_serial', 'id_user', 'for_home'], 'integer'],
            [['files'], 'file', 'extensions' => 'png, jpg'],
            [['title_alt', 'path', 'name'], 'string', 'max' => 255],
        ];
    }

Представление:

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
    <?= $form->field($model, 'title_alt')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'files[]')->fileInput(['multiple' => true]) ?>
    <?= $form->field($model, 'for_home')->radioList([
        '0' => Yii::t('app','NO'),
        '1' => Yii::t('app','YES')
    ]); ?>

Контролер:

public function actionCreate()
    {
        $model = new Image();
        $class=Yii::$app->request->get("class");
    $feilds =Yii::$app->request->get("feilds");
        $value=Yii::$app->request->get("value");
        if ($model->load(Yii::$app->request->post())) {
            $model->files = UploadedFile::getInstances($model, 'files');
            foreach ($model->files as $file) {
                $files_to = TransliteratorHelper::process($file->name, '', 'en');
                $years=date('Y');
                $mounts=date('m');
                $path =0;
                switch ($class) {
                    case 'category':
                        $path = 'category';
                        break;
                }
                if (file_exists(Yii::getAlias('@frontend/web/').$path.'/'.$years.'/'.$mounts.'/')) {
                } else {
                    mkdir(Yii::getAlias('@frontend/web/').$path.'/'.$years.'/'.$mounts.'/', 0775, true);
                }
                $file->saveAs(Yii::getAlias('@frontend/web/').$path.'/'.$years.'/'.$mounts.'/'.$files_to);
                $model->path=$path.'/'.$years.'/'.$mounts.'/';
                $model->name = $files_to;
                $model->save();
            } 

Дебаг показывает такую ошибку:

20:26:09.879 info yiidbActiveRecord::insert Model not inserted due to validation error.
C:OpenServerdomainsfilm.lcbackendcontrollersImageController.php (98)

print_r( $model->getErrors()) выдает такую ошибку:

Array ( [files] => Array ( [0] => Загрузите файл. ) ) 1

В чем проблема?

kwazaro

When I add comment sometimes appears javascript alert with message «No Reason Phrase». What is this and how can I control this?

Fatal-Errol

The code below

function r(a) {
    return /[\"<>.;]/.exec(a) != null &&
        typeof encodeURIComponent != v ? encodeURIComponent(a) : a
}

and this one:

/?/.test(b) && (b = b.split("?")[1]);

will throw an error:

An Error occurred while handling another error:
exception ‘RuntimeException’ with message ‘Unclosed string at position: 1317283’
in …/vendor/tedivm/jshrink/src/JShrink/Minifier.php:483

The first one is caused by the «unclosed» quote in the regex, not sure about the second one. A temporary fix that I did was to add a comment so that the parser ignores the issue:

function r(a) {
    return /[\"<>.;]/.exec(a) /*"*/ != null &&
        typeof encodeURIComponent != v ? encodeURIComponent(a) : a
}

and

/?/.test(b) /*this is a temp fix for the compressor. removing this comment will cause an error*/
                    && (b = b.split("?")[1]);

This happens when I add FusionCharts.js in my site so other third party libs might cause this as well.

Thanks for the help.

odai-alali

Hi

I am using pretty url’s. http://some-dev-domain.test/comments/index throws NotFoundException.

Where is this route registered?

Gawran

I used your extension to load comments in a modal window. It worked fine and the page is rendered correctly but after submitting new comment and after a «success» response the whole page is reloaded.

As far as I can say it happens because of the PJAX reload but I do not understand why the whole page gets reloaded instead of only PJAX container.

Any thoughts on this issue would be appreciated.

php-wizard

Hello,
i would like to ask if this widget enables users to add comments without neither authenticating nor giving their email.
Just an optional display name, no registration required.

Thanks

Legion112

I’m using advanced environment.
And me need to use it for not authorized users.
Can I do it?

bahrammzm

I have used kartik/treemanager extension model for this extension . Everything work as well for initial node , but when i change the node of tree and after that submit the comment , comment button stuck in «loading…» and shows the below error . although comment saved in database .

capture

nrob81

Hello,

When I delete one parent comment and after that trying to delete it’s child comment, i got a js alert popup, what says only: «Internal Server error».

I know that I not must to delete a childs of a deleted parent, but I can, because there won’t hide after parents deletion.
Maybe it would enough to disable/hide the delete link of the child coments.

in the debug-bar I see only this message: «Model not updated due to validation error.»

Anyway, great module, thanks for that!

aagge

Hi,

Does your widget work when enclosed in ActiveForm? It shows but does not save. Is this expected behavior? Can I make it work within ActiveForm?

<?php echo yii2modcommentswidgetsComment::widget([
         'model' => $model,
             'dataProviderConfig' => [
             'pagination' => [
             'pageSize' => 5
            ],
     ]]); ?>  

andreivadimovich

yii2 advanced (2.0.10-dev)
«yii2mod/yii2-comments»: «dev-master»

Пишу в /common/config/main.php
` ‘modules’ => [

    'comment' => [
        'class' => 'yii2modcommentsModule',
        'enableInlineEdit' => true,

        'controllerMap' => [
            'default' => [
                'class' => 'yii2modcommentscontrollersDefaultController',
                    'on beforeCreate' => ['frontendeventsBonusEvents', 'handleCheckFiveReview'],
                    'on afterCreate' => ['frontendeventsBonusEvents', 'handleAfterFirstComment'],

                    'on afterDelete' => ['frontendeventsBonusEvents', 'handleAfterDeleteComment'],`

beforeCreate , afterCreate — работают. А вот afterDelete не отрабатывает. Как быть ?

ztdan4ik

Hi all!
Thanks for your work with Yii2 Comments Extension. It really great!

Now I found one problem with level in comments tree.
I’m using default model and views.
Problem is, when I edited or delete comment with level > 1, after the action level of edited or deleted comment is upping. And it can be more then maxLevel, so with this case comment not showing.
I think, with that actions level should not up. Am i right?
You can see my short screen video, where I displaying a problem http://i.de-v.net/1504869692.webm

My module configuration is:

        'comment' => [
            'class' => 'yii2modcommentsModule',
            'enableInlineEdit' => true,
            'controllerMap' => [
                'default' => [
                    'class' => 'yii2modcommentscontrollersDefaultController'
                ]
            ]
        ],

Thanks for you answer!

YuriyKvit

We have an entity field in the database with char(10) and when the module name encrypting the length was bigger than it can store, so it`s trimmed. So how i can get fully entity name like «posts», «news» etc …

andrewpros

Hi.
Can someone explain to me whats the whole point of the encryption stuff? Well i get the intentions, probably, but it will not stop any bot software right?

vystepanenko

Hello!
I’m new to yii2 and if you dont mind I’ll ask you some question.
I’m use yii2-advanced template. Added your module via composer. Migrate all migrations without errors. Added to «common/config/main.php» this config string » ‘modules’ => [ ‘comment’ => [ ‘class’ => ‘yii2modcommentsModule’, ],] «

  1. If i havent config RBAC yet(but i have users table with user_role attribute) can I somehow access management section?
  2. Can I somehow make access to management section only from backend? for example backedn.mydomain.com/commets/index ?

aagge

Hi,

I have done the installation and configuration.

In my view after entering data in the comments field and clicking Post nothing saves.

I checked the comment table and there is nothing saved. No error messages. Where can I check?

HankBrown

(1) Setting unknown property: yii2modcommentsModule::enableInlineEdit

    'modules' => [
        // dsm 6 jun 17 : experimental
        'comment' => [
            'class' => 'yii2modcommentsModule',
            // when admin can edit comments on frontend
            // Setting unknown property: yii2modcommentsModule::enableInlineEdit
            //'enableInlineEdit' => false,
        ],

I grep the package for enableInlineEdit and find nothing?


(2)
https://test.mysite.com/index.php?r=/comment/manage/index

SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘a.username’ in ‘field list’

No mention of authors in the readme, no migrations.
A quick attempt to connect it to my user table failed (it wants a defined relation).


I am sorry to post idiot questions, and I suppose I will figure this out.
But if am doing something very stupid please let me know.
It seems like I have a half-baked version?

Looks very good. Thank you.

mtangoo

I had been fighting an error that I could not understand until I looked into sources. In module trait the module is hardcoded as «comment» and I had it as comments. I would prefer a Widget setting where we can pass module name or if it have to remain hardcoded then it should clearly be stated to avoid pains like mine.

Thank you for great extensions. I personally appreciate them

koquipizzi

I am using mdmsoft in order to adminitrate the accesses rules and I can not access to the comment admin.

I have

'admin' => [
           'class' => 'mdmadminModule',
           'layout' => 'left-menu', // defaults to null, using the application's layout without the menu
        ],

and

'authManager' => [
             'class' => 'yiirbacDbManager', 
        ],

What I should do for fix it?
Thanks!

igor-chepurnoi

Create the following list of events:

  • beforeCreate
  • afterCreate
  • beforeDelete
  • afterDelete

carlosgarcia8

I have an event attached to, for example, the reply option, but when a comment is created, everything is reloaded and the event is lost. I see that your comment.js is reloaded every time it creates a comment, how would I add my custom js file to that?

  1 <?php
  2 /**
  3  * @link http://www.yiiframework.com/
  4  * @copyright Copyright (c) 2008 Yii Software LLC
  5  * @license http://www.yiiframework.com/license/
  6  */
  7 
  8 namespace yiibehaviors;
  9 
 10 use yiibaseInvalidCallException;
 11 use yiidbBaseActiveRecord;
 12 
 13 /**
 14  * TimestampBehavior automatically fills the specified attributes with the current timestamp.
 15  *
 16  * To use TimestampBehavior, insert the following code to your ActiveRecord class:
 17  *
 18  * ```php
 19  * use yiibehaviorsTimestampBehavior;
 20  *
 21  * public function behaviors()
 22  * {
 23  *     return [
 24  *         TimestampBehavior::className(),
 25  *     ];
 26  * }
 27  * ```
 28  *
 29  * By default, TimestampBehavior will fill the `created_at` and `updated_at` attributes with the current timestamp
 30  * when the associated AR object is being inserted; it will fill the `updated_at` attribute
 31  * with the timestamp when the AR object is being updated. The timestamp value is obtained by `time()`.
 32  *
 33  * Because attribute values will be set automatically, it's a good idea to make sure `created_at` and `updated_at` aren't
 34  * in `rules()` method of the model.
 35  *
 36  * For the above implementation to work with MySQL database, please declare the columns(`created_at`, `updated_at`) as int(11) for being UNIX timestamp.
 37  *
 38  * If your attribute names are different or you want to use a different way of calculating the timestamp,
 39  * you may configure the [[createdAtAttribute]], [[updatedAtAttribute]] and [[value]] properties like the following:
 40  *
 41  * ```php
 42  * use yiidbExpression;
 43  *
 44  * public function behaviors()
 45  * {
 46  *     return [
 47  *         [
 48  *             'class' => TimestampBehavior::className(),
 49  *             'createdAtAttribute' => 'create_time',
 50  *             'updatedAtAttribute' => 'update_time',
 51  *             'value' => new Expression('NOW()'),
 52  *         ],
 53  *     ];
 54  * }
 55  * ```
 56  *
 57  * In case you use an [[yiidbExpression]] object as in the example above, the attribute will not hold the timestamp value, but
 58  * the Expression object itself after the record has been saved. If you need the value from DB afterwards you should call
 59  * the [[yiidbActiveRecord::refresh()|refresh()]] method of the record.
 60  *
 61  * TimestampBehavior also provides a method named [[touch()]] that allows you to assign the current
 62  * timestamp to the specified attribute(s) and save them to the database. For example,
 63  *
 64  * ```php
 65  * $model->touch('creation_time');
 66  * ```
 67  *
 68  * @author Qiang Xue <[email protected]>
 69  * @author Alexander Kochetov <[email protected]>
 70  * @since 2.0
 71  */
 72 class TimestampBehavior extends AttributeBehavior
 73 {
 74     /**
 75      * @var string the attribute that will receive timestamp value
 76      * Set this property to false if you do not want to record the creation time.
 77      */
 78     public $createdAtAttribute = 'created_at';
 79     /**
 80      * @var string the attribute that will receive timestamp value.
 81      * Set this property to false if you do not want to record the update time.
 82      */
 83     public $updatedAtAttribute = 'updated_at';
 84     /**
 85      * @inheritdoc
 86      *
 87      * In case, when the value is `null`, the result of the PHP function [time()](http://php.net/manual/en/function.time.php)
 88      * will be used as value.
 89      */
 90     public $value;
 91 
 92 
 93     /**
 94      * @inheritdoc
 95      */
 96     public function init()
 97     {
 98         parent::init();
 99 
100         if (empty($this->attributes)) {
101             $this->attributes = [
102                 BaseActiveRecord::EVENT_BEFORE_INSERT => [$this->createdAtAttribute, $this->updatedAtAttribute],
103                 BaseActiveRecord::EVENT_BEFORE_UPDATE => $this->updatedAtAttribute,
104             ];
105         }
106     }
107 
108     /**
109      * @inheritdoc
110      *
111      * In case, when the [[value]] is `null`, the result of the PHP function [time()](http://php.net/manual/en/function.time.php)
112      * will be used as value.
113      */
114     protected function getValue($event)
115     {
116         if ($this->value === null) {
117             returntime(); 
118         }
119         return parent::getValue($event);
120     }
121 
122     /**
123      * Updates a timestamp attribute to the current timestamp.
124      *
125      * ```php
126      * $model->touch('lastVisit');
127      * ```
128      * @param string $attribute the name of the attribute to update.
129      * @throws InvalidCallException if owner is a new record (since version 2.0.6).
130      */
131     public function touch($attribute)
132     {
133         /* @var $owner BaseActiveRecord */
134         $owner = $this->owner;
135         if ($owner->getIsNewRecord()) {
136             throw new InvalidCallException('Updating the timestamp is not possible on a new record.');
137         }
138         $owner->updateAttributes(array_fill_keys((array) $attribute, $this->getValue(null)));
139     }
140 }

The public function init(){} in TimestampBehavior initializes the binding event processing method data

 1 /**
 2      * @inheritdoc
 3      */
 4     public function init()
 5     {
 6         parent::init();
 7 
 8         if (empty($this->attributes)) {
 9             $this->attributes = [
10                 BaseActiveRecord::EVENT_BEFORE_INSERT => [$this->createdAtAttribute, $this->updatedAtAttribute],
11                 BaseActiveRecord::EVENT_BEFORE_UPDATE => $this->updatedAtAttribute,
12             ];
13         }
14     }

TimestampBehavior The events() method in the parent AttributeBehavior executes the handle :evaluateAttributes method for event binding

 1 /**
 2      * @inheritdoc
 3      */
 4     public function events()
 5     {
 6         return array_fill_keys(
 7             array_keys($this->attributes),
 8             'evaluateAttributes'
 9         );
10     }

Event binding method: evaluateAttributes method,

 1  /**
 2      * Evaluates the attribute value and assigns it to the current attributes.
 3      * @param Event $event
 4      */
 5     public function evaluateAttributes($event)
 6     {
 7         if ($this->skipUpdateOnClean
 8             && $event->name == ActiveRecord::EVENT_BEFORE_UPDATE
 9             && empty($this->owner->dirtyAttributes)
10         ) {
11             return;
12         }
13 
14         if (!empty($this->attributes[$event->name])) {
15             $attributes = (array) $this->attributes[$event->name];
16             $value = $this->getValue($event);
17             foreach ($attributes as $attribute) {
18                 // ignore attribute names which are not string (e.g. when set by TimestampBehavior::updatedAtAttribute)
19                 if (is_string($attribute)) {
20                     $this->owner->$attribute = $value;
21                 }
22             }
23         }
24     }

When update or insert save data, save() in BaseActiveRecord.php:

 1 /**
 2      * Saves the current record.
 3      *
 4      * This method will call [[insert()]] when [[isNewRecord]] is true, or [[update()]]
 5      * when [[isNewRecord]] is false.
 6      *
 7      * For example, to save a customer record:
 8      *
 9      * ```php
10      * $customer = new Customer; // or $customer = Customer::findOne($id);
11      * $customer->name = $name;
12      * $customer->email = $email;
13      * $customer->save();
14      * ```
15      *
16      * @param boolean $runValidation whether to perform validation (calling [[validate()]])
17      * before saving the record. Defaults to `true`. If the validation fails, the record
18      * will not be saved to the database and this method will return `false`.
19      * @param array $attributeNames list of attribute names that need to be saved. Defaults to null,
20      * meaning all attributes that are loaded from DB will be saved.
21      * @return boolean whether the saving succeeded (i.e. no validation errors occurred).
22      */
23     public function save($runValidation = true, $attributeNames = null)
24     {
25         if ($this->getIsNewRecord()) {
26             return $this->insert($runValidation, $attributeNames);
27         } else {
28             return $this->update($runValidation, $attributeNames) !== false;
29         }
30     }

Call insert() and update() in ActiveRecord.php:

 1  public function insert($runValidation = true, $attributes = null)
 2     {
 3         if ($runValidation && !$this->validate($attributes)) {
 4             Yii::info('Model not inserted due to validation error.', __METHOD__);
 5             return false;
 6         }
 7 
 8         if (!$this->isTransactional(self::OP_INSERT)) {
 9             return $this->insertInternal($attributes);
10         }
11 
12         $transaction = static::getDb()->beginTransaction();
13         try {
14             $result = $this->insertInternal($attributes);
15             if ($result === false) {
16                 $transaction->rollBack();
17             } else {
18                 $transaction->commit();
19             }
20             return $result;
21         } catch (Exception $e) {
22             $transaction->rollBack();
23             throw $e;
24         }
25     }
26 public function update($runValidation = true, $attributeNames = null)
27     {
28         if ($runValidation && !$this->validate($attributeNames)) {
29             Yii::info('Model not updated due to validation error.', __METHOD__);
30             return false;
31         }
32 
33         if (!$this->isTransactional(self::OP_UPDATE)) {
34             return $this->updateInternal($attributeNames);
35         }
36 
37         $transaction = static::getDb()->beginTransaction();
38         try {
39             $result = $this->updateInternal($attributeNames);
40             if ($result === false) {
41                 $transaction->rollBack();
42             } else {
43                 $transaction->commit();
44             }
45             return $result;
46         } catch (Exception $e) {
47             $transaction->rollBack();
48             throw $e;
49         }
50     }

transferActiveRecord.phpInsideinsertInternal() and updateInternal():

 1 /**
 2      * Inserts an ActiveRecord into DB without considering transaction.
 3      * @param array $attributes list of attributes that need to be saved. Defaults to null,
 4      * meaning all attributes that are loaded from DB will be saved.
 5      * @return boolean whether the record is inserted successfully.
 6      */
 7     protected function insertInternal($attributes = null)
 8     {
 9         if (!$this->beforeSave(true)) {
10             return false;
11         }
12         $values = $this->getDirtyAttributes($attributes);
13         if (($primaryKeys = static::getDb()->schema->insert(static::tableName(), $values)) === false) {
14             return false;
15         }
16         foreach ($primaryKeys as $name => $value) {
17             $id = static::getTableSchema()->columns[$name]->phpTypecast($value);
18             $this->setAttribute($name, $id);
19             $values[$name] = $id;
20         }
21 
22         $changedAttributes = array_fill_keys(array_keys($values), null);
23         $this->setOldAttributes($values);
24         $this->afterSave(true, $changedAttributes);
25 
26         return true;
27     }
28  /**
29      * @see update()
30      * @param array $attributes attributes to update
31      * @return integer number of rows updated
32      * @throws StaleObjectException
33      */
34     protected function updateInternal($attributes = null)
35     {
36         if (!$this->beforeSave(false)) {
37             return false;
38         }
39         $values = $this->getDirtyAttributes($attributes);
40         if (empty($values)) {
41             $this->afterSave(false, $values);
42             return 0;
43         }
44         $condition = $this->getOldPrimaryKey(true);
45         $lock = $this->optimisticLock();
46         if ($lock !== null) {
47             $values[$lock] = $this->$lock + 1;
48             $condition[$lock] = $this->$lock;
49         }
50         // We do not check the return value of updateAll() because it's possible
51         // that the UPDATE statement doesn't change anything and thus returns 0.
52         $rows = static::updateAll($values, $condition);
53 
54         if ($lock !== null && !$rows) {
55             throw new StaleObjectException('The object being updated is outdated.');
56         }
57 
58         if (isset($values[$lock])) {
59             $this->$lock = $values[$lock];
60         }
61 
62         $changedAttributes = [];
63         foreach ($values as $name => $value) {
64             $changedAttributes[$name] = isset($this->_oldAttributes[$name]) ? $this->_oldAttributes[$name] : null;
65             $this->_oldAttributes[$name] = $value;
66         }
67         $this->afterSave(false, $changedAttributes);
68 
69         return $rows;
70     }

Call beforeSave() in BaseActiveRecord.php to trigger$this->trigger($insert ? self::EVENT_BEFORE_INSERT : self::EVENT_BEFORE_UPDATE, $event) Event execution adds the event method bound beforeevaluateAttributes automatically adds attribute values:

1  public function beforeSave($insert)
2     {
3         $event = new ModelEvent;
4         $this->trigger($insert ? self::EVENT_BEFORE_INSERT : self::EVENT_BEFORE_UPDATE, $event);
5 
6         return $event->isValid;
7     }
}

Понравилась статья? Поделить с друзьями:
  • Model not inserted due to validation error
  • Model load error meshes morrowind
  • Model error matlab
  • Mode exception not handled windows 10 как исправить
  • Mode 255 flash status error