Запазете данни от колекция от формуляри

Следвам http://framework.zend.com/manual/2.1/en/modules/zend.form.collections.html и работи чудесно с валидиране и т.н.

Когато формулярът е валиден, ръководството просто изпълнява var_dump на обекта и изглежда по следния начин:

object(Application\Entity\Product)[622]
  protected 'name' => string 'Chair' (length=5)
  protected 'price' => string '25' (length=2)
  protected 'categories' =>
    array (size=2)
      0 =>
        object(Application\Entity\Category)[615]
          protected 'name' => string 'Armchair' (length=8)
      1 =>
        object(App1ication\Entity\Category)[621]
          protected 'name' => string 'Office' (length=6)

Категориите могат да бъдат повече от 2 или само 1. Разбирам как да запазя нормален формуляр в таблица с база данни и нямам проблем. Но тук имаме данни за две различни таблици. Предполагам, че мога ръчно да прочета категориите в моя контролер и да ги попълня в модел и да ги запазя ред по ред. Но това не изглежда като най-добрият начин да го направите.

Как да получа данните от обекта в модел или моята база данни? Може ли без Доктрина?


person Rickard    schedule 18.02.2013    source източник


Отговори (1)


Имате два избора: getData() или bind().

bind() е "автоматичният" начин - вие свързвате обект към вашия обект на формуляр, който има свойство на този обект, което съответства на името на вашата колекция. След това, когато се извика методът isValid() на формуляра, свързващият механизъм ще предаде стойностите от елементите на колекцията към съответстващото свойство на обекта.

Като алтернатива можете да използвате getData() върху обекта на колекцията и след това да направите каквото трябва.

След като имате обект, за да го запазите, обмислете използването на ZfcBase, тъй като това върши тежката работа вместо вас .

Това е прост примерен картограф:

namespace MyModule\Mapper;

use ZfcBase\Mapper\AbstractDbMapper;
use Zend\Stdlib\Hydrator\ArraySerializable;
use MyModule\Entity\MyEntity;

class MyMapper extends AbstractDbMapper
{
    protected $tableName  = 'my_table';

    public function __construct()
    {
        $this->setHydrator(new ArraySerializable());
        $this->setEntityPrototype(new MyEntity());
    }

    public function save(MyEntity $entity)
    {
        if (!$entity->getId()) {
            $result = $this->insert($entity);
            $entity->setId($result->getGeneratedValue());
        } else {
            $where = 'id = ' . (int)$entity->getId();
            $this->update($entity, $where);
        }
    }

    public function fetchAll($choiceGroupId)
    {
        $select = $this->getSelect($this->tableName);
        return $this->select($select);
    }

    public function loadById($id)
    {
        $select = $this->getSelect($this->tableName)
                       ->where(array('id' => (int)$id));

        return $this->select($select)->current();
    }        
}

Този картограф използва ArraySerializable hydrator, така че вашият обект обект (MyEntity в примера) трябва да имплементира методите getArrayCopy() и populate(). getArrayCopy() връща масив от данни за запазване, а populate() се използва за попълване на обекта от масив от данни от база данни.

person Rob Allen    schedule 19.02.2013
comment
Да, получаването на данните от обекта във формуляра работи много добре и обратното. След като валидирането е направено, ръководството завършва с var_dump($product);, там седя с обекта с данните, но не знам как да направя хидрататор и картограф. - person Rickard; 19.02.2013
comment
Благодаря, че отделихте времето си за този Роб! Мисля, че все още не съм ясен във въпроса си :) Сега го актуализирах малко и се надявам да е по-ясно какво не разбирам. - person Rickard; 20.02.2013
comment
Отказах се от това, по пътя на Доктрината :) Благодаря за помощта! - person Rickard; 01.03.2013
comment
@RobAllen, обичам $form-›bind() с колекции, тъй като се занимава с множество дъщерни обекти (използвайки мои собствени карти, хидрататори и т.н. - без доктрина). След обвързване в действие за редактиране аз включвам дъщерните обекти на родителя, които вече са били актуализирани при обвързването, и записвам всички един по един, като използвам действието за запазване на техния собствен картограф. Това помага само за редактиране на съществуващите деца, но не мога да разбера новите деца, които могат да бъдат добавени във формуляра. Не мога да намеря новите данни в getData(), а само в $request-›getPost(). Трябва ли наистина да повторя масива getPost() и да създам нови деца? Благодаря. - person smozgur; 10.07.2016
comment
Съжалявам, че добавям въпроса си тук, но това е единственият източник, който мога да намеря и най-близо до моята ситуация. Просто исках да обясня къде останах, тъй като ви накарах да говорите за същия проблем с надеждата, че можете да ми дадете идея. Благодаря ви много отново. - person smozgur; 10.07.2016