public function input($name, array $attributes = null, array $properties = null, $template = 'replace-with-default')
{
if ($properties === null) {
$properties = [];
}
if ($template === 'replace-with-default') {
$template = $this->template;
}
// Incremental input index is based on input name.
if (!isset($this->input_index[$name])) {
$this->input_index[$name] = [];
}
$index = count($this->input_index[$name]);
if (isset($properties['value'])) {
throw new Exception\InvalidArgumentException('Input instantiated using Form::input() method cannot explicitly define "value" property.');
}
if (isset($properties['uid'])) {
throw new Exception\InvalidArgumentException('Input instantiated using Form::input() method cannot explicitly define "uid" property.');
}
$properties['uid'] = crc32($this->uid . '_' . $name . '_' . $index);
$input = new Input($name, $attributes, $properties, $template);
#$template = $template ? $template : $this->template;
#$this->input_index[$name][] = $input;
$this->input_index[$name][] = null;
// Input name path (e.g. foo[bar]) is used to resolve input value from the Form instance data.
$path = $input->getNamePath();
$value = $this->getData();
// Indicates whether input name attribute implies that expected value is an array, e.g. foo[].
$declared_as_array = false;
if (strpos(strrev($name), '][') === 0) {
array_pop($path);
$declared_as_array = true;
}
foreach ($path as $crumble) {
if (!isset($value[$crumble])) {
$value = null;
break;
}
$value = $value[$crumble];
}
if (is_array($value)) {
if (!$declared_as_array) {
$value = null;
} else {
if (isset($attributes['multiple'])) {
$value = $value;
} else {
if (isset($value[$index])) {
$value = $value[$index];
} else {
$value = null;
}
}
}
} else {
if ($declared_as_array) {
$value = null;
}
}
$input->setProperty('value', $value);
return $input;
}