问题
I want to convert a value before saving the form.
I don't know where to add the code because the only method is form->save()
Could you please help me ?
Edit:
if ($this->form->isValid())
{
$url = $this->form->getObject()->getLink();
parse_str(parse_url($url, PHP_URL_QUERY), $my_array_of_vars);
$this->form->getObject()->setLink($my_array_of_vars['v']);
$song = $this->form->save();
$this->getUser()->setFlash('notice', 'Thank you, the song has been added');
$this->redirect('@homepage');
}
回答1:
The @pankar answer is almost good. But the $this->form->save()
will override the setLink
.
First of all, define the function to retrieve the youtube id, as defined here in a new tools class: lib/myTools.class.php
<?php
class myTools
{
/**
* Get youtube video ID from URL
*
* @see https://stackoverflow.com/a/6556662/569101
* @param string $url
* @return string Youtube video id or FALSE if none found.
*/
public static function youtube_id_from_url($url)
{
$pattern =
'%^# 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'
;
$result = preg_match($pattern, $url, $matches);
if (false !== $result)
{
return $matches[1];
}
return false;
}
}
Then, update your action with this:
if ($this->form->isValid())
{
// save the form
$song = $this->form->save();
// update saved value
$youtube_id = myTools::youtube_id_from_url($song->getLink());
$song->setLink($youtube_id);
$song->save();
$this->getUser()->setFlash('notice', 'Thank you, the song has been added');
$this->redirect('@homepage');
}
By the way, this method is ok if you use your form in only one place. Since the update is perform in the action and not in the form class. Otherwise, as @glerendegui said, you will have to do this action in the form class. But I will rather do it in the doUpdateObject
instead of doSave
. Since the code says:
/**
* Updates the values of the object with the cleaned up values.
*
* If you want to add some logic before updating or update other associated
* objects, this is the method to override.
*
* @param array $values An array of values
*/
abstract protected function doUpdateObject($values);
So I will do it in this way, inside your form (lib/form/doctrine/yourForm.class.php
):
class yourForm extends BaseYourForm
{
public function configure()
{
}
protected function doUpdateObject($values)
{
$youtube_id = myTools::youtube_id_from_url($values['link']);
$this->getObject()->setLink($youtube_id);
return parent::doUpdateObject($values);
}
}
回答2:
In your execute*
action after binding the form:
EDITED AFTER OP's input
if ($this->form->isValid())
{
$url = $this->form->getObject()->getLink(); // get the url
$videoId=parse_url($url, PHP_URL_QUERY); // extract the videoid portion
$this->form->getObject()->setLink($videoId); // update object with the new value
$song = $this->form->save(); // save the object
$this->getUser()->setFlash('notice', 'Thank you, the song has been added');
$this->redirect('@homepage');
}
回答3:
You should add this behavior inside the form itself, and not in the action (that's the idea about symfony forms). So, override the doSave($con = null)
of the form, something like:
class yourForm extends whateverForm {
public function configure() { ... }
public function doSave($con = null) {
// process form values
return parent::doSave();
}
}
来源:https://stackoverflow.com/questions/12636747/how-to-convert-a-value-before-saving-the-form