Пользовательские сообщения об ошибках при проверке доктрины - PullRequest
2 голосов
/ 05 августа 2009

Мне нужно изменить стандартные сообщения об ошибках проверки доктрины. Как я могу сделать это?

спасибо

Ответы [ 2 ]

5 голосов
/ 05 августа 2009

CrazyJoe правильно, в некотором смысле: это невозможно без некоторой тяжелой работы : - (

Но, если поискать достаточно сложно, вы можете найти способ ; -)


С Doctrine 1.1 вы моделируете классы, расширяющие Doctrine_Record.
Этот класс определяет этот метод:

/**
 * Get the record error stack as a human readable string.
 * Useful for outputting errors to user via web browser
 *
 * @return string $message
 */
public function getErrorStackAsString()
{
    $errorStack = $this->getErrorStack();

    if (count($errorStack)) {
        $message = sprintf("Validation failed in class %s\n\n", get_class($this));

        $message .= "  " . count($errorStack) . " field" . (count($errorStack) > 1 ?  's' : null) . " had validation error" . (count($errorStack) > 1 ?  's' : null) . ":\n\n";
        foreach ($errorStack as $field => $errors) {
            $message .= "    * " . count($errors) . " validator" . (count($errors) > 1 ?  's' : null) . " failed on $field (" . implode(", ", $errors) . ")\n";
        }
        return $message;
    } else {
        return false;
    }
}

Это метод, который генерирует сообщения; как видите, он полностью автоматический и вообще не настраивается : - (


Тем не менее, благодаря ООП, мы можем перегрузить этот метод в наших классах Model ...

Но, чтобы быть чище, я бы:

  • Создайте новый класс - скажем, My_Doctrine_Record, который расширяется Doctrine_Record
  • Этот класс переопределит этот метод, чтобы разрешить настройку сообщений об ошибках
  • И наши классы Model будут расширять этот класс My_Doctrine_Record.

Это позволит избежать дублирования этого метода внутри каждого из наших классов моделей; и может оказаться полезным в другой день ...


Наш My_Doctrine_Record::getErrorStackAsString метод может, конечно, полагаться на метод наших классов моделей, чтобы помочь генерировать сообщения со специальной настройкой для каждого класса моделей.

Вот рабочий пример; далеко не идеальный, но он может привести вас к тому, что вы хотите получить ; -)


Прежде всего, инициализации:

require_once '/usr/share/php/Doctrine/lib/Doctrine.php';
spl_autoload_register(array('Doctrine', 'autoload'));

$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);

$conn = Doctrine_Manager::connection('mysql://test:123456@localhost/test1');

Полагаю, у вас уже есть что-то подобное в вашем приложении ...


Далее наш новый My_Doctrine_Record класс:

class My_Doctrine_Record extends Doctrine_Record
{
    public function getErrorStackAsString()
    {
        $errorStack = $this->getErrorStack();
        if (count($errorStack)) {
            $message = sprintf("BAD DATA in class %s :\n", get_class($this));
            foreach ($errorStack as $field => $errors) {
                $messageForField = $this->_getValidationFailed($field, $errors);
                if ($messageForField === null) {
                    // No custom message for this case => we use the default one.
                    $message .= "    * " . count($errors) . " validator" . (count($errors) > 1 ?  's' : null) . " failed on $field (" . implode(", ", $errors) . ")\n";
                } else {
                    $message .= "    * " . $messageForField;
                }
            }
            return $message;
        } else {
            return false;
        }
    }

    protected function _getValidationFailed($field, $errors) {
        return null;
    }

}

Вы заметите, что метод getErrorStackAsString вдохновлен тем, что делается с помощью Doctrine - это кажется нормальным, я бы сказал, ^^

Еще одна вещь, на которую следует обратить внимание:

  • Он определяет и вызывает метод _ getValidationFailed
  • что следует создавать сообщения об ошибках; или верните null, если мы хотим использовать поведение по умолчанию
  • и мы можем перегрузить этот _getValidationFailed метод в наших классах Model, чтобы настроить вещи ; -)


А теперь мой класс Модель:

class Test extends My_Doctrine_Record
{
    protected function _getValidationFailed($field, $errors) {
        switch ($field) {
            case 'name': 
                    return "You entered wrong data from 'name' field.\n      Errors are for '" 
                        . implode("', '", $errors) . "'\n";
                break;
            // other fields ?
            default:
                return null;
        }
    }

    public function setTableDefinition()
    {
        $this->setTableName('test');
        $this->hasColumn('id', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'unsigned' => 0,
             'primary' => true,
             'autoincrement' => true,
             ));
        $this->hasColumn('name', 'string', 32, array(
             'type' => 'string',
             'length' => 32,
             'fixed' => false,
             'notnull' => true,
             'email'   => true,
             ));
        $this->hasColumn('value', 'string', 128, array(
             'type' => 'string',
             'length' => 128,
             'fixed' => false,
             'notnull' => true,
             'htmlcolor' => true,
             ));
        $this->hasColumn('date_field', 'integer', 4, array(
             'type' => 'timestamp',
             'notnull' => true,
             ));
    }
}

Он расширяет My_Doctrine_Record и определяет метод _getValidationFailed, который обрабатывает ошибки валидации в поле name моей модели.


Теперь предположим, что я делаю это для загрузки записи:

$test = Doctrine::getTable('Test')->find(1);
var_dump($test->toArray());

Попробуем изменить его, настроив «плохие» значения:

<code>$test->name = (string)time();
$test->value = 'glop';
try {
    $test->save();
} catch (Doctrine_Validator_Exception $e) {
    echo '<pre>';
    echo $e->getMessage();
    echo '
'; умереть; }

Оба поля name и value не в порядке ... Итак, мы рассмотрим наши методы проверки и сгенерируем это сообщение об ошибке:

BAD DATA in class Test :
    * You entered wrong data from 'name' field.
      Errors are for 'email'
    * 1 validator failed on value (htmlcolor)

Вы видите, что сообщение для "name" было настроено, а сообщение для "value" происходит из стандартного Doctrine.


Итак, сделаем вывод: не легко, но выполнимо ; -)

И теперь вы можете использовать это как руководство для точного решения вашей проблемы : -)
Мне понадобится еще немного кодирования, я думаю ... Но вы не далеко от реальной сделки!

Веселись!

0 голосов
/ 05 августа 2009

Это невозможно в текущей версии !!!

...