function &get_nested_pages($tpl_id, $tpl_name, $tpl_access_level, $orderbyfield = 'weightx', $order = 'asc', $force = 0) { global $DB; if (array_key_exists($tpl_id, $this->cached_nested_pages) && !$force) { $tree =& $this->cached_nested_pages[$tpl_id]; if ($tree->cmp_field != $orderbyfield || $tree->cmp_order != $order) { $tree->set_sort($orderbyfield, $order); $tree->sort(1); } } else { $tree = new KNestedPage(array('id' => '-1', 'name' => '_root_', 'pid' => '-1'), $tpl_name, new KError()); $tree->set_sort($orderbyfield, $order); $tree->crumbs = null; // will be filled, if required, by calling tags e.g. 'nested_pages'. $cols = array('p.id, p.page_title as title, p.page_name as name, p.creation_date, p.publish_date, p.access_level, p.comments_count, p.nested_parent_id as pid, p.weight, p.show_in_menu, p.menu_text, p.is_pointer, p.pointer_link, p.pointer_link_detail, p.open_external, p.masquerades, p.strict_matching, count(p2.id) as drafts_count'); $tables = K_TBL_PAGES . " p left outer join " . K_TBL_PAGES . " p2 on p.id = p2.parent_id"; $sql = 'p.template_id=' . $DB->sanitize($tpl_id); $sql .= " AND p.parent_id=0"; //skip drafts $sql .= ' group by p.id'; $rows = $DB->select($tables, $cols, $sql); $folders = array(); foreach ($rows as $r) { $r['template_id'] = $tpl_id; $r['template_name'] = $tpl_name; $r['template_access_level'] = $tpl_access_level; $f = new KNestedPage($r, $tpl_name, $tree); $folders[$f->id] =& $f; unset($f); } foreach ($folders as $f) { $folder =& $folders[$f->id]; if (isset($folders[$f->pid])) { $folders[$f->pid]->add_child($folder); } else { $tree->add_child($folder); } } $tree->sort(1); $tree->set_children_count(); $this->cached_nested_pages[$tpl_id] =& $tree; } return $tree; }
function nested_pages($params, $node, $variation = 0) { global $CTX, $FUNCS, $PAGE, $DB; $attr = $FUNCS->get_named_vars(array('masterpage' => '', 'root' => '', 'childof' => '', 'depth' => '0', 'orderby' => '', 'order' => '', 'exclude' => '', 'extended_info' => '0', 'ignore_show_in_menu' => '0', 'include_custom_fields' => '0', 'paginate' => 0, 'limit' => '', 'offset' => '0', 'startcount' => ''), $params); extract($attr); $masterpage = trim($masterpage); $root = trim($root); $childof = trim($childof); $hierarchical = 1; // always 1 $depth = $FUNCS->is_natural($depth) ? intval($depth) : 0; $orderby = strtolower(trim($orderby)); if (!in_array($orderby, array('name', 'title', 'id', 'weight'))) { $orderby = 'weight'; } if ($orderby == 'weight') { $orderby = 'weightx'; } $order = strtolower(trim($order)); if ($order != 'desc' && $order != 'asc') { $order = 'asc'; } $exclude = $exclude ? array_map("trim", explode(",", $exclude)) : array(); $extended_info = $extended_info == 1 ? 1 : 0; if ($variation == 1) { $extended_info = 1; } // always 1 with 'menu' $ignore_show_in_menu = $ignore_show_in_menu == 1 ? 1 : 0; $ignore_active_status = 0; // unpublished pages will always be ignored $include_custom_fields = $variation ? 0 : ($include_custom_fields == 1 ? 1 : 0); $paginate = $variation ? 0 : ($paginate == 1 ? 1 : 0); if ($paginate) { $extended_info = 0; } $limit = $FUNCS->is_non_zero_natural($limit) ? intval($limit) : 1000; //Practically unlimited. $offset = $FUNCS->is_natural($offset) ? intval($offset) : 0; $startcount = $FUNCS->is_int($startcount) ? intval($startcount) : 1; $startcount--; // see if masterpage exists if ($masterpage == '') { if (!$PAGE->tpl_nested_pages) { return; } $tree =& $FUNCS->get_nested_pages($PAGE->tpl_id, $PAGE->tpl_name, $PAGE->tpl_access_level, $orderby, $order); $tpl_name = $PAGE->tpl_name; } else { $rs = $DB->select(K_TBL_TEMPLATES, array('*'), "name='" . $DB->sanitize($masterpage) . "'"); if (!count($rs)) { return; } if (!$rs[0]['nested_pages']) { return; } $tpl_id = $rs[0]['id']; $tpl_name = $rs[0]['name']; $tpl_access_level = $rs[0]['access_level']; // get the tree of nested pages $tree =& $FUNCS->get_nested_pages($tpl_id, $tpl_name, $tpl_access_level, $orderby, $order); } // mark the active trail in the tree.. also creates the crumbs. $tree->mark_current(!$ignore_show_in_menu); // if called from 'nested_crumbs', return crumbs and exit .. if ($variation == 2) { // crumbs.. only $masterpage and $ignore_show_in_menu are the valid params here return $tree->crumbs; } // Check if either 'root' or 'childof' set to special keywords // keywords: // @1, @2 etc. - start from x level parent of the most current item. // @current - start from most current item. // @current-1, @current-2 etc. - start from parent of most current item at x level above it. if ($root || $childof) { // root takes precedence over childof $special = $root ? $root : $childof; if ($special[0] == '@') { $special = substr($special, 1); // find the most current item for ($x = 0; $x < count($tree->crumbs); $x++) { $item = $tree->crumbs[$x]; if ($item->most_current) { break; } } if ($x == count($tree->crumbs)) { return; } if ($FUNCS->is_non_zero_natural($special)) { // 1, 2, etc. $special = $special - 1; // Find the requested parent at the requested level, if any if ($special > $x) { return; } // cannot go past the current item's level $item = $tree->crumbs[$special]; $root ? $root = $item->name : ($childof = $item->name); } else { if ($special == 'current') { $root ? $root = $item->name : ($childof = $item->name); } else { $arr = array_map("trim", explode('-', $special)); if ($arr[0] == 'current' && $FUNCS->is_non_zero_natural($arr[1])) { // Find parent at requested level above the current item $special = $x - $arr[1]; if ($special < -1) { return; } if ($special == -1) { // _ROOT_ if ($root) { return; /* cannot add _ROOT_ to returned array */ } else { $childof = ''; } } else { $item = $tree->crumbs[$special]; $root ? $root = $item->name : ($childof = $item->name); } } else { // unknown value given return; } } } } } // root takes precedence over childof if ($root != '') { $f =& $tree->find($root); if (!$f) { return; } unset($tree); $tree = new KNestedPage(array('id' => '-1', 'name' => '_root_', 'pid' => '-1'), $tpl_name, new KError()); $tree->set_sort($orderby, $order); $tree->add_child($f); unset($f); } elseif ($childof != '') { $f =& $tree->find($childof); if (!$f || !count($f->children)) { return; } unset($tree); $tree = new KNestedPage(array('id' => '-1', 'name' => '_root_', 'pid' => '-1'), $tpl_name, new KError()); $tree->set_sort($orderby, $order); $count = count($f->children); for ($x = 0; $x < $count; $x++) { $tree->add_child($f->children[$x]); } unset($f); } $tree->set_dynamic_count($depth, $exclude, !$ignore_show_in_menu); // pagination.. goes into normal 'pages' listing mode if ($paginate) { $qs_param = 'pg'; $pgn_pno = 1; if ($paginate) { if (isset($_GET[$qs_param]) && $FUNCS->is_non_zero_natural($_GET[$qs_param])) { $pgn_pno = (int) $_GET[$qs_param]; } } $total_rows = $tree->total_children_ex - $offset; if ($total_rows < 1) { return; } $total_pages = ceil($total_rows / $limit); if ($pgn_pno > $total_pages && $total_pages > 0) { $pgn_pno = $total_pages; } $first_record_on_page = $limit * ($pgn_pno - 1) + 1 + $offset; $last_record_on_page = $first_record_on_page + $limit - 1; if ($last_record_on_page > $total_rows + $offset) { $last_record_on_page = $total_rows + $offset; } $total_records_on_page = $last_record_on_page - ($first_record_on_page - 1); // calculate the required links $page_link = K_SITE_URL . $PAGE->link; $sep = ''; foreach ($_GET as $qk => $qv) { if ($qk == 'p' || $qk == 'f' || $qk == 'd' || $qk == 'fname' || $qk == 'pname' || $qk == '_nr_') { continue; } if ($qk == $qs_param) { continue; } $qs .= $sep . $qk . '=' . urlencode($qv); $sep = '&'; } if ($qs) { $page_link .= strpos($page_link, '?') === false ? '?' : '&'; $page_link .= $qs; } if ($total_rows > $limit) { $paginated = 1; $sep = strpos($page_link, '?') === false ? '?' : '&'; // 'Prev' link if ($pgn_pno > 1) { if ($pgn_pno == 2) { $pgn_prev_link = $page_link; } else { $pgn_prev_link = sprintf("%s%s%s=%d", $page_link, $sep, $qs_param, $pgn_pno - 1); } } // 'Next' link if ($pgn_pno < $total_pages) { $pgn_next_link = sprintf("%s%s%s=%d", $page_link, $sep, $qs_param, $pgn_pno + 1); } } // pass data on to callback function to be set in context $node->_paginate = 1; $node->_total_records = $total_rows; $node->_from = $first_record_on_page; $node->_to = $last_record_on_page; $node->_total = $total_records_on_page; $node->_offset = $offset; $node->_startcount = $startcount; $node->_total_pages = $total_pages; $node->_current_page = $pgn_pno; $node->_paginate_limit = $limit; $node->_counter = 0; $node->_page_link = $page_link; $node->_qs_param = $qs_param; $node->_paginated = $paginated; $node->_pgn_next_link = $pgn_next_link; $node->_pgn_prev_link = $pgn_prev_link; } $html = ''; $visitor = !$variation ? '_nested_pages_visitor' : '_nested_pages_visitor_menu'; $CTX->set('k_show_extended_info', $extended_info); if (!$variation) { $node->_include_custom_fields = $include_custom_fields; } $tree->visit(array($this, $visitor), $html, $node, $depth, $extended_info, $exclude, 0, !$ignore_show_in_menu, !$ignore_active_status, $paginate); return $html; }