Symfony2 - как создать форму на основе динамических параметров из БД? (EAV) - PullRequest
7 голосов
/ 06 сентября 2011

Я хотел бы создать форму на основе динамических параметров, которые хранятся в БД.Поэтому я создал сущность с именем Parameter, которая определяет имя параметра, которое должно отображаться в виде метки поля формы.

/**
 * @ORM\Entity
 */
class Parameter
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(type="string", length="255")
     * @Assert\NotBlank()
     */
    protected $name; 
    /**
     * @ORM\OneToMany(targetEntity="ParameterValue", mappedBy="parameter")
     */
    protected $values;

Значения параметров для конкретного объекта (объекта Company) будут сохранены в таблице ParameterValue.

/**
 * @ORM\Entity
 */
class ParameterValue
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\ManyToOne(targetEntity="Parameter", inversedBy="values")
     * @ORM\JoinColumn(name="parameter_id", referencedColumnName="id", nullable=false)
     */
    protected $parameter;
    /**
     * @ORM\ManyToOne(targetEntity="Company", inversedBy="parameters")
     * @ORM\JoinColumn(name="company_id", referencedColumnName="id", nullable=false)
     */
    protected $company;

И, конечно, сущность Company содержит атрибут параметров, в котором хранятся только те параметры, которые были указаны для Company.

/**
 * @ORM\Entity
 */
class Company
{    
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(type="string", length="255")
     */
    protected $name;
    /**
     * @ORM\OneToMany(targetEntity="ParameterValue", mappedBy="hotel")
     */
    protected $parameters;

Как создать форму, которая динамически выбирает все параметры из БДсоздает текстовые поля с определенными метками (label = Parameter-> getName ()) и получает ParameterValues ​​для параметров, которые уже были связаны с компанией (для действия редактирования)?

Я уже создал поле 'collection', котороеполучает ParameterValues, но проблема в том, что я получаю форму с полями для параметров, которые были использованы для компании, но не для других.И, конечно, я не могу получить метку, потому что тип поля коллекции - ParameterType, а не Parameter.

1 Ответ

14 голосов
/ 08 сентября 2011

Мне недавно пришлось сделать что-то подобное. Я поделюсь своим опытом и попробую изложить вашу точку зрения. Возможно, вам придется изменить это в соответствии с вашими потребностями.

Моя компания была похожа на вашу. Я хотел, чтобы каждая компания хранила динамическое количество параметров и значений, связанных с ними, и могла редактировать их в формах, используя каркас форм symfony2.

Сначала я создал объект с именем CompanyParameter. Добавьте пространство имен и сохраните где-нибудь в вашем комплекте.

    class CompanyParameter {    
        protected $data;    
        public function __construct($parameters,$edit=false)
        {
               if ($edit==false) {
                foreach ($parameters as $k => $value) {
                        $name = $value->getId();
                        $this->data[$name] = array("label"=>$value->getName(),"value"=>"");
                        $this->{$name} = "";                    
                }
                } else {
                foreach ($parameters as $k => $value) {
                        $name = $value->getParameterid();
                        $pvalue = $value->getValue();
                        $this->data[$name] = array("label"=>$value->getName(),"value"=>$pvalue);
                        $this->{$name} = $pvalue;                    
                }
}
        }    
        public function get() { return $this->data; }    
    }

Создайте новую переменную с классом и отправьте в нее ваши параметры.

$parameters = $em->getRepository("YourBundle:Parameter")->findAll();
$companyparameter = new CompanyParameter($parameters);

Теперь у вас есть объект со всеми динамическими параметрами, которыми вы хотите управлять. (Если вы хотите загрузить CompanyParameter с уже сохраненными значениями для целей редактирования, просто отправьте CompanyParameter массив сущностей ParameterValue и установите $ edit = true в конструкторе.

Создайте CompanyParameterFormType, как описано в http://symfony.com/doc/current/book/forms.html#creating-form-classes Убедитесь, что data_class указывает на CompanyParameter

Создайте новую форму в вашем контроллере:

$form = $this->createForm(new CompanyParameterTypeBundle(), $companyparameter);

Внутри компанииParameterFormType:

    public function buildForm(FormBuilder $builder, array $options)
    {
        $data = $options["data"]->get();      
        foreach ($data as $k => $value) {
             $builder->add($k,"text",array("label"=>$value["label"]));
        }           
    }

Если бы мы использовали $ form-> createView (), у нас теперь была бы форма с двумя полями «Название компании» и «Генеральный директор».

Заполните форму и отправьте отправку формы обратно на то же действие.

В действии проверьте post и $ form-> bindRequest ($ this-> getRequest ()).

CompanyParameter теперь содержит все значения параметров, принадлежащих текущей компании. Чтобы сохранить эти данные:

$data = $companyparameter->get();
$counter = 0;
foreach($data as $k => $value) {
$parameter = new ParameterValue();
$parameter->setCompany($company);
$parameter->setParameter($parameters[$counter]);
$parameter->setValue($value["value"]);
$em->persist($parameter);
$counter++;
}

Если вы вместо этого редактируете параметры

$data = $companyparameter->get();
foreach ($parameters as $k => $value) {
$value->setValue($data[$value->getParameterid()]["value"]);
$em->persist($value);
}

Надеюсь, это поможет некоторым. Моя первая публикация, и я еще не привык «объяснять» код, так что имейте в виду, пожалуйста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...