'HTML', 'errorAlertEnabled' => true, ); protected $_ajaxValidation = true; protected $_cancelUrl; protected $_prependId = false; protected $_layout = 'default'; protected $_initializedRender = false; protected $_hiddenElements = array(); protected $_disabledInitRender = false; protected $_elementRemovableDecorators = array('HtmlTag', 'Label', 'DtDdWrapper'); protected $_groupRemovableDecorators = array('HtmlTag', 'Fieldset', 'DtDdWrapper'); public function init() { $this->addElementPrefixPath('Qs_Filter', 'Qs/Filter/', Zend_Form_Element::FILTER); $this->addElementPrefixPath('Zend_Validate', 'Zend/Validate/', 'validate'); $this->addElementPrefixPath('Zend_Validate_File', 'Zend/Validate/File', 'validate'); $this->addElementPrefixPath('Qs_Validate', 'Qs/Validate/', 'validate'); $this->addElementPrefixPath('Qs_Validate_File', 'Qs/Validate/File', 'validate'); $this->addElementPrefixPath('Qs_Form_Decorator', 'Qs/Form/Decorator/', 'decorator'); $this->addPrefixPath('Qs_Form_Element', 'Qs/Form/Element/', 'element'); $this->addPrefixPath('Qs_Form_Decorator', 'Qs/Form/Decorator/', 'decorator'); return $this; } public function prependId($flag = true) { $this->_prependId = $flag; return $this; } protected function _prepareData($data = null) { if (null === $data) { $method = strtoupper($this->getAttrib('method')); $data = ('GET' == $method) ? $_GET : $_POST; if (version_compare(phpversion(), '5.3.0', '<') && 1 == get_magic_quotes_gpc()) { $data = $this->_recursiveFilter('stripslashes', $data); } } return $data; } public function setScriptOptions(array $options) { $this->_scriptOptions = $options; return $this; } public function getScriptOptions() { $this->getErrorDisplayMethod(); // init ErrorDisplayMethod $this->_scriptOptions['prependId'] = $this->_prependId; $this->_scriptOptions['isErrors'] = $this->isErrors(); return $this->_scriptOptions; } public function setScriptOption($name, $value) { $this->_scriptOptions[$name] = $value; return $this; } public function hasScriptOption($name) { return array_key_exists($name, $this->_scriptOptions); } public function getScriptOption($name) { if ($this->hasScriptOption($name)) { return $this->_scriptOptions[$name]; } return null; } public function getErrorDisplayMethod() { if (!$this->hasScriptOption('errorDisplayMethod')) { $this->setErrorDisplayMethod('html'); } return $this->getScriptOption('errorDisplayMethod'); } public function setErrorDisplayMethod($method) { $method = strtoupper($method); if (!in_array($method, array('ALERT', 'HTML'))) { throw new Qs_Form_Exception('Invalid errorDisplayMethod "' . $method . '"'); } $this->_scriptOptions['errorDisplayMethod'] = $method; return $this; } protected function _setSubformErrors(Qs_Form $form, array $messages) { foreach ($messages as $elementName => $message) { if (null !== ($element = $form->getElement($elementName))) { if (is_array($message)) { $element->addErrors($message); } else { $element->addError($message); } } else if (null !== ($subForm = $form->getSubForm($elementName))) { $this->_setSubformErrors($subForm, $message); } else { if (is_array($message)) { $form->addErrors($message); } else { $form->addError($message); } } } return $this; } public function validate($data = null) { $data = $this->_prepareData($data); $valid = $this->isValid($data); foreach ($this->_formRules as $rule) { if (true !== ($res = call_user_func($rule, $data))) { if (is_array($res)) { $this->_setSubformErrors($this, $res); $valid = false; } else { throw new Zend_Form_Exception(__CLASS__ . '::' . __METHOD__ . '. Form rule callback returned invalid value'); } } } return $valid; } public function validatePartial($data = null) { $data = $this->_prepareData($data); $valid = $this->isValidPartial($data); foreach ($this->_formRules as $rule) { if (true !== ($res = call_user_func($rule, $data, true))) { // isXmlHttpRequest = true if (is_array($res)) { $res = array_intersect_key($res, $data); if (empty($res)) { continue; } } if (is_array($res)) { $this->_setSubformErrors($this, $res); $valid = false; } else { throw new Zend_Form_Exception(__CLASS__ . '::' . __METHOD__ . '. Form rule callback returned invalid value'); } } } return $valid; } public function validateAjax($data = null) { $this->setIgnoreFiles(true); $_data = $this->getValues(); // Get display value for Qs_Form_Element_Autocomplete foreach ($this as $item) { if ($item instanceof Qs_Form_Element_Autocomplete) { Qs_Array::set($_data, $item->getFullyQualifiedDisplayName(), ''); Qs_Array::set($_data, $item->getFullyQualifiedTitleName(), ''); } } // End get display value for Qs_Form_Element_Autocomplete $data = $this->_prepareData($data); $data = array_intersect_key($data, $_data); $data = array_merge($_data, $data); $valid = $this->isValidPartial($data); foreach ($this->_formRules as $rule) { if (true !== ($res = call_user_func($rule, $data, true))) { // isXmlHttpRequest = true if (is_array($res)) { $res = array_intersect_key($res, $data); if (empty($res)) { continue; } } if (is_array($res)) { $this->_setSubformErrors($this, $res); $valid = false; } else { throw new Zend_Form_Exception(__CLASS__ . '::' . __METHOD__ . '. Form rule callback returned invalid value'); } } } return $valid; } function _recursiveFilter($filter, $value) { if (is_array($value)) { $cleanValues = array(); foreach ($value as $k => $v) { $cleanValues[$k] = $this->_recursiveFilter($filter, $v); } return $cleanValues; } else { return call_user_func($filter, $value); } } public function getCancelUrl() { if (null === $this->_cancelUrl) { $this->_cancelUrl = Qs_Constant::get('BASE_URL_LANGUAGE') . '/' . Qs_Constant::get('CURRENT_PAGE') . '?action=cancel'; } return $this->_cancelUrl; } public function setCancelUrl($url) { $this->_cancelUrl = $url; return $this; } public function addFormRule($rule) { if (!is_callable($rule)) { // require_once 'Zend/Form/Exception.php'; throw new Zend_Form_Exception(__CLASS__ . '::' . __METHOD__ . '. Callback function does not exist'); } $this->_formRules[] = $rule; return $this; } public function getHtmlTagOptions() { $idForm = $this->getAttrib('id'); if (!empty($idForm)) { $htmlTagOptions = array('tag' => 'dl', 'class' => $idForm.'_elements', 'id' => $idForm.'_elements'); } else { $htmlTagOptions = array('tag' => 'dl', 'class' => 'zend_form'); } return $htmlTagOptions; } public function loadDefaultDecorators() { if ($this->loadDefaultDecoratorsIsDisabled()) { return; } $decorators = $this->getDecorators(); if (empty($decorators)) { $this->addDecorator('FormElements') ->addDecorator('HtmlTag', $this->getHtmlTagOptions()) ->addDecorator('Form'); } } public function getView() { if (null === $this->_view) { $view = Qs_View::getInstance(); $this->setView($view); } return $this->_view; } public function render(Zend_View_Interface $view = null) { $this->initRender(); if (null !== $view) { $this->setView($view); } $content = ''; foreach ($this->getDecorators() as $decorator) { $decorator->setElement($this); $content = $decorator->render($content); } return $content; } public function getElementsOrder() { return $this->_order; } public function setAjaxValidation($flag) { $this->_ajaxValidation = (bool) $flag; return $this; } public function getAjaxValidation() { return $this->_ajaxValidation; } public function setIgnoreFiles($flag) { foreach ($this->getElements() as $element) { if ($element instanceof Zend_Form_Element_File) { $element->setIgnore($flag); } } return $this; } protected function _elementInitRender($element) { foreach ($element->getDecorators() as $decorator) { if (method_exists($decorator, 'initRender')) { $decorator->setElement($element); $decorator->initRender(); } } return $this; } public function initRender() { if ($this->_initializedRender) { return false; } $belongsTo = $this->getElementsBelongTo(); foreach ($this as $item) { // automatic set enctype multipart if (($item instanceof Zend_Form_Element_File) || (($item instanceof Zend_Form) && (Zend_Form::ENCTYPE_MULTIPART == $item->getEnctype())) || (($item instanceof Zend_Form_DisplayGroup) && (Zend_Form::ENCTYPE_MULTIPART == $item->getAttrib('enctype'))) ) { if ($this instanceof Zend_Form) { $this->setEnctype(Zend_Form::ENCTYPE_MULTIPART); } elseif ($this instanceof Zend_Form_DisplayGroup) { $this->setAttrib('enctype', Zend_Form::ENCTYPE_MULTIPART); } } // set belongs if ($item instanceof Zend_Form_Element) { $item->setBelongsTo($belongsTo); if (method_exists($item, 'initRender')) { $item->initRender(); } } elseif (!empty($belongsTo) && ($item instanceof Zend_Form)) { if ($item->isArray()) { $name = $this->_mergeBelongsTo($belongsTo, $item->getElementsBelongTo()); $item->setElementsBelongTo($name, true); } else { $item->setElementsBelongTo($belongsTo, true); } } elseif ($item instanceof Zend_Form_DisplayGroup) { foreach ($item as $element) { if (!empty($belongsTo)) { $element->setBelongsTo($belongsTo); if (method_exists($element, 'initRender')) { $item->initRender(); } } if ($element instanceof Zend_Form_Element_File) { if ($this instanceof Zend_Form) { $this->setEnctype(Zend_Form::ENCTYPE_MULTIPART); } else if ($this instanceof Zend_Form_DisplayGroup) { $this->setAttrib('enctype', Zend_Form::ENCTYPE_MULTIPART); } } $this->_elementInitRender($element); } } } $this->_prepareForm($this); if (!$this->_disabledInitRender) { $this->_elementInitRender($this); foreach ($this as $item) { if ($item instanceof Zend_Form) { continue; } $this->_elementInitRender($item); } } $this->_initializedRender = true; return true; } protected function _mergeBelongsTo($baseBelongsTo, $belongsTo) { $endOfArrayName = strpos($belongsTo, '['); if ($endOfArrayName === false) { return $baseBelongsTo . '[' . $belongsTo . ']'; } $arrayName = substr($belongsTo, 0, $endOfArrayName); return $baseBelongsTo . '[' . $arrayName . ']' . substr($belongsTo, $endOfArrayName); } protected function _prepareForm(Qs_Form $form, $belongsTo = array()) { if ($form instanceof Zend_Form && ($_belongsTo = $form->getElementsBelongTo())) { if (strpos($_belongsTo, '[')) { $_belongsTo .= '[]'; $parts = explode('[', str_replace(']', '', $_belongsTo)); $parts = array_filter($parts, 'strlen'); $belongsTo = array_merge($belongsTo, $parts); } else { $belongsTo[] = $_belongsTo; } } if ($this->_prependId) { $form->getDecorator('HtmlTag')->setOption('id', $form->getId() . '-elements'); } foreach ($form as $item) { if ($item instanceof Zend_Form_Element) { $this->_prepareElement($item, $belongsTo); } elseif ($item instanceof Zend_Form) { $this->_prepareForm($item, $belongsTo); } elseif ($item instanceof Zend_Form_DisplayGroup) { $this->_prepareDisplayGroup($item, $belongsTo); } } return $this; } public function getDisabledInitRender() { return $this->_disabledInitRender; } public function setDisabledInitRender($flag) { $this->_disabledInitRender = (bool) $flag; foreach ($this as $item) { if ($item instanceof Zend_Form) { $item->setDisabledInitRender($flag); } } return $this; } protected function _prepareElement($element, $belongsTo) { if (!$element->getAttrib('class')) { $class = $element->getType(); $class = strtolower(str_replace(array('Zend_Form_Element_', 'Qs_Form_Element_'), '', $class)); $element->setAttrib('class', $class); } if ('disabled' === $element->getAttrib('disabled') && false === strpos($element->getAttrib('class'), 'disabled')) { $element->setAttrib('class', $element->getAttrib('class') . ' disabled'); } if ($this->_prependId) { $element->setAttrib('id', $this->getId() . '-' . $element->getId()); array_unshift($belongsTo, $this->getId()); } if ($belongsTo) { if (($htmlTag = $element->getDecorator('HtmlTag')) && ($id = $htmlTag->getOption('id'))) { $htmlTag->setOption('id', implode('-', $belongsTo) . '-'. $element->getName() . '-element'); } } return $this; } protected function _getIdFromName($name) { $id = $name; if (substr($id, -2) == '[]') { $id = substr($id, 0, strlen($id) - 2); } if (strstr($id, ']')) { $id = trim($id, ']'); $id = str_replace('][', '-', $id); $id = str_replace('[', '-', $id); } return $id; } protected function _prepareDisplayGroup($element, $belongsTo) { if (($dtDdWrapper = $element->getDecorator('DtDdWrapper'))) { $prefixId = ''; if ($this->_prependId) { $prefixId = $this->getId() . '-'; } if (!empty($belongsTo)) { $prefixId .= implode('-', $belongsTo) . '-'; } if (!empty($prefixId)) { $dtDdWrapper->setDtAttrib('id', $prefixId . $element->getName() . '-label'); $dtDdWrapper->setDdAttrib('id', $prefixId . $element->getName() . '-element'); } } foreach ($element as $item) { if ($item instanceof Zend_Form_Element) { $this->_prepareElement($item, $belongsTo); } elseif ($item instanceof Zend_Form) { $this->_prepareForm($item, $belongsTo); } elseif ($item instanceof Zend_Form_DisplayGroup) { $this->_prepareDisplayGroup($item, $belongsTo); } } return $this; } public function setElementRemovableDecorators(array $decorators) { $this->_elementRemovableDecorators = $decorators; return $this; } public function setGroupRemovableDecorators(array $decorators) { $this->_groupRemovableDecorators = $decorators; return $this; } public function unsetElementRemovableDecorator($spec) { return $this->_unsetRemovableDecorator('element', $spec); } public function unsetGroupRemovableDecorator($spec) { return $this->_unsetRemovableDecorator('group', $spec); } protected function _unsetRemovableDecorator($type, $spec) { $decorators = &$this->{"_{$type}RemovableDecorators"}; if (is_string($spec)) { $spec = array($spec); } foreach ($spec as $name) { if (!is_string($name)) { throw new Qs_Form_Exception('Invalid type in decorator name'); } if (false !== ($key = array_search($name, $decorators))) { unset($decorators[$key]); } } return $this; } public function removeContainers() { $this->removeDecorator('HtmlTag'); foreach ($this as $item) { if ($item instanceof Qs_Form) { $item->removeContainers(); continue; } else if ($item instanceof Zend_Form_DisplayGroup) { foreach ($this->_groupRemovableDecorators as $name) { $item->removeDecorator($name); } } else if ($item instanceof Zend_Form_Element) { foreach ($this->_elementRemovableDecorators as $name) { $item->removeDecorator($name); } } } return $this; } public function __clone() { $elements = array(); foreach ($this->getElements() as $name => $element) { $elements[] = clone $element; } $this->setElements($elements); $decorators = array(); foreach ($this->getDecorators() as $decorator) { $decorators[] = clone $decorator; } $this->setDecorators($decorators); $subForms = array(); foreach ($this->getSubForms() as $name => $subForm) { $subForms[$name] = clone $subForm; } $this->setSubForms($subForms); $displayGroups = array(); foreach ($this->_displayGroups as $group) { $clone = clone $group; $elements = array(); foreach ($clone->getElements() as $name => $e) { $elements[] = $this->getElement($name); } $clone->setElements($elements); $displayGroups[] = $clone; } $this->setDisplayGroups($displayGroups); } public function addGlobalFilter() { $arguments = func_get_args(); foreach ($this->getElements() as $element) { call_user_func_array(array($element, 'addFilter'), $arguments); } return $this; } }