PageRenderTime 108ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 1ms

/html/AppCode/expressionengine/third_party/structure/mod.structure.php

https://github.com/w3bg/www.hsifin.com
PHP | 3653 lines | 3190 code | 262 blank | 201 comment | 250 complexity | 035d48e9d548e1b2fa2c013355fec5a0 MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. error_reporting(0);
  3. ini_set('display_errors', FALSE);
  4. /**
  5. * Control Panel (MCP) File for Structure
  6. *
  7. * This file must be in your /system/third_party/structure directory of your ExpressionEngine installation
  8. *
  9. * @package Structure 2 for EE2 (Build 20100824)
  10. * @author Jack McDade (jack@jackmcdade.com)
  11. * @author Travis Schmeisser (travis@rockthenroll.com)
  12. * @copyright Copyright (c) 2010 Travis Schmeisser
  13. * @version Release: 2.1.5
  14. * @link http://buildwithstructure.com
  15. */
  16. // Thanks also to Tom Jaeger, Jeremy Messenger, Brian Litzinger and Adam Leder for their code contributions.
  17. require('libraries/nestedset/structure_nestedset.php');
  18. require('libraries/nestedset/structure_nestedset_adapter_ee.php');
  19. class Structure
  20. {
  21. var $nset;
  22. var $channel_type = '';
  23. function Structure()
  24. {
  25. $this->EE =& get_instance();
  26. $adapter = new Structure_Nestedset_Adapter_Ee('exp_structure', 'lft', 'rgt', 'entry_id');
  27. $this->nset = new Structure_Nestedset($adapter);
  28. }
  29. /** -------------------------------------
  30. /** Tag: nav_main
  31. /** -------------------------------------*/
  32. function nav_main()
  33. {
  34. $html = "";
  35. $site_id = $this->EE->config->item('site_id');
  36. // get current uri path
  37. $uri = $this->EE->uri->uri_string;
  38. $separator = $this->EE->config->item('word_separator') != 'dash' ? '_' : '-';
  39. $css_id = $this->EE->TMPL->fetch_param('css_id');
  40. // Set unique id prefix
  41. if ($css_id == NULL)
  42. $unique_prefix = 'nav';
  43. else
  44. $unique_prefix = $css_id;
  45. // Remove the id tag if set to "none"
  46. if ($css_id == "")
  47. $css_id = ' id="nav"';
  48. elseif ($css_id == "none")
  49. $css_id = NULL;
  50. else
  51. $css_id = ' id="'.$css_id.'"';
  52. $add_unique_id = $this->EE->TMPL->fetch_param('add_unique_id');
  53. $add_unique_id = $add_unique_id ? strtolower($add_unique_id) : 'no';
  54. $add_unique_to = ($this->EE->TMPL->fetch_param('add_unique_to')) ? $this->EE->TMPL->fetch_param('nav_class') : 'li';
  55. $current_class = ($this->EE->TMPL->fetch_param('current_class')) ? $this->EE->TMPL->fetch_param('current_class') : 'here';
  56. $include_ul = ($this->EE->TMPL->fetch_param('include_ul')) ? $this->EE->TMPL->fetch_param('include_ul') : 'yes';
  57. $add_span = ($this->EE->TMPL->fetch_param('add_span')) ? $this->EE->TMPL->fetch_param('add_span') : 'no';
  58. // CSS class
  59. $css_class = $this->EE->TMPL->fetch_param('css_class');
  60. $css_class = $css_class ? $css_class : '';
  61. // exclude and include entry_ids
  62. $exclude = explode("|", $this->EE->TMPL->fetch_param('exclude'));
  63. $include = ($this->EE->TMPL->fetch_param('include')) ? " AND `node`.`entry_id` IN(".str_replace("|", ",", $this->EE->TMPL->fetch_param('include')).") " : "";
  64. // DEPRECIATED SUPPORT for exclude_status and include_status
  65. $include_status = strtolower($this->EE->TMPL->fetch_param('include_status'));
  66. $exclude_status = strtolower($this->EE->TMPL->fetch_param('exclude_status'));
  67. // New, native EE status mode
  68. $status = $this->EE->TMPL->fetch_param('status');
  69. $status = $status == '' ? array() : explode('|', $status);
  70. $status = array_map('strtolower', $status); // match MySQL's case-insensitivity
  71. $status_state = 'positive';
  72. // Check for "not "
  73. if (substr($status[0], 0, 4) == 'not ')
  74. {
  75. $status_state = 'negative';
  76. $status[0] = trim(substr($status[0], 3));
  77. $status[] = 'closed';
  78. }
  79. else
  80. {
  81. $status[] = 'open';
  82. }
  83. $include_status_list = explode('|', $include_status);
  84. $exclude_status_list = explode('|', $exclude_status);
  85. // Remove the default "open" status if explicitely set
  86. if (in_array('open', $exclude_status_list))
  87. $status = array_filter($status, create_function('$v', 'return $v != "open";'));
  88. if ($status_state == 'positive')
  89. $status = array_merge($status, $include_status_list);
  90. elseif ($status_state == 'negative')
  91. $status = array_merge($status, $exclude_status_list);
  92. // get site pages data
  93. $site_pages = $this->get_site_pages();
  94. // get structure data from DB
  95. $sql = "SELECT node.*, expt.title, expt.status
  96. FROM exp_structure AS node
  97. INNER JOIN exp_channel_titles AS expt
  98. ON node.entry_id = expt.entry_id
  99. WHERE node.parent_id = 0
  100. AND node.site_id = $site_id {$include}
  101. GROUP BY node.entry_id
  102. ORDER BY node.lft";
  103. $result = $this->EE->db->query($sql);
  104. // Remove anything to be excluded from the results array
  105. foreach ($result->result_array() as $key => $entry_data)
  106. {
  107. if ($status_state == 'negative' && in_array(strtolower($entry_data['status']), $status)
  108. || ($status_state == 'positive' && ! in_array(strtolower($entry_data['status']), $status))
  109. || in_array($entry_data['entry_id'], $exclude))
  110. {
  111. unset($result->result_array[$key]);
  112. }
  113. }
  114. // Make sure array indices are incremental (0..X)
  115. // $result->result_array() = array_values($result->result_array());
  116. $segment_1 = $this->EE->uri->segment('1');
  117. if (count($result->num_rows()) > 0)
  118. {
  119. foreach ($result->result_array() as $entry_data)
  120. {
  121. // out entry uri of this loop instance
  122. $euri = $site_pages['uris'][$entry_data['entry_id']];
  123. $slug = $this->page_slug($entry_data['entry_id']);
  124. if ($slug == '')
  125. $slug = 'home';
  126. if ($separator == '_')
  127. {
  128. $slug = str_replace('-', $separator, $slug);
  129. }
  130. elseif ($separator == '-')
  131. {
  132. $slug = str_replace('_', $separator, $slug);
  133. }
  134. $a_class = '';
  135. $li_class = '';
  136. $list_item_id = '';
  137. // if we are adding the unique slug to the anchor
  138. // *!*!*!*!*!*!* Possibly Remove This
  139. if ($add_unique_to == 'a')
  140. {
  141. $a_class .= 'nav' . $separator . $slug;
  142. }
  143. // else
  144. else
  145. {
  146. // $li_class .= 'nav' . $separator . $slug;
  147. }
  148. if ($uri === $euri OR ($uri == '' && $euri == '/') OR $segment_1 === trim($euri, '/'))
  149. {
  150. $here = TRUE;
  151. $current_entry = $entry_data['entry_id'];
  152. $li_class .= ' ' . $current_class;
  153. }
  154. if ($entry_data == end($result->result_array()))
  155. {
  156. $li_class .= ' last';
  157. }
  158. $li_class = empty($li_class) ? '' : " class=\"".trim($li_class)."\"";
  159. $a_class = empty($a_class) ? "" : " class=\"".trim($a_class)."\"";
  160. // Make sure we have the site_url path in case we're operating in a subdirectory
  161. // If site_index is set then add it to URIs, otherwise leave it blank
  162. $site_url = $this->EE->functions->fetch_site_index();
  163. $the_uri = parse_url($this->EE->db->escape_str($site_url));
  164. $root_uri = $the_uri['path'];
  165. $index_uri = $site_url;
  166. $home = trim($this->EE->functions->fetch_site_index(0, 0), '/');
  167. $item_uri = $this->EE->functions->remove_double_slashes($home . $euri);
  168. if ($add_unique_id == 'yes')
  169. {
  170. $list_item_id = ' id="'. $unique_prefix . $separator . $slug .'"';
  171. }
  172. $title = htmlspecialchars($entry_data['title']);
  173. // Add a <span> wrapper inside the <a> tags
  174. if ($add_span == 'yes')
  175. {
  176. $html .= "\n<li{$li_class}{$list_item_id}><a href=\"" . $item_uri . "\"{$a_class}><span>" . $title."</span></a></li>";
  177. }
  178. else
  179. {
  180. $html .= "\n<li{$li_class}{$list_item_id}><a href=\"" . $item_uri . "\"{$a_class}>" . $title."</a></li>";
  181. }
  182. }
  183. $css_class = ($this->EE->TMPL->fetch_param('css_class')) ? " class=\"" . $this->EE->TMPL->fetch_param('css_class') . "\"" : "";
  184. // Add or remove the <ul> wrapper
  185. if ($include_ul == 'yes')
  186. {
  187. $html = "<ul{$css_id}{$css_class}>" . $html . "\n</ul>";
  188. }
  189. }
  190. return $html;
  191. }
  192. /** -------------------------------------
  193. /** Tag: nav_sub
  194. /** -------------------------------------*/
  195. function nav_sub()
  196. {
  197. $html = '';
  198. // get site pages data
  199. $site_pages = $this->get_site_pages();
  200. if ( ! $site_pages) return FALSE;
  201. /** -------------------------------------
  202. /** The Parameters
  203. /** -------------------------------------*/
  204. $separator = $this->EE->config->item('word_separator') != 'dash' ? '_' : '-';
  205. $exclude = explode('|', $this->EE->TMPL->fetch_param('exclude'));
  206. // DEPRECIATED SUPPORT for exclude_status and include_status
  207. $include_status = strtolower($this->EE->TMPL->fetch_param('include_status'));
  208. $exclude_status = strtolower($this->EE->TMPL->fetch_param('exclude_status'));
  209. // New, native EE status mode
  210. $status = $this->EE->TMPL->fetch_param('status');
  211. $status = $status == '' ? array() : explode('|', $status);
  212. $status = array_map('strtolower', $status); // match MySQL's case-insensitivity
  213. $status_state = 'positive';
  214. // Check for "not "
  215. if (substr($status[0], 0, 4) == 'not ')
  216. {
  217. $status_state = 'negative';
  218. $status[0] = trim(substr($status[0], 3));
  219. $status[] = 'closed';
  220. }
  221. else
  222. {
  223. $status[] = 'open';
  224. }
  225. $include_status_list = explode('|', $include_status);
  226. $exclude_status_list = explode('|', $exclude_status);
  227. // Remove the default "open" status if explicitely set
  228. if (in_array('open', $exclude_status_list))
  229. $status = array_filter($status, create_function('$v', 'return $v != "open";'));
  230. if ($status_state == 'positive')
  231. $status = array_merge($status, $include_status_list);
  232. elseif ($status_state == 'negative')
  233. $status = array_merge($status, $exclude_status_list);
  234. $include_ul = ($this->EE->TMPL->fetch_param('include_ul')) ? $this->EE->TMPL->fetch_param('include_ul') : 'yes';
  235. $add_span = ($this->EE->TMPL->fetch_param('add_span')) ? $this->EE->TMPL->fetch_param('add_span') : 'no';
  236. $css_id = $this->EE->TMPL->fetch_param('css_id') ? $this->EE->TMPL->fetch_param('css_id') : '';
  237. if ($css_id == '')
  238. {
  239. $css_id = 'nav'.$separator.'sub';
  240. }
  241. elseif ($css_id == 'none')
  242. {
  243. $css_id = NULL;
  244. }
  245. else
  246. {
  247. $css_id = $css_id;
  248. }
  249. // CSS class
  250. $css_class = $this->EE->TMPL->fetch_param('css_class');
  251. $css_class = $css_class ? $css_class : '';
  252. // Current CSS class
  253. $current_class = ($this->EE->TMPL->fetch_param('current_class')) ? $this->EE->TMPL->fetch_param('current_class') : 'here';
  254. // show_level_classes
  255. $show_level_classes = $this->EE->TMPL->fetch_param('show_level_classes');
  256. $show_level_classes = $show_level_classes ? strtolower($show_level_classes) : 'yes';
  257. // show_overview_link
  258. $show_overview_link = $this->EE->TMPL->fetch_param('show_overview_link');
  259. $show_overview_link = $show_overview_link ? strtolower($show_overview_link) : 'no';
  260. // Custom View Text
  261. $overview_text_title = $this->EE->TMPL->fetch_param('show_overview_link');
  262. $overview_text_title = $overview_text_title ? strtolower($overview_text_title) : 'no';
  263. // Rename Overview parameter
  264. $overview_link_text = $this->EE->TMPL->fetch_param('rename_overview');
  265. $overview_link_text = $overview_link_text ? $overview_link_text : 'Overview';
  266. // Add CSS ids based on the URI to all <li> elements
  267. $add_unique_id = $this->EE->TMPL->fetch_param('add_unique_id');
  268. $add_unique_id = $add_unique_id ? strtolower($add_unique_id) : 'no';
  269. // Add CSS ids based on the entry_id to all <li> elements
  270. $add_unique_entry_id = $this->EE->TMPL->fetch_param('add_unique_entry_id');
  271. $add_unique_entry_id = $add_unique_entry_id ? strtolower($add_unique_entry_id) : 'no';
  272. $wrap_start = $this->EE->TMPL->fetch_param('wrap_start');
  273. $wrap_start = $wrap_start ? $wrap_start : 'no';
  274. $wrap_end = $this->EE->TMPL->fetch_param('wrap_end');
  275. $wrap_end = $wrap_end ? $wrap_end : 'no';
  276. // Hide the entire sub nav if there are no children of the current page
  277. $hide_if_no_children = ($this->EE->TMPL->fetch_param('hide_if_no_children')) ? $this->EE->TMPL->fetch_param('hide_if_no_children') : 'no';
  278. $initiate_children_hiding = 'no';
  279. // depth to limit, never expand past this depth
  280. $depth_limit = $this->EE->TMPL->fetch_param('limit_depth');
  281. $depth_limit = $depth_limit ? $depth_limit : '';
  282. // depth to show, show all of tree up to specified depth
  283. $show_n_deep = $this->EE->TMPL->fetch_param('show_depth');
  284. $show_n_deep = ($show_n_deep != '') ? $show_n_deep : '';
  285. // special case to make the math work, if passing 0 then calculate based on -1
  286. if ($show_n_deep <= 0 && $show_n_deep != '')
  287. {
  288. $show_n_deep = -1;
  289. }
  290. // Retrieve start_from URL
  291. $start_from = $this->EE->TMPL->fetch_param('start_from');
  292. $start_from = $start_from ? $start_from : '';
  293. /** -------------------------------------
  294. /** The Logic
  295. /** -------------------------------------*/
  296. $fixed = false;
  297. if ($start_from != '')
  298. {
  299. $start_from = html_entity_decode($start_from);
  300. // Make sure passed URL starts with a '/'
  301. if (substr($start_from, 0, 1) != '/')
  302. {
  303. $start_from = '/' . $start_from;
  304. }
  305. // Make sure passed URL ends with a '/'
  306. if (substr($start_from, -1, 1) != '/')
  307. {
  308. $start_from .= '/';
  309. }
  310. $fixed = true;
  311. }
  312. $uri = '/'.$this->EE->uri->uri_string().'/';
  313. // get entry id + node of the start entry
  314. $entry_id = $start_from ? array_search($start_from, $site_pages['uris']) : array_search($uri, $site_pages['uris']);
  315. $node = $entry_id ? $this->nset->getNode($entry_id) : false;
  316. // get entry id + node of the current entry
  317. $current_entry_id = array_search($uri, $site_pages['uris']);
  318. $current_node = $current_entry_id ? $this->nset->getNode($current_entry_id) : false;
  319. // if current_node is a leaf then current_node should be parent
  320. if ($current_node == '' && $current_entry_id)
  321. {
  322. // get entry's parent id
  323. $pid = $this->get_pid_for_listing_entry($current_entry_id);
  324. $current_node = $this->nset->getNode($pid);
  325. }
  326. // If current location is a leaf then use parent as starting point for top + current
  327. if ($node['isLeaf'])
  328. {
  329. $leaf_node = $current_node;
  330. $node = $this->nset->getNode($node['parent_id']);
  331. $current_node = $this->nset->getNode($current_node['parent_id']);
  332. if ($hide_if_no_children == 'yes')
  333. {
  334. $initiate_children_hiding = 'yes';
  335. }
  336. elseif ($hide_if_no_children == 'conditional')
  337. {
  338. $initiate_children_hiding = 'conditional';
  339. }
  340. }
  341. // if start_from + show_depth then make sure top is treated as current
  342. if ($show_n_deep != '')
  343. {
  344. $actual_current = $current_node;
  345. $current_node = $node;
  346. }
  347. // get all pages/tree
  348. $pages = $this->get_data();
  349. // Get current parent's URI
  350. if (isset($site_pages['uris'][$node['id']]))
  351. {
  352. $top_uri = $site_pages['uris'][$node['id']];
  353. }
  354. else
  355. {
  356. $top_uri = '';
  357. }
  358. // Get current page URI
  359. if (isset($site_pages['uris'][$current_node['id']]))
  360. {
  361. $current_page_uri = $site_pages['uris'][$current_node['id']];
  362. }
  363. else
  364. {
  365. $current_page_uri = '';
  366. }
  367. $current_top_uri = $top_uri;
  368. // trim tree of uneeded branches + leaves
  369. foreach ($pages as $key => $entry_data)
  370. {
  371. // If not top level && not child of current
  372. if ($entry_data['parent_id'] != $node['id'] && $entry_data['parent_id'] != 0)
  373. {
  374. // Does entry's URI start with our current top URI
  375. if (preg_match("~^" . $current_top_uri . "~", $site_pages['uris'][$entry_data['entry_id']]))
  376. {
  377. // Only show immediate children
  378. // if the entry has depth greater than the current entry and it's parent isn't the current entry then we don't want it
  379. // if show_depth then check that items to be included are left alone
  380. if (($show_n_deep != '' && (($entry_data['depth'] - $current_node['depth']) > ($show_n_deep + 1)) && $entry_data['parent_id'] != $current_node['id'])
  381. || ($show_n_deep == '' && $entry_data['depth'] > ($current_node['depth']) && $entry_data['parent_id'] != $current_node['id'])
  382. || ($entry_data['depth'] == ($current_node['depth']) && $entry_data['parent_id'] != $current_node['parent_id']))
  383. {
  384. // Hide pages in the same branch group but at same depth. This only really applies to leaves on the end.
  385. unset($pages[$key]);
  386. }
  387. }
  388. elseif ($entry_data['parent_id'] != $current_node['parent_id'])
  389. {
  390. unset($pages[$key]);
  391. }
  392. elseif ($entry_data['parent_id'] != $current_node['id'])
  393. {
  394. // Possibly thowing errors, one way or the other. Keep flagged.
  395. unset($pages[$key]);
  396. }
  397. }
  398. elseif ($entry_data['parent_id'] == 0)
  399. {
  400. unset($pages[$key]);
  401. }
  402. $adjust_depth = $fixed ? 1 : 0;
  403. if (isset($pages[$key]) && array_key_exists('entry_id', $pages[$key]))
  404. {
  405. $pages[$key]['depth'] -= ($node['depth'] + $adjust_depth);
  406. }
  407. }
  408. // Discover the tree of the current page
  409. // Clean up items that aren't part of the current branch
  410. $tree = array();
  411. if ($fixed && $current_node['parent_id'] != 0)
  412. {
  413. $next_id = $current_node['id'];
  414. for($x = 0; $x < $current_node['depth']; $x++)
  415. {
  416. // Build the tree for the branch
  417. foreach ($pages as $key => $page)
  418. {
  419. if ($page['entry_id'] == $next_id)
  420. {
  421. $tree[] = $page['entry_id'];
  422. $next_id = $page['parent_id'];
  423. }
  424. }
  425. }
  426. // Remove the items that aren't part of the branch
  427. // If the items parent isn't part of the tree, and the item itself isn't part of the tree, and the items parent isn't the root of the tree
  428. foreach ($pages as $key => $page)
  429. {
  430. if (($page['depth'] < 0)
  431. || ( ! in_array($page['parent_id'], $tree
  432. && ! in_array($page['entry_id'], $tree)
  433. && $page['parent_id'] != $node['id'])))
  434. {
  435. unset($pages[$key]);
  436. }
  437. }
  438. }
  439. $closed_parents = array();
  440. // Remove anything to be excluded from the results array
  441. foreach ($pages as $key => $entry_data)
  442. {
  443. if ($status_state == 'negative' && in_array(strtolower($entry_data['status']), $status)
  444. || ($status_state == 'positive' && ! in_array(strtolower($entry_data['status']), $status))
  445. || in_array($entry_data['parent_id'], $closed_parents)
  446. || in_array($entry_data['entry_id'], $exclude))
  447. {
  448. $closed_parents[] = $entry_data['entry_id'];
  449. unset($pages[$key]);
  450. }
  451. }
  452. // Make sure array indices are incremental (0..X)
  453. $pages = array_values($pages);
  454. // If our first item is not depth 0 bring everything down accordingly
  455. if (isset($pages[0]['depth']) && $pages[0]['depth'] > 0)
  456. {
  457. $adjust_depth = $pages[0]['depth'] - $node['depth'];
  458. foreach ($pages as $key => $page)
  459. {
  460. $pages[$key]['depth'] -= $adjust_depth;
  461. }
  462. }
  463. // Clean up if we have a depth parameter, remove anything deeper than the requested depth
  464. if ($depth_limit != '')
  465. {
  466. foreach ($pages as $key => $page)
  467. {
  468. if ($page['depth'] > $depth_limit)
  469. {
  470. unset($pages[$key]);
  471. }
  472. }
  473. }
  474. // Make sure array indices are incremental (0..X)
  475. $pages = array_values($pages);
  476. // If show_overview_link is true then
  477. // check if parent is top level, if true then show overview link
  478. // Get the parent of the first page. Allows us to check if it's parent is top level for the Overview link
  479. if ( ! $fixed)
  480. {
  481. $parent_node = $this->nset->getNode(@$pages[0]['parent_id']);
  482. }
  483. else
  484. {
  485. $parent_node = array('parent_id' => '');
  486. }
  487. if ($show_overview_link == "yes" && ($node['parent_id'] == 0 OR $parent_node['parent_id'] == 0))
  488. {
  489. $overview_data = ($parent_node['parent_id'] != '') ? $parent_node : $node;
  490. // Apply custom Overview title if set
  491. if ($overview_link_text)
  492. {
  493. $overview_data['title'] = $overview_link_text;
  494. }
  495. elseif ($overview_text_title)
  496. {
  497. $parent_id = $overview_data['id'];
  498. $sql = "SELECT title
  499. FROM exp_channel_titles
  500. WHERE entry_id = '".$parent_id."'";
  501. $result = $this->EE->db->query($sql);
  502. $overview_data['title'] = $result->result_array[0]['title'];
  503. }
  504. $overview_data['entry_id'] = $overview_data['id'];
  505. $overview_data['depth'] = 0;
  506. $overview_data['overview'] = "yes";
  507. array_unshift($pages, $overview_data);
  508. }
  509. // If show_depth then set the current_node back to what it should be (actual_current)
  510. if ($show_n_deep != '')
  511. {
  512. $current_node = $actual_current;
  513. }
  514. $ul_open = false;
  515. $last_page_depth = 0;
  516. $last = "";
  517. // Begin building out the tree
  518. foreach ($pages as $page)
  519. {
  520. //@@@ PHP Notice: Triggered from (assuming) empty array key. [Undefined index: 0]
  521. @$page_uri = $site_pages['uris'][$page['entry_id']];
  522. //Create unique CSS ID based on the URIs
  523. $css_uri = substr_replace(str_replace("/", "_", $page_uri) ,"",-1);
  524. $home = trim($this->EE->functions->fetch_site_index(0, 0), '/');
  525. $item_uri = $this->EE->functions->remove_double_slashes($home . $page_uri);
  526. $page['class'] = "";
  527. // Start a sub nav
  528. if ($page['depth'] > $last_page_depth)
  529. {
  530. $html = substr($html, 0, -6);
  531. $html .= "\n<ul>\n";
  532. $ul_open = true;
  533. }
  534. // Close a sub nav
  535. if ($page['depth'] < $last_page_depth)
  536. {
  537. // Calculate how many levels back I need to go
  538. $back_to = $last_page_depth - $page['depth'];
  539. $html .= str_repeat("</ul>\n</li>\n", $back_to);
  540. $ul_open = false;
  541. }
  542. $here = '';
  543. // CURRENT CLASS DETECTION
  544. // If current location/leaf is within the left/right limits of the item then this is a "here" parent item
  545. if (($current_node['left'] > @$page['lft'] && $current_node['right'] < @$page['rgt']) OR (@$leaf_node['left'] > @$page['lft'] && @$leaf_node['right'] < @$page['rgt']))
  546. {
  547. $page['class'] .= ' parent' . $separator . $current_class;
  548. }
  549. elseif ($current_node['left'] == @$page['lft'] && $current_node['right'] == @$page['rgt'] && $page['entry_id'] != $current_entry_id && $page['entry_id'] != @$leaf_node['id'])
  550. {
  551. $page['class'] .= " ".$current_class;
  552. }
  553. elseif ($page['entry_id'] == $current_entry_id OR $page['entry_id'] == @$leaf_node['id'])
  554. {
  555. $page['class'] .= " ".$current_class;
  556. }
  557. // LAST CLASS DETECTION
  558. // Grab parent item's data
  559. $upper_node = $this->nset->getNode($page['parent_id']);
  560. // If an entry's RIGHT is one less than the parent's RIGHT, is the last item in a <ul>.
  561. if ((@$page['rgt']+1) == $upper_node['right'])
  562. {
  563. $page['class'] .= " last";
  564. }
  565. // elseif ($page == end($pages))
  566. // {
  567. // $last = 'last';
  568. // }
  569. // If show_level_classes then build level class name
  570. $level = "";
  571. if ($show_level_classes == 'yes')
  572. {
  573. $page['class'] .= ' sub' . $separator . 'level' . $separator . $page['depth'];
  574. }
  575. if (isset($page['overview']) && strtolower($page['overview']) == 'yes')
  576. {
  577. $page['class'] .= ' overview';
  578. }
  579. // Build classes string
  580. $classes = array($level, $here, $last);
  581. $classes_string = '';
  582. $classes_string = trim($page['class']);
  583. $list_item_class = '';
  584. // Set current class (Don't pass an empty class)
  585. if ($classes_string != '')
  586. {
  587. $list_item_class = " class=\"$classes_string\"";
  588. }
  589. $list_item_id = "";
  590. // Add unique id to <li> elements
  591. if ($add_unique_entry_id == "yes")
  592. {
  593. $list_item_id .= ' id="'.$css_id.$separator.$page['entry_id'].'"';
  594. }
  595. if ($add_unique_id == "yes")
  596. {
  597. $list_id_contents = explode ("/", $page_uri);
  598. array_pop($list_id_contents);
  599. array_shift($list_id_contents);
  600. $seg_1 = reset($list_id_contents);
  601. $seg_2 = end($list_id_contents);
  602. $list_item_id .= ' id="'.$seg_1.$separator.$seg_2.'"';
  603. }
  604. // The IDs and Classes
  605. $li_contents = $list_item_id.''.$list_item_class;
  606. $page_title = htmlspecialchars($page['title']);
  607. if ($add_span == "yes")
  608. {
  609. $page_title = "<span>".$page_title."</span>";
  610. }
  611. // THE BIG LIST OUTPUT
  612. $list_item = '<li'.$li_contents.'><a href="'.$item_uri.'">'.$page_title.'</a></li>'."\n";
  613. $html .= $list_item;
  614. $last_page_depth = $page['depth'];
  615. }
  616. // Close any open UL + LI combos
  617. if ($ul_open)
  618. {
  619. $html .= str_repeat("</ul></li>\n", $last_page_depth);
  620. $ul_open = false;
  621. $last_page_depth--;
  622. }
  623. // Make sure all the ULs are closed
  624. if ($last_page_depth > 0)
  625. {
  626. //$html .= str_repeat("</ul>\n", $last_page_depth + 1);
  627. $html .= "</ul>\n";
  628. }
  629. elseif ($include_ul == "no")
  630. {
  631. $html .= $ul_open ? "</ul>\n</li>\n" : "\n";
  632. }
  633. else
  634. {
  635. $html .= $ul_open ? "</ul>\n</li>\n</ul>" : "</ul>\n";
  636. }
  637. // Assign classes
  638. $css_class = ($this->EE->TMPL->fetch_param('css_class')) ? " class=\"" . $this->EE->TMPL->fetch_param('css_class') . "\"" : "";
  639. // Turn on or off the <ul>
  640. if ($include_ul == "yes")
  641. {
  642. if($css_id && $css_class)
  643. {
  644. $html = "\n<ul id=\"$css_id\"{$css_class}>\n" . $html;
  645. }
  646. else if($css_id)
  647. {
  648. $html = "\n<ul id=\"$css_id\"{$css_class}>\n" . $html;
  649. }
  650. else
  651. {
  652. $html = "\n<ul{$css_class}>\n" . $html;
  653. }
  654. }
  655. if ($initiate_children_hiding == "yes")
  656. {
  657. $html = NULL;
  658. }
  659. elseif ($initiate_children_hiding == "conditional")
  660. {
  661. $html = "empty";
  662. }
  663. if ($html != "" && $wrap_start != "no" && $wrap_end != "no")
  664. {
  665. $html = $wrap_start.$html.$wrap_end;
  666. }
  667. return $html;
  668. }
  669. /** -------------------------------------
  670. /** Tag: nav_full
  671. /** -------------------------------------*/
  672. function nav_full()
  673. {
  674. $html = '';
  675. /** -------------------------------------
  676. /** PARAMETERS: HTML/CSS Based
  677. /** -------------------------------------*/
  678. $separator = $this->EE->config->item('word_separator') != 'dash' ? '_' : '-';
  679. $css_id = ($this->EE->TMPL->fetch_param('css_id')) ? "".$this->EE->TMPL->fetch_param('css_id')."" : "";
  680. $css_class = ($this->EE->TMPL->fetch_param('css_class')) ? " class=\"" . $this->EE->TMPL->fetch_param('css_class') . "\"" : "";
  681. $current_class = ($this->EE->TMPL->fetch_param('current_class')) ? $this->EE->TMPL->fetch_param('current_class') : "here";
  682. $add_span = ($this->EE->TMPL->fetch_param('add_span')) ? $this->EE->TMPL->fetch_param('add_span') : "no";
  683. $add_unique_id = $this->EE->TMPL->fetch_param('add_unique_id');
  684. $add_unique_id = $add_unique_id ? strtolower($add_unique_id) : 'no';
  685. /** -------------------------------------
  686. /** PARAMETERS: Output and Behavior
  687. /** -------------------------------------*/
  688. // DEPRECIATED SUPPORT for exclude_status and include_status
  689. $include_status = strtolower($this->EE->TMPL->fetch_param('include_status'));
  690. $exclude_status = strtolower($this->EE->TMPL->fetch_param('exclude_status'));
  691. // New, native EE status mode
  692. $status = $this->EE->TMPL->fetch_param('status');
  693. $status = $status == '' ? array() : explode('|', $status);
  694. $status = array_map('strtolower', $status); // match MySQL's case-insensitivity
  695. $status_state = 'positive';
  696. // Check for "not "
  697. if (substr($status[0], 0, 4) == 'not ')
  698. {
  699. $status_state = 'negative';
  700. $status[0] = trim(substr($status[0], 3));
  701. $status[] = 'closed';
  702. }
  703. else
  704. {
  705. $status[] = 'open';
  706. }
  707. $include_status_list = explode('|', $include_status);
  708. $exclude_status_list = explode('|', $exclude_status);
  709. // Remove the default "open" status if explicitely set
  710. if (in_array('open', $exclude_status_list))
  711. $status = array_filter($status, create_function('$v', 'return $v != "open";'));
  712. if ($status_state == 'positive')
  713. $status = array_merge($status, $include_status_list);
  714. elseif ($status_state == 'negative')
  715. $status = array_merge($status, $exclude_status_list);
  716. // Retrieve entry_ids to exclude
  717. $exclude = explode('|', $this->EE->TMPL->fetch_param('exclude'));
  718. // get site pages data
  719. $site_pages = $this->get_site_pages();
  720. $segment_1 = $this->EE->uri->segment('1');
  721. $segment_2 = $this->EE->uri->segment('2');
  722. /** -------------------------------------
  723. /** Function Logic
  724. /** -------------------------------------*/
  725. // get all pages
  726. $pages = $this->get_data();
  727. // Remove anything to be excluded from the results array
  728. $closed_parents = array();
  729. foreach ($pages as $key => $entry_data)
  730. {
  731. if ($status_state == 'negative' && in_array(strtolower($entry_data['status']), $status)
  732. || ($status_state == 'positive' && ! in_array(strtolower($entry_data['status']), $status))
  733. || in_array($entry_data['parent_id'], $closed_parents)
  734. || in_array($entry_data['entry_id'], $exclude))
  735. {
  736. $closed_parents[] = $entry_data['entry_id'];
  737. unset($pages[$key]);
  738. }
  739. }
  740. // Make sure array indices are incremental (0..X)
  741. $pages = array_values($pages);
  742. if ($css_id == "")
  743. {
  744. $css_id = ' id="nav"';
  745. }
  746. elseif (strtolower($css_id) == 'none')
  747. {
  748. $css_id = NULL;
  749. }
  750. else
  751. {
  752. $css_id = ' id="'.$css_id.'"';
  753. }
  754. // Start building the navigation
  755. $html = "<ul{$css_id}{$css_class}>\n";
  756. $ul_open = false;
  757. $last_page_depth = 0;
  758. foreach ($pages as $page)
  759. {
  760. $page_uri = $site_pages['uris'][$page['entry_id']];
  761. $uri = $this->EE->functions->fetch_current_uri();
  762. // Make sure we have the site_url path in case we're operating in a subdirectory
  763. $home = trim($this->EE->functions->fetch_site_index(0, 0), '/');
  764. $item_uri = $this->EE->functions->remove_double_slashes($home . $page_uri);
  765. // Start a sub nav
  766. if ($page['depth'] > $last_page_depth)
  767. {
  768. $html = substr($html, 0, -6);
  769. $html .= "\n<ul>\n";
  770. $ul_open = true;
  771. }
  772. // Close a sub nav
  773. if ($page['depth'] < $last_page_depth)
  774. {
  775. // Calculate how many levels back to go
  776. $back_to = $last_page_depth - $page['depth'];
  777. $html .= str_repeat("</ul>\n</li>\n", $back_to);
  778. $ul_open = false;
  779. }
  780. // if ($page == end($pages))
  781. // {
  782. // $back_to = $last_page_depth - $page['depth'];
  783. // $html .= str_repeat("</ul>\n</li>\n", $back_to);
  784. // }
  785. // get entry id + node of the start entry
  786. $uri = '/'.$this->EE->uri->uri_string().'/';
  787. $entry_id = array_search($uri, $site_pages['uris']);
  788. $node = $entry_id ? $this->nset->getNode($entry_id) : false;
  789. // get entry id + node of the current entry
  790. $current_entry_id = array_search($uri, $site_pages['uris']);
  791. $current_node = $current_entry_id ? $this->nset->getNode($current_entry_id) : false;
  792. // if current_node is a leaf then current_node should be parent
  793. if ($current_node == '' && $current_entry_id)
  794. {
  795. // get entry's parent id
  796. $pid = $this->get_pid_for_listing_entry($current_entry_id);
  797. $current_node = $this->nset->getNode($pid);
  798. }
  799. $li_class = '';
  800. // if (($current_node['left'] > $page['lft'] && $current_node['right'] < $page['rgt']) OR (@$leaf_node['left'] > $page['lft'] && @$leaf_node['right'] < $page['rgt']))
  801. if (($current_node['left'] > $page['lft'] && $current_node['right'] < $page['rgt']))
  802. {
  803. $li_class .= 'parent' . $separator . $current_class;
  804. }
  805. elseif ($uri === $page_uri OR ($uri == '' && $page_uri == '/') OR $segment_1 == trim($page_uri, '/') && $segment_2 == "")
  806. {
  807. $here = TRUE;
  808. $current_entry = $entry_data['entry_id'];
  809. $li_class .= " ".$current_class;
  810. }
  811. /** -------------------------------------
  812. /** Last class detection
  813. /** -------------------------------------*/
  814. $upper_node = $this->nset->getNode($page['parent_id']);
  815. $last = "";
  816. // If an entry's RIGHT is one less than the parent's, is the last in a <ul>.
  817. if (($page['rgt']+1) == $upper_node['right'])
  818. {
  819. $last = ' last';
  820. }
  821. $li_class .= $last;
  822. // Check if the class is empty.
  823. if (empty($li_class))
  824. {
  825. $li_class = "";
  826. }
  827. else
  828. {
  829. $li_class=' class="'.trim($li_class).'"';
  830. }
  831. $page_title = ($page['title']);
  832. if ($add_span == "yes")
  833. {
  834. $page_title = "<span>".$page_title."</span>";
  835. }
  836. /** -------------------------------------
  837. /** Add Unique ID
  838. /** -------------------------------------*/
  839. $unique_prefix = "nav";
  840. $list_item_id = "";
  841. $slug = str_replace("/", $separator, $page_uri);
  842. $slug = substr($slug,1,-1);
  843. if ($separator == "_")
  844. {
  845. $slug = str_replace("-", $separator, $slug);
  846. }
  847. elseif ($separator == "-")
  848. {
  849. $slug = str_replace("_", $separator, $slug);
  850. }
  851. if ($slug == "")
  852. {
  853. $slug = "home";
  854. }
  855. if ($add_unique_id == "yes")
  856. {
  857. $list_item_id = ' id="'. $unique_prefix . $separator . $slug .'"';
  858. }
  859. // THE BIG LIST OUTPUT
  860. $list_item = '<li'.$li_class.''.$list_item_id.'><a href="'.$item_uri.'">'.$page_title.'</a></li>'."\n";
  861. // $list_item = '<li'.$li_class.''.$list_item_id.'><a href="'.$item_uri.'">'.$page_title.'</a> - Page Depth:'.$page['depth'].' ///// Last Page Depth: '.$last_page_depth.'</li>'."\n";
  862. // $list_item = '<li'.$li_class.''.$list_item_id.'><a href="'.$item_uri.'">'.$page_title.'</a> - Page Left:'.$page['lft'].' ///// Node Left:: '.$current_node['left'].'</li>'."\n";
  863. $html .= $list_item;
  864. $last_page_depth = $page['depth'];
  865. }
  866. // Make sure all the ULs are closed
  867. // This WAS > 0, didn't close properly. >1 looks like it solves it.
  868. if ($last_page_depth > 1)
  869. {
  870. $html .= "</ul>\n";
  871. $html .= str_repeat("</li>\n</ul>\n", $last_page_depth);
  872. }
  873. else
  874. {
  875. $html .= $ul_open ? "</ul>\n</li>\n</ul>" : "</ul>\n";
  876. }
  877. return $html;
  878. }
  879. /** -------------------------------------
  880. /** Tag: sitemap
  881. /**
  882. /** Returns a full tree of all site
  883. /** pages in <ul>, <xml> or text format.
  884. /** -------------------------------------*/
  885. function sitemap()
  886. {
  887. $html = "";
  888. $css_id = $this->EE->TMPL->fetch_param('css_id');
  889. $css_id = $css_id ? strtolower($css_id) : "sitemap";
  890. if ($css_id == "none")
  891. {
  892. $css_id = '';
  893. }
  894. $css_class = $this->EE->TMPL->fetch_param('css_class');
  895. $css_class = $css_class ? strtolower($css_class) : '';
  896. // DEPRECIATED SUPPORT for exclude_status and include_status
  897. $include_status = strtolower($this->EE->TMPL->fetch_param('include_status'));
  898. $exclude_status = strtolower($this->EE->TMPL->fetch_param('exclude_status'));
  899. // New, native EE status mode
  900. $status = $this->EE->TMPL->fetch_param('status');
  901. $status = $status == '' ? array() : explode('|', $status);
  902. $status = array_map('strtolower', $status); // match MySQL's case-insensitivity
  903. $status_state = 'positive';
  904. // Check for "not "
  905. if (substr($status[0], 0, 4) == 'not ')
  906. {
  907. $status_state = 'negative';
  908. $status[0] = trim(substr($status[0], 3));
  909. $status[] = 'closed';
  910. }
  911. else
  912. {
  913. $status[] = 'open';
  914. }
  915. $include_status_list = explode('|', $include_status);
  916. $exclude_status_list = explode('|', $exclude_status);
  917. // Remove the default "open" status if explicitely set
  918. if (in_array('open', $exclude_status_list))
  919. $status = array_filter($status, create_function('$v', 'return $v != "open";'));
  920. if ($status_state == 'positive')
  921. $status = array_merge($status, $include_status_list);
  922. elseif ($status_state == 'negative')
  923. $status = array_merge($status, $exclude_status_list);
  924. // Retrieve entry_ids to exclude
  925. $exclude = explode("|", $this->EE->TMPL->fetch_param('exclude'));
  926. // Sitemap mode -- Completely alternate output
  927. $mode = strtolower($this->EE->TMPL->fetch_param('mode'));
  928. if ($mode == "")
  929. {
  930. $mode = "html";
  931. }
  932. // Get site pages data
  933. $site_pages = $this->get_site_pages();
  934. // Get all pages
  935. $pages = $this->get_data();
  936. // Remove anything to be excluded from the results array
  937. $closed_parents = array();
  938. foreach ($pages as $key => $entry_data)
  939. {
  940. if ($status_state == 'negative' && in_array(strtolower($entry_data['status']), $status)
  941. || ($status_state == 'positive' && ! in_array(strtolower($entry_data['status']), $status))
  942. || in_array($entry_data['parent_id'], $closed_parents)
  943. || in_array($entry_data['entry_id'], $exclude))
  944. {
  945. $closed_parents[] = $entry_data['entry_id'];
  946. unset($pages[$key]);
  947. }
  948. }
  949. // Make sure array indices are incremental (0..X)
  950. $pages = array_values($pages);
  951. $home = $this->EE->functions->fetch_site_index(0,0);
  952. /** --------------------------------
  953. /** XML Sitemap Output
  954. /** --------------------------------*/
  955. if ($mode == "xml")
  956. {
  957. $html .= '<?xml version="1.0" encoding="UTF-8"?>'."\n".'<urlset'."\n\t".'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'."\n\t".'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n\t".'xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">'."\n".'<!-- Created with Structure for ExpressionEngine (http://buildwithstructure.com) -->'."\n";
  958. foreach ($pages as $page)
  959. {
  960. $page_uri = $site_pages['uris'][$page['entry_id']];
  961. $item_uri = $this->EE->functions->remove_double_slashes($home . $page_uri);
  962. $xml_item = '<url>'."\n\t".'<loc>'.$item_uri.'</loc>'."\n\t".'<priority>1.00</priority>'."\n".'</url>'."\n";
  963. $html .= $xml_item;
  964. }
  965. $html .= '</urlset>';
  966. }
  967. elseif ($mode == "text")
  968. {
  969. foreach ($pages as $page)
  970. {
  971. $page_uri = $site_pages['uris'][$page['entry_id']];
  972. $item_uri = $this->EE->functions->remove_double_slashes($home.$page_uri);
  973. $xml_item = $item_uri."\n";
  974. $html .= $xml_item;
  975. }
  976. }
  977. /** --------------------------------
  978. /** HTML Sitemap Output
  979. /** --------------------------------*/
  980. else
  981. {
  982. $html .= "<ul id=\"$css_id\"" . ($css_class != '' ? " class=\"$css_class\"" : '') . ">\n";
  983. $ul_open = false;
  984. $last_page_depth = 0;
  985. foreach ($pages as $page)
  986. {
  987. $page_uri = $site_pages['uris'][$page['entry_id']];
  988. $item_uri = $this->EE->functions->remove_double_slashes($home . $page_uri);
  989. // Start a sub nav
  990. if ($page['depth'] > $last_page_depth)
  991. {
  992. $html = substr($html, 0, -6);
  993. $html .= "\n<ul>\n";
  994. $ul_open = true;
  995. }
  996. // Close a sub nav
  997. if ($page['depth'] < $last_page_depth)
  998. {
  999. // Finds the previous entry
  1000. preg_match("~\<li( class=\".+?\"){0,1}>(\<.+?\</.+?>)~", $list_item, $matches);
  1001. // Creates the new class entry
  1002. if ($matches[1])
  1003. {
  1004. $last_item_class = substr($matches[1], 0, -1) . " last\"";
  1005. }
  1006. else
  1007. {
  1008. $last_item_class = " class=\"last\"";
  1009. }
  1010. // Stores the inner of the <li>
  1011. $last_item_inner = $matches[2];
  1012. // Replace the string
  1013. $html = str_replace($list_item, "<li$last_item_class>$last_item_inner</li>\n", $html);
  1014. // Calculate how many levels back I need to go
  1015. $back_to = $last_page_depth - $page['depth'];
  1016. $html .= str_repeat("</ul>\n</li>\n", $back_to);
  1017. $ul_open = false;
  1018. }
  1019. // Is this the last in the list?
  1020. $classes = '';
  1021. $page_title = "";
  1022. if ($page == end($pages))
  1023. {
  1024. $classes = ' class="last"';
  1025. }
  1026. if ($this->EE->config->item('auto_convert_high_ascii') != 'n')
  1027. {
  1028. $page_title = $page['title'];
  1029. }
  1030. else
  1031. {
  1032. $page_title = htmlspecialchars($page['title']);
  1033. }
  1034. $list_item = "<li$classes><a href='$item_uri'>".$page_title."</a></li>\n";
  1035. $html .= $list_item;
  1036. $last_page_depth = $page['depth'];
  1037. }
  1038. // Make sure all the ULs are closed
  1039. if ($last_page_depth > 1)
  1040. {
  1041. $html .= "</ul>\n";
  1042. $html .= str_repeat("</li>\n</ul>\n", $last_page_depth);
  1043. }
  1044. else
  1045. {
  1046. $html .= $ul_open ? "</ul>\n</li>\n</ul>" : "</ul>\n";
  1047. }
  1048. }
  1049. return $html;
  1050. }
  1051. /** -------------------------------------
  1052. /** Create a Breadcrumb Trail
  1053. /** -------------------------------------*/
  1054. function breadcrumb()
  1055. {
  1056. $site_pages = $this->get_site_pages();
  1057. if ( ! $site_pages) return FALSE;
  1058. // Get parameters
  1059. $separator = $this->EE->TMPL->fetch_param('separator');
  1060. $separator = $separator ? $separator : '&raquo;';
  1061. $inc_separator = $this->EE->TMPL->fetch_param('inc_separator');
  1062. $separator = $inc_separator === 'no' ? '' : $separator;
  1063. $inc_home = $this->EE->TMPL->fetch_param('inc_home');
  1064. $inc_home = $inc_home === 'no' ? false : true;
  1065. $inc_here = $this->EE->TMPL->fetch_param('inc_here');
  1066. $inc_here = $inc_here === 'no' ? false : true;
  1067. $here_as_title = $this->EE->TMPL->fetch_param('here_as_title');
  1068. $here_as_title = $here_as_title === 'yes' ? true : false;
  1069. $wrap_each = $this->EE->TMPL->fetch_param('wrap_each');
  1070. $wrap_each = $wrap_each ? $wrap_each : '';
  1071. $wrap_here = $this->EE->TMPL->fetch_param('wrap_here');
  1072. $wrap_here = $wrap_here ? $wrap_here : '';
  1073. $wrap_separator = $this->EE->TMPL->fetch_param('wrap_separator');
  1074. $wrap_separator = $wrap_separator ? $wrap_separator : '';
  1075. $separator = $wrap_separator ? "<{$wrap_separator}>{$separator}</{$wrap_separator}>" : $separator;
  1076. // Are we passed a URI to work from? If not use current URI
  1077. $uri = $this->EE->TMPL->fetch_param('uri');
  1078. $uri = $uri ? $uri : '/'.$this->EE->uri->uri_string().'/';
  1079. $uri = html_entity_decode($uri);
  1080. // get current entry id
  1081. $entry_id = array_search($uri, $site_pages['uris']);
  1082. // get node of the current entry
  1083. $node = $entry_id ? $this->nset->getNode($entry_id) : false;
  1084. // node does not have any structure data we return nothing to prevent errors
  1085. if ($node === false && ! $entry_id)
  1086. {
  1087. return '';
  1088. }
  1089. // if we have an entry id but no node, we have listing entry
  1090. if ($entry_id && ! $node)
  1091. {
  1092. // get entry's parent id
  1093. $pid = $this->get_pid_for_listing_entry($entry_id);
  1094. // get node of parent entry
  1095. $node = $this->nset->getNode($pid);
  1096. }
  1097. $right = $node['right'];
  1098. $inc_current = isset($pid) ? '=' : '';
  1099. $sql = "SELECT node.*, expt.title
  1100. FROM exp_structure AS node
  1101. INNER JOIN exp_channel_titles AS expt
  1102. ON node.entry_id = expt.entry_id
  1103. WHERE node.lft > 1
  1104. AND node.lft < $right
  1105. AND node.rgt >$inc_current $right
  1106. ORDER BY node.lft";
  1107. $result = $this->EE->db->query($sql);
  1108. $home = trim($this->EE->functions->fetch_site_index(0, 0), '/');
  1109. $crumbs = array();
  1110. if ($inc_home)
  1111. {
  1112. $crumbs[] = '<a href="' . $home . '">Home</a>';
  1113. }
  1114. foreach ($result->result_array() as $entry)
  1115. {
  1116. $crumbs[] = '<a href="' . $home . $site_pages['uris'][$entry['entry_id']] . '">' . $entry['title'] . '</a>';
  1117. }
  1118. // If inc_here param is yes/true then show the here name
  1119. if ($inc_here)
  1120. {
  1121. // If here_as_title is yes/true then show here as page title
  1122. if ($here_as_title)
  1123. {
  1124. $sql2 = "SELECT title
  1125. FROM exp_channel_titles
  1126. WHERE entry_id = $entry_id";
  1127. $result2 = $this->EE->db->query($sql2);
  1128. $result2 = $result2->result_array();
  1129. $crumbs[] = !empty($wrap_here) ? "<{$wrap_here}>{$result2[0]['title']}</{$wrap_here}>" : $result2[0]['title'];
  1130. }
  1131. else
  1132. {
  1133. $crumbs[] = !empty($wrap_here) ? "<{$wrap_here}>Here</{$wrap_here}>" : "Here";
  1134. }
  1135. }
  1136. for ($i=0, $count=count($crumbs); $i < $count; $i++)
  1137. {
  1138. if ( ! empty( $separator) && $i != ($count-1))
  1139. {
  1140. $crumbs[$i] = "{$crumbs[$i]} {$separator} ";
  1141. }
  1142. if ( ! empty($wrap_each))
  1143. {
  1144. $crumbs[$i] = "<{$wrap_each}>{$crumbs[$i]}</{$wrap_each}>";
  1145. }
  1146. }
  1147. return implode('', $crumbs);
  1148. }
  1149. /** -------------------------------------
  1150. /** Tag: titletrail
  1151. /** -------------------------------------*/
  1152. function titletrail()
  1153. {
  1154. // get site pages data
  1155. $site_pages = $this->get_site_pages();
  1156. if (!$site_pages) return FALSE;
  1157. // get current uri path
  1158. $uri = '/'.$this->EE->uri->uri_string().'/';
  1159. // get current entry id
  1160. $entry_id = array_search($uri, $site_pages['uris']);
  1161. // get node of the current entry
  1162. $node = $entry_id ? $this->nset->getNode($entry_id) : false;
  1163. // node does not have any structure data we return site_name to prevent errors
  1164. if ($node === false && !$entry_id)
  1165. {
  1166. return stripslashes($this->EE->config->item('site_name'));
  1167. }
  1168. // if we have an entry id but no node, we have listing entry
  1169. if ($entry_id && ! $node)
  1170. {
  1171. // get entry's parent id
  1172. $pid = $this->get_pid_for_listing_entry($entry_id);
  1173. // get node of parent entry
  1174. // because we will be showing nav sub from its view point
  1175. $node = $this->nset->getNode($pid);
  1176. }
  1177. // Fetch params
  1178. $separator = $this->EE->TMPL->fetch_param('separator');
  1179. $separator = $separator ? " " . $separator . " " : ' | ';
  1180. $reverse = $this->EE->TMPL->fetch_param('reverse');
  1181. $reverse = ($reverse == 'yes') ? true : false;
  1182. $right = $node['right'];
  1183. $inc_current = isset($pid) ? '=' : '';
  1184. $sql = "SELECT node.*, expt.title
  1185. FROM exp_structure AS node
  1186. INNER JOIN exp_channel_titles AS expt
  1187. ON node.entry_id = expt.entry_id
  1188. WHERE node.lft > 1
  1189. AND node.lft < $right
  1190. AND node.rgt >$inc_current $right
  1191. ORDER BY node.lft DESC";
  1192. $result = $this->EE->db->query($sql);
  1193. $sql2 = "SELECT title
  1194. FROM exp_channel_titles
  1195. WHERE entry_id = $entry_id";
  1196. $result2 = $this->EE->db->query($sql2);
  1197. // Create an array of the page titles and site name
  1198. // If reverse param is true then flip it prior to output
  1199. $title_row = $result2->result_array();
  1200. $title_row = $title_row[0]['title'];
  1201. $title_array = array();
  1202. $title_array[] = $title_row;
  1203. foreach ($result->result_array() as $entry)
  1204. {
  1205. $title_array[] = $entry['title'];
  1206. }
  1207. $title_array[] = stripslashes($this->EE->config->item('site_name'));
  1208. if ($reverse === true)
  1209. {
  1210. $title_array = array_reverse($title_array);
  1211. }
  1212. $html = implode($separator, $title_array);
  1213. return $html;
  1214. }
  1215. /** -------------------------------------
  1216. /** Tag: top_level_title
  1217. /** Outputs the first segment's title
  1218. /** -------------------------------------*/
  1219. function top_level_title()
  1220. {
  1221. $site_pages = $this->get_site_pages(); // get site pages data
  1222. if ( ! $site_pages)
  1223. return FALSE;
  1224. $seg1 = '/'.$this->EE->uri->segment(1).'/'; // get segment 1 value
  1225. $top_id = array_search($seg1, $site_pages['uris']);
  1226. if ($top_id)
  1227. {
  1228. $this->EE->db->where('entry_id', $top_id);
  1229. $this->EE->db->limit(1);
  1230. $query=$this->EE->db->get('exp_channel_titles');
  1231. if ($query->num_rows() == 1)
  1232. {
  1233. $row = $query->row();
  1234. return $row->title;
  1235. }
  1236. }
  1237. return '';
  1238. }
  1239. /** -------------------------------------
  1240. /** Tag: parent_title
  1241. /** -------------------------------------*/
  1242. function parent_title($entry_id = NULL)
  1243. {
  1244. $html = "";
  1245. // get site pages data
  1246. $site_pages = $this->get_site_pages();
  1247. if (!$site_pages) return FALSE;
  1248. // get current uri path
  1249. $uri = '/'.$this->EE->uri->uri_string().'/';
  1250. // get current entry id
  1251. $entry_id = $entry_id ? $entry_id : array_search($uri, $site_pages['uris']);
  1252. // get node of the current entry
  1253. $node = $entry_id ? $this->nset->getNode($entry_id) : false;
  1254. // node does not have any structure data we return site_name to prevent errors
  1255. if ($node === false && ! $entry_id)
  1256. {
  1257. return stripslashes($this->EE->config->item('site_name'));
  1258. }
  1259. // if we have an entry id but no node, we have listing entry
  1260. if ($entry_id && ! $node)
  1261. {
  1262. // get entry's parent id
  1263. $pid = $this->get_pid_for_listing_entry($entry_id);
  1264. // get node of parent entry
  1265. // because we will be showing nav sub from its view point
  1266. $node = $this->nset->getNode($pid);
  1267. }
  1268. $right = $node['right'];
  1269. $inc_current = isset($pid) ? '=' : '';
  1270. $sql = "SELECT node.*, expt.title
  1271. FROM exp_structure AS node
  1272. INNER JOIN exp_channel_titles AS expt
  1273. ON node.entry_id = expt.entry_id
  1274. WHERE node.lft > 1
  1275. AND node.lft < $right
  1276. AND node.rgt >$inc_current $right
  1277. ORDER BY node.lft DESC";
  1278. $result = $this->EE->db->query($sql);
  1279. $html = $result->result_array();
  1280. $html = @$html[0]['title'];
  1281. return $html;
  1282. }
  1283. /** -------------------------------------
  1284. /** Tag: page_slug
  1285. /** -------------------------------------*/
  1286. function page_slug($entry_id = NULL)
  1287. {
  1288. $slug = "";
  1289. $uri = "";
  1290. // get site pages data
  1291. $site_pages = $this->get_site_pages();
  1292. if (!$site_pages) return FALSE;
  1293. $uri = '/'.$this->EE->uri->uri_string().'/';
  1294. if ($entry_id == NULL)
  1295. {
  1296. // get current entry id
  1297. $current_page_entry_id = array_search($uri, $site_pages['uris']);
  1298. // Fetch params
  1299. $entry_id = $this->EE->TMPL->fetch_param('entry_id');
  1300. $entry_id = $entry_id ? $entry_id : $current_page_entry_id;
  1301. }
  1302. // get page uri slug without parents
  1303. @$uri = $site_pages['uris'][$entry_id];
  1304. // if there are no / then we have a root slug already, else get the end
  1305. $slug .= trim($uri, '/');
  1306. if (strpos($slug, '/'))
  1307. {
  1308. $slug = substr(strrchr($slug, '/'), 1);
  1309. }
  1310. return $slug;
  1311. }
  1312. /** -------------------------------------
  1313. /** Tag: page_id
  1314. /** -------------------------------------*/
  1315. function page_id($entry_uri = NULL)
  1316. {
  1317. $slug = "";
  1318. // get site pages data
  1319. $site_pages = $this->get_site_pages();
  1320. if ( ! $site_pages) return FALSE;
  1321. // Fetch params
  1322. $entry_uri = $this->EE->TMPL->fetch_param('entry_uri');
  1323. // echo $entry_uri;
  1324. if ($entry_uri == NULL || $entry_uri == '')
  1325. {
  1326. $entry_uri = '/'.$this->EE->uri->uri_string().'/';
  1327. }
  1328. // get current entry id
  1329. $current_page_entry_id = array_search($entry_uri, $site_pages['uris']);
  1330. return $current_page_entry_id;
  1331. }
  1332. // --------------------------------------------------------------------
  1333. // Child IDs function
  1334. // Returns a string of IDs for a given parent
  1335. function child_ids()
  1336. {
  1337. $site_pages = $this->get_site_pages();
  1338. if (!$site_pages) return FALSE;
  1339. // Fetch our parent ID, or if none default to the current page
  1340. $parent = $this->EE->TMPL->fetch_param('entry_id');
  1341. $start_from = $this->EE->TMPL->fetch_param('start_from') ? $this->EE->TMPL->fetch_param('start_from') : false;
  1342. // Only do an automatic lookup if we're not requiring a parent ID, and no entry_id was defined.
  1343. if ( ! $parent AND ! $start_from)
  1344. {
  1345. // Find the parent in the site pages array using URL
  1346. $current_uri = implode('/', $this->EE->uri->segment_array());
  1347. $parent = array_search("/$current_uri/", $site_pages['uris']);
  1348. }
  1349. elseif($start_from)
  1350. {
  1351. $start_from = trim($start_from, '/');
  1352. $parent = array_search("/$start_from/", $site_pages['uris']);
  1353. }
  1354. /

Large files files are truncated, but you can click here to view the full file