PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Menus/View/Helper/MenusHelper.php

https://github.com/kareypowell/croogo
PHP | 257 lines | 154 code | 25 blank | 78 comment | 24 complexity | 5357ea92a87e806523118ebc86269999 MD5 | raw file
  1. <?php
  2. App::uses('AppHelper', 'View/Helper');
  3. App::uses('StringConverter', 'Croogo.Lib/Utility');
  4. /**
  5. * Menus Helper
  6. *
  7. * @category Menus.View/Helper
  8. * @package Croogo.Menus.View.Helper
  9. * @version 1.0
  10. * @author Fahad Ibnay Heylaal <contact@fahad19.com>
  11. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  12. * @link http://www.croogo.org
  13. */
  14. class MenusHelper extends AppHelper {
  15. public $helpers = array(
  16. 'Html',
  17. );
  18. /**
  19. * constructor
  20. */
  21. public function __construct(View $view, $settings = array()) {
  22. parent::__construct($view);
  23. $this->_setupEvents();
  24. $this->_converter = new StringConverter();
  25. }
  26. /**
  27. * setup events
  28. */
  29. protected function _setupEvents() {
  30. $events = array(
  31. 'Helper.Layout.beforeFilter' => array(
  32. 'callable' => 'filter', 'passParams' => true,
  33. ),
  34. );
  35. $eventManager = $this->_View->getEventManager();
  36. foreach ($events as $name => $config) {
  37. $eventManager->attach(array($this, 'filter'), $name, $config);
  38. }
  39. }
  40. /**
  41. * beforeRender
  42. */
  43. public function beforeRender($viewFile) {
  44. if (isset($this->request->params['admin']) && !$this->request->is('ajax')) {
  45. $this->_adminMenu();
  46. }
  47. }
  48. /**
  49. * Inject admin menu items
  50. */
  51. protected function _adminMenu() {
  52. if (empty($this->_View->viewVars['menus_for_admin_layout'])) {
  53. return;
  54. }
  55. $menus = $this->_View->viewVars['menus_for_admin_layout'];
  56. foreach ($menus as $m) {
  57. $weight = 9999 + $m['Menu']['weight'];
  58. $htmlAttributes = $this->__isCurrentMenu($m['Menu']['id']) ? array('class' => 'current') : array();
  59. CroogoNav::add('sidebar', 'menus.children.' . $m['Menu']['alias'], array(
  60. 'title' => $m['Menu']['title'],
  61. 'url' => array(
  62. 'plugin' => 'menus',
  63. 'admin' => true,
  64. 'controller' => 'links',
  65. 'action' => 'index',
  66. '?' => array('menu_id' => $m['Menu']['id'])
  67. ),
  68. 'weight' => $weight,
  69. 'htmlAttributes' => $htmlAttributes
  70. ));
  71. };
  72. }
  73. /**
  74. * Checks wether $id is the current active menu
  75. *
  76. * The value is checked against the menuId variable set in
  77. * LinksController::admin_add() and LinksController::admin_edit()
  78. *
  79. * @param string $id Menu id
  80. * @return bool True if $id is currently the active menu
  81. */
  82. private function __isCurrentMenu($id) {
  83. $currentMenuId = $this->_View->get('menuId');
  84. return $currentMenuId === $id;
  85. }
  86. /**
  87. * Filter content for Menus
  88. *
  89. * Replaces [menu:menu_alias] or [m:menu_alias] with Menu list
  90. *
  91. * @param string $content
  92. * @return string
  93. */
  94. public function filter(&$content, $options = array()) {
  95. preg_match_all('/\[(menu|m):([A-Za-z0-9_\-]*)(.*?)\]/i', $content, $tagMatches);
  96. for ($i = 0, $ii = count($tagMatches[1]); $i < $ii; $i++) {
  97. $regex = '/(\S+)=[\'"]?((?:.(?![\'"]?\s+(?:\S+)=|[>\'"]))+.)[\'"]?/i';
  98. preg_match_all($regex, $tagMatches[3][$i], $attributes);
  99. $menuAlias = $tagMatches[2][$i];
  100. $options = array();
  101. for ($j = 0, $jj = count($attributes[0]); $j < $jj; $j++) {
  102. $options[$attributes[1][$j]] = $attributes[2][$j];
  103. }
  104. $content = str_replace($tagMatches[0][$i], $this->menu($menuAlias, $options), $content);
  105. }
  106. return $content;
  107. }
  108. /**
  109. * Show Menu by Alias
  110. *
  111. * @param string $menuAlias Menu alias
  112. * @param array $options (optional)
  113. * @return string
  114. */
  115. public function menu($menuAlias, $options = array()) {
  116. $_options = array(
  117. 'tag' => 'ul',
  118. 'tagAttributes' => array(),
  119. 'selected' => 'selected',
  120. 'dropdown' => false,
  121. 'dropdownClass' => 'sf-menu',
  122. 'element' => 'Menus.menu',
  123. );
  124. $options = array_merge($_options, $options);
  125. if (!isset($this->_View->viewVars['menus_for_layout'][$menuAlias])) {
  126. return false;
  127. }
  128. $menu = $this->_View->viewVars['menus_for_layout'][$menuAlias];
  129. $output = $this->_View->element($options['element'], array(
  130. 'menu' => $menu,
  131. 'options' => $options,
  132. ));
  133. return $output;
  134. }
  135. /**
  136. * Merge Link options retrieved from Params behavior
  137. *
  138. * @param array $link Link data
  139. * @param string $param Parameter name
  140. * @param array $attributes Default options
  141. * @return string
  142. */
  143. protected function _mergeLinkParams($link, $param, $options = array()) {
  144. if (isset($link['Params'][$param])) {
  145. $options = array_merge($options, $link['Params'][$param]);
  146. }
  147. $booleans = array('true', 'false');
  148. foreach ($options as $key => $val) {
  149. if ($val == null) {
  150. unset($options[$key]);
  151. }
  152. if (is_string($val) && in_array(strtolower($val), $booleans)) {
  153. $options[$key] = (bool)$val;
  154. }
  155. }
  156. return $options;
  157. }
  158. /**
  159. * Nested Links
  160. *
  161. * @param array $links model output (threaded)
  162. * @param array $options (optional)
  163. * @param integer $depth depth level
  164. * @return string
  165. */
  166. public function nestedLinks($links, $options = array(), $depth = 1) {
  167. $_options = array();
  168. $options = array_merge($_options, $options);
  169. $output = '';
  170. foreach ($links as $link) {
  171. $linkAttr = array(
  172. 'id' => 'link-' . $link['Link']['id'],
  173. 'rel' => $link['Link']['rel'],
  174. 'target' => $link['Link']['target'],
  175. 'title' => $link['Link']['description'],
  176. 'class' => $link['Link']['class'],
  177. );
  178. $linkAttr = $this->_mergeLinkParams($link, 'linkAttr', $linkAttr);
  179. // if link is in the format: controller:contacts/action:view
  180. if (strstr($link['Link']['link'], 'controller:')) {
  181. $link['Link']['link'] = $this->linkStringToArray($link['Link']['link']);
  182. }
  183. // Remove locale part before comparing links
  184. if (!empty($this->_View->request->params['locale'])) {
  185. $currentUrl = substr($this->_View->request->url, strlen($this->_View->request->params['locale'] . '/'));
  186. } else {
  187. $currentUrl = $this->_View->request->url;
  188. }
  189. if (Router::url($link['Link']['link']) == Router::url('/' . $currentUrl)) {
  190. if (!isset($linkAttr['class'])) {
  191. $linkAttr['class'] = '';
  192. }
  193. $linkAttr['class'] .= ' ' . $options['selected'];
  194. }
  195. $linkOutput = $this->Html->link($link['Link']['title'], $link['Link']['link'], $linkAttr);
  196. if (isset($link['children']) && count($link['children']) > 0) {
  197. $linkOutput .= $this->nestedLinks($link['children'], $options, $depth + 1);
  198. }
  199. $liAttr = $this->_mergeLinkParams($link, 'liAttr');
  200. $linkOutput = $this->Html->tag('li', $linkOutput, $liAttr);
  201. $output .= $linkOutput;
  202. }
  203. if ($output != null) {
  204. $tagAttr = $options['tagAttributes'];
  205. if ($options['dropdown'] && $depth == 1) {
  206. $tagAttr['class'] = $options['dropdownClass'];
  207. }
  208. $output = $this->Html->tag($options['tag'], $output, $tagAttr);
  209. }
  210. return $output;
  211. }
  212. /**
  213. * Converts strings like controller:abc/action:xyz/ to arrays
  214. *
  215. * @param string|array $link link
  216. * @return array
  217. * @see Use StringConverter::linkStringToArray()
  218. */
  219. public function linkStringToArray($link) {
  220. return $this->_converter->linkStringToArray($link);
  221. }
  222. /**
  223. * Converts array into string controller:abc/action:xyz/value1/value2
  224. *
  225. * @param array $url link
  226. * @return array
  227. * @see StringConverter::urlToLinkString()
  228. */
  229. public function urlToLinkString($url) {
  230. return $this->_converter->urlToLinkString($url);
  231. }
  232. }