Skip to content

Error when retrieving and unserialising null DateTime fields #47

@matteorebeschi

Description

@matteorebeschi

Hi,
I am using this functionality and I have encountered a bug when I try to retrieve a version of an entry that had a timestamp field with a NULL value.

IE, I have this Model:

<?php

namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * News Model
 */
class NewsTable extends Table
{
    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('news');
        $this->setPrimaryKey('id');

        $this->addBehavior(
            'Version',
            [
                'versionTable' => 'news_versions',
            ]
        );
    }

    /**
     * Default validation rules.
     *
     * @param Validator $validator
     * @return Validator
     */
    public function validationDefault(Validator $validator): Validator
    {
        $validator
            ->integer('id')
            ->allowEmptyString('id', 'create');

        $validator
            ->scalar('title')
            ->requirePresence('title', 'create')
            ->notEmptyString('title')
            ->maxLength('title', 200);

        $validator
            ->scalar('subtitle')
            ->allowEmptyString('subtitle')
            ->maxLength('subtitle', 300);

        $validator
            ->dateTime('visible_from')
            ->allowEmptyString('visible_from');

        $validator
            ->dateTime('visible_to')
            ->allowEmptyString('visible_to');
    }

<?php

namespace App\Model\Entity;

use Cake\ORM\Entity;
use Josegonzalez\Version\Model\Behavior\Version\VersionTrait;

/**
 * News Entity
 *
 * @property int $id
 * @property string $title
 * @property string $subtitle
 * @property \Cake\I18n\Time $visible_from
 * @property \Cake\I18n\Time $visible_to
 *
 * @property \App\Model\Entity\Version $version
 *
 * @property array $sitemap
 */
class News extends Entity implements SearchEngineInterface
{
    use VersionTrait;

    protected $_accessible = [
        'id' => false
    ];
}

When I save it, entries in the news_versions table are correctly created for each field, Since the visible_from and visible_to fields are set as nullable on my DB, they are correctly saved with a value of "N;".
When I retrieve the versions for my News entity by calling $news->versions(), I get this error:

2022-03-31 15:14:41 Error: [Exception] DateTimeImmutable::__construct(): Failed to parse time string (N;) at position 1 (;): Unexpected character in /var/www/repo/public/vendor/cakephp/chronos/src/Chronos.php on line 109

I have found out that this caused by the convertFieldsToType method, called in the groupVersions method of VersionBehavior.
This happens only for Datetime fields, (other nullable fields that are saved as "N;" are being unserialized correctly) and only after updating to CakePHP 4, with version 4.0.1 of this package. This was working fine with CakePHP 3.x, and version 2 of this package.
I have found that commenting the call to convertFieldsToType solves the problem (and in fact, this call wasn't present in version 2 of the library), but I'm not sure that that's the most correct way to go, therefore I haven't submitted a pull request.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions