Skip to content

Instantly share code, notes, and snippets.

@makerlabs
Last active May 2, 2018 13:34
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 makerlabs/dd42a36d3a6c72e84717704e3af6319c to your computer and use it in GitHub Desktop.
Save makerlabs/dd42a36d3a6c72e84717704e3af6319c to your computer and use it in GitHub Desktop.
Phalcon Form array notation support
<?php
namespace Library\Forms;
class Form extends \Phalcon\Forms\Form
{
protected $_name = null;
protected $_namespace = null;
protected $_namespaceId = null;
protected $_forms = array();
protected $_parent = null;
/**
* Set parent form instance
* @param Form $parent
*/
public function setParent(Form $parent)
{
$this->_parent = $parent;
}
/**
* Get parent form instance
* @return Form
*/
public function getParent()
{
return $this->_parent;
}
/**
* Check if parent form exists
* @return bool
*/
public function hasParent()
{
return $this->_parent !== null;
}
/**
* {@inheritdoc}
*/
public function bind(array $data, $entity, $whitelist = null)
{
$data = $this->getData($data);
$ret = parent::bind($data, $entity, $whitelist);
foreach ($this->_forms as $form) {
$form->bind($data, $form->getEntity());
}
return $ret;
}
/**
* {@inheritdoc}
*/
public function isValid($data = null, $entity = null)
{
$data = $this->getData($data);
$ret = parent::isValid($data, $entity);
foreach ($this->_forms as $form) {
if (!$form->isValid($data)) {
$ret = false;
}
}
return $ret;
}
/**
* Sets form name
* @param string $name
* @return Form
*/
public function setName($name)
{
$this->_name = $name;
$this->_namespace = null;
$this->_namespaceId = null;
return $this;
}
/**
* Get form name (if not provided the name is autogenerated from class namespace)
* @return string
*/
public function getName()
{
if (null === $this->_name) {
$this->_name = preg_replace('/[^a-z]+/', '_', strtolower((new \ReflectionClass($this))->getName()));
}
return $this->_name;
}
/**
* Adds child form
* @param Form $form
* @param string $name Form name
* @return Form
*/
public function addForm(Form $form, $name = null)
{
if (null !== $name) {
$form->setName($name);
}
$form->setParent($this);
$this->_forms[$form->getName()] = $form;
return $this;
}
/**
* Returns all child forms
* @return array
*/
public function getForms()
{
return $this->_forms;
}
/**
* Returns child form instance
* @param string $name child form name
* @return Form
*/
public function getForm($name)
{
if (!isset($this->_forms[$name])) {
throw new \Exception("Form \"" . name . "\" is not part of the form");
}
return $this->_forms[$name];
}
/**
* {@inheritdoc}
*/
public function render($name, $attributes = null)
{
$element = $this->get($name);
$element->setAttribute('name', $this->getElementName($name));
$element->setAttribute('id', $this->getElementId($name));
return $element->render($attributes);
}
/**
* Get form namespace
* @return string
*/
protected function getNamespace()
{
if (null === $this->_namespace) {
$this->_namespace = $this->hasParent() ? $this->getParent()->getNamespace().'['.$this->getName().']' : $this->getName();
}
return $this->_namespace;
}
/**
* Get form namespace Id
* @return string
*/
protected function getNamespaceId()
{
if (null === $this->_namespaceId) {
$this->_namespaceId = rtrim(preg_replace('/[\[\]]+/', '_', $this->getNamespace()), '_');
}
return $this->_namespaceId;
}
/**
* Get form element name with namespace
* @param string $name Form element name
* @return string
*/
protected function getElementName($name)
{
return $this->getNamespace().'['.$name.']';
}
/**
* Get form element id with namespace
* @param string $name Form element name
* @return string
*/
protected function getElementId($name)
{
return $this->getNamespaceId().'_'.$name;
}
/**
* Get form data helper method
* @param array $data Form data
* @return array
*/
protected function getData(array $data)
{
return null !== $data && $this->getName() && isset($data[$this->getName()]) ? $data[$this->getName()] : $data;
}
}
@evolic
Copy link

evolic commented May 2, 2018

@makerlabs Can you provide some sample code how to use your class?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment