'300 Multiple Choices', 301 => '301 Moved Permanently', 302 => '302 Moved temporarily', 303 => '303 See Other', 304 => '304 Not Modified', 307 => '307 Temporary Redirect' ); protected $_currentPageId = null; /** @var App_Cms_Obj */ protected $_dataObj; protected $_hasButtons = false; protected $_pageHeaderInherited = true; public function init() { $this->addElementPrefixPath('App_Cms_Validate', 'App/Cms/Validate', 'validate'); $this->_initDataObj(); return parent::init(); } protected function _initDataObj() { $this->_dataObj = new App_Cms_Obj(); $idPage = $this->_getData('id'); if ($idPage) { $this->_dataObj->setPrimaryKey($idPage); } return $this; } public function getMode() { if (null == $this->_mode) { $this->_mode = 'edit'; } return $this->_mode; } public function setMode($mode) { $this->_mode = $mode; } public function setLanguage($language) { $this->_language = $language; return $this; } public function setMetaOptions($options) { $this->_metaOptions = $options; } public function setIsRedirectFields($value) { $this->_isRedirectFields = (bool) $value; } public function getIsRedirectFields() { if (App_Admin_Auth::getInstance()->getSuMode()) { return ($this->_isRedirectFields && isset($this->_metaOptions['redirect'])); } return ($this->_isRedirectFields && isset($this->_metaOptions['redirect']) && 'y' == $this->_metaOptions['redirect']['show']); } public function getLanguage() { return $this->_language; } public function isDefaultLanguage() { return $this->_language === Qs_Constant::get('DEFAULT_LANGUAGE'); } protected function _getParentId() { if (Qs_Request::isXmlHttpRequest()) { if (App_Admin_Auth::getInstance()->getSuMode()) { $parentId = $this->_getData('idParent'); } else { $parentId = $this->_dataObj->getData('meta[idParent]'); } } else { $parentId = $this->_getData('meta[idParent]'); } return $parentId; } protected function _initElements() { $this->addElement('hidden', 'id'); $this->_initInformationElements(); $this->_initMetaElements(); $this->_initVisibilityElements(); $this->_addMetaButtons(); return $this; } /** * @param string $label * @param null|string $description * @return string */ protected function _renderElementLabel($label, $description = null) { $label = htmlspecialchars($label); if ($description) { $label .= '' . htmlspecialchars($description) . ''; } return $label; } /** * @param string $type * @param string $name * @param array|null $options * @return App_Cms_Form_SubForm_Meta */ protected function _addElementExtended($type, $name, array $options = null) { $escapeLabel = true; if (!empty($options['label']) && !empty($options) && !empty($options['labelDescription'])) { $options['label'] = $this->_renderElementLabel($options['label'], $options['labelDescription']); unset($options['labelDescription']); $escapeLabel = false; } $this->addElement($type, $name, $options); if (!$escapeLabel) { $this->getElement($name)->getDecorator('Label')->setOption('escape', false); } return $this; } protected function _initInformationElements() { if (!$this->isDefaultLanguage()) { return $this; } $this->addElement('header', 'informationHeader', array('value' => 'Information About This Page')); if (App_Admin_Auth::getInstance()->getSuMode()) { $this->addElement( 'select', 'idParent', array( 'label' => 'Parent Page', 'escapeLabel' => false, 'multioptions' => array(0 => 'Root') + (array) $this->_dataObj->getParent4Select() ) ); $informationElements[] = 'idParent'; } else { $this->addElement('hidden', 'idParent'); } $this->_addElementExtended( 'text', 'menuTitle', array( 'label' => 'Menu Title', 'required' => true, 'labelDescription' => 'What you enter here will show in the main navigation (menu) of the website.' ) ); $this->_addElementExtended('text', 'header', [ 'label' => 'Page Header', 'labelDescription' => 'What you enter here will show in the header area (top) of the webpage.' . ($this->isPageHeaderInherited() ? ' If you leave this field empty - the Page Header will be the same as Menu Title.' : '') ]); $idParent = $this->_getParentId(); $this->_addElementExtended( 'pageAlias', 'alias', array( 'label' => 'Alias', 'required' => true, 'maxlength' => 200, 'sourceField' => 'meta-menuTitle', 'labelDescription' => 'What you enter here will show in the actual page URL; no spaces are allowed', 'aliasValidatorOptions' => array( 'table' => new Qs_Db_Table('Page'), 'column' => 'alias', 'currentId' => $this->_getData('id'), 'options' => array('where' => array('idParent' => (int) $idParent)) ) ) ); $parentAlias = Qs_SiteMap::findFirst(array('id' => $idParent), null, null, 'fullAlias'); $this->getElement('alias')->addValidator('XmlAliasUnique', true, array('parentAlias' => $parentAlias)); if (App_Admin_Auth::getInstance()->getSuMode()) { $this->addElement('select', 'handler', array('label' => 'Handler', 'required' => true)); $this->addElement('select', 'bodyTemplate', array('label' => 'Body Template')); } else { $this->addElement('hidden', 'handler'); $this->addElement('hidden', 'bodyTemplate'); } return $this; } protected function _initMetaElements() { $this->addElement('header', 'metaHeader', array('value' => 'Meta Tags')); $description = 'This information is used to describe the webpage\'s content. ' . 'Most search engines use this data when adding pages to their search index.'; $this->addElement('static', 'metaStatic', array('value' => $description, 'tag' => 'p', 'class' => 'description')); /** @var Qs_Form_Decorator_Label $label */ $label = $this->getElement('metaStatic')->getDecorator('Label'); $label->setTagOptions(array('class' => 'hidden')); $this->_addElementExtended( 'text', 'title', array( 'label' => 'Title', 'labelDescription' => 'This information will show in the browser tab and in search results. ' . 'If you leave this field empty - the Title will be the same as Menu Title.' ) ); $this->_addElementExtended( 'textarea', 'keywords', array( 'label' => 'Keywords', 'labelDescription' => 'This information will not show on the site at all; ' . 'it is stored in the site\'s code "behind the scenes".' ) ); $this->_addElementExtended( 'textarea', 'description', array( 'label' => 'Description', 'labelDescription' => 'This information will not show on the site at all but it will show in search ' . 'results, below the Title tag.' ) ); return $this; } protected function _initVisibilityElements() { $isSu = App_Admin_Auth::getInstance()->getSuMode(); $hasOptions = in_array('y', Qs_Array::fetchCol($this->_metaOptions, 'show')); $isRedirectFields = $this->getIsRedirectFields(); if ($isSu || $hasOptions || $isRedirectFields) { $this->addElement('header', 'visibilityHeader', array('value' => 'Visibility Options')); } $this->_addOptionsGroup(); if ($isRedirectFields) { $this->addElement( 'select', 'redirectType', array( 'label' => 'Redirect Type', 'multiOptions' => array('' => '- Select Type -', 'page' => 'Site Page', 'url' => 'Url') ) ); $this->_currentPageId = intval(Qs_Request::getRequestValue('id')); $this->addElement( 'select', 'redirectPageId', array( 'label' => 'Site Page', 'multiOptions' => array('0' => '- Select Page -'), 'escapeLabel' => false, ) ); $this->addElement( 'text', 'redirectAlias', array( 'label' => 'Redirect page to:', 'description' => 'Example: http://www.adaptainc.com', ) ); $this->addElement( 'select', 'redirectStatus', array( 'label' => 'Redirect Status', 'required' => true, 'value' => 301, 'multiOptions' => $this->_redirectStatuses, ) ); $this->getElement('redirectType')->getDecorator('label')->setOption('class', 'required'); $this->getElement('redirectPageId')->getDecorator('label')->setOption('class', 'required'); $this->getElement('redirectAlias')->addValidator('StringLength', false, array('max' => 255)); $this->getElement('redirectAlias')->getDecorator('label')->setOption('class', 'required'); if ($isSu) { $this->addElement( 'textarea', 'customOptions', array( 'label' => 'Custom Options', 'description' => 'Note: Allowed json only. Example: {"glossary": {"title": "example glossary"}}' ) ); } $this->addFormRule(array($this, 'validateForm')); } return $this; } protected function _addMetaButtons() { $decorators = array('ViewHelper', 'HtmlTag'); $this->addElement('button', 'save', array('label' => 'Save', 'decorators' => $decorators, 'class' => 'btn btn-primary')); $this->addElement('button', 'cancel', array('label' => 'Cancel', 'decorators' => $decorators, 'class' => 'btn')); $this->addElement('button', 'edit', array('label' => 'Edit', 'decorators' => $decorators, 'class' => 'btn')); $this->addDisplayGroup( array('save', 'cancel', 'edit'), 'meta_toolbar', array( 'decorators' => array( 'FormElements', array( 'decorator' => 'HtmlTag', 'options' => array('tag' => 'dd', 'class' => 'meta_toolbar') ) ) ) ); return $this; } protected function _addOptionsGroup() { $isSu = App_Admin_Auth::getInstance()->getSuMode(); $hasOptions = in_array('y', Qs_Array::fetchCol($this->_metaOptions, 'show')); $groupOptions = [ 'decorators' => [ ['FormElements'], ['DtDdWrapper', ['ddAttribs' => ['class' => 'option-group-wrap']]] ], ]; if ($isSu) { $this->addElement('static', 'optionGroupHeader', ['value' => '┌ Visible']); $this->getElement('optionGroupHeader')->getDecorator('label')->setTagOption('class', 'hidden'); foreach($this->_metaOptions as $name => $options) { $this->_addOptionCheckbox($name . '4Dummy', $options, true); $this->_addOptionCheckbox($name, $options); $this->addDisplayGroup([$name . '4Dummy', $name], 'optionGroup' . ucfirst($name), $groupOptions); } } else if ($hasOptions) { foreach ($this->_metaOptions as $name => $options) { if ('y' == $options['show']) { $this->_addOptionCheckbox($name, $options); $this->addDisplayGroup([$name], 'optionGroup' . ucfirst($name), $groupOptions); } } } return $this; } protected function _addOptionCheckbox($name, $options, $suMode = false) { if ($suMode) { $label = ''; } else { $label = $options['title']; } $elementOptions = array( 'label' => $label, 'class' => ($suMode) ? 'allow_change' : '', 'decoration' => 'simple' ); if ($suMode) { $elementOptions['title'] = 'Allow change "' . $options['title'] . '"'; } if (!App_Admin_Auth::getInstance()->getSuMode() && Qs_Array::get($options, 'disabled')) { $elementOptions['disabled'] = 'disabled'; // так додає клас disabled до чекбокса $elementOptions['disable'] = true; // дісейблить і не малює хідден $elementOptions['uncheckedValue'] = null; } $this->addElement('checkbox', $name, $elementOptions); if ($suMode) { $this->{$name}->getDecorator('Label')->setOption('class', 'allow_change_label'); } if ($suMode && 'y' == $options['show']) { $this->{$name}->checked = 'checked'; } $this->{$name}->removeDecorator('DtDdWrapper'); $this->{$name}->addDecorator('HtmlTag', [ 'tag' => 'div', 'id' => $this->getName() . '-element', 'class' => $suMode ? 'option-visible-wrap' : 'option-wrap', ]); $this->_optionsElements[] = $name; return $this; } public function validateForm($data) { $errors = array(); if ($this->getIsRedirectFields()) { if (isset($data['redirect']) && 'y' == $data['redirect']) { if (!isset($data['redirectType']) || empty($data['redirectType'])) { $errors['redirectType'] = 'This is a required field'; } else { if ('page' == $data['redirectType']) { if (empty($data['redirectPageId'])) { $errors['redirectPageId'] = 'This is a required field'; } elseif (isset($this->_currentPageId) && $this->_currentPageId == $data['redirectPageId']) { $errors['redirectPageId'] = 'Please choose another page to prevent recursive redirects'; } else { $validator = new Zend_Validate_Int(); if (!$validator->isValid($data['redirectPageId'])) { $errors['redirectPageId'] = '"Site Page" is in wrong format'; } $page = Qs_SiteMap::findFirst(array('id' => intval($data['redirectPageId']))); if (!empty($page) && $page['redirect'] == 'y') { $errors['redirectPageId'] = 'Please choose another page. Page "' . $page['title'] . '" has redirect'; } } } else { if (empty($data['redirectAlias'])) { $errors['redirectAlias'] = 'This is a required field'; } else { $url = str_replace('{BASE_URL}', BASE_URL_LANGUAGE, $data['redirectAlias']); $validator = new Qs_Validate_Url(); if (!$validator->isValid($url)) { $errors['redirectAlias'] = '"Redirect page to" is in wrong format'; } } } } } } if (!empty($data['customOptions'])) { if (null === json_decode($data['customOptions'])) { $errors['customOptions'] = 'Field must contain only json'; } } return (empty($errors)) ? true : $errors; } public function beforeRender() { $mode = $this->getMode(); switch ($mode) { case 'view': $this->getDecorator('HtmlTag')->setOption('class', 'meta view_mode'); break; default: break; } } public function render(Zend_View_Interface $view = null) { $this->beforeRender(); return parent::render($view); } public function loadDefaultDecorators() { if ($this->loadDefaultDecoratorsIsDisabled()) { return $this; } $decorators = $this->getDecorators(); if (empty($decorators)) { $this->addDecorator('FormElements') ->addDecorator('HtmlTag', array('tag' => 'dl')) ->addDecorator('Fieldset') ->addDecorator('DtDdWrapper'); } return $this; } public function addElement($element, $name = null, $options = null) { if (in_array($name, $this->getHiddenFields())) { return $this; } parent::addElement($element, $name, $options); return $this; } public function getHiddenFields() { if (null === $this->_hiddenFields) { /** @var $hiddenFields Zend_Config */ if (null === ($hiddenFields = Qs_Config::getByInstance($this)->get('hiddenFields'))) { $this->_hiddenFields = array(); } else { $this->_hiddenFields = $hiddenFields->toArray(); } } return $this->_hiddenFields; } public function isPageHeaderInherited() { return $this->_pageHeaderInherited; } public function setPageHeaderInherited($pageHeaderInherited) { $this->_pageHeaderInherited = $pageHeaderInherited; return $this; } }