カテゴリー
diary

Symfony2 with custom validator

昨日の投稿の後にちゃっかり自分でカスタムバリデート作っているコード見つけたので一応ここに貼り付けておく。symfonyの公式ドキュメントにもそのまんま記載してある。

ただこれだとヤヤ面倒くさめなのでAssert\Trueなんかの手軽さでAssertのエラーメッセージをカスタマイズしたい!

[php]
<?php
// src/Hc100/DemoBundle/Validator/constraints/ExistsDepartmentNumber.php

namespace Hc100\DemoBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*/
class ExistsDepartmentNumber extends Constraint
{
public $message = ‘部門番号 "%string%" が部門マスタに登録されていません’;

public function validatedBy()
{
return ‘existsdepartmentnumber’;
}
}
[/php]

validatedByには src/Hc100/DemoBundle/Resources/config/services.xml に定義してあるserviceを返す

[php]
<?php
// src/Hc100/DemoBundle/Validator/constraints/ExistsDepartmentNumberValidator.php

namespace Hc100\DemoBundle\Validator\Constraints;

use Doctrine\ORM\EntityManager;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Hc100\DemoBundle\Entity\Department;

class ExistsDepartmentNumberValidator extends ConstraintValidator
{
private $entityManager;

public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}

public function validate($value, Constraint $constraint)
{
if ($value == ”)
return;

$department = $this->entityManager->getRepository(‘Hc100DemoBundle:Department’)
->findMatchByDepartmentNumber($value);
if (!$department) {
$this->context->addViolation($constraint->message, array(‘%string%’ => $value));
}
}
}
[/php]

src/Hc100/DemoBundle/Resources/config/services.xmlにサービスを追記

[xml]
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="hc100_validator.constraint.existsdepartmentnumber" class="Hc100\DemoBundle\Validator\Constraints\ExistsDepartmentNumberValidator">
<argument type="service" id="doctrine.orm.entity_manager"/>
<tag name="validator.constraint_validator" alias="existsdepartmentnumber" />
</service>

</services>
</container>
[/xml]

あとはEntityの中でカスタムAssertを追加

[php]
use Hc100\DemoBundle\Validator\Constraints as Hc100Assert;

/**
* 部門
* @var string $department_number
*
* @ORM\Column(name="department_number", type="integer")
* @Hc100Assert\ExistsDepartmentNumber()
*/
private $department_number;
[/php]

カテゴリー
diary

symfony2 Assert customizing messages

EntityのバリデーションのAssertで通らなかった時に指定するメッセージ文字列、これにplaceholderを使えないか検索してみたんだけどどうやらできない模様。時間がなくてソースコードまでは確認してない

例えば、こんな事をしたいと思った

[php]
/*
* @Assert\True(message = "未登録部門 {{ value }}")
*/
public function isValidDepartmentNumber() {
return (valid) ? true : false;
}
[/php]

もちろん、これは出来ないでのそのまま {{ value }} という文字列がエラーとして表示される

ウェブ上のフォームの場合は入力文字列(送信した値)が画面上に出ているだろうから、あえて何がバリデーションで失敗したかなんてエラー文字列に入れる必要はない。しかし今回はバッチ的な処理の中でEntityをいくつも作成してそれを検証する形だったので、まとめた処理のエラーを出す場合に単純なエラー原因だけでは何がどういった理由でエラーになったのか非常に分かりづらいという問題に陥った

こんな処理

[php]
for (someloop) {
// validate
$errors = $this->container->get(‘validator’)->validate($entity);
if (count($errors) > 0) {
// if error, stack error list
foreach ($errors as $error) {
$this->errors[] = $error->getMessage();
}
}
}
[/php]

結局ちょう場当たり的な対応をした

[php]
for (someloop) {
// validate
$errors = $this->container->get(‘validator’)->validate($entity);
if (count($errors) > 0) {
// if error, stack error list
foreach ($errors as $error) {
$_str = $error->getMessage();
// custom error messaging
$_str = preg_replace("/{{ value }}/", ‘ (‘.$entity->getDepartmentNumber().’)’, $_str);
$this->errors[] = $_str;
}
}
}
[/php]

symfony2関連のサンプルコードってまだまだ少ない感じがするなぁ