如何在保存表单之前转换值?

时间:2012-09-28 08:56:50

标签: php symfony-1.4

我希望在保存表单之前转换值。 我不知道在哪里添加代码,因为唯一的方法是form->save()

你能帮我吗?

修改

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

3 个答案:

答案 0 :(得分:3)

@pankar答案几乎是好的。但$this->form->save()会覆盖setLink

首先,在新的工具类中定义用于检索youtube ID的函数,如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);
  }
}

答案 1 :(得分:0)

绑定后的execute*操作 表单:

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

答案 2 :(得分:0)

您应该在表单本身内添加此行为,而不是在操作中添加(这是关于symfony表单的想法)。因此,覆盖表单的doSave($con = null),例如:

class yourForm extends whateverForm {

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