We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Model automatic timestamps as seen in Laravel

I really like the automatic timestamps in Laravels models that handle the created_at, updated_at and deleted_at columns of a model.

This means that this:

$user = new User();
$user->name = $this->request->getPost('name');
$user->email = $this->request->getPost('email');
$user->password = !empty($this->request->getPost('password')) ? $this->security->hash($this->request->getPost('password'), 14) : null;
$user->save();

Would generate this in the database:

id, name, email, password, created_at, updated_at, deleted_at
1, Jim, [email protected], $2a$14$ff5L9UWTw3agWhgbpcr..., 2014-03-16 16:16:27, 2014-03-16 16:16:27, NULL

How could (should) this be done in Phalcon?

edited Mar '14

Hi, this way:

class ModelBase extends \Phalcon\Mvc\Model
{

    public function beforeCreate()
    {
        $this->created_at = date("Y-m-d H:i:s");
        $this->updated_at = date("Y-m-d H:i:s");
    }

    public function beforeUpdate()
    {
        $this->updated_at = date("Y-m-d H:i:s");
    }

} 
class User extends ModelBase
{
    public function initialize()
    {
        $this->addBehavior(new SoftDelete(
            array(
                'field' => 'active',
                'value' => 0
            )
        ));
    }
}

You can also use these events:

    public function beforeValidationOnCreate()
    {
        $this->created_at = time(); // Whatever your storage is - I am using integers
        $this->updated_at = time();
    }

    public function beforeValidationOnUpdate()
    {
        $this->updated_at = time();
    }

Or you can use model _preSave method like this:

public function _preSave()
{
    if (!$this->id) {
        $this->created_at = date('Y-m-d H:i:s');
    }
    $this->updated_at = date('Y-m-d H:i:s');
}

But as Karol suggested beforeCreate and beforeUpdate are probably best for this.

Use either a trait or simply a behavior. In the intialize method of your specific model, use the following for the recommended behavior method:

$this->addBehavior(
    new Timestampable(array(
        'beforeCreate' => array(
            'field'  => 'date_created',
            'format' => $this->now(),
        ),
        'beforeUpdate' => array(
            'field'  => 'date_updated',
            'format' => $this->now()
        ),
        'beforeDelete' => array(
            'field'  => 'date_deleted',
            'format' => $this->now()
        ),
    ))
);

now should be something like this:

public function now()
{
    $datetime = new Datetime(
        "now",
        new DateTimeZone(
            $this->getDI()->getConfig()->application->timezone
        )
    );
    return $datetime->format(
        $this
        ->getDi()
        ->getConfig()->database->datetime
    );
}