2012-09-28 6 views
0

Я хочу преобразовать значение до, сохраняя форму. Я не знаю, где добавить код, поскольку единственный способ: form->save()Как преобразовать значение перед сохранением формы?

Не могли бы вы помочь?

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'); 
    } 
+0

Вы должны использовать эту форму в другом месте (например: в интерфейсе, в профиле пользователя, в редактировании видео и т. д.) или просто ** один раз **? – j0k

+0

Я буду использовать его только в моем основном модуле. – Elwyn

ответ

2

@pankar ответ почти хорошо. Но $this->form->save() переопределит setLink.

Прежде всего, определить функцию для извлечения идентификатора YouTube, как это определенно here в новом инструментов класса: 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; 
    } 
} 

Затем обновить свои действия с этим:

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'); 
} 

Кстати, этот метод в порядке, если вы используете свою форму в только в одном месте. Поскольку обновление выполняется в действии, а не в классе формы. В противном случае, как сказал @glerendegui, вам нужно будет сделать это действие в классе формы. Но я скорее сделаю это в doUpdateObject вместо doSave. Так как код говорит:

/** 
    * 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); 

Так что я буду делать это таким образом, внутри формы (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); 
    } 
} 
+0

Поскольку с успехом пользователь перенаправляется на '@ homepage', это не имеет значения, если метод setLink переопределяется вычисленным значением. После того, как нужный ввод для этого поля будет вычисленным значением, а не представленным! У вас есть точка, хотя если форма была снова представлена ​​пользователю. – pankar

+0

+1 для того, чтобы попасть в неприятности, чтобы представить полный ответ, требующий централизованного/обобщенного метода для извлечения youtube videoIds – pankar

+0

Спасибо, я проверил его очень скоро. Я должен создать специальный валидатор, чтобы проверить, является ли моя ссылка ссылкой на YouTube, не так ли? – Elwyn

0

В вашем execute* действия после связывания форма:

EDITED ПОСЛЕ входа OP в

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'); 
    } 
+0

Это прекрасно, я нашел много тем, которые объясняют, как переопределить метод сохранения. Я предпочитаю это решение. – Elwyn

+0

Я тестировал, но он не работает. Я редактирую свой пост, чтобы показать вам мой код. – Elwyn

+0

Я получил это свойство Неизвестной записи/связанное с ней «значение» в «Песне» – Elwyn

0

Вы должны добавить это поведение внутри формировать эльфа, а не в действии (это идея о формах symfony). Таким образом, переопределите doSave($con = null) из формы, что-то вроде:

class yourForm extends whateverForm { 

public function configure() { ... } 
public function doSave($con = null) { 
    // process form values 
    return parent::doSave(); 
} 
} 
+0

Если я выберу этот метод, где мне нужно написать этот код? Это лучшая практика по сравнению с другим решением? – Elwyn

+0

Это код вашей формы. Например, в вашем действии, если вы выполните: $ this-> form = new xxxForm (...), затем отредактируйте xxxForm.class (возможно, в lib/form/doctrine/xxxForm.class.php). Единственное, что вам нужно добавить - это сделать doSave(). – glerendegui

+0

О, если это лучшая практика, это зависит от того, что вы хотите сделать. Теория форм Symfony говорит, что формы должны быть независимыми от действий, поэтому таким образом они могут использоваться в любое время повсюду вашего кода (даже другие проекты тоже, в пользовательском коде или сгенерированных модулях). Это идея повторного использования кода. Если это значение изменится, то, что вы хотите сделать, является частью формы, тогда должно быть частью его поведения. Подумайте об использовании вашего в каком-то сгенерированном модуле. – glerendegui

Смежные вопросы