Skip to content

Instantly share code, notes, and snippets.

@juzna
Created December 27, 2011 14:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juzna/1523774 to your computer and use it in GitHub Desktop.
Save juzna/1523774 to your computer and use it in GitHub Desktop.
Data binding in Nette
<?php
class EntityForm extends Form {
/**
* Bind entity to this form and set default values from it
*
* @param \Nella\Models\IEntity $entity
* @throws \Nette\InvalidStateException
*/
public function bind(\Nella\Models\IEntity $entity)
{
if (!$this->isAnchored()) throw new \Nette\InvalidStateException("Form is not attached to a presenter, unable to set");
if (!$this->isSubmitted()) $this->populateFormControls($entity);
}
/**
* Populate values from entity
*
* @param \Nella\Models\IEntity $object
*/
public function populateFormControls(\Nella\Models\IEntity $object)
{
foreach ($this->controls as /** @var \Nette\Forms\Controls\BaseControl $control */ $control) {
if ($binding = $control->getDataBinding()) {
$control->setValue($this->getEntityField($object, $binding));
}
}
}
/**
* Populate one field of entity with a given value
*
* @param \Nella\Models\IEntity $object
* @param string $property
* @return mixed
*/
protected function getEntityField(\Nella\Models\IEntity $object, $property)
{
$ident = '[a-zA-Z0-9_]+';
if (preg_match("/^$ident$/i", $property)) { // simple property
return $object->$property;
} elseif (preg_match("/^($ident)(?:\\[($ident)\\])?(?:\\.(.+))?$/i", $property, $match)) { // property[index].x
$baseName = $match[1];
$index = isset($match[2]) ? $match[2] : null;
$hasSubProperty = isset($match[3]);
if ($hasSubProperty) { // recurse
$subProperty = $match[3];
$ref = $object->$baseName;
if ($index !== null) $ref = $ref[$index];
return $this->getEntityField($ref, $subProperty);
} else { // no sub-property, assign directly to index
if ($index === null) throw new \Nette\InvalidStateException('Should never happen!');
return $object->$property[$index];
}
} else {
return NULL; // Unknown
}
}
/**
* Populate entity with data from this form
*
* @param \Nella\Models\IEntity $object
*/
public function populateEntity(\Nella\Models\IEntity $object)
{
foreach ($this->controls as /** @var \Nette\Forms\Controls\BaseControl $control */ $control) {
if ($binding = $control->getDataBinding()) {
$this->populateEntityField($object, $binding, $control->getValue());
}
}
}
/**
* Populate one field of entity with a given value
*
* @param \Nella\Models\IEntity $object
* @param string $property
* @param mixed $value
*/
protected function populateEntityField(\Nella\Models\IEntity $object, $property, $value)
{
$ident = '[a-zA-Z0-9_]+';
if (preg_match("/^$ident$/i", $property)) { // simple property
$object->$property = $value;
} elseif (preg_match("/^($ident)(?:\\[($ident)\\])?(?:\\.(.+))?$/i", $property, $match)) { // property[index].x
$baseName = $match[1];
$index = isset($match[2]) ? $match[2] : null;
$hasSubProperty = isset($match[3]);
if ($hasSubProperty) { // recurse
$subProperty = $match[3];
$ref = $object->$baseName;
if ($index !== null) $ref = $ref[$index];
$this->populateEntityField($ref, $subProperty, $value);
} else { // no sub-property, assign directly to index
if ($index === null) throw new \Nette\InvalidStateException('Should never happen!');
$object->$property[$index] = $value;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment