Array helper class for element tag name
<?php
class Arr {
/**
* Convert string a[b][c] TO a.b.c
* @param type $string
* @return type
*/
public static function stringToDotString($string) {
return trim(preg_replace('/[\[\]]+/', '.', $string), '.');
}
/**
* Convert array a[b][c] TO a.b.c
* @param type $array
* @param type $prefix
* @return array
*/
public static function arrayToPath(array $array, $prefix = '') {
$result = array();
foreach ($array as $key => $value) {
$new_key = $prefix . (empty($prefix) ? '' : '.') . $key;
if (is_array($value)) {
$result = array_merge($result, self::arrayToPath($value, $new_key));
} else {
$result[$new_key] = $value;
}
}
return $result;
}
/**
* a.b.c convert TO a[b][c]
* @param string $string
* @param mixed $value
* @param string $separator
* @return array
*/
static function stringPathToArray($string, $value = '', $separator = '.') {
$keys = array_reverse(explode($separator, $string));
$tmp = $value;
foreach ($keys as $key) {
$tmp = [$key => $tmp];
}
return $tmp;
}
/**
* Convert Array a.b.c to a[b][c]
* @param array $array
* @param string $separator
* @return array
*/
public static function pathToArray(array $array, $separator = '.') {
$result = [];
foreach ($array as $string => $value) {
$single = self::stringPathToArray($string, $value, $separator);
$result = array_merge_recursive($result, $single);
}
return $result;
}
public static function arrayToHtmlTagNames($array) {
$result = array();
$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array));
foreach ($iterator as $value) {
$dotString = '';
for ($i = 0; $i <= $iterator->getDepth(); $i++) {
if ($i == 0) {
$dotString .= $iterator->getSubIterator($i)->key();
} else {
$dotString .= "[" . $iterator->getSubIterator($i)->key() . "]";
}
}
$result[$dotString] = $value;
}
return $result;
}
/**
* a.b.c TO a[b][c]
* @param type $string
* @param type $separator
* @return type
*/
public static function stringToHtmlTagName($string, $separator = '.') {
$result = static::stringPathToArray($string, '', $separator);
$array = self::arrayToHtmlTagNames($result);
return array_keys($array)[0];
}
public static function array_values_recursive(array $array) {
$result = array();
foreach (array_keys($array) as $key) {
$value = $array[$key];
if (is_scalar($value)) {
$result[] = $value;
} elseif (is_array($value)) {
$result = array_merge($result, self::array_values_recursive($value));
}
}
return $result;
}
}
Extending form
<?php
use Arr;
use Phalcon\Forms\Element\AbstractElement;
class CustomForm extends \Phalcon\Forms\Form {
/**
* POST values to form
* @param array $data
*/
public function setDefaults(array $data) {
foreach ($data as $name => $value) {
if ($this->has($name)) {
$this->get($name)->setDefault($value); //for single element
} elseif (is_string($value) && $this->has($name . $value)) {
$this->get($name . $value)->setDefault($value); //for single radio group element
} else {
$keysValues = Arr::arrayToPath([$name => $value]);
foreach ($keysValues as $k => $v) {
if ($this->has($k)) {
$this->get($k)->setDefault($v);
} else {
$forMultipleSelectKey = join('.', explode('.', $k, -1)); //for multiple values, SELECT[] or CHECK[]
if ($this->has($k . $v)) {
$this->get($k . $v)->setDefault($v);
} else if ($this->has($forMultipleSelectKey)) {
$this->get($forMultipleSelectKey)->setDefault(Arr::array_values_recursive($value));
}
}
}
}
}
}
/**
* Render HTML element
* @param AbstractElement $element
* @return AbstractElement
*/
public function renderElement(AbstractElement $element) {
$elementID = $this->formatElementId($element);
$this->formatElementHtmlName($element);
$str = '';
$str .= '<label for="' . $elementID . '">' . $element->getLabel() . '</label>';
$str .= $element;
return $str;
}
public function formatElementId(AbstractElement $element) {
$id = $element->getAttribute('id', false);
if ($id === false) {
$element->setAttribute('id', str_replace('.', '_', $element->getName()));
}
return $element->getAttribute('id');
}
public function formatElementHtmlName(AbstractElement $element) {
$name = $element->getAttribute('name', $element->getName());
$nameAttribute = Arr::stringToHtmlTagName($name);
if ($element instanceof \Phalcon\Forms\Element\Select) {
$options = $element->getOptions();
if (isset($options['multiple'])) {
$nameAttribute .= '[]';
}
}
$element->setAttribute('name', $nameAttribute);
}
}
And yours custom form
<?php
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Select;
use App\Models\Food\CategoryModel;// use yours model
use Phalcon\Forms\Element\Check;
use Phalcon\Forms\Element\Radio;
class DummyForm extends CustomForm {
public function initialize() {
$title = new Text('a.d.f.e.f.sa.dd.f.g.h.h.e.e.e');
$title->setLabel('title');
$category = new Select('c.a.t.e.g.o.r.i.e.s.a.b.c', CategoryModel::find(), [
'emptyText' => 'Please Select...',
'emptyValue' => '',
'useEmpty' => true,
'using' => [
'id',
'title',
],
'multiple' => true,
]);
$category->setLabel('Multiple categories');
$this->add($title);
$this->add($category);
$checks = ['a', 'b', 'c'];
foreach ($checks as $key) {
$this->add(new Check('a.s.f.g.h.j.check.' . $key, ['value' => $key]));
}
foreach ($checks as $key) {
$elementId = 'sd.dg.h.j.d.d.s.s.a.b.x.radio-elements';
$this->add(new Radio($elementId . $key, ['value' => $key, 'name' => $elementId]));
}
}
}
<?php
class IndexController extends \Phalcon\Mvc\Controller {
public function indexAction() {
$form = new DummyForm();
if ($this->request->isPost()) {
$form->setDefaults($_POST);
}
$this->view->form = $form;
}
}
AND VIEW
<?php
foreach($form->getElements() as $element){
$form->renderElement($element); //important to use renderElement method
}
Thanks "_