PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/system/cms/modules/pages/plugin.php

https://github.com/marcoscoelho/pyrocms
PHP | 421 lines | 222 code | 64 blank | 135 comment | 28 complexity | 4f4d4d176940ac27427b05d2a6ed2839 MD5 | raw file
  1. <?php defined('BASEPATH') OR exit('No direct script access allowed');
  2. /**
  3. * Pages Plugin
  4. *
  5. * Create links and whatnot.
  6. *
  7. * @package PyroCMS
  8. * @author PyroCMS Dev Team
  9. * @copyright Copyright (c) 2008 - 2011, PyroCMS
  10. *
  11. */
  12. class Plugin_Pages extends Plugin
  13. {
  14. /**
  15. * Get a page's URL
  16. *
  17. * @param int $id The ID of the page
  18. * @return string
  19. */
  20. public function url()
  21. {
  22. $id = $this->attribute('id');
  23. $page = $this->pyrocache->model('page_m', 'get', array($id));
  24. return site_url($page ? $page->uri : '');
  25. }
  26. // --------------------------------------------------------------------------
  27. /**
  28. * Get a page by ID or slug
  29. *
  30. * @param int $id The ID of the page
  31. * @param string $slug The uri of the page
  32. * @return array
  33. */
  34. public function display()
  35. {
  36. $page = $this->db->where('pages.id', $this->attribute('id'))
  37. ->or_where('pages.slug', $this->attribute('slug'))
  38. ->where('status', 'live')
  39. ->get('pages')
  40. ->row_array();
  41. // Grab all the chunks that make up the body
  42. $page['chunks'] = $this->db->get_where('page_chunks', array('page_id' => $page['id']))->result();
  43. $page['body'] = '';
  44. foreach ($page['chunks'] as $chunk)
  45. {
  46. $page['body'] .= '<div class="page-chunk ' . $chunk->slug . '">' .
  47. (($chunk->type == 'markdown') ? $chunk->parsed : $chunk->body) .
  48. '</div>'.PHP_EOL;
  49. }
  50. // we'll unset the chunks array as Lex is grouchy about mixed data at the moment
  51. unset($page['chunks']);
  52. return $this->content() ? array($page) : $page['body'];
  53. }
  54. // --------------------------------------------------------------------------
  55. /**
  56. * Get a page chunk by page ID and chunk name
  57. *
  58. * @param int $id The ID of the page
  59. * @param string $slug The name of the chunk
  60. * @return array
  61. */
  62. function chunk()
  63. {
  64. $chunk = $this->db->select('*')
  65. ->where('page_id', $this->attribute('id'))
  66. ->where('slug', $this->attribute('name'))
  67. ->get('page_chunks')
  68. ->row_array();
  69. return ($chunk ? ($this->content() ? $chunk : $chunk['body']) : FALSE);
  70. }
  71. // --------------------------------------------------------------------------
  72. /**
  73. * Children list
  74. *
  75. * Creates a list of child pages
  76. *
  77. * Usage:
  78. * {{ pages:children id="1" limit="5" }}
  79. * <h2>{title}</h2>
  80. * {body}
  81. * {{ /pages:children }}
  82. *
  83. * @return array
  84. */
  85. public function children()
  86. {
  87. $limit = $this->attribute('limit', 10);
  88. $pages = $this->db->select('pages.*')
  89. ->where('pages.parent_id', $this->attribute('id'))
  90. ->where('status', 'live')
  91. ->limit($limit)
  92. ->get('pages')
  93. ->result_array();
  94. if ($pages)
  95. {
  96. foreach ($pages AS &$page)
  97. {
  98. // Grab all the chunks that make up the body for this page
  99. $page['chunks'] = $this->db->get_where('page_chunks', array('page_id' => $page['id']))->result();
  100. $page['body'] = '';
  101. foreach ($page['chunks'] as $chunk)
  102. {
  103. $page['body'] .= '<div class="page-chunk ' . $chunk->slug . '">' .
  104. (($chunk->type == 'markdown') ? $chunk->parsed : $chunk->body) .
  105. '</div>'.PHP_EOL;
  106. }
  107. }
  108. }
  109. return $pages;
  110. }
  111. // --------------------------------------------------------------------------
  112. /**
  113. * Page tree function
  114. *
  115. * Creates a nested ul of child pages
  116. *
  117. * Usage:
  118. * {{ pages:page_tree start-id="5" }}
  119. * optional attributes:
  120. *
  121. * disable-levels="slug"
  122. * order-by="title"
  123. * order-dir="desc"
  124. * list-tag="ul"
  125. * link="true"
  126. *
  127. * @param array
  128. * @return array
  129. */
  130. public function page_tree()
  131. {
  132. $start = $this->attribute('start');
  133. $start_id = $this->attribute('start-id', $this->attribute('start_id'));
  134. $disable_levels = $this->attribute('disable-levels');
  135. $order_by = $this->attribute('order-by', 'title');
  136. $order_dir = $this->attribute('order-dir', 'ASC');
  137. $list_tag = $this->attribute('list-tab', 'ul');
  138. $link = $this->attribute('link', TRUE);
  139. // If we have a start URI, let's try and
  140. // find that ID.
  141. if($start)
  142. {
  143. $page = $this->page_m->get_by_uri($start);
  144. if(!$page) return NULL;
  145. $start_id = $page->id;
  146. }
  147. // If our start doesn't exist, then
  148. // what are we going to do? Nothing.
  149. if(!$start_id) return NULL;
  150. // Disable individual pages or parent pages by submitting their slug
  151. $this->disable = explode("|", $disable_levels);
  152. return '<'.$list_tag.'>' . $this->_build_tree_html(array(
  153. 'parent_id' => $start_id,
  154. 'order_by' => $order_by,
  155. 'order_dir' => $order_dir,
  156. 'list_tag' => $list_tag,
  157. 'link' => $link
  158. )) . '</'.$list_tag.'>';
  159. }
  160. // --------------------------------------------------------------------------
  161. /**
  162. * Page is function
  163. *
  164. * Check the pages parent or descendent relation
  165. *
  166. * Usage:
  167. * {{ pages:is child="7" parent="cookbook" }} // return 1 (TRUE)
  168. * {{ pages:is child="recipes" descendent="books" }} // return 1 (TRUE)
  169. * {{ pages:is children="7,8,literature" parent="6" }} // return 0 (FALSE)
  170. * {{ pages:is children="recipes,ingredients,9" descendent="4" }} // return 1 (TRUE)
  171. *
  172. * Use Id or Slug as param, following usage data reference
  173. * Id: 4 = Slug: books
  174. * Id: 6 = Slug: cookbook
  175. * Id: 7 = Slug: recipes
  176. * Id: 8 = Slug: ingredients
  177. * Id: 9 = Slug: literature
  178. *
  179. * @param array Plugin attributes
  180. * @return int 0 or 1
  181. */
  182. public function is()
  183. {
  184. $children_ids = $this->attribute('children');
  185. $child_id = $this->attribute('child');
  186. if ( ! $children_ids)
  187. {
  188. return (int) $this->_check_page_is($child_id);
  189. }
  190. $children_ids = explode(',', $children_ids);
  191. $children_ids = array_map('trim', $children_ids);
  192. if ($child_id)
  193. {
  194. $children_ids[] = $child_id;
  195. }
  196. foreach ($children_ids as $child_id)
  197. {
  198. if ( ! $this->_check_page_is($child_id))
  199. {
  200. return (int) FALSE;
  201. }
  202. }
  203. return (int) TRUE;
  204. }
  205. // --------------------------------------------------------------------------
  206. /**
  207. * Page has function
  208. *
  209. * Check if this page has children
  210. *
  211. * Usage:
  212. * {{ pages:has id="4" }}
  213. *
  214. * @param int id The id of the page you want to check
  215. * @return bool
  216. */
  217. public function has()
  218. {
  219. return $this->page_m->has_children($this->attribute('id'));
  220. }
  221. // --------------------------------------------------------------------------
  222. /**
  223. * Check Page is function
  224. *
  225. * Works for page is function
  226. *
  227. * @param mixed The Id or Slug of the page
  228. * @param array Plugin attributes
  229. * @return int 0 or 1
  230. */
  231. private function _check_page_is($child_id = 0)
  232. {
  233. $descendent_id = $this->attribute('descendent');
  234. $parent_id = $this->attribute('parent');
  235. if ($child_id && $descendent_id)
  236. {
  237. if ( ! is_numeric($child_id))
  238. {
  239. $child_id = ($child = $this->page_m->get_by(array('slug' => $child_id))) ? $child->id: 0;
  240. }
  241. if ( ! is_numeric($descendent_id))
  242. {
  243. $descendent_id = ($descendent = $this->page_m->get_by(array('slug' => $descendent_id))) ? $descendent->id: 0;
  244. }
  245. if ( ! ($child_id && $descendent_id))
  246. {
  247. return FALSE;
  248. }
  249. $descendent_ids = $this->page_m->get_descendant_ids($descendent_id);
  250. return in_array($child_id, $descendent_ids);
  251. }
  252. if ($child_id && $parent_id)
  253. {
  254. if ( ! is_numeric($child_id))
  255. {
  256. $parent_id = ($parent = $this->page_m->get_by(array('slug' => $parent_id))) ? $parent->id : 0;
  257. }
  258. return $parent_id ? (int) $this->page_m->count_by(array(
  259. (is_numeric($child_id) ? 'id' : 'slug') => $child_id,
  260. 'parent_id' => $parent_id
  261. )) > 0 : FALSE;
  262. }
  263. }
  264. // --------------------------------------------------------------------------
  265. /**
  266. * Tree html function
  267. *
  268. * Creates a page tree
  269. *
  270. * @param array
  271. * @return array
  272. */
  273. function _build_tree_html($params)
  274. {
  275. $params = array_merge(array(
  276. 'tree' => array(),
  277. 'parent_id' => 0
  278. ), $params);
  279. extract($params);
  280. if ( ! $tree)
  281. {
  282. $this->db->select('id, parent_id, slug, uri, title')
  283. ->where_not_in('slug', $this->disable);
  284. // check if they're logged in
  285. if ( isset($this->current_user->group) )
  286. {
  287. // admins can see them all
  288. if ($this->current_user->group != 'admin')
  289. {
  290. $id_list = array();
  291. $page_list = $this->db->select('id, restricted_to')
  292. ->get('pages')
  293. ->result();
  294. foreach ($page_list AS $list_item)
  295. {
  296. // make an array of allowed user groups
  297. $group_array = explode(',', $list_item->restricted_to);
  298. // if restricted_to is 0 or empty (unrestricted) or if the current user's group is allowed
  299. if (($group_array[0] < 1) OR in_array($this->current_user->group_id, $group_array))
  300. {
  301. $id_list[] = $list_item->id;
  302. }
  303. }
  304. // if it's an empty array then evidentally all pages are unrestricted
  305. if (count($id_list) > 0)
  306. {
  307. // select only the pages they have permissions for
  308. $this->db->where_in('id', $id_list);
  309. }
  310. // since they aren't an admin they can't see drafts
  311. $this->db->where('status', 'live');
  312. }
  313. }
  314. else
  315. {
  316. //they aren't logged in, show them all live, unrestricted pages
  317. $this->db->where('status', 'live')
  318. ->where('restricted_to <', 1)
  319. ->or_where('restricted_to', NULL);
  320. }
  321. $pages = $this->db->order_by($order_by, $order_dir)
  322. ->get('pages')
  323. ->result();
  324. if ($pages)
  325. {
  326. foreach($pages as $page)
  327. {
  328. $tree[$page->parent_id][] = $page;
  329. }
  330. }
  331. }
  332. if ( ! isset($tree[$parent_id]))
  333. {
  334. return;
  335. }
  336. $html = '';
  337. foreach ($tree[$parent_id] as $item)
  338. {
  339. $html .= '<li';
  340. $html .= (current_url() == site_url($item->uri)) ? ' class="current">' : '>';
  341. $html .= ($link === TRUE) ? '<a href="' . site_url($item->uri) . '">' . $item->title . '</a>' : $item->title;
  342. $nested_list = $this->_build_tree_html(array(
  343. 'tree' => $tree,
  344. 'parent_id' => (int) $item->id,
  345. 'link' => $link,
  346. 'list_tag' => $list_tag
  347. ));
  348. if ($nested_list)
  349. {
  350. $html .= '<'.$list_tag.'>' . $nested_list . '</'.$list_tag.'>';
  351. }
  352. $html .= '</li>';
  353. }
  354. return $html;
  355. }
  356. }
  357. /* End of file plugin.php */