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; } }