PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Ip/Menu/Helper.php

https://gitlab.com/x33n/ImpressPages
PHP | 233 lines | 159 code | 23 blank | 51 comment | 43 complexity | 01f01956f56eb8c3c292297269f2f0e8 MD5 | raw file
  1. <?php
  2. /**
  3. * @package ImpressPages
  4. *
  5. *
  6. */
  7. namespace Ip\Menu;
  8. /**
  9. *
  10. * Get menu item arrays for menu generation
  11. *
  12. */
  13. class Helper
  14. {
  15. /**
  16. * Get specific levels of menu.
  17. *
  18. * Common usage:
  19. * Get items of a first menu level (to display on top of the site), e.g., $result = \Ip\Menu\Helper::getMenuItems('menu1', 1, 1);
  20. * Get 7 levels of children of selected page on top menu (to display on a side): $result = \Ip\Menu\Helper::getMenuItems('menu1', 2, 7);
  21. *
  22. * Pass the result to ipSlot('menu', array('items' => $result));
  23. *
  24. * Please note, that items of a child level can only be returned if a selected page is in a breadcrumb parent page.
  25. * In opposite case, the function returns an empty array.
  26. *
  27. * @param string $menuName eg menu1
  28. * @param int $depthFrom
  29. * @param int $depthTo
  30. * @param string $orderBy can be set to 'title' to change ordering
  31. * @return array
  32. * @throws \Ip\Exception
  33. */
  34. public static function getMenuItems($menuName, $depthFrom = 1, $depthTo = 1000, $orderBy = null)
  35. {
  36. if ($orderBy == 'title') {
  37. $order = '`title`';
  38. } else {
  39. $order = '`pageOrder`';
  40. }
  41. // variable check
  42. if ($depthFrom < 1) {
  43. $backtrace = debug_backtrace();
  44. if (isset($backtrace[0]['file']) && $backtrace[0]['line']) {
  45. throw new \Ip\Exception(
  46. '$depthFrom can\'t be less than one. (Error source: ' . $backtrace[0]['file'] . ' line: ' . $backtrace[0]['line'] . ' ) '
  47. );
  48. } else {
  49. throw new \Ip\Exception ('$depthFrom can\'t be less than one.');
  50. }
  51. }
  52. if ($depthTo < $depthFrom) {
  53. $backtrace = debug_backtrace();
  54. if (isset($backtrace[0]['file']) && $backtrace[0]['line']) {
  55. throw new \Ip\Exception(
  56. '$depthTo can\'t be lower than $depthFrom. (Error source: ' . $backtrace[0]['file'] . ' line: ' . $backtrace[0]['line'] . ' ) '
  57. );
  58. } else {
  59. throw new \Ip\Exception('$depthTo can\'t be lower than $depthFrom.');
  60. }
  61. }
  62. // end variable check
  63. $breadcrumb = ipContent()->getBreadcrumb();
  64. $languageCode = ipContent()->getCurrentLanguage()->getCode();
  65. $menuRootId = ipDb()->selectValue(
  66. 'page',
  67. 'id',
  68. array('languageCode' => $languageCode, 'alias' => $menuName, 'isDeleted' => 0)
  69. );
  70. if ($depthFrom == 1) {
  71. $elements = ipDb()->selectAll(
  72. 'page',
  73. '*',
  74. array('isVisible' => 1, 'isSecured' => 0, 'parentId' => $menuRootId, 'isDeleted' => 0),
  75. "ORDER BY $order"
  76. ); //get first level elements
  77. } elseif (isset($breadcrumb[$depthFrom - 2])) { // if we need a second level (2), we need to find a parent element at first level. And it is at position 0. This is where -2 comes from.
  78. if (!empty($breadcrumb[0])) {
  79. $rootPage = ipContent()->getPage($breadcrumb[0]->getParentId());
  80. if ($rootPage && $rootPage->getAlias() == $menuName) {
  81. $parent = $breadcrumb[$depthFrom - 2];
  82. $elements = ipDb()->selectAll(
  83. 'page',
  84. '*',
  85. array('isVisible' => 1, 'isSecured' => 0, 'parentId' => $parent->getId(), 'isDeleted' => 0),
  86. "ORDER BY $order"
  87. );
  88. } else {
  89. $elements = array();
  90. }
  91. } else {
  92. $elements = array();
  93. }
  94. }
  95. $items = array();
  96. if (!empty($elements)) {
  97. $items = self::arrayToMenuItem($elements, $depthTo, $depthFrom, $order);
  98. }
  99. return $items;
  100. }
  101. /**
  102. * Get children items of current or specified page.
  103. *
  104. * @param int|string $pageId pageId or an alias
  105. * @param int $depthLimit limit the depth of items to be returned
  106. * @param string $orderBy can be set to 'title' to change ordering
  107. * @return array
  108. */
  109. public static function getChildItems($pageId = null, $depthLimit = 1000, $orderBy = null)
  110. {
  111. if ($orderBy == 'title') {
  112. $order = '`title`';
  113. } else {
  114. $order = '`pageOrder`';
  115. }
  116. if (is_string($pageId) && !ctype_digit($pageId)) {
  117. // $pageId is an alias. Get the real id;
  118. $pageId = ipContent()->getPage($pageId)->getId();
  119. if (!$pageId) {
  120. return array();
  121. }
  122. }
  123. if ($pageId === null) {
  124. $pageId = ipContent()->getCurrentPage()->getId();
  125. }
  126. $elements = ipDb()->selectAll(
  127. 'page',
  128. '*',
  129. array('isVisible' => 1, 'isSecured' => 0, 'parentId' => $pageId, 'isDeleted' => 0),
  130. "ORDER BY $order"
  131. ); //get first level elements
  132. $items = array();
  133. if (!empty($elements)) {
  134. $items = self::arrayToMenuItem($elements, $depthLimit, 1, $order);
  135. }
  136. return $items;
  137. }
  138. /**
  139. * @param array $pages
  140. * @param int $depth
  141. * @param int $curDepth
  142. * @param string $order
  143. * @return array
  144. */
  145. private static function arrayToMenuItem($pages, $depth, $curDepth, $order)
  146. {
  147. $items = array();
  148. foreach ($pages as $pageRow) {
  149. $page = new \Ip\Page($pageRow['id']);
  150. $item = new Item();
  151. $subSelected = false;
  152. if ($curDepth < $depth) {
  153. $children = ipDb()->selectAll(
  154. 'page',
  155. '*',
  156. array('parentId' => $page->getId(), 'isVisible' => 1, 'isSecured' => 0, 'isDeleted' => 0),
  157. "ORDER BY $order"
  158. );
  159. if ($children) {
  160. $childrenItems = self::arrayToMenuItem($children, $depth, $curDepth + 1, $order);
  161. $item->setChildren($childrenItems);
  162. }
  163. }
  164. if ($page->isCurrent() || $page->getRedirectUrl() && $page->getLink(
  165. ) == \Ip\Internal\UrlHelper::getCurrentUrl()
  166. ) {
  167. $item->markAsCurrent(true);
  168. } elseif ($page->isInCurrentBreadcrumb() || $subSelected || $page->getRedirectUrl(
  169. ) && self::existInBreadcrumb($page->getLink())
  170. ) {
  171. $item->markAsInCurrentBreadcrumb(true);
  172. }
  173. if ($page->isDisabled()) {
  174. $item->setUrl('');
  175. } elseif ($page->getRedirectUrl()) {
  176. $url = $page->getRedirectUrl();
  177. if (!preg_match('/^((http|https):\/\/)/i', $url)) {
  178. $url = 'http://' . $url;
  179. }
  180. $item->setUrl($url);
  181. } else {
  182. $item->setUrl($page->getLink());
  183. }
  184. $metaTitle = $page->getMetaTitle();
  185. $item->setBlank($page->isBlank());
  186. $item->setTitle($page->getTitle());
  187. $item->setDepth($curDepth);
  188. $item->setDisabled($page->isDisabled());
  189. $item->setId($page->getId());
  190. $item->setAlias($page->getAlias());
  191. $item->setPageTitle(empty ($metaTitle) ? $page->getTitle() : $metaTitle);
  192. $items[] = $item;
  193. }
  194. return $items;
  195. }
  196. /**
  197. * @param string $link
  198. * @return bool
  199. */
  200. private static function existInBreadcrumb($link)
  201. {
  202. $breadcrumb = ipContent()->getBreadcrumb();
  203. foreach ($breadcrumb as $element) {
  204. if ($element->getLink() == $link && !$element->getRedirectUrl()) {
  205. return true;
  206. }
  207. }
  208. return false;
  209. }
  210. }