'site',
];
protected static $_siteMapXml;
protected static $_siteMapDb;
protected static $_siteMapMenu;
protected static $_siteMapFooter;
protected static $_siteMapUserend;
protected static $_siteMapBackendFull;
protected static $_siteMapBackendMenu;
protected static $_fullSitemap;
protected static function _getFromXml($file = 'sitemap.xml')
{
if (null === Qs_SiteMap::$_siteMapXml) {
$config = new Zend_Config_Xml(BASE_PATH . '/' . $file);
$siteMap = $config->toArray();
if (0 === strpos(CURRENT_PAGE, 'tribal-admin')) {
$siteMap['tribal-admin'] = $siteMap['admin'];
unset($siteMap['admin']);
} else {
unset($siteMap['tribal-admin']);
}
Qs_SiteMap::$_siteMapXml = Qs_SiteMap::_prepareSiteMapXml($siteMap);
}
return Qs_SiteMap::$_siteMapXml;
}
public static function reload($file)
{
Qs_SiteMap::$_siteMapXml = null;
Qs_SiteMap::$_siteMapBackendMenu = null;
Qs_SiteMap::_getFromXml($file);
}
public static function loadXml($file = 'sitemap.xml')
{
Qs_SiteMap::_getFromXml($file);
}
public static function getFromDb($options = [])
{
return Qs_SiteMap::_getFromDb($options);
}
protected static function _getFromDb($options = [])
{
if (array_key_exists('select', $options)) {
return App_Cms_Obj::getInstance()->getSiteMap($options);
}
if (null === Qs_SiteMap::$_siteMapDb) {
Qs_SiteMap::$_siteMapDb = App_Cms_Obj::getInstance()->getSiteMap();
}
if (empty($options)) {
return Qs_SiteMap::$_siteMapDb;
} else {
if (empty($options['filter']) || !is_array($options['filter'])) {
$options['filter'] = [];
}
if (!empty($options['idParent'])) {
$siteMap = Qs_Array::treeBranch(Qs_SiteMap::$_siteMapDb, $options['idParent']);
} else {
$siteMap = Qs_SiteMap::$_siteMapDb;
}
return Qs_SiteMap::_siteMapFilter($siteMap, $options);
}
}
/**
* Example:
*
* $filtered = Qs_SiteMap::_siteMapFilter(
* Qs_SiteMap::$_siteMapDb,
* array(
* 'filter' => array('system' => 'n', 'showInSiteMap' => 'y'),
* 'idParent' => 6,
* )
* );
*
* @param array $siteMap
* @param array $options
* @return array
*/
protected static function _siteMapFilter(array $siteMap, array $options)
{
$tree = [];
foreach ($siteMap as $key => $page) {
if (!array_diff_assoc($options['filter'], $page)) {
$tree[$key] = $page;
$sub = Qs_Array::get($page, 'sub', []);
if ($sub) {
unset($tree[$key]['sub']);
$tree[$key]['sub'] = Qs_SiteMap::_siteMapFilter($sub, $options);
}
}
}
return $tree;
}
protected static function _prepareRedirectAdminAlias(&$items)
{
foreach($items as &$item){
if ($item['type'] == 'Redirect_') {
$aliasParts = explode('/', $item['alias']);
$adminPath = (0 === strpos(CURRENT_PAGE, 'tribal-admin')) ? 'tribal-admin' : 'admin';
$aliasParts[0] = $adminPath;
$item['alias'] = implode('/', $aliasParts);
}
}
}
protected static function _prepareSiteMapXmlPage(&$page, $fullAlias = '', $parent = null)
{
$page['source'] = 'xml';
$parent = $parent ? Qs_Array::map($parent, array_keys(self::$_defaults)) : self::$_defaults;
$page = array_merge($parent, $page);
if (isset($page['item'])) {
if (Qs_Array::isAssoc($page['item'])) {
$page['items'] = [$page['item']];
} else {
$page['items'] = $page['item'];
}
unset($page['item']);
}
if ($page['handler'] == 'admin' && isset($page['items'])) {
self::_prepareRedirectAdminAlias($page['items']);
}
if ($page['handler'] == 'admin') {
$menuTitle = (0 === strpos(CURRENT_PAGE, 'tribal-admin') && isset($page['menuTitleTribal']))
? $page['menuTitleTribal']
: ((isset($page['menuTitle'])) ? $page['menuTitle'] : '');
$page['menuTitle'] = $menuTitle;
}
if (!isset($page['header']) || empty($page['header'])) {
$page['header'] = Qs_Array::get($page, 'menuTitle');
}
if (!isset($page['title']) || empty($page['title'])) {
$page['title'] = Qs_Array::get($page, 'menuTitle');
}
$page['fullAlias'] = $fullAlias;
$page['alias'] = basename($fullAlias);
if (Qs_SiteMap::isSecurePage($page)) {
$page['url'] = BASE_URL_LANGUAGE_HTTPS . ((empty($page['fullAlias'])) ? '' : '/') . $page['fullAlias'];
} else {
$page['url'] = BASE_URL_LANGUAGE_HTTP . ((empty($page['fullAlias'])) ? '' : '/') . $page['fullAlias'];
}
if (isset($page['sub'])) {
$page['sub'] = Qs_SiteMap::_prepareSiteMapXml($page['sub'], $page);
}
}
protected static function _prepareSiteMapXml($siteMap, $parent = null)
{
if (method_exists(App_Cms_Obj::getInstance(), 'getDefaultMetaPairs')) {
$defaultMetaValues = App_Cms_Obj::getInstance()->getDefaultMetaPairs();
} else {
$defaultMetaValues = [];
Qs_Debug::log('App_Cms_Obj::getDefaultMetaPairs() is not defined. '
. 'Please update your App_Cms_Obj class mamualy.');
}
foreach ($siteMap as $alias => &$page) {
if (!is_array($page)) {
continue;
}
if (Qs_SiteMap::_isPageWrongAdminType($page)) {
unset($siteMap[$alias]);
continue;
}
Qs_SiteMap::_prepareSiteMapXmlPage($page, (($parent) ? $parent['fullAlias'] . '/' : '') . $alias, $parent);
$page = array_merge($defaultMetaValues, (array) $page);
}
return $siteMap;
}
protected static function _isPageWrongAdminType($page)
{
$adminType = (0 === strpos(CURRENT_PAGE, 'tribal-admin')) ? 'tribal' : 'admin';
return (isset($page['adminType']) && $adminType != $page['adminType']) ? true : false;
}
/**
* @param string $page
* @return bool|null
* @throws Qs_Exception
*/
public static function isSecurePage($page)
{
if (is_string($page)) {
$alias = $page;
if (0 === strpos($alias, BASE_URL_HTTP)) {
$alias = (string) substr($alias, strlen(BASE_URL_HTTP) + 1);
} elseif (0 === strpos($alias, BASE_URL_HTTPS)) {
$alias = (string) substr($alias, strlen(BASE_URL_HTTPS) + 1);
} else {
return null;
}
if (!is_array($page = Qs_SiteMap::getPage($alias, false, null))) {
return null;
}
} elseif (!is_array($page)) {
throw new Qs_Exception('invalid page parameter');
}
return (isset($page['isSecure']) && $page['isSecure'] == 'y');
}
public static function getPage($alias, $breakIfFinal = true, $defaults = null)
{
if (!($siteMap = Qs_SiteMap::getFull())) {
return Qs_SiteMap::NOT_FOUND;
}
if (null === $defaults) {
$defaults = Qs_SiteMap::$_defaults;
}
if (empty($alias)) {
// home page
return current($siteMap);
}
$page = Qs_SiteMap::_getPageEx($alias, $siteMap, $breakIfFinal, $defaults);
if (!is_array($page)) {
return $page;
}
if ('y' == $page['final']) {
if (null !== ($_page = self::_getSubFinal($page))) {
$page = array_merge($defaults, $_page);
}
}
if (array_key_exists('sub', $page)) {
unset($page['sub']);
}
if (isset($page['_restAlias'])) {
Qs_SiteMap::setRestAlias($page, $page['_restAlias']);
unset($page['_restAlias']);
}
return $page;
}
protected static function _getSubFinal(array $page)
{
if (empty($page['_restAlias'])) {
return null;
}
$restParams = explode('/', $page['_restAlias']);
$subAlias = array_shift($restParams);
if (isset($page['sub']) && is_array($page['sub']) && array_key_exists($subAlias, $page['sub'])
&& 'y' == $page['sub'][$subAlias]['final']
) {
$page = $page['sub'][$subAlias];
$page['_restAlias'] = implode('/', $restParams);
if (null !== ($_page = self::_getSubFinal($page))) {
return $_page;
}
return $page;
}
return null;
}
public static function filter($siteMap, $filter)
{
return Qs_SiteMap::_filter($siteMap, $filter);
}
protected static function _filter($siteMap, $filter)
{
foreach ($siteMap as $alias => &$page) {
foreach ($filter as $field => $value) {
if (!(isset($page[$field]) && $page[$field] == $value)) {
unset($siteMap[$alias]);
continue 2;
}
}
if (isset($page['sub']) && !empty($page['sub'])) {
$page['sub'] = Qs_SiteMap::_filter($page['sub'], $filter);
}
}
return $siteMap;
}
public static function prepareMobileMenu(array &$menu, $appendItem = null)
{
foreach ($menu as &$menuItem) {
if (array_key_exists('sub', $menuItem) && $menuItem['sub']) {
$parentItem = null;
$hasItems = (array_key_exists('items', $menuItem) && $menuItem['items']);
$hasPageRedirect = ('y' == $menuItem['redirect'] && 'page' == Qs_Array::get($menuItem, 'redirectType'));
if ($hasItems && !$hasPageRedirect || (!$hasItems && !$hasPageRedirect)) {
$parentItem = $menuItem;
unset($parentItem['sub']);
}
$menuItem['url'] = '#';
self::prepareMobileMenu($menuItem['sub'], $parentItem);
}
}
if ($appendItem) {
$menu = [$appendItem['fullAlias'] => $appendItem] + $menu;
}
return true;
}
public static function getMenu()
{
if (null === Qs_SiteMap::$_siteMapMenu) {
Qs_SiteMap::$_siteMapMenu = Qs_SiteMap::filter(self::getFull(), ['showInMenu' => 'y', 'enabled' => 'y']);
}
return Qs_SiteMap::$_siteMapMenu;
}
public static function getFooter()
{
if (null === Qs_SiteMap::$_siteMapFooter) {
Qs_SiteMap::$_siteMapFooter = Qs_SiteMap::filter(self::getFull(), ['showInFooter' => 'y', 'enabled' => 'y']);
}
return Qs_SiteMap::$_siteMapFooter;
}
public static function get4Userend()
{
if (null === Qs_SiteMap::$_siteMapUserend) {
Qs_SiteMap::$_siteMapUserend = Qs_SiteMap::filter(self::getFull(), ['showInSiteMap' => 'y', 'enabled' => 'y']);
}
return Qs_SiteMap::$_siteMapUserend;
}
public static function getBackendSiteMapFull()
{
if (null === Qs_SiteMap::$_siteMapBackendFull) {
$siteMap = Qs_SiteMap::_getFromXml();
//@todo AdminPath
$adminPath = (0 === strpos(CURRENT_PAGE, 'tribal-admin')) ? 'tribal-admin' : 'admin';
Qs_SiteMap::$_siteMapBackendFull = [$adminPath => $siteMap[$adminPath]];
}
return Qs_SiteMap::$_siteMapBackendFull;
}
public static function getBackendMenu()
{
if (null === Qs_SiteMap::$_siteMapBackendMenu) {
$siteMap = Qs_SiteMap::_getFromXml();
//@todo AdminPath
$adminPath = (0 === strpos(CURRENT_PAGE, 'tribal-admin')) ? 'tribal-admin' : 'admin';
Qs_SiteMap::$_siteMapBackendMenu = Qs_SiteMap::_filter($siteMap[$adminPath]['sub'], ['showInMenu' => 'y']);
}
return Qs_SiteMap::$_siteMapBackendMenu;
}
protected static function _getPageEx($_alias, $siteMap, $breakIfFinal = true, $defaults = [])
{
$parts = explode('/', $_alias);
$alias = array_shift($parts);
$restAlias = implode('/', $parts);
if (isset($siteMap[$alias])) {
if ($siteMap[$alias]['enabled'] == 'n') {
return Qs_SiteMap::NOT_FOUND;
}
if (!strlen($restAlias)) {
if (empty($parts)) {
return array_merge($defaults, $siteMap[$alias]);
}
return Qs_SiteMap::ENDS_WITH_SLASH;
}
if (isset($siteMap[$alias]['final']) && $siteMap[$alias]['final'] == 'y' && $breakIfFinal) {
$page = array_merge($defaults, $siteMap[$alias]);
$page['_restAlias'] = $restAlias;
$partsCount = count($parts);
if (2 <= $partsCount && empty($parts[$partsCount - 1])) {
return Qs_SiteMap::ENDS_WITH_SLASH;
}
return $page;
}
if (isset($restAlias[0]) && $restAlias[0] == '/') {
return Qs_SiteMap::NOT_FOUND;
}
if (isset($siteMap[$alias]['sub'])) {
$_defaults = array_intersect_key(array_merge($defaults, $siteMap[$alias]), $defaults);
return Qs_SiteMap::_getPageEx($restAlias, $siteMap[$alias]['sub'], $breakIfFinal, $_defaults);
}
}
return Qs_SiteMap::NOT_FOUND;
}
public static function setRestAlias(&$page, $restAlias)
{
if (isset($page['items'])) {
foreach ($page['items'] as &$item) {
$item['restAlias'] = $restAlias;
}
}
}
public static function get404Page()
{
return [
'title' => '404 Not Found',
'handler' => 'speedy',
'items' => [['type' => 'NotFound_']],
];
}
public static function templateExists($template)
{
if (file_exists($template) && is_file($template)) {
return true;
}
return false;
}
public static function getTemplate($template, $templatePath = null)
{
if (null !== $templatePath) {
if (is_array($templatePath)) {
foreach ($templatePath as $path) {
$templateName = BASE_PATH . '/tpl/' . $path . '/' . $template;
if (Qs_SiteMap::templateExists($templateName)) {
return $templateName;
}
}
return false;
} else {
$applicationFileName = BASE_PATH . '/tpl/' . $templatePath . '/' . $template;
if (Qs_SiteMap::templateExists($applicationFileName)) {
return $applicationFileName;
}
}
}
$commonFileName = BASE_PATH . '/tpl/' . $template;
if (Qs_SiteMap::templateExists($commonFileName)) {
return $commonFileName;
}
return false;
}
protected static function getCacheFile()
{
$suffix = '';
if (0 === strpos(CURRENT_PAGE, 'tribal-admin')) {
$suffix = '-tribal';
}
return BASE_PATH . '/tmp/cache-sitemap-' . CURRENT_LANGUAGE . $suffix . '.php';
}
public static function clearCache()
{
$file = self::getCacheFile();
if (file_exists($file)) {
unlink($file);
}
}
public static function getFull()
{
if (null === Qs_SiteMap::$_fullSitemap) {
$file = self::getCacheFile();
if (file_exists($file)) {
Qs_SiteMap::$_fullSitemap = include($file);
return Qs_SiteMap::$_fullSitemap;
}
Qs_SiteMap::loadXml();
Qs_SiteMap::$_fullSitemap = App_Cms_Obj::getInstance()->getSiteMap();
Qs_SiteMap::$_fullSitemap = array_merge(Qs_SiteMap::$_fullSitemap, Qs_SiteMap::$_siteMapXml);
file_put_contents(
$file,
' 'News_'), array('type' => 'default'), 'fullAlias');
* - Qs_SiteMap::find('(final=y)(isSecure=y)[type=default]', 'fullAlias');
*
* String selector structure: [page options](item options){config}
*/
public static function findFirst($page = null, $item = null, $config = null, $field = null, $siteMap = null)
{
if (false !== ($result = Qs_SiteMap::find($page, $item, $config, $field, 1, $siteMap))) {
if (is_string($page)) {
$field = (is_string($item)) ? $item : null;
}
return (null === $field) ? reset($result) : $result;
}
return $result;
}
/**
* Find pages (or page's column) that match the page options, item options or item config.
* If field set - return just field of first item from result
* @static
* @param array|string|null $page [OPTIONAL] page options or string selector
* @param array|null $item [OPTIONAL] item options
* @param array|null $config [OPTIONAL] item config options
* @param string|null $field [OPTIONAL] field of the page that be returned
* @param int|null $limit [OPTIONAL] result limit
* @param array|null $siteMap [OPTIONAL] context to search in
* @return mixed|bool list of pages with matched options or result value (if $field is defined)
*/
public static function find($page = null, $item = null, $config = null, $field = null,
$limit = null, $siteMap = null)
{
$result = static::_findAllPages($page, $item, $config, $field, $limit, $siteMap);
if (empty($result)) {
return false;
}
return (isset($field)) ? Qs_Array::get(reset($result), $field) : $result;
}
/**
* Find pages (or page's column) that match the page options, item options or item config.
* @static
* @param array|string|null $page [OPTIONAL] page options or string selector
* @param array|null $item [OPTIONAL] item options
* @param array|null $config [OPTIONAL] item config options
* @param string|null $field [OPTIONAL] field of the page that be returned
* @param int|null $limit [OPTIONAL] result limit
* @param array|null $siteMap [OPTIONAL] context to search in
* @return mixed|bool list of pages with matched options or result value (if $field is defined)
*/
public static function findAll($page = null, $item = null, $config = null, $field = null,
$limit = null, $siteMap = null)
{
$result = static::_findAllPages($page, $item, $config, $field, $limit, $siteMap);
if (empty($result)) {
return false;
}
return (isset($field)) ? Qs_Array::fetchCol($result, $field) : $result;
}
/**
* Find pages that match the page options, item options or item config.
* @static
* @param array|string|null $page [OPTIONAL] page options or string selector
* @param array|null $item [OPTIONAL] item options
* @param array|null $config [OPTIONAL] item config options
* @param string|null $field [OPTIONAL] field of the page that be returned
* @param int|null $limit [OPTIONAL] result limit
* @param array|null $siteMap [OPTIONAL] context to search in
* @return mixed|bool list of pages with matched options or result value (if $field is defined)
*/
protected static function _findAllPages($page = null, $item = null, $config = null, &$field = null,
$limit = null, $siteMap = null)
{
if (is_string($page)) {
$selector = $page;
$field = (is_string($item)) ? $item : null;
$page = Qs_SiteMap::_selectorToArray($selector, '/\(([^\)]+)\)/');
$item = Qs_SiteMap::_selectorToArray($selector, '/\<([^\>]+)\>/');
$config = Qs_SiteMap::_selectorToArray($selector, '/\[([^\]]+)\]/');
} else {
$page = (is_array($page)) ? $page : [];
$item = (is_array($item)) ? $item : [];
$config = (is_array($config)) ? $config : [];
}
$siteMap = (null === $siteMap) ? Qs_SiteMap::getFull() : $siteMap;
if (empty($siteMap) || !is_array($siteMap) || (empty($page) && empty($item) && empty($config))) {
return false;
}
$result = [];
Qs_SiteMap::_find($siteMap, $page, $item, $config, $result, (null !== $field) ? 1 : $limit);
if (empty($result)) {
return false;
}
return $result;
}
protected static function _selectorToArray($selector, $pattern)
{
$matches = [];
preg_match_all($pattern, $selector, $matches);
$result = [];
if (isset($matches[1])) {
foreach ($matches[1] as $string) {
$parts = explode('=', $string);
$name = array_shift($parts);
$value = array_shift($parts);
$result[$name] = $value;
}
}
return $result;
}
protected static function _find(&$siteMap, $page, $item, $config, &$result, $limit = null)
{
foreach ($siteMap as &$_page) {
$diff = array_diff_assoc($page, $_page);
if (empty($diff)) {
if (empty($item) && empty($config)) {
$result[] = $_page;
} else {
$_page['items'] = (isset($_page['items'])) ? $_page['items'] : [];
foreach ($_page['items'] as &$_item) {
$diff = array_diff_assoc($item, $_item);
if (empty($diff)) {
$_config = (array) Qs_Array::get($_item, 'config');
$diff = array_diff_assoc($config, $_config);
if (empty($diff)) {
$result[] = $_page;
}
}
}
}
}
if (isset($_page['sub']) && (null === $limit || $limit > count($result))) {
Qs_SiteMap::_find($_page['sub'], $page, $item, $config, $result);
}
}
}
public static function getAliasByItem($type)
{
if (false !== ($page = Qs_SiteMap::findFirst([], ['type' => $type]))) {
if (isset($page['isRoot']) && 'y' == $page['isRoot']) {
return '';
}
return $page['fullAlias'];
}
return false;
}
public static function createPageItemView($item)
{
$separator = (false !== strpos($item['type'], '\\')) ? '\\' : '_';
$class = 'App' . $separator . $item['type'] . 'View';
$file = BASE_PATH . '/' . str_replace(['_', '\\'], '/', $class) . '.php';
if (!file_exists($file)) {
Qs_Debug::log('Page item "' . $item['type'] . '" not found');
return false;
}
if (array_key_exists('id', $item)) {
$item['idItem'] = $item['id'];
}
return new $class($item);
}
public static function getSubClass($classNamePrefix, $suffix)
{
$separator = (false !== strpos($classNamePrefix, '\\')) ? '\\' : '_';
return $classNamePrefix . str_replace('_', $separator, $suffix);
}
public static function getItemTypeClass($type, $suffix)
{
$separator = (false !== strpos($type, '\\')) ? '\\' : '_';
return 'App' . $separator . $type . $suffix;
}
/**
* "App\Cms\View" => "Cms\"
* @param string|\Qs_ViewController $class
* @return string
*/
public static function classToType($class)
{
$class = (is_object($class)) ? get_class($class) : (string) $class;
if ('App' === substr($class, 0, 3) && 'View' === substr($class, -4)) {
$class = substr(substr($class, 4), 0, -4);
}
return $class;
}
/**
* @param string|\Qs_ViewController $class
* @return string
*/
public static function classToPath($class)
{
$class = (is_object($class)) ? get_class($class) : (string) $class;
$path = str_replace(['_', '\\'], '/', $class);
if ('App/' === substr($path, 0, 4)) {
$path = substr($path, 4);
$path = substr($path, 0, strrpos($path, '/'));
}
return rtrim($path, '/');
}
public static function classToId($class)
{
return str_replace('/', '-', strtolower(self::classToPath($class)));
}
public static function getDefaults()
{
return self::$_defaults;
}
public static function setDefaults(array $defaults)
{
self::$_defaults = $defaults;
}
public static function hasItem(array $page, array $item)
{
foreach ($page['items'] as $pageItem) {
if (!array_diff_assoc($item, $pageItem)) {
return true;
}
}
return false;
}
}
function SMGetTemplate($template, $templatePath = null)
{
return Qs_SiteMap::getTemplate($template, $templatePath);
}
function SMGetAliasByItem($type)
{
return Qs_SiteMap::getAliasByItem($type);
}