Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

Error when extending Uniqueness validator

Hi,

I'm extending the Uniqueness validator for use in a model. When the validator is run for a table update, I'm getting the following error:

Phalcon\Mvc\Model\Exception: Column 'primaryKey' doesn't belong to any of the selected models (1), when preparing: SELECT COUNT(*) AS rowcount FROM [Test] WHERE mappedData = ?0 AND primaryKey <> ?1

I am using a columnMap for my model and when the query is constructed the mapped column name is used but not the mapped primary key name. This only happens when using my extension of the uniqueness validator. If I use the parent class directly there is no problem.

The validator in my sample code simply calls the parent validate method and it still fails. Am I running into some PHP inheritance issue here?

Sample code below:

<?php

error_reporting( E_ALL );

function printError( $inError )
{
    echo "<pre>";
    echo get_class( $inError ), ": ", $inError->getMessage(), "\n\n";

    echo "Phalcon Version: ", Phalcon\Version::get(), "\n";
    echo "File: ", $inError->getFile(), "\n";
    echo "Line: ", $inError->getLine(), "\n\n";

    echo $inError->getTraceAsString();

    echo "</pre>";
}

class ExtendedUniquenessValidator extends Phalcon\Validation\Validator\Uniqueness
{
    public function validate( Phalcon\Validation $inValidation, $inField )
    {
        return parent::validate( $inValidation, $inField );
    }
}

class Test extends \Phalcon\Mvc\Model
{
    public $mappedPrimaryKey;
    public $mappedData;

    public function columnMap()
    {
        // Keys are the real names in the table and
        // the values their names in the application
        //
        return array(
            "primaryKey"    => "mappedPrimaryKey",  
            "data"          => "mappedData"
        );
    }

    public function validation()
    {
        $validator = new Phalcon\Validation();          

        //$uv = new Phalcon\Validation\Validator\Uniqueness( array("message" => "Data must be unique" ));       // works
        $uv = new ExtendedUniquenessValidator( array("message" => "Data must be unique" ));                     // doesn't work

        $validator->add( "mappedData", $uv );

        return $this->validate( $validator );
    }
}

try
{

$di = new Phalcon\DI\FactoryDefault();

$di->setShared('db', function () {
    return new \Phalcon\Db\Adapter\PDO\Sqlite(array(
        'dbname'   => ':memory:'
    ));
});

$di['db']->createTable(
    'test',
    null,
    [
       'columns' => [
            new \Phalcon\Db\Column(
                'primaryKey',
                [
                    'type'          => \Phalcon\Db\Column::TYPE_INTEGER,
                    'notNull'       => true,
                    'autoIncrement' => true,
                    'primary'       => true,
                ]
            ),
            new \Phalcon\Db\Column(
                'data',
                [
                    'type'    => \Phalcon\Db\Column::TYPE_TEXT,
                    'notNull' => true,
                ]
            )
        ]
    ]
);

$testObject1 = new Test;
$testObject1->mappedData = "Object 1";
$testObject1->save();

$result = Test::findFirst();
$result->mappedData = "Object 2"; 
$result->save();        // Triggers exception

echo "end";

}
catch ( \Exception $e )
{
    printError( $e );
}
catch ( \Error $e )
{
    printError( $e );
}

Yea actualy it was a bug which was fixed on 3.4.1. Why even have primary key other than in database?



416
edited Aug '18

The issue I am having does not seem to be related to issue #13398 if this is what you are referring to. This issue exists also in 3.4.1.

The error does not appear when I use the Uniqueness validator directly, only when I subclass it. It is very strange and I do not understand the reason for it. It is as if the columnMap property in the validator is always null if I subclass it, but I don't see why that would happen.

I'm using PHP7.2, can it be reproduced in other PHP versions? Is there anything special I should do when subclassing a phalcon class?



416
Accepted
answer

I fixed the issue by adding the "columnMap" property to my derived class, duplicating the property declaration of the Uniqueness class.

I have no idea why this is required, probably some PHP inheritance issue and not a Phalcon issue.