จะบันทึก sfForm ซึ่งมีรูปแบบฝังหลักคำสอนได้อย่างไร

ฉันมีรูปแบบหลักคำสอน (KanoonGoodForm) ตามคลาสโมเดล KanoonGood ซึ่งมีลักษณะดังนี้:

class KanoonGoodForm extends BaseKanoonGoodForm
{
    public function configure()
    {
       $this->widgetSchema['count_num']->setAttribute('size', '1');
       $this->widgetSchema['price']->setAttribute('size', '1');

       $this->validatorSchema['category_id']->setOption('required', false);
       $this->validatorSchema['owner_id']->setOption('required', false);
       $this->validatorSchema['shop_id']->setOption('required', false);
       $this->validatorSchema['name']->setOption('required', false);
       $this->validatorSchema['price']->setOption('required', false);
       $this->validatorSchema['count_num']->setOption('required', false);
       $this->validatorSchema['description']->setOption('required', false);
    }
}

จากนั้นผมจึงสร้างคลาส KanoonGoodsGroupForm เพื่อให้มีแบบฟอร์มที่ฝังแบบฟอร์ม KanoonGoodForm ไว้ตามจำนวนที่ต้องการ:

class KanoonGoodsGroupForm extends sfForm
{
    public function configure() 
   { 
       for ($i = 0; $i < 2; $i++) 
       {
           $this->embedForm('good_'.($i+1), new KanoonGoodForm());
       }
       $this->widgetSchema->setNameFormat('KanoonGoodsGroup[%s]');
       $this->mergePostValidator(new KanoonGoodValidatorSchema());
   }
}

ในโมดูล (ชื่อ good) ฉันสะท้อนอินสแตนซ์ของ KanoonGoodsGroupForm เมื่อมีการเรียกการกระทำใหม่:

public function executeNew(sfWebRequest $request)
{
    $this->form = new KanoonGoodsGroupForm();
}

เนื่องจากไม่จำเป็นต้องกรอกแบบฟอร์มที่ฝังไว้ทั้งหมด เนื่องจาก บทความนี้ บอกว่า ฉันสร้างเครื่องมือตรวจสอบของตัวเอง:

class KAnoonGoodValidatorSchema extends sfValidatorSchema
{
  protected function configure($options = array(), $messages = array())
  {
    $this->addMessage('category_id', 'The category_id is required.');
    $this->addMessage('owner_id', 'The owner_id is required.');
    $this->addMessage('shop_id', 'The shop_id is required.');
    $this->addMessage('name', 'The name is required.');
    $this->addMessage('price', 'The price is required.');
    $this->addMessage('count_num', 'The count_num is required.');
    $this->addMessage('description', 'The description is required.');
  }

  protected function doClean($values)
  {
    $errorSchema = new sfValidatorErrorSchema($this);

    foreach($values as $key => $value)
    {
      $errorSchemaLocal = new sfValidatorErrorSchema($this);
      // no caption and no filename, remove the empty values
      if (!$value['name'] && !$value['price']&& !$value['count_num']&& !$value['description'])
      {
        unset($values[$key]);
      }

      // some error for this embedded-form
      if (count($errorSchemaLocal))
      {
        $errorSchema->addError($errorSchemaLocal, (string) $key);
      }
    }

    // throws the error for the main form
    if (count($errorSchema))
    {
      throw new sfValidatorErrorSchema($this, $errorSchema);
    }

    return $values;
  }
}

ตอนนี้ฉันต้องการบันทึกแบบฟอร์มฝังตัวที่ผู้ใช้กรอก ฉันควรทำอย่างไรในการดำเนินการสร้างเพื่อให้บรรลุผลนี้

public function executeCreate(sfWebRequest $request)
{
    $this->forward404Unless($request->isMethod(sfRequest::POST));
    $this->form = new KanoonGoodsGroupForm();
    $this->form->bind($request->getParameter('KanoonGoodsGroup'), $request->getFiles('KanoonGoodsGroup'));

    if ($this->form->isValid())
    {

         //what should I do here? to save those filled embedded forms?
    }

   $this->setTemplate('edit');
  }

person Ehsan    schedule 01.08.2012    source แหล่งที่มา
comment
ลอง foreach ($this->form->getEmbeddedForms() as $form) { $form->save(); }   -  person 1ed    schedule 02.08.2012
comment
ฉันลองแล้ว แต่ได้ 500 | ข้อผิดพลาดภายในเซิร์ฟเวอร์ | sfValidatorErrorSchema ในบรรทัดนี้: $this-›errorSchema = new sfValidatorErrorSchema($this-›validatorSchema); ใน BaseKanoonGoodForm.class.php ของฉัน   -  person Ehsan    schedule 02.08.2012


คำตอบ (3)


เมื่อฉันประสบปัญหาที่คล้ายกัน ฉันแก้ไขมันด้วยวิธี custom save() ในรูปแบบที่รวบรวมแบบฟอร์มที่ฝังไว้เช่นนี้

public function save($conn = null){
    foreach ($this->getEmbeddedForms() as $key => $form) {
        $object = $form->getObject();
        $object->merge($this->getValue($key));
        $object->save($conn);
    }
}

โดยจะเดินผ่านแบบฟอร์มที่ฝังไว้และรวมออบเจ็กต์กับข้อมูลที่ได้รับการตรวจสอบแล้วจากแบบฟอร์มกลุ่ม จากนั้นจึงบันทึก

person Andrey Yaroshenko    schedule 25.11.2012

คุณต้องโทร:

$this->form->save();

แต่ คุณต้องใช้ส่วนที่เกี่ยวข้องกับ saveEmbeddedForms

person j0k    schedule 01.08.2012
comment
เนื่องจากแบบฟอร์มนี้เป็น sfForm จึงไม่มีฟังก์ชันบันทึกหรือ saveEmbeddedForms ฉันพยายามนำไปใช้ด้วยตัวเอง แต่ฉันพบข้อผิดพลาด เช่น ข้อกำหนด csrf_token สำหรับแต่ละแบบฟอร์มที่ฝังไว้! - person Ehsan; 01.08.2012

คุณจะต้องใช้วิธีบันทึกสำหรับ KanoonGoodsGroupForm ดังนี้:

public function save() {
    $this->updateObjectEmbeddedForms($this->getTaintedValues());
    $this->saveEmbeddedForms();
  }

  public function saveEmbeddedForms($forms = null) {
    if (null === $forms) {
      $forms = $this->embeddedForms;
    }

    foreach ($forms as $form) {
      if ($form instanceof sfFormObject) {
        $form->getObject()->save();
        $form->saveEmbeddedForms();
      } else {
        $this->saveEmbeddedForms($form->getEmbeddedForms());
      }
    }
  }


  public function updateObjectEmbeddedForms($values, $forms = null) {
    if (null === $forms) {
      $forms = $this->embeddedForms;
    }

    foreach ($forms as $name => $form) {
      if (!isset($values[$name]) || !is_array($values[$name])) {
        continue;
      }

      if ($form instanceof sfFormObject) {
        $form->updateObject($values[$name]);
      } else {
        $this->updateObjectEmbeddedForms($values[$name], $form->getEmbeddedForms());
      }
    }
  }
person Rene Ramirez    schedule 20.05.2015