/** * Recursivable method to build the created groups and the controls stroed as FormElement objects within each * FormGroup object. * * @param FormGroup $group * * @return string */ private function buildGroup(FormGroup $group, array $names = [], $data = [], array $errors = []) { $html = ''; // Get groupname $group_name = $group->getName(); // If group has a name, add it to the names array if ($group_name === 0 || !empty($group_name)) { $names[] = $group_name; } // Get grouperrors $group_errors = ($group_name === 0 || !empty($group_name)) && !empty($errors[$group_name]) ? $errors[$group_name] : $errors; // Get group data $group_data = ($group_name === 0 || !empty($group_name)) && !empty($data[$group_name]) ? $data[$group_name] : $data; // Build elements $elements = $group->getElements(); // Get the control size set for this group $control_size = $group->getControlSize(); /* @var $element \Core\Html\FormDesigner\FormElement */ foreach ($elements as $element) { $builder = new ControlBuilder(); $content = $element->getContent(); switch ($element->getType()) { case 'control': if (!empty($control_size)) { $content->setControlSize($control_size); } // Get control name $name = $content->getName(); // Set control id if (empty($content->getId())) { // Create control id elements $id = $this->namespace . '-'; if (!empty($names)) { $id .= implode('-', $names); } $id .= '-' . empty($name) ? uniqid('control-') : $name; $content->setId($id); } // Create control name for bound controls... if ($content->isBound()) { if (empty($name)) { throw new FormDesignerException(sprintf('Bound controls without a name are not allowed. %s', print_r($content, true))); } // Create name parts based on current group names $pieces = array_map(function ($name) { return '[' . $name . ']'; }, $names); $pieces[] = '[' . $name . ']'; $content->setName($this->namespace . implode('', $pieces)); } else { // ...and remove name from the unbound ones! $content->removeName(); } // Any errors? if (!empty($group_errors[$name])) { $builder->setErrors($group_errors[$name]); } if (isset($group_data[$name])) { switch (true) { case $content instanceof Checkbox: if ($content->getValue() == $group_data[$name]) { $content->isChecked(); } break; default: if (empty($content->getValue()) && method_exists($content, 'setValue')) { $content->setValue($group_data[$name]); } break; } } // Handle buttons if ($content instanceof Button) { // Add needed ajax data attribute if ($this->getSendMode() == 'ajax') { $content->addData('ajax'); } // Submit buttons need the id and action of and for the form to submit if ($content->isSubmit()) { $content->setFormId($this->html->getId()); $content->setFormAction($this->html->getAttribute('action')); $content->setFormMethod('post'); } } $builder->setControl($content); $builder->setDisplayMode($this->display_mode, $this->grid_size, $this->label_width); // Build control $html .= $builder->build(); break; case 'collection': /* @var $builder \Core\Html\FormDesigner\ControlBuilder */ $builder = $this->di->instance(__NAMESPACE__ . '\\ControlBuilder'); foreach ($content->getControls() as $control) { if ($control instanceof AbstractForm) { $builder->setControl($control); $content->addInner($builder->build()); } else { $content->addInner($control->build()); } } $content->clearControls(); $html .= $content->build(); break; case 'factory': $html .= $content->build(); break; case 'html': $html .= $content; break; case 'group': $html .= $this->buildGroup($content, $names, $group_data, $group_errors); break; } } $group->html->addInner($html); return $group->html->build(); }