0

我想在保存表单之前转换一个值。我不知道在哪里添加代码,因为唯一的方法是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');
  }
4

3 回答 3

3

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

首先,定义检索 youtube id 的函数,如这里在新工具类中定义的那样: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 所说,您将不得不在表单类中执行此操作。但我宁愿用 indoUpdateObject而不是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);
  }
}
于 2012-10-01T08:27:59.020 回答
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');
  }
于 2012-09-28T12:45:28.477 回答
0

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

class yourForm extends whateverForm {

 public function configure() { ... }
 public function doSave($con = null) {
   // process form values
   return parent::doSave();
 }
}
于 2012-09-28T21:10:22.663 回答