用户可以发布音乐链接,因为音乐提供商可以变化(Youtube,Deezer,Soundcloud等等),我有一个自定义验证器和自定义 setLink()。 在我的数据库中,链接是视频的ID(youtube示例:CWMYxYoaRBQ)
但结果是我的sfValidatorDoctrineUnique不再起作用了。
我的验证员:
<?php
class videoValidator extends sfValidatorUrl
{
protected function configure($options = array(), $messages = array())
{
parent::configure($options, $messages);
$this->setMessage('invalid', 'Error message.');
}
protected function doClean($url)
{
$videoProvider = new videoProvider($url);
if (false === $videoProvider->isValid())
{
throw new sfValidatorError($this, 'invalid', array('value' => $url));
}
return $url;
}
}
?>
我的videoProvider类:
class videoProvider
{
private $url;
private $providers = array('youtube','deezer','soundcloud');
private $youtubePattern = '%^# Match any youtube URL
(?:https?://)? # Optional scheme. Either http or https
(?:www\.)? # Optional www subdomain
(?: # Group host alternatives
youtu\.be/ # Either youtu.be,
| youtube\.com # or youtube.com
(?: # Group path alternatives
/embed/ # Either /embed/
| /v/ # or /v/
| /watch\?v= # or /watch\?v=
) # End path alternatives.
) # End host alternatives.
([\w-]{10,12}) # Allow 10-12 for 11 char youtube id.
$%x';
private $deezerPattern = '/\d+/';
private $soundcloudPattern = '[\w-]+/[\w-]+$';
public function __construct($url)
{
$this->url = $url;
}
/**
* @return true / false
*/
private function checkYoutube()
{
return preg_match($this->youtubePattern, $this->url) ? true : false;
}
/**
* @return true / false
*/
private function checkDeezer()
{
// A Deezer URL has this format : http://www.deezer.com/track/61340079
return preg_match($this->deezerPattern, $this->url) ? true : false;
}
/**
* @return true / false
*/
private function checkSoundcloud()
{
// A Soundcloud URL has this format : http://soundcloud.com/[A-Z Artist]/[A-Z Title]
return preg_match($this->soundcloudPattern, $this->url) ? true : false;
}
/**
* @return true / false
*/
public function isValid()
{
// check all video provider as you do in your validator
// so it will return true if it find one, otherwise false
foreach ($this->providers as $provider)
{
$function = 'check'.ucfirst($provider);
if (true === $this->$function())
{
return true;
}
}
return false;
}
/**
* @return string
*/
public function getId()
{
if ($this->checkYoutube() && preg_match($this->youtubePattern, $this->url, $matches))
{
return $matches[1];
}
if ($this->checkDeezer() && preg_match($this->deezerPattern, $this->url, $matches))
{
return $matches[1];
}
if ($this->checkSoundcloud() && preg_match($this->deezerPattern, $this->url, $matches))
{
return $matches[1];
}
}
/**
* @return string
*/
public function getProvider()
{
if ($this->checkYoutube())
{
return 'youtube';
}
if ($this->checkDeezer())
{
return 'deezer';
}
if ($this->checkSoundcloud())
{
return 'soundcloud';
}
}
}
我的歌班:
class Song extends BaseSong
{
public function setLink($value)
{
// only perform this tweak if the value is a http link
if (preg_match('/^http/i', $value))
{
$videoProvider = new videoProvider($value);
// define url id
parent::_set('link', $videoProvider->getId());
// define type id
$provider = $videoProvider->getProvider();
$type = Doctrine_Core::getTable('Type')->findOneByName($provider);
parent::_set('type_id', $type->getId());
}
}
}
我认为sfValidatorDoctrineUnique尝试将完整的URL(表单字段)与视频ID(数据库字段)进行比较。我该如何解决?
答案 0 :(得分:0)
我认为我找到了一个经过测试和运作的解决方案。
class videoValidator extends sfValidatorUrl
{
protected function configure($options = array(), $messages = array())
{
parent::configure($options, $messages);
$this->setMessage('invalid', 'Le lien n\'est pas valide. Veuillez entrer un lien Youtube, Deezer ou Soundcloud.');
}
protected function doClean($url)
{
$videoProvider = new videoProvider($url);
if (false === $videoProvider->isValid())
{
throw new sfValidatorError($this, 'invalid', array('value' => $url));
}
$unique = Doctrine_Core::getTable('Song')->findOneByLink($videoProvider->getId());
if (!empty($unique))
{
return $videoProvider->getId();
}
return $url;
}
}
我返回视频的ID,视频已存在于数据库中。然后,我认为sfValidatorDoctrineUnique能够执行它的测试。
这对你来说是否合乎逻辑?