我問了this question,發現我們無法得到DataTransformer拋出的錯誤信息(根據唯一回答的用戶,也許這是可能的,我不知道)。Symfony2數據轉換器,驗證器和錯誤信息
無論如何,現在我知道了,我被困在一個驗證問題。假設我的模型是這樣的:我有包含幾個參與者(用戶)的線程。
<?php
class Thread
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToMany(targetEntity="My\UserBundle\Entity\User")
* @ORM\JoinTable(name="messaging_thread_user")
*/
private $participants;
// other fields, getters, setters, etc
}
對於線程的創建,我希望用戶指定一個textarea參與者的用戶名,用「\ n」分隔。 我希望如果指定的一個或多個用戶名不存在,則會顯示一條消息,其中不存在用戶名。 例如,「用戶titi,tata和toto不存在」。
爲此我創建了一個DataTransformer,它將textarea中的原始文本轉換爲包含用戶實例的ArrayCollection。由於我無法獲取DataTransformer提供的錯誤信息(這真是太可惜了!),我不檢查DataTransformer中是否存在每個用戶名,但在Validator中是否存在。
這裏是\ n分隔的用戶列表轉換爲ArrayCollection(這樣的數據綁定是確定)的DataTransformer:
<?php
public function reverseTransform($val)
{
if (empty($val)) {
return null;
}
$return = new ArrayCollection();
// Extract usernames in an array from the raw text
$val = str_replace("\r\n", "\n", trim($val));
$usernames = explode("\n", $val);
array_map('trim', $usernames);
foreach ($usernames as $username) {
$user = new User();
$user->setUsername($username);
if (!$return->contains($user)) {
$return->add($user);
}
}
return $return;
}
這裏是我的驗證:
<?php
public function isValid($value, Constraint $constraint)
{
$repo = $this->em->getRepository('MyUserBundle:User');
$notValidUsernames = array();
foreach ($value as $user) {
$username = $user->getUsername();
if (!($user = $repo->findOneByUsername($username))) {
$notValidUsernames[] = $username;
}
}
if (count($notValidUsernames) == 0) {
return true;
}
// At least one username is not ok here
// Create the list of usernames separated by commas
$list = '';
$i = 1;
foreach ($notValidUsernames as $username) {
if ($i < count($notValidUsernames)) {
$list .= $username;
if ($i < count($notValidUsernames) - 1) {
$list .= ', ';
}
}
$i++;
}
$this->setMessage(
$this->translator->transChoice(
'form.error.participant_not_found',
count($notValidUsernames),
array(
'%usernames%' => $list,
'%last_username%' => end($notValidUsernames)
)
)
);
return false;
}
這個電流實現看起來很醜。我可以很好地看到錯誤消息,但DataTransformer返回的ArrayCollection中的用戶不與Doctrine同步。
我有兩個問題:
- 是否有我的驗證可以修改參數給出的值什麼辦法?這樣我可以將DataTransformer返回的ArrayCollection中的簡單User實例替換爲從數據庫中檢索的實例?
- 有沒有一種簡單而優雅的方式來做我正在做的事情?
我想最簡單的方法來做到這一點是能夠得到由DataTransformer給出的錯誤消息。在食譜中,他們拋出了這個異常:throw new TransformationFailedException(sprintf('An issue with number %s does not exist!', $val));
,如果我可以在錯誤消息中放置不存在的用戶名列表,它會很酷。
謝謝!
而你如何處理數據綁定?如果Doctrine沒有爲「參與者」字段(它是OneToMany)獲取ArrayCollection,它會給出錯誤。我應該以與「參與者」無關的形式製作一個專業領域嗎?也許你有一個鏈接呢? – Nanocom 2012-02-22 20:11:21
無論如何,感謝您的回答 – Nanocom 2012-02-22 20:11:32
添加了一個新字段「用戶名」到我的線程實體,包含數組。如果表單有效,我在ArrayCollection中添加用戶名。但仍然存在問題。如何從驗證程序獲取用戶實例? – Nanocom 2012-02-22 20:46:54