/** * Adds field for editing named property of associated item using provided * editor element. * * @param string $propertyName name of property to edit using provided editor element * @param string|null $label label to use on field * @param model_editor_element $type editor element to use on adjusting property * @return $this */ public function addField($propertyName, $label = null, model_editor_element $type = null) { $propertyName = trim($propertyName); if (!$this->class->getMethod('isPropertyName')->invoke(null, $propertyName)) { $isRelation = false; if ($type instanceof model_editor_related) { try { $this->class->getMethod('relation')->invoke(null, $propertyName); $isRelation = true; } catch (\InvalidArgumentException $e) { } } if (!$isRelation) { throw new \InvalidArgumentException('no such property in associated model: ' . $propertyName); } } if ($type === null) { $type = new model_editor_text(); } $type->setEditor($this); if ($label === null) { $label = $this->class->getMethod('nameToLabel')->invoke(null, $propertyName); } if (trim($label) === '') { throw new \InvalidArgumentException('missing label on editor property: ' . $propertyName); } $fieldName = $this->propertyToField($propertyName); if (array_key_exists($fieldName, $this->fields)) { throw new \InvalidArgumentException('field exists already'); } $field = new model_editor_field($fieldName, $label, $type); $this->fields[$fieldName] = $field; if ($this->item) { // ensure field may act on selecting particular item (done before) $type->onSelectingItem($this, $this->item, $field); } return $this; }