setAction($action);
if ($csrf === true) {
$this->addElement(new Element\Csrf());
}
}
/**
*
* get form action
*
* @return string
*/
public function getAction()
{
return $this->_action;
}
/**
*
* set the action of the form
*
* @param string $action
*
* @return $this
*/
public function setAction($action)
{
$this->_action = $action;
return $this;
}
/**
*
* get form method
*
* @return string
*/
public function getMethod()
{
return $this->_method;
}
/**
*
* set the method of the form
*
* @param string $method get|post
*
* @return $this
* @throws \InvalidArgumentException
*/
public function setMethod($method)
{
$method = strtoupper($method);
if ($method !== self::METHOD_GET && $method !== self::METHOD_POST) {
throw new \InvalidArgumentException(
sprintf("Invalid form method provided, '%s'.", $method));
}
$this->_method = $method;
return $this;
}
/**
*
* get form elements
*
* @return array
*/
public function getElements()
{
return $this->_elements;
}
/**
*
* return true if the form has elements, false otherwise
*
* @return bool
*/
public function hasElements()
{
return (count($this->_elements) > 0) ? true : false;
}
/**
*
* get a single form element
*
* @param string $name
*
* @return \Cube\Form\Element
* @throws \InvalidArgumentException
*/
public function getElement($name)
{
if (isset($this->_elements[$name])) {
return $this->_elements[$name];
}
else {
throw new \InvalidArgumentException(
sprintf("The element with the name '%s' does not exist in the form.", $name));
}
}
/**
*
* check if an element exists in the form
*
* @param string $name
*
* @return bool
*/
public function hasElement($name)
{
return (isset($this->_elements[$name])) ? true : false;
}
/**
*
* remove an element from the form
*
* @param string $name
*
* @return $this
*/
public function removeElement($name)
{
if (isset($this->_elements[$name])) {
unset($this->_elements[$name]);
}
return $this;
}
/**
*
* remove all elements from the form
*
* @return $this
*/
public function clearElements()
{
$this->_elements = array();
return $this;
}
/**
*
* add elements to the form
*
* @param array $elements
*
* @return $this
*/
public function addElements(array $elements)
{
foreach ($elements as $element) {
$this->addElement($element);
}
return $this;
}
/**
*
* add a string element to the form
* overwrites an element with the same name
*
* @param \Cube\Form\Element $element
*
* @return $this
* @throws \InvalidArgumentException
*/
public function addElement(Element $element)
{
$this->_elements[(string)$element->getName()] = $element;
return $this;
}
/**
*
* method to create a new form element
*
* @param string $element the element type
* @param string $name the name of the element
*
* @return \Cube\Form\Element returns a form element object
*/
public function createElement($element, $name)
{
$elementClass = '\\Cube\\Form\\Element\\' . ucfirst($element);
if (class_exists($element)) {
return new $element($name);
}
else if (class_exists($elementClass)) {
return new $elementClass($name);
}
else {
return new Element($element, $name);
}
}
/**
*
* get data
*
* @param string $key
*
* @return mixed
*/
public function getData($key = null)
{
if ($key !== null) {
if (!empty($this->_data[$key])) {
return $this->_data[$key];
}
return null;
}
return $this->_data;
}
/**
*
* set the data of the submitted form,
* plus set the submit data for each element in the form
* the data array is filter on a per element basis
*
* @param array $data form data
*
* @return $this
*/
public function setData(array $data = null)
{
$this->_data = $data;
/* @var \Cube\Form\Element $element */
foreach ($this->_elements as $element) {
$elementName = $element->getName();
preg_match_all("/\[([^\]]*)\]/", $elementName, $matches);
$matches = array_filter($matches);
$betweenBrackets = null;
if (count($matches) > 0) {
$betweenBrackets = reset($matches[1]);
$elementName = str_replace(reset($matches[0]), '', $elementName);
}
if (array_key_exists($elementName, $this->_data)) {
if (!empty($betweenBrackets)) {
$elementData = isset($this->_data[$elementName][$betweenBrackets]) ?
$this->_data[$elementName][$betweenBrackets] : null;
$element->setData($elementData);
$this->_data[$elementName][$betweenBrackets] = $element->getValue();
}
else {
$element->setData($this->_data[$elementName]);
$this->_data[$elementName] = $element->getValue();
}
}
}
return $this;
}
/**
*
* get the title set for the form
*
* @return string
*/
public function getTitle()
{
$translate = $this->getTranslate();
if (null !== $translate) {
return $translate->_($this->_title);
}
return $this->_title;
}
/**
*
* set a title for the form
*
* @param string $title
*
* @return $this
*/
public function setTitle($title)
{
$this->_title = (string)$title;
return $this;
}
/**
*
* get the description set for the form
*
* @return string
*/
public function getDescription()
{
$translate = $this->getTranslate();
if (null !== $translate) {
return $translate->_($this->_description);
}
return $this->_description;
}
/**
*
* set a description for the form
*
* @param string $description
*
* @return $this
*/
public function setDescription($description)
{
$this->_description = (string)$description;
return $this;
}
/**
*
* get the messages resulted from an isValid function
*
* @return array
*/
public function getMessages()
{
return $this->_messages;
}
/**
*
* set multiple validation messages
*
* @param array $messages
*
* @return $this
*/
public function setMessages(array $messages = null)
{
foreach ($messages as $message) {
$this->setMessage($message);
}
return $this;
}
/**
*
* clear form validator messages
*
* @return $this
*/
public function clearMessages()
{
$this->_messages = array();
return $this;
}
/**
*
* add a new validation message, but only if the message is not empty
* also translate the message if a translate adapter is available
*
* @param string $message
*/
public function setMessage($message)
{
if (!empty($message)) {
$translate = $this->getTranslate();
if (null !== $translate) {
$message = $translate->_($message);
}
$this->_messages[] = $message;
}
}
/**
*
* get the view object
*
* @return \Cube\View
*/
public function getView()
{
if ($this->_view === null) {
$this->setView();
}
return $this->_view;
}
/**
* set the view object
*
* @param \Cube\View $view
*
* @return $this
*/
public function setView(View $view = null)
{
if (!$view instanceof View) {
$bootstrap = Front::getInstance()->getBootstrap();
if ($bootstrap->hasResource('view')) {
$view = $bootstrap->getResource('view');
}
else {
$view = new View();
}
}
$this->_view = $view;
return $this;
}
/**
*
* get the view file
*
* @return string
*/
public function getPartial()
{
return $this->_partial;
}
/**
*
* set the view partial
*
* @param string $partial
*
* @return $this
*/
public function setPartial($partial)
{
$this->_partial = $partial;
return $this;
}
/**
*
* set translate adapter
*
* @param \Cube\Translate\Adapter\AbstractAdapter $translate
*
* @return $this
*/
public function setTranslate(TranslateAdapter $translate)
{
$this->_translate = $translate;
return $this;
}
/**
*
* get translate adapter
*
* @return \Cube\Translate\Adapter\AbstractAdapter
*/
public function getTranslate()
{
if (!$this->_translate instanceof TranslateAdapter) {
$translate = Front::getInstance()->getBootstrap()->getResource('translate');
if ($translate instanceof Translate) {
$this->setTranslate(
$translate->getAdapter());
}
}
return $this->_translate;
}
/**
*
* checks if the form is valid based on the validators entered for each element
*
* @return bool
*/
public function isValid()
{
$valid = true;
/* @var \Cube\Form\Element $element */
foreach ($this->_elements as $element) {
$required = $element->getRequired();
/**
* in case we have an array in the required field, we will check
* for the dependency first to see whether the field is required or not.
*/
if (is_array($required)) {
$required = ($this->_data[$required[0]] == $required[1]) ? $required[2] : !$required[2];
}
if ($required === true) {
$element->addValidator(
new Validate\NotEmpty());
}
$valid = ($elementValid = $element->isValid()) ? $valid : false;
if (!$elementValid) {
$this->setMessages(
$element->getMessages());
}
}
return (bool)$valid;
}
/**
*
* renders all hidden elements for the form
* called in the view partial file, usable through the __get() magic method
* Important: by default, multiple hidden elements are not rendered
*
* @param bool $multiple
*
* @return string
*/
public function getHiddenElements($multiple = false)
{
$elements = null;
/* @var \Cube\Form\Element $element */
foreach ($this->_elements as $element) {
if ($element->isHidden() && (!$element->getMultiple() || $multiple)) {
$elements .= $element->render() . "\n";
}
}
return $elements;
}
/**
*
* renders the form
* if no action is set, use the request uri
*
* @return string the formatted html
*/
public function render()
{
$this->renderHeaderCode();
$this->renderBodyCode();
if (!$this->getAction()) {
$request = Front::getInstance()->getRequest();
$action = $request->getBaseUrl() . $request->getRequestUri();
$this->setAction($action);
}
$view = $this->getView();
$view->set('form', $this);
return $view->process(
$this->getPartial(), true);
}
/**
*
* when called, it will get the header code from all elements
* and append it to the Script view helper
*
* @return string
*/
public function renderHeaderCode()
{
/* @var \Cube\View\Helper\Script $helper */
$helper = $this->getView()->getHelper('script');
/* @var \Cube\Form\Element $element */
foreach ($this->_elements as $element) {
$elementHeaderCode = $element->getHeaderCode();
foreach ($elementHeaderCode as $code) {
$helper->addHeaderCode($code);
}
}
return $this;
}
/**
*
* when called, it will get the body code from all elements
* and append it to the Script view helper
*
* @return string
*/
public function renderBodyCode()
{
/* @var \Cube\View\Helper\Script $helper */
$helper = $this->getView()->getHelper('script');
/* @var \Cube\Form\Element $element */
foreach ($this->_elements as $element) {
$elementBodyCode = $element->getBodyCode();
foreach ($elementBodyCode as $code) {
$helper->addBodyCode($code);
}
}
return $this;
}
/**
*
* get magic method, enables echo $form->name
* name will be the name of an element, and when called, it will render it
*
* @param string $name
*
* @return mixed|string the rendered element
* @throws \InvalidArgumentException an error is thrown if the element doesnt exist
*/
public function get($name)
{
$method = 'get' . ucfirst($name);
if (method_exists($this, $method)) {
return $this->$method();
}
else if (isset($this->_elements[$name])) {
return $this->_elements[$name]->render();
}
else {
throw new \InvalidArgumentException(
sprintf("The element with the name '%s' does not exist in the form.", $name));
}
}
/**
*
* get magic method, proxy to $this->get($name)
*
* @param string $name
*
* @return string|null
*/
public function __get($name)
{
return $this->get($name);
}
/**
*
* toString magic method, enabled echo $form
*
* @return string
*/
public function __toString()
{
try {
$render = $this->render();
} catch (\Exception $e) {
$render = 'Form rendering error: ' . $e->getMessage();
}
return $render;
}
}