null, 'automatic_serialization' => true ); protected $_hasFilter = true; protected $_insertPlacement = 'APPEND'; protected $_dataMetaOptions = null; protected $_dataCleanMetaOptions = null; protected $_dataDraftMetaOptions = null; protected $_dataDraftCleanMetaOptions = null; protected $_urlParseFields = array('meta' => array('redirectAlias')); protected $_fileFields = array('headerImage'); protected $_itemView = array(); protected $_reorderTitleColumn = 'menuTitle'; public $idParent = 0; public static function getInstance() { if (null === self::$_instance) { self::$_instance = new self(); } return self::$_instance; } protected function _arrayParseTag2Url(array &$array, $fields = null) { if (null === $fields) { $fields = $this->_urlParseFields; } if (empty($fields) || !is_array($array) || empty($array)) { return false; } foreach ($fields as $key => $field) { if (is_scalar($field)) { if (isset($array[$field])) { $array[$field] = $this->_tag2BaseUrl($array[$field]); } } else { if (isset($array[$key])) { $this->_arrayParseTag2Url($array[$key], $field); } } } return true; } protected function _arrayParseUrl2Tag(&$array, $fields = null) { if (null === $fields) { $fields = $this->_urlParseFields; } if (empty($fields) || !is_array($array) || empty($array)) { return false; } foreach ($fields as $key => $field) { if (is_scalar($field)) { if (isset($array[$field])) { $array[$field] = $this->_baseUrl2Tag($array[$field]); } } else { if (isset($array[$key])) { $this->_arrayParseUrl2Tag($array[$key], $field); } } } return true; } public function resetListSelect() { $this->_select = null; return $this; } public function getListSelect() { if (null !== $this->_select) { return $this->_select; } $select = parent::getListSelect()->where("`{$this->_tableAlias}`.`alias` IS NOT NULL"); $select->join( array('cDef' => $this->_getTableName('PageContent')), "`cDef`.`idPage` = `{$this->_tableAlias}`.`id` " . "AND `cDef`.`language` = " . $this->_db->quote(Qs_Db_Language::getDefault()), array( new Zend_Db_Expr('`c`.`title` AS title'), new Zend_Db_Expr('IF(`c`.`menuTitle` > "", `c`.`menuTitle`, `cDef`.`menuTitle`) AS menuTitle'), new Zend_Db_Expr('`c`.`header` AS header') ) ); $select->joinLeft( array('c' => $this->_getTableName('PageContent')), "`c`.`idPage` = `{$this->_tableAlias}`.`id` AND `c`.`language` = " . $this->_db->quote($this->getLanguage()), array() ); $select->joinLeft( array('dp' => $this->_getTableName('DraftPage')), "`dp`.`id` = `{$this->_tableAlias}`.`id` ", array('hasDraft' => "IF(`dp`.`id` IS NOT NULL AND `dp`.`added` <> `dp`.`changed`, 'y', 'n')") ); return $select; } public function draftExists() { $key = $this->getPrimaryKey(); if (!is_array($key)) { $key = (array) $key; } $rows = call_user_func_array(array($this->_getTable('DraftPage'), 'find'), $key); if (count($rows)) { return true; } return false; } public function createDraft() { if (false === ($data = $this->_getDataEx())) { return false; } $this->deleteDraftItems($data['id']); $this->_saveDraftDataEx($data); return $this; } public function draftPageOptionExists() { $options = $this->getMetaOptions($this->getPrimaryKey(), true, true); return !empty($options); } public function createPageOptionDraft() { $this->_deleteDraftMetaOptions($this->getPrimaryKey()); $select = $this->_db->select(); $select->from( $this->_getPair('PageOption'), array('idPage', 'name', 'show', 'value') ); $select->where('`idPage`=' . $this->_db->quote($this->getPrimaryKey(), Zend_Db::INT_TYPE)); $data = $this->_db->fetchAll($select); if (false === $data) { return false; } $table = $this->_getTable('DraftPageOption'); foreach ($data as $option) { $table->insert($option); } return $this; } public function getDraftMeta($idPage) { return $this->getMeta($idPage, true); } protected function _getMetaRow($idPage, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $rowset = $this->_getTable($draftPrefix . 'Page')->find($idPage); if (!count($rowset)) { return false; } return $rowset->current(); } public function getMeta($idPage, $draft = false) { if (!empty(self::$_dataCache['meta'][$idPage][$draft])) { return self::$_dataCache['meta'][$idPage][$draft]; } $draftPrefix = ($draft) ? 'Draft' : ''; if (($row = $this->_getMetaRow($idPage, $draft))) { $data = $row->toArray(); $this->_arrayParseTag2Url($data, $this->_urlParseFields['meta']); $content = $this->_getTable($draftPrefix . 'PageContent')->select() ->where('idPage = ? ', $idPage) ->where('language = ?', $this->getLanguage()) ->query() ->fetch(); if (is_array($content) && !empty($content)) { $data = array_merge($data, $content); } $data['customOptions'] = json_decode($data['customOptions'], true); self::$_dataCache['meta'][$idPage][$draft] = $data; return $data; } return false; } /** * @param int $level * @param array|string|Zend_Db_Expr|null $where [OPTIONAL] * @return array|bool */ public function getFilteredPages4Select($level = 1, $where = null) { $select = $this->getSelect4SiteMap(); if ($where) { $select->where(Qs_Db::getWhereSql($where)); } $siteMap = $this->getSiteMap(array('select' => $select)); $options = $this->_prepareParentOptions($siteMap, $level); return $options; } public function getPages4Select($indentLevel = 0, $where = null) { $_where = array(); if (!$this->_suMode) { $_where[] = '`' . $this->_tableAlias . '`.`showInDropdowns` = "y"'; $parts = array('`' . $this->_tableAlias . '`.`system` != "y"'); if ($this->_primaryKey && 0 != ($redirectPageId = (int) $this->getDraftData('meta[redirectPageId]'))) { $parts[] = '`' . $this->_tableAlias . '`.`id` = ' . (int) $redirectPageId; } $_where[] = '(' . implode(' OR ', $parts) . ')'; } if ($where) { $_where[] = Qs_Db::getWhereSql($where); } return $this->getFilteredPages4Select($indentLevel, $_where); } /** * Повертає масив сторінок для дропдауна "Parent Page". В масив попадають всі сторінкикрім фінальних * та сторінок які є частиною гілки поточної сторінки. * * @param int $indentLevel * @param int $currPageId * @return array|bool */ public function getParent4Select($indentLevel = 1, $currPageId = null) { $currPageId = (null === $currPageId) ? $this->getPrimaryKey() : $currPageId; $select = $this->getSelect4SiteMap(); $select->where("`{$this->_tableAlias}`.`id` <> " . (int) $currPageId); $select->where("`{$this->_tableAlias}`.`final` <> 'y'"); $select->joinLeft( $this->_getPair('PageOption'), "(`PageOption`.`idPage` = `" . $this->_tableAlias . "`.`id`) AND (`PageOption`.`name` = 'isAdditional')", array('isAdditional' => new Zend_Db_Expr('IFNULL(PageOption.value, DPageOption.value)')) ); $select->joinLeft( $this->_getPair('DPageOption'), "`DPageOption`.`name` = 'isAdditional'", null ); $select->reset('order'); $select->order(array($this->_tableAlias . '.idParent', 'isAdditional', $this->_tableAlias . '.sorter')); $siteMap = $this->getSiteMap(array('select' => $select)); $options = $this->_prepareParentOptions($siteMap, $indentLevel); return $options; } protected function _prepareParentOptions($siteMap, $indentLevel = 0) { $options = array(); $additionalPages = array(); foreach ($siteMap as $page) { if ('y' == $page['isAdditional']) { $additionalPages[$page['id']] = str_repeat(' ', $indentLevel * 4) . $page['menuTitle']; if (isset($page['sub'])) { $subOptions = $this->_prepareParentOptions($page['sub'], $indentLevel + 1); $additionalPages = Qs_Array::mergeAssoc($additionalPages, $subOptions); } } else { $options[$page['id']] = str_repeat(' ', $indentLevel * 4) . $page['menuTitle']; if (isset($page['sub'])) { $subOptions = $this->_prepareParentOptions($page['sub'], $indentLevel + 1); $options = Qs_Array::mergeAssoc($options, $subOptions); } } } $options = Qs_Array::mergeAssoc($options, $additionalPages); return $options; } public function getSelect4SiteMap($options = array()) { $_filter = $this->_filter; if (isset($options['filter'])) { $this->setFilter($options['filter']); } $select = clone $this->getListSelect(); $select->order(array($this->_tableAlias . '.idParent', $this->_tableAlias . '.sorter')); if (isset($options['filter'])) { $this->_filter = $_filter; } return $select; } public function getAdditionalSelect4SiteMap($options = array()) { $select = $this->getSelect4SiteMap($options); $select->reset('order'); $select->joinLeft( $this->_getPair('PageOption'), "(`PageOption`.`idPage` = `" . $this->_tableAlias . "`.`id`) AND (`PageOption`.`name` = 'isAdditional')", array('isAdditional' => new Zend_Db_Expr('IFNULL(PageOption.value, DPageOption.value)')) ); $select->joinLeft( $this->_getPair('DPageOption'), "`DPageOption`.`name` = 'isAdditional'", null ); $select->group($this->_tableAlias . '.id'); $select->order(array('isAdditional', $this->_tableAlias . '.idParent', $this->_tableAlias . '.sorter')); return $select; } public function getAllItems() { $select = $this->_db->select(); $select->from($this->_getPair('PageItem')); $select->order(array('PageItem.idPage', 'PageItem.sorter')); return $this->_db->fetchAll($select); } public function getAllItemConfigs() { $select = $this->_db->select(); $select->from($this->_getPair('PageItemConfig')); return $this->_db->fetchAll($select); } public function getAllMetaOptions() { static $data = null; if (null === $data) { $data = array(); $data['defaults'] = $this->getDefaultMetaPairs(); $select = $this->_db->select(); $select->from($this->_getTableName('PageOption')); $data['options'] = $this->_db->fetchAll($select); } return $data; } public function getSiteMap($options = array()) { if (empty($options) && empty($this->_filter) && null !== $this->_siteMap) { return $this->_siteMap; } $idParent = 0; /** @var $select Zend_Db_Select */ $select = null; if (!isset($options['select'])) { $select = $this->getSelect4SiteMap($options); } extract($options); $_list = $this->_db->fetchAssoc($select); $metaOptions = $this->getAllMetaOptions(); foreach ($metaOptions['options'] as $option) { if (array_key_exists($option['idPage'], $_list)) { $_list[$option['idPage']][$option['name']] = $option['value']; } } foreach($_list as &$page) { $page = array_merge($metaOptions['defaults'], $page); $this->_arrayParseTag2Url($page, $this->_urlParseFields['meta']); $this->_initPageCustomOptions($page); } // Item Options $itemConfigs = array(); $_itemConfigs = $this->getAllItemConfigs(); foreach ($_itemConfigs as $itemConfig) { if (!array_key_exists($itemConfig['idItem'], $itemConfigs)) { $itemConfigs[$itemConfig['idItem']] = array(); } Qs_Array::set($itemConfigs[$itemConfig['idItem']], $itemConfig['name'], $itemConfig['value']); } // Page Items $items = array(); $_items = $this->getAllItems(); foreach ($_items as $item) { if (array_key_exists($item['id'], $itemConfigs)) { $item['config'] = $itemConfigs[$item['id']]; } $items[$item['idPage']][] = $item; } foreach ($_list as &$page) { if (array_key_exists($page['id'], $items)) { $page['items'] = $items[$page['id']]; } } $list = array(); $additionalList = array(); foreach($_list as $v) { if ('y' == $v['isAdditional']) { $additionalList[$v['idParent']][$v['alias']] = $v; } else { $list[$v['idParent']][$v['alias']] = $v; } } $list = Qs_Array::mergeRecursive($list, $additionalList); $siteMap = (isset($list[$idParent])) ? $list[$idParent] : array(); unset($list[$idParent]); $parentAlias = ''; if (is_array($siteMap) && !empty($siteMap)) { $this->_prepareSiteMap($siteMap, $list, $parentAlias); } if (empty($options) && empty($this->_filter)) { $this->_siteMap = $siteMap; } return $siteMap; } protected function _initPageCustomOptions(&$page) { if (!array_key_exists('customOptions', $page)) { return $this; } if (!($customOptions = json_decode($page['customOptions'], true))) { return $this; } foreach ($customOptions as $name => $value) { $page['x' . ucfirst($name)] = $value; } unset($page['customOptions']); return $this; } protected function _prepareSiteMap(&$siteMap, &$list, $parent = []) { foreach ($siteMap as &$page) { $parentAlias = Qs_Array::get($parent, 'fullAlias', ''); $page['fullAlias'] = rtrim($parentAlias, '/') . (($parentAlias) ? '/' : '') . $page['alias']; if (Qs_SiteMap::isSecurePage($page)) { $page['url'] = BASE_URL_LANGUAGE_HTTPS; } else { $page['url'] = BASE_URL_LANGUAGE_HTTP; } if ('y' != $page['isRoot']) { $page['url'] .= ((empty($page['fullAlias'])) ? '' : '/') . $page['fullAlias']; } if (empty($page['header']) && $this->getConfig('autofillHeader')) { $page['header'] = $page['menuTitle']; } if (empty($page['title'])) { $page['title'] = $page['menuTitle']; } if (isset($parent['enabled']) && 'n' == $parent['enabled']) { $page['enabled'] = 'n'; } if (isset($list[$page['id']])) { $page['sub'] = $list[$page['id']]; unset($list[$page['id']]); $this->_prepareSiteMap($page['sub'], $list, $page); } } return $this; } public function getSiteMapPageCount($siteMap) { $count = count($siteMap); foreach ($siteMap as $page) { if (isset($page['sub'])) { $count += $this->getSiteMapPageCount($page['sub']); } } return $count; } public function getDItemType4Select() { if (null === $this->_itemTypes) { $select = $this->_db->select(); $select->from($this->_getTableName('DPageItemType'), array('type', 'title')); $select->order('sorter'); $this->_itemTypes = $this->_db->fetchPairs($select); foreach ($this->_itemTypes as $type => $title) { if (!$this->_itemTypeClassExists($type)) { Qs_Debug::log('Cms item "' . $type . '" not found'); unset($this->_itemTypes[$type]); } } } return $this->_itemTypes; } protected function _itemTypeClassExists($type) { return class_exists(Qs_SiteMap::getItemTypeClass($type, 'View')); } public function getDraftItems($idPage) { return $this->getItems($idPage, true); } public function getItemsList($idPage, $draft = false) { if (!empty(self::$_dataCache['itemsList'][$idPage][$draft])) { return self::$_dataCache['itemsList'][$idPage][$draft]; } $draftPrefix = ($draft) ? 'Draft' : ''; $select = $this->_db->select(); $select->from(array('i' => $this->_getTableName($draftPrefix . 'PageItem'))); $select->join( array('g' => $this->_getTableName('DPageItemGroup')), 'g.id = i.idGroup', array('groupTitle' => 'g.title', 'groupName' => 'g.name') ); $select->where('`i`.idPage = ?', $idPage, Zend_Db::INT_TYPE); $select->order(array('g.sorter', 'i.sorter')); $stmt = $select->query(); $items = $stmt->fetchAll(); $itemsIds = Qs_Array::fetchCol($items, 'id'); $itemsConfigs = $this->_getItemsConfigs($itemsIds, $draft); $sorter = 0; foreach ($items as &$item) { $item['sorter'] = $sorter++; $item['config'] = Qs_Array::get($itemsConfigs, $item['id'], array()); } self::$_dataCache['itemsList'][$idPage][$draft] = $items; return $items; } public function getItems($idPage, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $_items = $this->getItemsList($idPage, $draft); $items = array(); foreach ($_items as $item) { if ($itemObject = $this->getItemObject($item['type'])) { $itemObject->setLanguage($this->getLanguage()); $itemObject->setDraftPrefix($draftPrefix); $itemObject->setPrimaryKey($item['number']); $item['data'] = $itemObject->getData(); } if (!isset($items[$item['groupName']])) { $items[$item['groupName']] = array(); } $items[$item['groupName']]['i' . $item['id']] = $item; } return $items; } public function getDraftItem($id) { return $this->getItem($id, true); } public function getDraftItemRow($id) { return $this->getItemRow($id, true); } /** * @param $id * @param bool $draft * @return bool|Zend_Db_Table_Row_Abstract */ public function getItemRow($id, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $rowset = $this->_getTable($draftPrefix . 'PageItem')->find($id); if (!count($rowset)) { return false; } return $rowset->current(); } /** * @param $id * @param bool $draft * @return array|bool return item data on success or false otherwise */ public function getItem($id, $draft = false) { if (! ($row = $this->getItemRow($id, $draft))) { return false; } $item = $row->toArray(); if ($itemObject = $this->getItemObject($item['type'])) { $draftPrefix = ($draft) ? 'Draft' : ''; $itemObject->setLanguage($this->getLanguage()); $itemObject->setDraftPrefix($draftPrefix); $itemObject->setPrimaryKey($item['number']); $item['data'] = $itemObject->getData(); } $groupData = $this->getItemGroupById($item['idGroup']); if (!empty($groupData)) { $item['groupTitle'] = $groupData['title']; $item['groupName'] = $groupData['name']; } $item['config'] = $this->_getItemConfig($item['id'], $draft); return $item; } public function getItemGroupById($idGroup, $field = null) { $select = $this->_db->select(); $select->from($this->_getPair('DPageItemGroup'), array('name', 'title')) ->where("`DPageItemGroup`.`id` = " . (int) $idGroup); $data = $this->_db->fetchRow($select); if (null !== $field && !empty($data) && array_key_exists($field, $data)) { return $data[$field]; } return $data; } /** * @param $type * @return App_Cms_Item_HtmlBlock_Obj */ public function getItemObject($type) { $class = 'App_Cms_Item_' . rtrim($type, '_') . '_Obj'; $file = BASE_PATH . '/' . str_replace('_', '/', $class) . '.php'; if (!array_key_exists($class, $this->_itemObjects)) { if (!file_exists($file)) { $this->_itemObjects[$class] = null; } else { $this->_itemObjects[$class] = new $class(); } } /** @var $dataObj App_Cms_Item_HtmlBlock_Obj */ $dataObj = $this->_itemObjects[$class]; if ($dataObj) { $dataObj->clearData(); } return $dataObj; } public function getDraftData($field = null) { return $this->getData($field, true); } public function getData($field = null, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $property = '_data' . $draftPrefix; if (null === $this->{$property} && $this->getPrimaryKey() && $data = $this->_getFromDb($this->getPrimaryKey(), null, $draft) ) { $this->$property = $data; } if (null === $this->$property) { return null; } return Qs_Array::get($this->$property, $field); } public function initDraftData() { return $this->initData(true); } public function initData($draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $property = '_data' . $draftPrefix; $this->$property = $this->_getFromDb($this->getPrimaryKey(), null, $draft); foreach ($this->_fileFields as $fieldName) { if (($file = Qs_Request::getPostValue($fieldName))) { $this->{$property}[$fieldName] = $file; } else { if (isset($this->{$property}['meta']) && isset($this->{$property}['meta'][$fieldName])) { $this->{$property}[$fieldName] = $this->{$property}['meta'][$fieldName]; } } } return $this; } protected function _getFromDb($idPage, $field = null, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; if (null === $this->{'_data' . $draftPrefix}) { $this->{'_data' . $draftPrefix} = array(); if (false !== ($meta = $this->{"get{$draftPrefix}Meta"}($idPage))) { $options = $this->_getPageOptions($idPage, $meta, $draft); foreach ($options as $name => $option) { $meta[$name] = $option['value']; } $this->{'_data' . $draftPrefix}['meta'] = $meta; $items = $this->{"get{$draftPrefix}Items"}($idPage); $this->{'_data' . $draftPrefix} = array_merge($this->{'_data' . $draftPrefix}, $items); } } return Qs_Array::get($this->{'_data' . $draftPrefix}, $field); } public function draftHtmlBlock($idBlock) { $rowset = $this->_getTable('HtmlBlock')->find($idBlock); if (!count($rowset)) { return false; } $htmlBlockData = $rowset->current()->toArray(); unset($htmlBlockData['id']); $id_draft_block = $this->_getTable('DraftHtmlBlock')->insert($htmlBlockData); $contentItems = $this->_getTable('HtmlBlockContent')->select() ->where('idBlock = ?', $idBlock) ->query() ->fetchAll(); foreach ($contentItems as $data) { $data['idBlock'] = $id_draft_block; $this->_getTable('DraftHtmlBlockContent')->insert($data); } return $id_draft_block; } public function initNewPage(array &$page) { if (($idParent = Qs_Array::get($page, 'meta[idParent]'))) { $meta = &$page['meta']; $parent = $this->_getTable('Page')->search($idParent); foreach (['handler'] as $field) { if (empty($meta[$field])) { $meta[$field] = Qs_Array::get($parent, $field); } } } return $this; } public function insertDefaultPage($defaults) { if (isset($defaults['meta'])) { $metaData = $defaults['meta']; } else { $metaData = array(); } if (!empty($defaults['options'])) { $metaOptions = array( 'methods' => array_fill(0, count($defaults['options']), 'insert'), 'options' => array_values($defaults['options']), ); $metaData = array_merge($metaData, $this->extractMeta($defaults['options'])); } else { $metaOptions = null; } $metaData['sorter'] = $this->_getSorter(); $metaData['language'] = DEFAULT_LANGUAGE; $this->_db->beginTransaction(); $itemData = array(); try { $this->_primaryKey = $this->insertMeta($metaData); $this->_updateMetaOptions($metaOptions, false, $this->_primaryKey); $itemData = array('idPage' => $this->_primaryKey, 'type' => 'HtmlBlock_'); $this->_db->commit(); } catch (Exception $e) { Qs_Debug::log($e->getMessage(), 3); $this->_db->rollBack(); } if (isset($this->_primaryKey)) { $this->insertItem($itemData); return $this->_primaryKey; } return false; } public function insertDraftMeta($data = array()) { return $this->insertMeta($data, true); } public function insertMeta($data = array(), $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $data['idPage'] = $id = $this->_getTable($draftPrefix . 'Page')->insert($data); $this->_getTable($draftPrefix . 'PageContent')->insert($data); return $id; } public function insertDraftItem($data) { return $this->insertItem($data, true); } public function insertItem($data, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; unset($data['id']); $this->_db->beginTransaction(); try { if ($itemObject = $this->getItemObject($data['type'])) { $itemObject->setLanguage($this->getLanguage()); $itemObject->setDraftPrefix($draftPrefix); $itemData = isset($data['data'])?$data['data']:array(); $data['number'] = $itemObject->insert($itemData); } if (!isset($data['sorter'])) { $idGroup = (isset($data['idGroup'])) ? $data['idGroup'] : 1; $data['sorter'] = 1 + $this->{"get{$draftPrefix}ItemSorter"}($data['idPage'], $idGroup); } $id = $this->_getTable($draftPrefix . 'PageItem')->insert($data); $this->touch($draft); $this->_db->commit(); return $id; } catch (Exception $e) { Qs_Debug::log($e->getMessage(), 3); $this->_db->rollBack(); } return false; } public function getDraftItemSorter($idPage, $idGroup) { return $this->getItemSorter($idPage, $idGroup, true); } public function getItemSorter($idPage, $idGroup, $draft = true) { $draftPrefix = ($draft) ? 'Draft' : ''; $select = $this->_db->select(); $select->from($this->_getTableName($draftPrefix . 'PageItem'), 'MAX(sorter)'); $select->where('`idPage` = ' . $this->_db->quote($idPage, Zend_Db::INT_TYPE)); $select->where('`idGroup` = ' . $this->_db->quote($idGroup, Zend_Db::INT_TYPE)); $sorter = (int)$this->_db->fetchOne($select); return $sorter; } public function updateDraftItem($id, $type, $data) { return $this->updateItem($id, $type, $data, true); } public function updateItem($id, $type, $data, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; /** @var $row Zend_Db_Table_Row_Abstract */ if (!($row = $this->{"get{$draftPrefix}ItemRow"}($id))) { return false; } $this->setPrimaryKey($row->idPage); $this->_db->beginTransaction(); try { if (isset($data['config']) && !empty($data['config'])) { $this->updateItemConfig($id, $data['config'], $draft); } $data['changed'] = date('Y-m-d H:i:s'); $row->setFromArray($data); $row->save(); if (isset($data['data'])) { if ($itemObject = $this->getItemObject($row->type)) { $itemObject->setLanguage($this->getLanguage()); $itemObject->setDraftPrefix($draftPrefix); $itemObject->setPrimaryKey($row->number); $itemObject->update($data['data']); } } $this->_db->commit(); $this->touch($draft); return true; } catch (Exception $e) { Qs_Debug::log($e->getMessage(), 3); $this->_db->rollBack(); } return false; } public function updateItemConfig($id, array $data, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $data = Qs_Array::collapse($data); $sql = 'DELETE ' . 'FROM ' . $this->_db->quoteIdentifier($this->_getTableName("{$draftPrefix}PageItemConfig")) . ' ' . 'WHERE `idItem` = ' . $this->_db->quote($id, Qs_Db::INT_TYPE); $this->_db->query($sql); foreach ($data as $name => $value) { $updateData = array( 'idItem' => $id, 'name' => $name, 'value' => $value ); $this->_getTable($draftPrefix . 'PageItemConfig')->insert($updateData); } } public function updateDraftMeta($data = array()) { return $this->updateMeta($data, true); } protected function _metaOptionsFromForm($data = array(), $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $metaOptions = array(); if (false === ($oldValues = $this->getMetaOptions($this->getPrimaryKey(), $draft, true))) { $oldValues = array(); } $defOptions = $this->_getDefaultMetaOptions($this->getPrimaryKey()); $availableOptions = array_keys($defOptions); $defValues = array_merge($defOptions, $oldValues); foreach ($availableOptions as $name) { if (!array_key_exists($name, $data)) { continue; } $allowName = $name . '4Dummy'; $method = array_key_exists($name, $oldValues) ? 'update' : 'insert'; $option = array(); $option['idPage'] = $this->getPrimaryKey(); $option['name'] = $name; $option['show'] = array_key_exists($allowName, $data) ? $data[$allowName] : $defValues[$name]['show']; $option['value'] = array_key_exists($name, $data) ? $data[$name] : $defValues[$name]['value']; $metaOptions['methods'][] = $method; $metaOptions['options'][] = $option; } return $metaOptions; } public function updateMeta($data = array(), $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $metaOptions = $this->_metaOptionsFromForm($data, $draft); if (isset($data['redirect']) && isset($data['redirectType'])) { if ($data['redirectType'] == 'page' && isset($data['redirectPageId'])) { $data['redirectAlias'] = BASE_URL_LANGUAGE . '/' . Qs_SiteMap::findFirst(array('id' => $data['redirectPageId']), null, null, 'fullAlias'); } $data['redirectAlias'] = str_replace(BASE_URL_LANGUAGE, '{BASE_URL}', $data['redirectAlias']); } unset($data['id'], $data['idPage']); $this->_db->beginTransaction(); try { $this->_getTable($draftPrefix . 'Page')->updateByKey($data, $this->getPrimaryKey()); $where = '`idPage` = ' . $this->_db->quote($this->getPrimaryKey(), Zend_Db::INT_TYPE) . ' ' . 'AND `language` = ' . $this->_db->quote($this->getLanguage()); if ($row = $this->_getTable($draftPrefix . 'PageContent')->fetchRow($where)) { $row->setFromArray($data); $row->save(); } else { $data['idPage'] = $this->getPrimaryKey(); $data['language'] = $this->getLanguage(); $this->_getTable($draftPrefix . 'PageContent')->insert($data); } if (isset($metaOptions)) { $this->_updateMetaOptions($metaOptions, $draft); } $this->_db->commit(); $this->touch($draft); return true; } catch (Exception $e) { Qs_Debug::log($e->getMessage(), 3); $this->_db->rollBack(); } return false; } protected function _updateMetaOptions($metaOptions = array(), $draft = false, $idPage = null) { if (empty($metaOptions) || !isset($metaOptions['methods']) || !isset($metaOptions['options'])) { return false; } $idParent = ($idPage) ? intval($idPage) : $this->getPrimaryKey(); $draftPrefix = ($draft) ? 'Draft' : ''; $optionsTable = $this->_getTable($draftPrefix.'PageOption'); foreach ($metaOptions['methods'] as $key => $method) { if ($method == 'insert') { if (!isset($metaOptions['options'][$key]['idPage'])) { $metaOptions['options'][$key]['idPage'] = $idParent; } $optionsTable->insert($metaOptions['options'][$key]); } else { $where = $this->_db->quoteInto('(`idPage`=?) ', $idParent) . $this->_db->quoteInto('AND (`name`=?)', $metaOptions['options'][$key]['name']); $optionsTable->update( $metaOptions['options'][$key], $where ); } $option = &$metaOptions['options'][$key]; if ('enabled' == $option['name'] && 'n' == $option['value']) { $this->_updateSubPageEnabledOption($idParent, $option['value'], $draft); } } return true; } protected function _updateSubPageEnabledOption($idParent, $value, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $optionTable = $this->_getTable($draftPrefix . 'PageOption'); $pageTable = $this->_getTable($draftPrefix . 'Page'); $ids = $this->_getChildIds($idParent, $draft, ['system' => 'n']); foreach ($ids as $id) { $data['idPage'] = $id; $where = $this->_db->quoteInto('(`idPage` = ?) ', $id) . $this->_db->quoteInto('AND (`name` = ?)', 'enabled'); $optionTable->update(['idPage' => $id, 'value' => $value], $where); if ($draft) { $pageTable->updateDataBy(['enabled' => $value], ['id' => $id, 'system' => 'n']); } else { $pageTable->updateBy(['enabled' => $value], ['id' => $id, 'system' => 'n']); } $this->_updateSubPageEnabledOption($id, $value, $draft); } return $this; } protected function _where4Sorter(Zend_Db_Select $select) { $select->where("`{$this->_tableAlias}`.`idParent` = ?", $this->idParent); return $this; } public function deleteDraftItem($id_item) { return $this->deleteItem($id_item, true); } public function deleteItem($id_item, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; if (false === ($itemRow = $this->{"get{$draftPrefix}ItemRow"}($id_item))) { return false; }; if ($itemObject = $this->getItemObject($itemRow->type)){ $itemObject->setPrimaryKey($itemRow->number); $itemObject->setDraftPrefix($draftPrefix); $itemObject->delete(); } $this->_getTable($draftPrefix . 'PageItem')->delete('`id` = ' . $this->_db->quote($id_item, Zend_Db::INT_TYPE)); $this->_getTable($draftPrefix . 'PageItemConfig')->delete('`idItem` = ' . $this->_db->quote($id_item, Zend_Db::INT_TYPE)); $this->touch($draft); return true; } public function getItemGroupNames() { if (null === $this->_itemGroupNames) { $cache = Qs_Cache::factory('Core', 'File', $this->_cacheFrontendOptions); if(!$this->_itemGroupNames = $cache->load(self::PAGE_ITEM_GROUP_NAMES_CACHE_ID)) { $select = $this->_db->select(); $select->from($this->_getTableName('DPageItemGroup'), array('name', 'title')); $select->order('sorter'); $this->_itemGroupNames = $this->_db->fetchPairs($select); $cache->save($this->_itemGroupNames, self::PAGE_ITEM_GROUP_NAMES_CACHE_ID); } } return $this->_itemGroupNames; } public function getGroupIdByName($name) { $select = $this->_db->select(); $select->from($this->_getTableName('DPageItemGroup'), array('id')); $select->where('`name` = ?', $name); return $this->_db->fetchOne($select); } public function reorderDraftItemsGroup($order) { if (!is_array($order) || empty($order)) { return false; } foreach ($order as $id => $sorter) { $this->_getTable('DraftPageItem')->update( array('sorter' => $sorter), 'id = ' . $this->_db->quote($id, Zend_Db::INT_TYPE) ); } $this->touchDraft(); return true; } protected function _getDraftDataEx() { return $this->_getDataEx(true); } protected function _getDataEx($draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; if (null === $this->_dataEx) { $id = intval($this->getPrimaryKey()); if (!($rowMeta = $this->_getMetaRow($id, $draft))) { return false; }; $this->_dataEx = Qs_Array::excludeKey($rowMeta->toArray(), 'added', 'changed'); $this->_dataEx['content'] = array(); $stmt = $this->_getTable($draftPrefix . 'PageContent')->select() ->where('idPage = ?', $id) ->query(); while ($row = $stmt->fetch()) { $this->_dataEx['content'][$row['language']] = Qs_Array::excludeKey($row, 'idPage', 'language', 'added', 'changed'); } $this->_dataEx['items'] = array(); $stmt = $this->_getTable($draftPrefix . 'PageItem')->select() ->where('idPage = ?', $id) ->query(); while ($row = $stmt->fetch()) { $item = Qs_Array::excludeKey($row, 'id', 'idPage', 'number', 'added', 'changed'); if ($itemObject = $this->getItemObject($row['type'])) { $itemObject->setDraftPrefix($draftPrefix); $itemObject->setPrimaryKey($row['number']); if ($data = $itemObject->getDataEx()) { $item['data'] = $data; } } $item['config'] = Qs_Array::expand($this->_getItemConfig($row['id'], $draft)); $this->_dataEx['items'][] = $item; } } return $this->_dataEx; } protected function _getItemConfig($idItem, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $select = $this->_db->select(); $select->from($this->_getPair($draftPrefix . 'PageItemConfig'), array('name', 'value')); $select->where("`{$draftPrefix}PageItemConfig`.`idItem` = ?", $idItem, Qs_Db::INT_TYPE); $select->order($draftPrefix . 'PageItemConfig.id'); $data = $this->_db->fetchPairs($select); $data = Qs_Array::expand($data); return $data; } protected function _getItemsConfigs(array $itemIds, $draft = false) { $data = array(); if ($itemIds) { $draftPrefix = ($draft) ? 'Draft' : ''; $select = $this->_db->select(); $select->from($this->_getPair($draftPrefix . 'PageItemConfig'), array('idItem', 'name', 'value')); $select->where("`{$draftPrefix}PageItemConfig`.`idItem` IN (?)", $itemIds, Qs_Db::INT_TYPE); $select->order($draftPrefix . 'PageItemConfig.id'); $list = $this->_db->fetchAll($select, array(), Qs_Db::FETCH_GROUP); foreach ($list as $itemId => $config) { foreach ($config as $option) { $data[$itemId][$option['name']] = $option['value']; } $data[$itemId] = Qs_Array::expand($data[$itemId]); } } return $data; } protected function _isValidDataEx($data) { if (!is_array($data) || empty($data)) { return false; } $requiredFields = array('id', 'alias', 'content'); foreach ($requiredFields as $name) { if (!array_key_exists($name, $data)) { return false; } } if (!is_array($data['content']) || empty($data['content'])) { return false; } if (isset($data['items'])) { if (!is_array($data['items'])) { return false; } } return true; } protected function _saveDraftDataEx($data) { return $this->_saveDataEx($data, true); } protected function _saveDataEx($data, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; if (!$this->_isValidDataEx($data)) { throw new App_Cms_Exception('Invalid data array'); } $idPage = intval($data['id']); if (!$idPage) { unset($data['id']); } $this->_db->beginTransaction(); try { $idPage = $this->_getTable($draftPrefix . 'Page')->save($data, $idPage); foreach ($data['content'] as $language => $content) { $content['idPage'] = $idPage; $content['language'] = $language; $this->_getTable($draftPrefix . 'PageContent')->save($content, array($idPage, $language)); } if (!isset($data['items'])) { return $idPage; } foreach ($data['items'] as $item) { if ($itemObject = $this->getItemObject($item['type'])){ $itemObject->setDraftPrefix($draftPrefix); $item['number'] = $itemObject->insertDataEx($item['data']); } $item['idPage'] = $idPage; $idItem = $this->_getTable($draftPrefix . 'PageItem')->insert($item); if (isset($item['config']) && !empty($item['config'])) { $this->updateItemConfig($idItem, $item['config'], $draft); } } $this->_db->commit(); return true; } catch (Exception $e) { Qs_Debug::log($e->getMessage(), 3); $this->_db->rollBack(); } return false; } public function publish() { if (false === ($data = $this->_getDataEx(true))) { return false; } if (false === ($metaOptions = $this->_getMetaOptions4Publish())) { return false; } $this->_updateMetaOptions($metaOptions, false); $this->_publishRedirection($data['id']); $this->deleteItems($data['id']); $this->_saveDataEx($data, false); $this->clearCache(); $this->_updateRoot(); $this->_updateHasBlocks(); $this->_handleFiles(); $event = new App_Cms_Event(array('pageId' => (int) $data['id'], 'pageData' => $data)); Qs_Event_Dispatcher::getInstance()->dispatch('postPublish', $event, $this); return true; } protected function _getMetaOptions4Publish() { $idPage = intval($this->getPrimaryKey()); $options = $this->getDraftMetaOptions($idPage, true); $oldOptions = $this->getMetaOptions($idPage, false, true); $metaOptions = array(); foreach ($options as $name => $option) { $method = array_key_exists($name, (array)$oldOptions) ? 'update' : 'insert'; unset($option['title']); $option['idPage'] = $idPage; $option['name'] = $name; $metaOptions['methods'][] = $method; $metaOptions['options'][] = $option; } return $metaOptions; } public function updateOrder(array $order) { parent::updateOrder($order); $this->_updateRoot(); } protected function deleteDraftItems($idPage) { return $this->deleteItems($idPage, true); } protected function deleteItems($idPage, $draft = false) { $list = $this->getItemsId($idPage, $draft); foreach ($list as $id_item) { $this->deleteItem($id_item, $draft); } return $this; } public function getItemsId($idPage, $draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $select = $this->_db->select(); $select->from($this->_getPair($draftPrefix . 'PageItem'), 'id'); $select->where("`idPage`=?", $idPage, Zend_Db::INT_TYPE); $list = $this->_db->fetchCol($select); return $list; } public function deleteDraft() { return $this->_delete(true); } public function delete() { $this->_clearErrors(); if (null === $this->getData()) { $this->_addError(static::MSG_INVALID_RECORD_ID); return false; } $this->deleteDraft(); $this->_delete(); $this->clearCache(); // todo: clear site-map cache in Qs_SiteMap using Qs_Event_Dispatcher return 1; // affected rows } protected function _delete($draft = false, $idPage = null) { if (null === $idPage) { $idPage = (int) $this->getPrimaryKey(); } if ($draft) { $draftPrefix = 'Draft'; $eventName = 'draftPostDelete'; } else { $draftPrefix = ''; $eventName = 'postDelete'; $this->_deleteRedirection($idPage); $this->_deleteFiles(null, $idPage); $children = $this->_getChildIds($idPage); if ($children) { foreach ($children as $childId) { $this->_delete(true, $childId); $this->_delete(false, $childId); } } } $this->deleteItems($idPage, $draft); $this->_getTable($draftPrefix . 'Page')->delete('`id` = ' . $idPage); $this->_getTable($draftPrefix . 'PageContent')->delete('`idPage` = ' . $idPage); $this->_deleteMetaOptions($idPage, $draft); $event = new App_Cms_Event(array('pageId' => $idPage)); Qs_Event_Dispatcher::getInstance()->dispatch($eventName, $event, $this); return $this; } protected function _deleteFiles($row = null, $idPage = null) { if (null === $idPage) { $idPage = (int) $this->getPrimaryKey(); } if (is_array($this->_fileFields) && !empty($this->_fileFields)) { $adapter = new Qs_File_Transfer_Adapter_Db(); if (null === $row) { if (false !== ($row = $this->_getTable()->findRow($idPage))) { $row = $row->toArray(); } } if (is_array($row) && !empty($row)) { foreach ($this->_fileFields as $name) { if (isset($row[$name]) && !empty($row[$name])) { $adapter->delete($row[$name], $name); } } } unset($adapter); } } protected function _getChildIds($idPage, $draft = false, array $filter = []) { $tablePrefix = ($draft) ? 'Draft' : ''; $select = $this->_db->select(); $select->from($this->_getPair($tablePrefix . 'Page', 'p'), 'id'); $select->where('`idParent` = ?', (string) $idPage, Qs_Db::INT_TYPE); Qs_Db::filter($select, $filter, 'p'); return $this->_db->fetchCol($select); } protected function _deleteDraftMetaOptions($idPage = null) { return $this->_deleteMetaOptions($idPage, true); } protected function _deleteMetaOptions($idPage = null, $draft = false) { $idPage = ($idPage) ? $idPage : intval($this->getPrimaryKey()); $draftPrefix = ($draft) ? 'Draft' : ''; return $this->_getTable($draftPrefix.'PageOption')->delete('`idPage`='.$idPage); } public function getItemTypeTitle($name) { $types = $this->getDItemType4Select(); if (isset($types[$name])) { return $types[$name]; } return null; } public function getLanguageNames() { return array_keys(Qs_Db_Language::getList()); } public function getLanguages() { if (null === $this->_languages) { $this->_languages = Qs_Db_Language::getList(); } return $this->_languages; } protected function _getFullAliasById($id) { if (empty($this->_id2Page)) { $this->getSiteMap(); } if (isset($this->_id2Page[$id])) { return $this->_id2Page[$id]['fullAlias']; } return false; } public function getPageById($id) { return $this->_getPageById($id); } protected function _getPageById($id) { if (empty($this->_id2Page)) { $this->_initId2Page($this->getSiteMap()); } if (isset($this->_id2Page[$id])) { return $this->_id2Page[$id]; } return false; } protected function _initId2Page(array $siteMap) { foreach ($siteMap as $page) { $this->_id2Page[$page['id']] = $page; if (!empty($page['sub'])) { $this->_initId2Page($page['sub']); } } return $this; } public function clearCache() { $cache = Qs_Cache::factory('Core', 'File', $this->_cacheFrontendOptions); foreach($this->_cacheId as $id) { $cache->remove($id); } return $this; } public function updateIndex($data) { $this->_db->beginTransaction(); try { $table = $this->_getTable("{$this->_tableAlias}Index"); $select = $this->_db->select(); $select->from($this->_getTableName("{$this->_tableAlias}Index"), array('id')); $select->where('`url` = ?', $data['url']); if (!($id = $this->_db->fetchOne($select))) { $result = $table->insert($data); } else { $result = $table->updateByKey($data, $id); } $this->_db->commit(); } catch (Exception $e) { Qs_Debug::log($e->getMessage(), 3); $this->_db->rollBack(); return $e; } return $result; } protected function _updateRoot() { $sql = 'UPDATE ' . $this->_db->quoteIdentifier($this->_tableName) . ' SET `isRoot` = \'n\''; $this->_db->query($sql); $select = $this->_db->select(); $select->from($this->_getPair(), 'id'); $select->where('`Page`.`idParent` = 0'); $select->join($this->_getPair('DPageOption'), '`DPageOption`.`name` = "isAdditional"', array()) ->joinLeft( $this->_getPair('PageOption'), '`Page`.`id` = `PageOption`.`idPage` AND `PageOption`.`name` = `DPageOption`.`name`', array() ) ->where('IFNULL(`PageOption`.`value`, `DPageOption`.`value`) = "n"'); $select->order('Page.sorter'); $select->limit(1); $rootId = $this->_db->fetchOne($select); $sql = 'UPDATE ' . $this->_db->quoteIdentifier($this->_tableName) . ' ' . 'SET `isRoot` = \'y\' ' . 'WHERE id = ' . $this->_db->quote($rootId, Qs_Db::INT_TYPE); $this->_db->query($sql); } protected function _updateHasBlocks() { $select = $this->_db->select(); $select->from($this->_tableName . 'Item', new Zend_Db_Expr('1')) ->where('`idPage` = ' . (int) $this->getPrimaryKey()); $hasBlocks = (bool) $this->_db->fetchOne($select); $sql = 'UPDATE ' . $this->_db->quoteIdentifier($this->_tableName) . "SET `hasBlocks` = '" . (($hasBlocks) ? 'y' : 'n') . "' " . "WHERE id = " . (int) $this->getPrimaryKey(); $this->_db->query($sql); } public function deleteIndex($idPage) { throw new Qs_Exception('deleteIndex - ' . $idPage); } public function reindexPage($idPage) { throw new Qs_Exception('reindexPage - ' . $idPage); } public function touchDraft() { return $this->touch(true); } public function touch($draft = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $this->_getTable($draftPrefix . 'Page')->updateByKey(array('changed' => date('Y-m-d H:i:s')), $this->_primaryKey); return $this; } public function getDraftMetaOptions($idPage, $ignoreDefault = false) { return $this->getMetaOptions($idPage, true, $ignoreDefault); } public function getMetaOptions($idPage, $draft = false, $ignoreDefault = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $ignorePrefix = ($ignoreDefault) ? 'Clean' : ''; if (!isset($this->{"_data{$draftPrefix}{$ignorePrefix}MetaOptions"}[$idPage])) { $options = $this->_getPageOptions($idPage, null, $draft, $ignoreDefault); if (is_array($options) && array_key_exists('enabled', $options) && $this->isParentDisabled($idPage)) { $options['enabled']['disabled'] = true; } $this->{"_data{$draftPrefix}{$ignorePrefix}MetaOptions"}[$idPage] = $options; } else { $options = $this->{"_data{$draftPrefix}{$ignorePrefix}MetaOptions"}[$idPage]; } return $options; } protected function _getPageOptions($idPage, $meta = null, $draft = false, $ignoreDefault = false) { $draftPrefix = ($draft) ? 'Draft' : ''; $pageOptions = ($ignoreDefault) ? array() : $this->_getDefaultMetaOptions($idPage); if (!$ignoreDefault) { if (null === $meta) { $meta = $this->_getMetaRow($idPage, $draft); $meta = ($meta) ? $meta->toArray() : array(); } foreach ($meta as $name => $value) { if (array_key_exists($name, $pageOptions)) { $pageOptions[$name]['value'] = $value; } } } $select = $this->_db->select(); $select->from($this->_getPair($draftPrefix . 'PageOption')); $select->joinLeft( $this->_getPair('DPageOption'), "`DPageOption`.`name` = `{$draftPrefix}PageOption`.`name`", array('title') ); $select->where("`{$draftPrefix}PageOption`.`idPage`=?", intval($idPage)); $select->order('sorter'); $data = $this->_db->fetchAll($select); foreach ($data as $option) { $pageOptions[$option['name']] = array( 'name' => $option['name'], 'show' => $option['show'], 'value' => $option['value'], 'title' => $option['title'], ); } return ($ignoreDefault && empty($pageOptions)) ? false : $pageOptions; } protected function _getDefaultAccountMetaOptions() { $options = $this->getConfigArray('accountDefaultOptions'); $availableOptions = $this->_get4Select('DPageOption', array('name','title','show','value')); $options = array_merge($availableOptions, $options); return $options; } protected function isInAccountBranch($pageId) { $accountPageId = Qs_SiteMap::findFirst(null, ['type' => 'User\\'], ['defaultAction' => 'edit'], 'idParent'); do { if ($accountPageId == $pageId) { return true; } } while ($pageId = $this->_getTable('Page')->search($pageId, 'idParent')); return false; } protected function _getDefaultMetaOptions($pageId) { if ($this->isInAccountBranch($pageId)) { return $this->_getDefaultAccountMetaOptions(); } static $pageOptions = null; if (null === $pageOptions) { $pageOptions = $this->getConfigArray('defaultOptions'); $availableOptions = $this->_get4Select('DPageOption', array('name','title','show','value')); $pageOptions = array_merge($availableOptions, $pageOptions); } return $pageOptions; } public function getDefaultMetaPairs() { static $result = null; if (null === $result) { $result = $this->_get4Select('DPageOption', array('name', 'value'), null, 'sorter'); } return (array) $result; } protected function extractMeta($options) { if (!is_array($options)) { return false; } $meta = array(); foreach ($options as $name => $option) { $meta[$name] = (is_array($option)) ? $option['value'] : $option; } return $meta; } public function isRedirectFields() { $redirectFields = array('redirect', 'redirectType', 'redirectPageId', 'redirectStatus', 'redirectAlias'); $metaData = $this->_getTable($this->_tableAlias)->getMetaData(); $diff = array_diff($redirectFields, array_keys($metaData)); if (empty($diff)) { return true; } return false; } protected function _getReorderSelect($isAdditional = false) { $select = parent::_getReorderSelect(); if (0 === $this->idParent && null !== $isAdditional) { $select->joinLeft( $this->_getPair('PageOption'), "(`PageOption`.`idPage` = `" . $this->_tableAlias . "`.`id`) AND (`PageOption`.`name` = 'isAdditional')", array('PageOption.value') ); $select->group($this->_tableAlias . '.id'); if (true === $isAdditional) { $select->where("PageOption.value = 'y'"); } else { $select->where("PageOption.value IS NULL OR PageOption.value = 'n'"); } } return $select; } public function getReorderOptions($keyColumn = null, $titleColumn = null, $isAdditional = null) { $keyColumn = (null === $keyColumn) ? $this->_reorderKeyColumn : $keyColumn; $titleColumn = (null === $titleColumn) ? $this->_reorderTitleColumn : $titleColumn; $list = $this->_db->fetchAll($this->_getReorderSelect((bool) $isAdditional)); $options = array(); foreach ($list as $row) { $options[$row[$keyColumn]] = $row[$titleColumn]; } return $options; } public function setRedirection($value) { $this->_hasRedirection = (bool) $value; return $this; } public function getRedirection() { return (false !== $this->_hasRedirection); } protected function _getRedirectionObj() { return new App_Redirection_Obj(); } protected function _deleteRedirection($idPage) { if ($this->getRedirection()) { $this->_getRedirectionObj()->removePageRedirection($idPage); return true; } return false; } protected function _publishRedirection($idPage) { if ($this->getRedirection()) { $this->_getRedirectionObj()->updatePageRedirection($idPage); return true; } return false; } public function setSuMode($suMode = true) { $this->_suMode = (bool) $suMode; return $this; } public function getSuMode() { return $this->_suMode; } public static function getImageHeaderExcludePageIds() { $pages = array(); /** @var $selectors Zend_Config */ if (null === ($selectors = Qs_Application::getConfig('cms')->get('headerImageExcludePages')) || !$selectors->count() ) { return $pages; } $selectors = $selectors->toArray(); foreach ($selectors as $selector) { if (empty($selector)) { continue; } if (is_array($selector)) { $selector = array_slice($selector, 0, 3); $selector = array_pad($selector, 3, null); $selector[] = 'id'; $id = call_user_func_array('Qs_SiteMap::findAll', $selector); } else { $id = Qs_SiteMap::findAll($selector, 'id'); } if (!empty($id)) { if (is_array($id)) { $pages = array_merge($pages, $id); } else { $pages[] = $id; } } } return $pages; } public function getBodyTemplate4Select($handler = 'site') { $handlerClass = 'App_Doc_' . ucfirst($handler); $handlerFile = BASE_PATH . '/App/Doc/' . ucfirst($handler) . '.php'; if (!file_exists($handlerFile)) { throw new App_Cms_Exception('Handler file not found: ' . $handlerFile); } /** @var $handlerObj Qs_Doc */ $handlerObj = new $handlerClass(array('authentication' => false)); $paths = (array) $handlerObj->getTemplatePath(); unset($handlerObj); $files = array(); foreach ($paths as $path) { $dir = BASE_PATH . '/tpl/' . $path . '/Body'; if (file_exists($dir) && is_dir($dir)) { $pattern = $dir . '/*.tpl'; $_files = glob($pattern); if ($_files) { $files = array_merge($files, $_files); } } } $templates = array(); foreach ($files as $file) { $templates[basename($file)] = basename($file); } return $templates; } public function getFilteredHtmlBlockViewContent($content) { if (empty($content)) { return $content; } $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); $content = preg_replace("/\]*\>.*\<\/script\>/imsUu", '', $content); $dom = new Zend_Dom_Query(); $dom->setDocumentHtml($content); $results = $dom->query('form'); foreach ($results as $tag) { /** @var $tag DOMElement */ foreach (array('action', 'autocomplete', 'enctype', 'method', 'name', 'target', 'onsubmit') as $attribute) { $tag->removeAttribute($attribute); } } $document = new DOMDocument(); $body = $results->getDocument()->documentElement->firstChild; for ($i = 0; $i < $body->childNodes->length; $i++) { $document->appendChild($document->importNode($body->childNodes->item($i), true)); } $content = $document->saveHtml(); $content = str_replace(array(''), array(''), $content); return $content; } public function getItemView($item) { global $Doc; if (!array_key_exists($item['id'], $this->_itemView)) { $class = Qs_SiteMap::getItemTypeClass($item['type'], 'View'); if (class_exists($class)) { /** @var $itemObj Qs_ViewController */ $itemObj = new $class($item); $itemObj->setDoc($Doc); $this->_itemView[$item['id']] = $itemObj; } else { $this->_itemView[$item['id']] = null; } } return $this->_itemView[$item['id']]; } public function getObjectInfo() { $data = (array) $this->getData('meta'); if (array_key_exists('title', $data)) { $data['itemTitle'] = $data['menuTitle']; } return $data; } public function isAdditional($pageId = null, $isDraft = null) { if (null === $pageId) { $pageId = $this->getPrimaryKey(); } $select = $this->_db->select(); if (null === $isDraft) { $what = 'IF (`DraftPageOption`.`value` IS NULL, `PageOption`.`value`, `DraftPageOption`.`value`)'; $select->from($this->_getPair('PageOption'), new Zend_Db_Expr($what)); $select->where('`PageOption`.`idPage` = ?', $pageId, Qs_Db::INT_TYPE); $select->where('`PageOption`.`name` = "isAdditional"'); $select->joinLeft( $this->_getPair('DraftPageOption'), '`DraftPageOption`.`idPage` = `PageOption`.`idPage` AND `DraftPageOption`.`name` = `PageOption`.`name`', '' ); } else { $tableAlias = (($isDraft) ? 'Draft' : '') . 'PageOption'; $select->from($this->_getPair($tableAlias), 'value'); $select->where('`idPage` = ?', $pageId, Qs_Db::INT_TYPE); $select->where('`name` = "isAdditional"'); } return ('y' == $this->_db->fetchOne($select)); } public function isParentDisabled($pageId = null, $recursive = true) { if (null === $pageId) { $pageId = $this->getPrimaryKey(); } $parentSelect = $this->_db->select(); $parentSelect->from($this->_getPair($this->_tableAlias, 'Parent' . $this->_tableAlias), 'idParent'); $parentSelect->where('`Parent' . $this->_tableAlias . '`.`id` = ?', $pageId, Qs_Db::INT_TYPE); $what = array(); $what[] = 'id'; $what[] = 'idParent'; $what['enabled'] = 'IF (' . ' `Draft' . $this->_tableAlias . '`.`id` IS NULL, ' . ' `' . $this->_tableAlias . '`.`enabled`, ' . ' `Draft' . $this->_tableAlias . '`.`enabled`' . ')'; $select = $this->_db->select(); $select->from($this->_getPair(), $what); $select->joinLeft( $this->_getPair('Draft' . $this->_tableAlias), '`' . $this->_tableAlias . '`.`id` = `Draft' . $this->_tableAlias . '`.`id`', array() ); $select->where('`' . $this->_tableAlias . '`.`id` = ?', $parentSelect); $page = $this->_db->fetchRow($select); if (!$page) { return false; } if ($recursive && $page['idParent'] && 'y' == $page['enabled']) { return $this->isParentDisabled($page['id'], $recursive); } return ('n' == $page['enabled']); } }