displayLanguageOrder = []; } public function s_export_structure($structure_id) { global $exportlib, $tikidomain; global $dbTiki; include_once('lib/wiki/exportlib.php'); include_once('lib/tar.class.php'); $page_info = $this->s_get_structure_info($structure_id); $page_name = $page_info['pageName']; $zipname = $page_name . '.zip'; $tar = new tar(); $pages = $this->s_get_structure_pages($page_info['page_ref_id']); foreach ($pages as $page) { $data = $exportlib->export_wiki_page($page['pageName'], 0); $tar->addData($page['pageName'], $data, $this->now); } $dump = 'dump'; if ($tikidomain) { $dump .= "/$tikidomain"; } $tar->toTar("$dump/$page_name.tar", false); header("location: $dump/$page_name.tar"); return ''; } public function s_export_structure_tree($structure_id, $level = 0) { $structure_tree = $this->get_subtree($structure_id); $level = 0; $first = true; header('Content-type: text/plain; charset=utf-8'); foreach ($structure_tree as $node) { //This special case indicates head of structure if ($node['first'] and $node['last']) { print (tra('Use this tree to copy the structure') . ': ' . $node['pageName'] . "\n\n"); } elseif ($node['first'] or ! $node['last']) { if ($node['first'] and ! $first) { $level++; } $first = false; for ($i = 0; $i < $level; $i++) { print (' '); } print ($node['pageName']); if (! empty($node['page_alias'])) { print("->" . $node['page_alias']); } print("\n"); } else { //node is a place holder for last in level $level--; } } } public function s_remove_page($page_ref_id, $delete, $name = '') { // Now recursively remove global $user, $prefs, $tiki_p_remove; if ($prefs['feature_user_watches'] == 'y') { include_once('lib/notifications/notificationemaillib.php'); sendStructureEmailNotification(['action' => 'remove', 'page_ref_id' => $page_ref_id, 'name' => $name]); } $query = 'select `page_ref_id`, ts.`page_id`, `pageName` '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where tp.`page_id`=ts.`page_id` and `parent_id`=?'; $result = $this->query($query, [(int) $page_ref_id]); //Iterate down through the child nodes while ($res = $result->fetchRow()) { $this->s_remove_page($res['page_ref_id'], $delete); } //Only delete a page if other structures arent referencing it if ($delete && $tiki_p_remove == 'y') { $page_info = $this->s_get_page_info($page_ref_id); $query = 'select count(*) from `tiki_structures` where `page_id`=?'; $count = $this->getOne($query, [(int) $page_info['page_id']]); $wikilib = TikiLib::lib('wiki'); if ($count == 1 && $wikilib->is_editable($page_info['pageName'], $user)) { $this->remove_all_versions($page_info['pageName']); } } // Remove the space created by the removal $page_info = $this->s_get_page_info($page_ref_id); if (isset($page_info["parent_id"])) { $query = "update `tiki_structures` set `pos`=`pos`-1 where `pos`>? and `parent_id`=?"; $this->query($query, [(int) $page_info["pos"], (int) $page_info["parent_id"]]); } //Remove the structure node $query = 'delete from `tiki_structures` where `page_ref_id`=?'; $result = $this->query($query, [(int) $page_ref_id]); return true; } public function promote_node($page_ref_id) { global $prefs; $page_info = $this->s_get_page_info($page_ref_id); $parent_info = $this->s_get_parent_info($page_ref_id); //If there is a parent and the parent isnt the structure root node. if (isset($parent_info) && $parent_info["parent_id"]) { //Make a space for the node after its parent $query = 'update `tiki_structures` set `pos`=`pos`+1 where `pos`>? and `parent_id`=?'; $this->query($query, [(int) $parent_info['pos'], (int) $parent_info['parent_id']]); //Move the node up one level $query = 'update `tiki_structures` set `parent_id`=?, `pos`=(? + 1) where `page_ref_id`=?'; $this->query($query, [(int) $parent_info['parent_id'], (int) $parent_info['pos'], (int) $page_ref_id]); //Remove the space that was created by the promotion $query = "update `tiki_structures` set `pos`=`pos`-1 where `pos`>? and `parent_id`=?"; $this->query($query, [(int) $page_info["pos"], (int) $page_info["parent_id"]]); if ($prefs['feature_user_watches'] == 'y') { include_once('lib/notifications/notificationemaillib.php'); sendStructureEmailNotification(['action' => 'move_up', 'page_ref_id' => $page_ref_id, 'parent_id' => $page_info['parent_id']]); } } } public function demote_node($page_ref_id) { $page_info = $this->s_get_page_info($page_ref_id); $parent_info = $this->s_get_parent_info($page_ref_id); $query = 'select `page_ref_id`, `pos` from `tiki_structures` where `pos` and `parent_id`=? order by `pos` desc'; $result = $this->query($query, [(int) $page_info['pos'], (int) $page_info['parent_id']]); if ($previous = $result->fetchRow()) { //Get last child nodes for previous sibling $query = 'select `pos` from `tiki_structures` where `parent_id`=? order by `pos` desc'; $result = $this->query($query, [(int) $previous['page_ref_id']]); if ($res = $result->fetchRow()) { $pos = $res['pos']; } else { $pos = 0; } $query = 'update `tiki_structures` set `parent_id`=?, `pos`=(? + 1) where `page_ref_id`=?'; $this->query($query, [(int) $previous['page_ref_id'], (int) $pos, (int) $page_ref_id]); //Remove the space created by the demotion $query = "update `tiki_structures` set `pos`=`pos`-1 where `pos`>? and `parent_id`=?"; $this->query($query, [(int) $page_info["pos"], (int) $page_info["parent_id"]]); global $prefs; if ($prefs['feature_user_watches'] == 'y') { include_once('lib/notifications/notificationemaillib.php'); sendStructureEmailNotification(['action' => 'move_down', 'page_ref_id' => $page_ref_id, 'parent_id' => $previous['page_ref_id']]); } } } public function move_after_next_node($page_ref_id) { $page_info = $this->s_get_page_info($page_ref_id); $query = 'select `page_ref_id`, `pos` from `tiki_structures` where `pos`>? and `parent_id`=? order by `pos` asc'; $result = $this->query($query, [(int) $page_info['pos'], (int) $page_info['parent_id']]); $res = $result->fetchRow(); if ($res) { //Swap position values $query = 'update `tiki_structures` set `pos`=? where `page_ref_id`=?'; $this->query($query, [(int) $page_info['pos'], (int) $res['page_ref_id']]); $this->query($query, [(int) $res['pos'], (int) $page_info['page_ref_id']]); } } public function move_before_previous_node($page_ref_id) { $page_info = $this->s_get_page_info($page_ref_id); $query = 'select `page_ref_id`, `pos` from `tiki_structures` where `pos` and `parent_id`=? order by `pos` desc'; $result = $this->query($query, [(int) $page_info['pos'], (int) $page_info['parent_id']]); $res = $result->fetchRow(); if ($res) { //Swap position values $query = 'update `tiki_structures` set `pos`=? where `page_ref_id`=?'; $this->query($query, [(int) $res['pos'], (int) $page_info['page_ref_id']]); $this->query($query, [(int) $page_info['pos'], (int) $res['page_ref_id']]); } elseif ($page_info['pos'] > 1) { // a bug occurred - try to fix $query = 'update `tiki_structures` set `pos`=? where `page_ref_id`=?'; $this->query($query, [$page_info['pos'] - 1, (int) $page_info['page_ref_id']]); } } /** * @param $data array - from from nestedSortable('toHierarchy') */ public function reorder_structure($data) { global $user; if (! empty($data)) { $parent_ref_id = $data[0]->structure_id; $structure_info = $this->s_get_structure_info($parent_ref_id); // "root" if (TikiLib::lib('tiki')->user_has_perm_on_object($user, $structure_info['pageName'], 'wiki page', 'tiki_p_edit_structures')) { $structure_id = $structure_info['structure_id']; $tiki_structures = TikiDb::get()->table('tiki_structures'); $orders = []; $conditions = ['structure_id' => (int) $structure_id]; foreach ($data as $node) { if ($node->item_id != 'root') { if (! isset($orders[$node->depth])) { $orders[$node->depth] = 1; } else { $orders[$node->depth]++; } $node->parent_id = $node->parent_id == 'root' || empty($node->parent_id) ? $parent_ref_id : $node->parent_id; $fields = [ 'parent_id' => $node->parent_id, 'pos' => $orders[$node->depth], 'page_alias' => $node->page_alias, ]; if ($node->item_id < 1000000) { $conditions['page_ref_id'] = (int) $node->item_id; $tiki_structures->update( $fields, $conditions ); } else { // new nodes with id > 1000000 $fields['page_id'] = TikiLib::lib('tiki')->get_page_id_from_name($node->page_name); $fields['structure_id'] = $structure_id; $tiki_structures->insert($fields); } } } return $structure_info; } } return false; } /** \brief Create a structure entry with the given name \param parent_id The parent entry to add this to. If NULL, create new structure. \param after_ref_id The entry to add this one after. If NULL, put it in position 0. \param name The wiki page to reference \param alias An alias for the wiki page name. \return the new entries page_ref_id or null if not created. */ public function s_create_page($parent_id, $after_ref_id, $name, $alias = '', $structure_id = null, $options = []) { global $prefs; $ret = null; $hide_toc = isset($options['hide_toc']) ? $options['hide_toc'] : 'n'; $creator = isset($options['creator']) ? $options['creator'] : tra('system'); $creator_msg = isset($options['creator_msg']) ? $options['creator_msg'] : tra('created from structure'); $ip_source = isset($options['ip_source']) ? $options['ip_source'] : '0.0.0.0'; $description = isset($options['description']) ? $options['description'] : ''; $lang = isset($options['lang']) ? $options['lang'] : ''; $is_html = isset($options['is_html']) ? $options['is_html'] : false; $hash = isset($options['hash']) ? $options['hash'] : false; $wysiwyg = isset($options['wysiwyg']) ? $options['wysiwyg'] : null; $wiki_authors_style = isset($options['wiki_authors_style']) ? $options['wiki_authors_style'] : ''; // If the page doesn't exist then create a new wiki page! $newpagebody = ''; if ($hide_toc !== 'y') { $newpagebody = tra("Table of contents") . ":" . "{toc}\n\n"; } $newpagebody .= isset($options['content']) ? $options['content'] : ''; $created = $this->page_exists($name); // If page exists if (! $created) { $created = $this->create_page( $name, 0, $newpagebody, $this->now, $creator_msg, $creator, $ip_source, $description, $lang, $is_html, $hash, $wysiwyg, $wiki_authors_style ); } if (! empty($parent_id) || $created || ! $this->page_is_in_structure($name)) { // if were not trying to add a duplicate structure head $query = 'select `page_id` from `tiki_pages` where `pageName`=?'; $page_id = $this->getOne($query, [$name]); if (! empty($after_ref_id)) { $max = $this->getOne('select `pos` from `tiki_structures` where `page_ref_id`=?', [(int) $after_ref_id]); } else { $max = 0; } if (! isset($after_ref_id)) { // after_ref_id The entry to add this one after. If NULL, put it in position 0. $max = 0; $query = 'update `tiki_structures` set `pos`=`pos`+1 where `pos`>? and `parent_id`=?'; $this->query($query, [(int) $max, (int) $parent_id]); } elseif ($after_ref_id != 0) { if ($max > 0) { //If max is 5 then we are inserting after position 5 so we'll insert 5 and move all // the others $query = 'update `tiki_structures` set `pos`=`pos`+1 where `pos`>? and `parent_id`=?'; $result = $this->query($query, [(int) $max, (int) $parent_id]); } } elseif (! $created) { $max = $this->getOne('select max(`pos`) from `tiki_structures` where `parent_id`=?', [(int) $parent_id]); } // //Create a new structure entry $max++; $query = 'insert into `tiki_structures`(`parent_id`,`page_id`,`page_alias`,`pos`, `structure_id`) values(?,?,?,?,?)'; $result = $this->query($query, [(int) $parent_id, (int) $page_id, $alias, (int) $max, (int) $structure_id]); //Get the page_ref_id just created if (isset($parent_id)) { $parent_check = ' and `parent_id`=?'; $attributes = [(int) $page_id,$alias,(int) $max, (int) $parent_id]; } else { $parent_check = ' and (`parent_id` is null or `parent_id`=0)'; $attributes = [(int) $page_id,$alias,(int) $max]; } $query = 'select `page_ref_id` from `tiki_structures` '; $query .= 'where `page_id`=? and `page_alias`=? and `pos`=?'; $query .= $parent_check; $ret = $this->getOne($query, $attributes); if (empty($parent_id)) { $query = 'update `tiki_structures` set `structure_id`=? where `page_ref_id`=?'; $this->query($query, [$ret, $ret]); } if ($prefs['feature_wiki_categorize_structure'] == 'y') { $this->categorizeNewStructurePage($name, $this->s_get_structure_info($parent_id)); } if ($prefs['feature_user_watches'] == 'y') { include_once('lib/notifications/notificationemaillib.php'); sendStructureEmailNotification(['action' => 'add', 'page_ref_id' => $ret, 'name' => $name]); } } return $ret; } /** * Categorizes a (new) page the same as the parent structure * Called from s_create_page if feature_wiki_categorize_structure = y * * @param string $page name of new page * @param array $structure_info structure info */ public function categorizeNewStructurePage($page, $structure_info) { $categlib = TikiLib::lib('categ'); $cat_type = 'wiki page'; $cat_href = "tiki-index.php?page=" . urlencode($page); $structObjectId = $categlib->is_categorized($cat_type, $structure_info["pageName"]); if ($structObjectId) { // structure is categorized $pageObjectId = $categlib->is_categorized($cat_type, $page); $structure_cats = $categlib->get_object_categories($cat_type, $structure_info["pageName"]); if (! $pageObjectId) { // added page is not categorized $pageObjectId = $categlib->add_categorized_object($cat_type, $page, '', $page, $cat_href); foreach ($structure_cats as $cat_acat) { $categlib->categorize($pageObjectId, $cat_acat); } } else { // added page is already categorized (somehow?) $cats = $categlib->get_object_categories($cat_type, $page); foreach ($structure_cats as $cat_acat) { if (! in_array($cat_acat, $cats, true)) { $categlib->categorize($pageObjectId, $cat_acat); } } } } } public function get_subtree($page_ref_id, $level = 0, $parent_pos = '') { $tikilib = TikiLib::lib('tiki'); $ret = []; $pos = 1; //The structure page is used as a title if ($level == 0) { $struct_info = $this->s_get_page_info($page_ref_id); $aux['first'] = true; $aux['last'] = true; $aux['pos'] = ''; $aux['page_ref_id'] = $struct_info['page_ref_id']; $aux['pageName'] = $struct_info['pageName']; $aux['page_alias'] = $struct_info['page_alias']; $wikilib = TikiLib::lib('wiki'); $is_locked = $wikilib->is_locked($struct_info['pageName']); if ($is_locked) { $aux['flag'] = 'L'; $aux['user'] = $is_locked; } $perms = $tikilib->get_perm_object($struct_info['pageName'], 'wiki page', '', false); $aux['editable'] = $perms['tiki_p_edit']; $aux['viewable'] = $perms['tiki_p_view']; $ret[] = $aux; $level++; } //Get all child nodes for this page_ref_id $query = 'select `page_ref_id`, `page_alias`, `pageName`, `flag`, `user`, `pos` as db_pos '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id` = tp.`page_id` and `parent_id`=? order by `pos` asc'; $result = $this->query($query, [(int) $page_ref_id]); $subs = []; $row_max = $result->numRows(); while ($res = $result->fetchRow()) { //Add $aux['first'] = ($pos == 1); $aux['db_pos'] = $res['db_pos']; $aux['last'] = false; $aux['page_ref_id'] = $res['page_ref_id']; $aux['pageName'] = $res['pageName']; $aux['page_alias'] = $res['page_alias']; $aux["flag"] = $res["flag"]; $aux["user"] = $res["user"]; global $user; if ($this->user_has_perm_on_object($user, $res['pageName'], 'wiki page', 'tiki_p_edit')) { $aux['editable'] = 'y'; $aux['viewable'] = 'y'; } else { $aux['editable'] = 'n'; if ($this->user_has_perm_on_object($user, $res['pageName'], 'wiki page', 'tiki_p_view')) { $aux['viewable'] = 'y'; } else { $aux['viewable'] = 'n'; } } if (strlen($parent_pos) == 0) { $aux['pos'] = "$pos"; } else { $aux['pos'] = $parent_pos . '.' . "$pos"; } $ret[] = $aux; //Recursively add any child nodes $subs = $this->get_subtree($res['page_ref_id'], ($level + 1), $aux['pos']); if (isset($subs)) { $ret = array_merge($ret, $subs); } // Insert a dummy entry to close table/list if ($pos == $row_max) { $aux['first'] = false; $aux['last'] = true; $ret[] = $aux; } $pos++; } return $ret; } /**Returns an array of page_info arrays This can be used to construct a path from the structure head to the requested page. */ public function get_structure_path($page_ref_id) { global $prefs; $structure_path = []; $page_info = $this->s_get_page_info($page_ref_id); if ($page_info['parent_id']) { $structure_path = $this->get_structure_path($page_info['parent_id']); } $structure_path[] = $page_info; foreach ($structure_path as $key => $value) { if ( $prefs['namespace_indicator_in_structure'] === 'y' && ! empty($prefs['namespace_separator']) && strpos($value['pageName'], $prefs['namespace_separator']) !== false ) { $arr = explode($prefs['namespace_separator'], $value['pageName']); $structure_path[$key]['stripped_pageName'] = end($arr); } else { $structure_path[$key]['stripped_pageName'] = $value['pageName']; } } return $structure_path; } /* get all the users that watches a page or a page above */ public function get_watches($pageName = '', $page_ref_id = 0, $recurs = true) { global $tiki_p_watch_structure; if ($tiki_p_watch_structure != 'y') { return []; } $query = "SELECT ts.`parent_id`,tuw.`email`,tuw.`user`, tuw.`event`"; $query .= " FROM `tiki_structures` ts"; $query .= " LEFT JOIN ( SELECT watchId, user, event, object, title, type, url, email FROM `tiki_user_watches` UNION DISTINCT SELECT watchId, uu.login as user, event, object, title, type, url, uu.email FROM `tiki_group_watches` tgw INNER JOIN users_usergroups ug ON tgw.`group` = ug.groupName INNER JOIN users_users uu ON ug.userId = uu.userId AND uu.email IS NOT NULL AND uu.email <> '' ) tuw ON (tuw.`object`=ts.`page_ref_id` AND tuw.`event`=?)"; if (empty($page_ref_id)) { $query .= " LEFT JOIN `tiki_pages` tp ON ( tp.`page_id`=ts.`page_id`)"; $query .= " WHERE tp.`pageName`=?"; $result = $this->query($query, ['structure_changed', $pageName]); } else { $query .= " WHERE ts.`page_ref_id`=?"; $result = $this->query($query, ['structure_changed', $page_ref_id]); } $ret = []; while ($res = $result->fetchRow()) { $parent_id = $res['parent_id']; unset($res['parent_id']); if (! empty($res['email']) || ! empty($res['user'])) { $ret[] = $res; } } if (! empty($parent_id) && $recurs) { $ret2 = $this->get_watches('', $parent_id); if (! empty($ret2)) { $ret = array_merge($ret2, $ret); } } return $ret; } /**Returns a structure_info array See get_page_info for details of array */ public function s_get_structure_info($page_ref_id) { $parent_id = $this->getOne('select `parent_id` from `tiki_structures` where `page_ref_id`=?', [(int) $page_ref_id]); if (! $parent_id) { return $this->s_get_page_info($page_ref_id); } return $this->s_get_structure_info($parent_id); } /**Returns an array of info about the parent page_ref_id See get_page_info for details of array */ public function s_get_parent_info($page_ref_id) { // Try to get the parent of this page $parent_id = $this->getOne('select `parent_id` from `tiki_structures` where `page_ref_id`=?', [(int) $page_ref_id]); if (! $parent_id) { return null; } return ($this->s_get_page_info($parent_id)); } public function use_user_language_preferences($langContext = null) { global $prefs; if ($prefs['feature_multilingual'] != 'y') { return; } if ($prefs['feature_multilingual_structures'] != 'y') { return; } $multilinguallib = TikiLib::lib('multilingual'); $this->displayLanguageOrder = $multilinguallib->preferredLangs($langContext); } public function build_language_order_clause(&$args, $pageTable = 'tp', $structTable = 'ts') { $query = " CASE\n"; // Languages in preferences go first foreach ($this->displayLanguageOrder as $key => $lang) { $query .= "\tWHEN $pageTable.lang = ? THEN ?\n"; $args[] = $lang; $args[] = $key; } // If nothing in preferences, use structure default $query .= "\tWHEN $structTable.page_id = $pageTable.page_id THEN ?\n"; $args[] = count($this->displayLanguageOrder); // Else should never be required $query .= "\tELSE ?\nEND\n"; $args[] = count($this->displayLanguageOrder) + 1; return $query; } /** Return an array of page info */ public function s_get_page_info($page_ref_id) { if (empty($this->displayLanguageOrder)) { $query = 'select `pos`, `page_ref_id`, `parent_id`, ts.`page_id`, `pageName`, `page_alias`, `structure_id` '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and `page_ref_id`=?'; $result = $this->query($query, [(int) $page_ref_id]); } else { $args = [ (int) $page_ref_id ]; $query = " SELECT `pos`, `page_ref_id`, `parent_id`, ts.`page_id`, `pageName`, `page_alias`, `structure_id` FROM `tiki_structures` ts LEFT JOIN tiki_translated_objects a ON a.type = 'wiki page' AND a.objId = ts.page_id LEFT JOIN tiki_translated_objects b ON b.type = 'wiki page' AND a.traId = b.traId LEFT JOIN `tiki_pages` tp ON b.`objId` = tp.`page_id` OR ts.page_id = tp.page_id WHERE `page_ref_id` = ? ORDER BY " . $this->build_language_order_clause($args) . " LIMIT 1"; $result = $this->query($query, $args); } if ($res = $result->fetchRow()) { return $res; } else { return null; } } // that is intended to replace the get_subtree_toc and get_subtree_toc_slide // it's used only in {toc} thing hardcoded in parse tikilib->parse -- (mose) // the $tocPrefix can be used to Prefix a subtree as it would start from a given number (e.g. 2.1.3) public function build_subtree_toc($id, $slide = false, $order = 'asc', $tocPrefix = '') { global $user, $tikilib, $prefs; $ret = []; $cant = $this->getOne('select count(*) from `tiki_structures` where `parent_id`=?', [(int) $id]); if ($cant) { // TODO : FIX $args = []; if (! $this->displayLanguageOrder) { $query = 'select `page_ref_id`, `pageName`, `page_alias`, tp.`description` from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and `parent_id`=? order by ' . $this->convertSortMode('pos_' . $order); $args[] = (int) $id; } else { $query = " SELECT `page_ref_id`, `pageName`, `page_alias`, tp.`description` FROM `tiki_structures` ts INNER JOIN tiki_pages tp ON tp.page_id = ( SELECT tp.page_id FROM `tiki_pages` tr LEFT JOIN tiki_translated_objects a ON tr.page_id = a.objId AND a.type = 'wiki page' LEFT JOIN tiki_translated_objects b ON b.type = 'wiki page' AND a.traId = b.traId LEFT JOIN tiki_pages tp ON b.objId = tp.page_id OR tr.page_id = tp.page_id WHERE tr.page_id = ts.page_id ORDER BY " . $this->build_language_order_clause($args) . " LIMIT 1 ) WHERE parent_id = ? order by " . $this->convertSortMode('pos_' . $order); $args[] = (int) $id; } $result = $this->query($query, $args); $prefix = 1; while ($res = $result->fetchRow()) { if (! $tikilib->user_has_perm_on_object($user, $res['pageName'], 'wiki page', 'tiki_p_view')) { continue; } if ( $prefs['namespace_indicator_in_structure'] === 'y' && ! empty($prefs['namespace_separator']) && ! empty($res['pageName']) && strpos($res['pageName'], $prefs['namespace_separator']) !== false ) { $arr = explode($prefs['namespace_separator'], $res['pageName']); $res['short_pageName'] = end($arr); } else { $res['short_pageName'] = $res['pageName']; } $res['prefix'] = ($tocPrefix == '') ? '' : "$tocPrefix."; $res['prefix'] .= $prefix; $prefix++; if ($res['page_ref_id'] != $id) { $sub = $this->build_subtree_toc($res['page_ref_id'], $slide, $order, $res['prefix']); if (is_array($sub)) { $res['sub'] = $sub; } } //if ($res['page_alias']<>'') $res['pageName']=$res['page_alias']; $back[] = $res; } } else { return false; } return $back; } public function get_toc($page_ref_id, $order = 'asc', $showdesc = false, $numbering = true, $numberPrefix = '', $type = 'plain', $page = '', $maxdepth = 0, $mindepth = 0, $sortalpha = 0, $structurePageName = '') { global $user, $prefs; $structure_tree = $this->build_subtree_toc($page_ref_id, false, $order, $numberPrefix); if ($type === 'admin') { // check perms here as we still have $page_ref_id $structure_info = $this->s_get_structure_info($page_ref_id); $perms = Perms::get('wiki page', $structure_info["pageName"]); if ($prefs['lock_wiki_structures'] === 'y') { $lockedby = TikiLib::lib('attribute')->get_attribute('wiki structure', $structure_info['pageName'], 'tiki.object.lock'); if ($lockedby && $lockedby === $user && $perms->lock_structures || ! $lockedby || $perms->admin_structures) { $editable = $perms->edit_structures; } else { $editable = false; } } else { $editable = $perms->edit_structures; } if (! $editable) { $type = 'plain'; } else { TikiLib::lib('smarty')->assign('structure_name', $structure_info["pageName"]); $json_params = json_encode( [ 'page_ref_id' => $page_ref_id, 'order' => $order, 'showdesc' => $showdesc, 'numbering' => $numbering, 'numberPrefix' => $numberPrefix, 'type' => $type, 'page' => $page, 'maxdepth' => $maxdepth, 'mindepth' => $mindepth, 'sortalpha' => $sortalpha, 'structurePageName' => $structurePageName ] ); TikiLib::lib('smarty')->assign('json_params', $json_params); } } if ($structure_tree != '') { if ($mindepth > 0) { $currentLevel = $structure_tree; for ($i = 0; $i < $mindepth; $i++) { $deeperLevel = []; if ($currentLevel != '') { foreach ($currentLevel as $leaf) { if (isset($leaf['sub']) && is_array($leaf['sub'])) { foreach ($leaf['sub'] as $sub) { $deeperLevel[] = $sub; } } } } $currentLevel = $deeperLevel; } if ($maxdepth > 0) { $maxdepth = $maxdepth - $mindepth; if ($maxdepth <= 0) { $maxdepth = 1; } } $structure_tree = $currentLevel; } if ($sortalpha == 'alpha') { if ($order == 'asc') { usort($structure_tree, [$this, 'compareByPageName']); } else { usort($structure_tree, [$this, 'compareByPageNameDesc']); } } } $nodelist = $this->fetch_toc($structure_tree, $showdesc, $numbering, $type, $page, $maxdepth, 0, $structurePageName); if ($type === 'admin' && empty($nodelist)) { $nodelist = "