'HTML', 'formErrorsDisplayMethod' => 'HTML', 'errorAlertEnabled' => true, ]; protected $_ajaxValidation = true; protected $_cancelUrl; protected $_prependId = false; protected $_prependString; protected $_layout = 'default'; protected $_initializedRender = false; protected $_hiddenElements = []; protected $_disabledInitRender = false; protected $_elementRemovableDecorators = ['HtmlTag', 'Label', 'DtDdWrapper']; protected $_groupRemovableDecorators = ['HtmlTag', 'Fieldset', 'DtDdWrapper']; protected $_defaults = []; protected $_cmsItemId; protected $_primaryKey = []; protected $_template; protected $_hasButtons = true; protected $_controllerAction; protected $_hasSpamProtection = false; protected $_spamProtectionType = self::SPAM_PROTECTION_COOKIE; protected $_spamProtectionMessage = 'Your data were not submitted'; protected $_spamProtectionField = [ 'label' => 'Leave Empty', 'name' => 'alternative_email_address', ]; /** @var Qs_Form */ protected $_parentForm; public function init() { $this->_initPaths(); $this->_initCmsItemIdElement(); $this->_initPrimaryKeyElements(); $this->_initElements(); $this->_initControllerAction(); $this->_initSpamProtection(); $this->_initButtons(); return $this; } protected function _initPaths() { $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 setOptions(array $options) { if (isset($options['defaults'])) { $this->_defaults = $options['defaults']; unset($options['defaults']); } return parent::setOptions($options); } protected function _initElements() { return $this; } protected function _initControllerAction() { if (null !== $this->_controllerAction && null === $this->getElement('action')) { $this->addElement('hidden', 'action', ['value' => $this->_controllerAction]); } return $this; } protected function _getDefaults() { return $this->_defaults; } public function setDefaults(array $defaults = []) { $defaults = Qs_Array::mergeRecursive($this->_getDefaults(), $defaults); return parent::setDefaults($defaults); } public function setDefaultValue($name, $value) { $this->_defaults[$name] = $value; $this->setDefault($name, $value); } public function addButtons() { $this->addElement( 'submit', 'btnSubmit', [ 'label' => 'Save', 'attribs' => ['class' => 'btn btn-primary'], ] ); $this->addElement( 'submit', 'btnCancel', [ 'label' => 'Cancel', 'attribs' => [ 'class' => 'btn', 'onclick' => "window.location.href = '" . htmlspecialchars($this->getCancelUrl()) . "';", 'helper' => 'formInputButton', ], ] ); $this->addDisplayGroup(['btnSubmit', 'btnCancel'], 'submitGroup'); return $this; } protected function _initButtons() { if ($this->_hasButtons) { $this->addButtons(); } return $this; } protected function _initCmsItemIdElement() { if ($this->getCmsItemId()) { $this->addElement('hidden', '__idItem', ['value' => $this->getCmsItemId()]); } return $this; } protected function _initPrimaryKeyElements() { foreach ($this->_primaryKey as $name => $value) { $this->addElement('hidden', $name, ['value' => $value]); } return $this; } public function setCmsItemId($id) { $this->_cmsItemId = $id; return $this; } public function getCmsItemId() { return $this->_cmsItemId; } public function setPrimaryKey(array $key) { $this->_primaryKey = $key; return $this; } public function getPrimaryKey() { return $this->_primaryKey; } public function setTemplate($template) { $this->_template = $template; return $this; } public function getTemplate() { return $this->_template; } protected function _getData($field = null, $default = null) { $result = null; $method = $this->getMethod(); if (0 === strcasecmp($_SERVER['REQUEST_METHOD'], $method)) { if (false === $field) { $result = Qs_Request::get($method); } else { $method = 'get' . ucfirst(strtolower($method)) . 'Value'; $result = Qs_Request::$method($field); } } if (null === $result) { if (null === $field) { $result = $this->_defaults; } else { $result = Qs_Array::get($this->_defaults, $field); } } return (null === $result) ? $default : $result; } public function prependId($flag = true) { $this->_prependId = $flag; return $this; } public function setPrependString($value) { $this->_prependString = (string) $value; return $this; } public function getPrependString() { if (null === $this->_prependString) { $this->_prependString = $this->getId(); } return $this->_prependString; } public function getRequestValues() { $method = strtoupper($this->getAttrib('method')); return ('GET' == $method) ? $_GET : $_POST; } public function getValidationValues() { return Qs_Array::mergeAssoc($this->getValues(), $this->getRequestValues()); } 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->_scriptOptions['prependId'] = $this->_prependId; $this->_scriptOptions['isErrors'] = $this->isErrors(); $this->_scriptOptions['requiredFiles'] = $this->_getRequiredFiles(); if (!array_key_exists('response', $this->_scriptOptions)) { $this->_scriptOptions['response']['formErrors'] = $this->getErrorMessages(); $this->_scriptOptions['response']['elementsErrors'] = $this->_getAjaxElementsErrors( $this, $this->getMessages(null, true) ); } return $this->_scriptOptions; } /** * @param null|Qs_Form $form * @return array */ protected function _getRequiredFiles(Qs_Form $form = null) { $files = []; if (null === $form) { $form = $this; } foreach ($form as $element) { if ($element instanceof Zend_Form_Element_File) { /** @var $element Zend_Form_Element_File */ if ($element->isRequired() && !$element->getValue()) { $files[] = [ 'name' => $element->getName(), 'label' => $element->getLabel(), ]; } } else if ($element instanceof Zend_Form) { /** @var $element Zend_Form */ $files = array_merge($files, $this->_getRequiredFiles($element)); } } return $files; } 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 getElementsErrorsDisplayMethod() { return Qs_Array::get($this->_scriptOptions, 'elementsErrorsDisplayMethod'); } public function setElementsErrorsDisplayMethod($method) { $method = strtoupper($method); if (!in_array($method, ['ALERT', 'HTML'])) { throw new Qs_Form_Exception('Invalid elementsErrorsDisplayMethod "' . $method . '"'); } $this->_scriptOptions['elementsErrorsDisplayMethod'] = $method; return $this; } public function getFormErrorsDisplayMethod() { return Qs_Array::get($this->_scriptOptions, 'formErrorsDisplayMethod'); } public function setFormErrorsDisplayMethod($method) { $method = strtoupper($method); if (!in_array($method, ['ALERT', 'HTML'])) { throw new Qs_Form_Exception('Invalid formErrorsDisplayMethod "' . $method . '"'); } $this->_scriptOptions['formErrorsDisplayMethod'] = $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) { if (!$this->_validateSpamProtection()) { return false; } $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) { if (!$this->_validateSpamProtection()) { return false; } $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 getAjaxData() { $this->setIgnoreFiles(true); $isArray = $this->isArray(); $this->setIsArray(false); $data = $this->getValues(); $this->setIsArray($isArray); foreach ($this as $item) { if ($item instanceof Qs_Form_Element_Autocomplete) { /** @var $item Qs_Form_Element_Autocomplete */ Qs_Array::set($data, $item->getFullyQualifiedDisplayName(), ''); Qs_Array::set($data, $item->getFullyQualifiedTitleName(), ''); } else if ( $item instanceof Qs_Form_Element_Checkbox || $item instanceof Zend_Form_Element_Radio || $item instanceof Qs_Form_Element_Rating || $item instanceof Qs_Form_Element_MultiCheckbox || $item instanceof Qs_Form_Element_MultiDraggableSelect || ($item instanceof Zend_Form_Element_Select && 'multiple' == strtolower($item->getAttrib('multiple'))) ) { /** @var $item Zend_Form_Element */ $name = $item->getName(); if ($item->isRequired() && null === Qs_Array::get($data, $name, null)) { Qs_Array::set($data, $name, ''); } } else if ($item instanceof Qs_Form_SubForm) { /** @var $item Qs_Form_SubForm */ $data[$item->getName()] = $item->getAjaxData(); } } return $data; } public function isValidAjax($data = null) { $_data = $this->getAjaxData(); $data = $this->_prepareData($data); $data = array_intersect_key($data, $_data); $data = Qs_Array::mergeRecursive($_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; } protected function _getAjaxElementsErrors(Qs_Form $form, array $elementsErrors) { $errors = []; /** @var Zend_Form_Element $element */ foreach ($form->getElements() as $name => $element) { if (isset($elementsErrors[$name])) { $pars = explode('_', get_class($element)); $elementErrors = [ 'type' => strtolower(array_pop($pars)), 'id' => $element->getId(), 'label' => $element->getLabel(), 'errors' => $elementsErrors[$name], ]; if ($element instanceof Zend_Form_Element_Captcha) { /** @var $element Zend_Form_Element_Captcha */ /** @var $captcha Qs_Captcha_Image */ $captcha = $element->getCaptcha(); $elementErrors['captcha'] = [ 'id' => $captcha->generate(), 'src' => $captcha->getImgUrl() . $captcha->getId() . $captcha->getSuffix(), ]; if ($captcha->getRefreshUrl()) { $elementErrors['captcha']['href'] = $captcha->getRefreshUrl() . '?id=' . $captcha->getId(); } if (empty($elementErrors['label'])) { $elementErrors['label'] = 'Captcha'; /** @var $translator Zend_Translate_Adapter_Gettext */ $translator = $element->getTranslator(); if (null !== $translator) { $elementErrors['label'] = $translator->translate($elementErrors['label']); } } } $errors[] = $elementErrors; } } /** @var Qs_Form_SubForm $subForm */ foreach ($form->getSubForms() as $subFormName => $subForm) { if (isset($elementsErrors[$subFormName])) { $subForm->initRender(); $errors = array_merge( $errors, $this->_getAjaxElementsErrors($subForm, $elementsErrors[$subFormName]) ); } } return $errors; } public function validateAjax() { $result = []; if (false === ($result['isValid'] = $this->isValidAjax())) { $result['formErrors'] = $this->getErrorMessages(); $result['elementsErrors'] = []; $elementsErrors = $this->getMessages(null, true); if (!empty($elementsErrors)) { $this->initRender(); // /** @var $element Zend_Form_Element */ $result['elementsErrors'] = array_merge( $result['elementsErrors'], $this->_getAjaxElementsErrors($this, $elementsErrors) ); } } return $result; } protected function _recursiveFilter($filter, $value) { if (is_array($value)) { $cleanValues = []; foreach ($value as $k => $v) { $cleanValues[$k] = $this->_recursiveFilter($filter, $v); } return $cleanValues; } else { return call_user_func($filter, $value); } } public function isSubmitted() { return 0 == strcasecmp($_SERVER['REQUEST_METHOD'], $this->getMethod()); } public function getCancelUrl() { if (null === $this->_cancelUrl) { $this->_cancelUrl = Qs_Constant::get('BASE_URL_LANGUAGE') . '/' . Qs_Constant::get('CURRENT_PAGE') . '?action=cancel'; if ($this->_getData('id')) { $this->_cancelUrl .= '&id=' . $this->_getData('id', 0); } } return $this->_cancelUrl; } public function setCancelUrl($url) { $this->_cancelUrl = $url; return $this; } /** * @param $rule * @return $this * @throws Zend_Form_Exception * @deprecated */ 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 = ['tag' => 'dl', 'class' => $idForm . '_elements', 'id' => $idForm . '_elements']; } else { $htmlTagOptions = ['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') ->addDecorator('FormErrors', ['placement' => Zend_Form_Decorator_Errors::PREPEND]); } } /** * @return Qs_View */ 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) { /*if (null !== $this->_template) { $this->initRender(); $this->removeContainers(); }*/ $this->initRender(); if (null !== $view) { $this->setView($view); } $content = ''; foreach ($this->getDecorators() as $decorator) { /** @var $decorator Zend_Form_Decorator_Abstract */ $decorator->setElement($this); if (method_exists($decorator, 'initRender')) { $decorator->initRender(); } $content = $decorator->render($content); } $this->_addResources(); 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) { /** @var $element Zend_Form_Element_File */ $element->setIgnore($flag); } } return $this; } /** * @param $element Zend_Form_Element * @return Qs_Form */ protected function _elementInitRender($element) { foreach ($element->getDecorators() as $decorator) { /** @var $decorator Zend_Form_Decorator_Abstract */ if (method_exists($decorator, 'initRender')) { $decorator->setElement($element); $decorator->initRender(); } } return $this; } public function setInitializedRender($value = true) { $this->_initializedRender = (bool) $value; return $this; } public function getInitializedRender() { return $this->_initializedRender; } public function initRender() { if ($this->getInitializedRender()) { return $this; } $this->_prepareForm($this); $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) { /** @var $item Zend_Form_Element */ $item->setBelongsTo($belongsTo); if (method_exists($item, 'initRender')) { $item->initRender(); } } else if ($item instanceof Zend_Form) { /** @var $item Qs_Form */ if (!empty($belongsTo)) { if ($item->isArray()) { $name = $this->_mergeBelongsTo($belongsTo, $item->getElementsBelongTo()); $item->setElementsBelongTo($name, true); } else { $item->setElementsBelongTo($belongsTo, true); } } } else if ($item instanceof Zend_Form_DisplayGroup) { /** @var Zend_Form_Element $element */ 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); } } } if (!$this->_disabledInitRender) { //$this->_elementInitRender($this); /* перенесено в render() */ foreach ($this as $item) { if ($item instanceof Zend_Form) { continue; } $this->_elementInitRender($item); } } $this->setInitializedRender(); return $this; } protected function _prepareForm(Qs_Form $form, $belongsTo = []) { 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) { $prefix = $form->getPrependString(); if (!empty($belongsTo)) { $prefix .= '-' . implode('-', $belongsTo); } $form->getDecorator('HtmlTag')->setOption('id', $prefix . '-elements'); } foreach ($form as $item) { if ($item instanceof Zend_Form_Element) { $this->_prepareElement($item, $belongsTo); } else if ($item instanceof Zend_Form) { $this->_prepareSubForm($item, $belongsTo); } else if ($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) { /** @var Qs_Form $item */ $item->setDisabledInitRender($flag); } } return $this; } /** * @param $element Zend_Form_Element * @param $belongsTo * @return Qs_Form */ protected function _prepareElement($element, $belongsTo) { if (!$element->getAttrib('class')) { $class = $element->getType(); $class = str_replace('\\', '_', $class); if (false !== ($position = strpos($class, 'Form_Element_'))) { $class = substr($class, $position + 13); } $element->setAttrib('class', strtolower($class)); } if ('disabled' === $element->getAttrib('disabled') && false === strpos($element->getAttrib('class'), 'disabled') ) { $element->setAttrib('class', $element->getAttrib('class') . ' disabled'); } if ($this->_prependId) { $elementBelongsTo = $element->getBelongsTo(); if (!empty($belongsTo) && empty($elementBelongsTo)) { $elementBelongsTo = $belongsTo; $belongsToString = array_shift($elementBelongsTo); if (!empty($elementBelongsTo)) { $belongsToString .= '[' . implode('][', $elementBelongsTo) . ']'; } $element->setBelongsTo($belongsToString); } $element->setAttrib('id', $this->getPrependString() . '-' . $element->getId()); array_unshift($belongsTo, $this->getPrependString()); } 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; } /** * @param $element Zend_Form_Element | Zend_Form * @param $belongsTo array * @return Qs_Form */ protected function _prepareContainersIds($element, $belongsTo) { $prefixId = ''; if ($this->_prependId) { $prefixId = $this->getPrependString() . '-'; } if (!empty($belongsTo)) { $prefixId .= implode('-', $belongsTo) . '-'; } if (!empty($prefixId)) { /** @var $dtDdWrapper Qs_Form_Decorator_DtDdWrapper */ if (($dtDdWrapper = $element->getDecorator('DtDdWrapper'))) { $dtDdWrapper->setDtAttrib('id', $prefixId . $element->getName() . '-label'); $dtDdWrapper->setDdAttrib('id', $prefixId . $element->getName() . '-element'); } /** @var $fieldSet Zend_Form_Decorator_FieldSet */ if (($fieldSet = $element->getDecorator('FieldSet'))) { $fieldSet->setOption('id', $prefixId . 'fieldset-' . $element->getName()); } } return $this; } /** * @param $element Zend_Form_Element * @param $belongsTo * @return Qs_Form */ protected function _prepareDisplayGroup($element, $belongsTo) { $this->_prepareContainersIds($element, $belongsTo); foreach ($element as $item) { if ($item instanceof Zend_Form_Element) { $this->_prepareElement($item, $belongsTo); } elseif ($item instanceof Zend_Form) { $this->_prepareSubForm($item, $belongsTo); } elseif ($item instanceof Zend_Form_DisplayGroup) { $this->_prepareDisplayGroup($item, $belongsTo); } } return $this; } /** * @param Qs_Form_SubForm $form * @param array $belongsTo * @return Qs_Form */ protected function _prepareSubForm(Qs_Form_SubForm $form, $belongsTo) { $form->prependId($this->_prependId); $form->setPrependString($this->getPrependString()); $this->_prepareContainersIds($form, $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 = [$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) { /** @var $item Qs_Form */ 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 = []; foreach ($this->getElements() as $name => $element) { $elements[] = clone $element; } $this->setElements($elements); $decorators = []; foreach ($this->getDecorators() as $decorator) { $decorators[] = clone $decorator; } $this->setDecorators($decorators); $subForms = []; foreach ($this->getSubForms() as $name => $subForm) { $subForms[$name] = clone $subForm; } $this->setSubForms($subForms); $displayGroups = []; foreach ($this->_displayGroups as $group) { /** @var Zend_Form_DisplayGroup $clone */ $clone = clone $group; $elements = []; 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([$element, 'addFilter'], $arguments); } return $this; } public function setHasButtons($hasButtons) { $this->_hasButtons = $hasButtons; return $this; } public function getHasButtons() { return $this->_hasButtons; } /** * Merges given two belongsTo (array notation) strings * * @param string $baseBelongsTo * @param string $belongsTo * @return string */ 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 _initSpamProtection() { if ($this->_hasSpamProtection) { if (self::SPAM_PROTECTION_COOKIE == $this->_spamProtectionType) { $this->_initCookieProtection(); } else { $this->_initEmptyFieldProtection(); } } return $this; } protected function _initCookieProtection() { $cookieUrl = Qs_SiteMap::findFirst(null, ['type' => 'FormCookie\\'], null, 'url'); if (!$cookieUrl) { throw new Qs_Form_Exception('Page for cookie protection is not found!'); } $cookieUrl .= '?form=' . rawurlencode($this->getId()); /** @var Qs_Doc $doc */ $doc = Zend_Registry::get('doc'); $doc->addNonCriticalStylesheet($cookieUrl, ['skipPacking' => true]); return $this; } protected function _initEmptyFieldProtection() { $field = $this->_spamProtectionField; $this->addElement('text', $field['name'], ['label' => $field['label']]); $element = $this->getElement($field['name']); if (($label = $element->getDecorator('Label'))) { /** @var Qs_Form_Decorator_Label $label */ $label->setTagOption('class', $field['name']); } if (($htmlTag = $element->getDecorator('HtmlTag'))) { /** @var Qs_Form_Decorator_HtmlTag $htmlTag */ $htmlTag->setOption('class', $field['name']); } return $this; } protected function _validateSpamProtection() { if ($this->_hasSpamProtection) { if (self::SPAM_PROTECTION_COOKIE == $this->_spamProtectionType) { $method = '_validateCookieProtection'; } else if (self::SPAM_PROTECTION_EMPTY_FIELD == $this->_spamProtectionType) { $method = '_validateEmptyFieldProtection'; } else { throw new Qs_Form_Exception('Unknown spam protections validation method'); } if (!$this->{$method}()) { $this->addError($this->_spamProtectionMessage); return false; } } return true; } protected function _validateCookieProtection() { if (!App\FormCookie\View::getCookie($this->getId())) { return false; } return true; } protected function _validateEmptyFieldProtection() { if ('' != Qs_Request::getRequestValue($this->_spamProtectionField['name'])) { return false; } return true; } /** * @return Qs_Doc */ protected function getDoc() { /** @var Qs_Doc $doc */ $doc = Zend_Registry::get('doc'); return $doc; } protected function _addResources() { return $this; } public function addSubForm(Zend_Form $form, $name, $order = null) { $name = (string) $name; foreach ($this->_loaders as $type => $loader) { $loaderPaths = $loader->getPaths(); foreach ($loaderPaths as $prefix => $paths) { foreach ($paths as $path) { $form->addPrefixPath($prefix, $path, $type); } } } if (!empty($this->_elementPrefixPaths)) { foreach ($this->_elementPrefixPaths as $spec) { list($prefix, $path, $type) = array_values($spec); $form->addElementPrefixPath($prefix, $path, $type); } } if (!empty($this->_displayGroupPrefixPaths)) { foreach ($this->_displayGroupPrefixPaths as $spec) { list($prefix, $path) = array_values($spec); $form->addDisplayGroupPrefixPath($prefix, $path); } } if (null !== $order) { $form->setOrder($order); } if (($oldName = $form->getName()) && $oldName !== $name && $oldName === $form->getElementsBelongTo() ) { $form->setElementsBelongTo($name); } $form->setName($name); $form->setParentForm($this); $this->_subForms[$name] = $form; $this->_order[$name] = $order; $this->_orderUpdated = true; return $this; } public function setParentForm(Qs_Form $form) { $this->_parentForm = $form; return $this; } public function hasParentForm() { return (bool) $this->_parentForm; } public function getFullId() { $id = $this->getId(); if ('' != $id && $this->hasParentForm() && $this->_parentForm->hasParentForm()) { $parentId = $this->_parentForm->getFullId(); if ($parentId) { $id = $parentId . '-' . $id; } } return $id; } public function getFullName() { $fullName = ''; $form = $this; do { $name = $form->getName(); $form = $form->_parentForm; $fullName = (($form && $form->_parentForm) ? '[' . $name . ']' : $name) . $fullName; } while ($form); return $fullName; } }