0byt3m1n1
Path:
/
data
/
applications
/
aps
/
tikiwiki
/
7.0-0
/
standard
/
htdocs
/
lib
/
structures
/
[
Home
]
File: structlib.php
<?php // (c) Copyright 2002-2011 by authors of the Tiki Wiki CMS Groupware Project // // All Rights Reserved. See copyright.txt for details and a complete list of authors. // Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. // $Id: structlib.php 34804 2011-06-07 11:52:05Z jonnybradley $ //this script may only be included - so its better to die if called directly. if (strpos($_SERVER['SCRIPT_NAME'],basename(__FILE__)) !== false) { header('location: index.php'); exit; } class StructLib extends TikiLib { var $displayLanguageOrder; function __construct() { global $prefs; parent::__construct(); $this->displayLanguageOrder = array(); } 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 ''; } 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"); } //node is a place holder for last in level else { $level--; } } } 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(array('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,array((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, array((int)$page_info['page_id'])); global $wikilib; include_once('lib/wiki/wikilib.php'); 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,array((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, array((int)$page_ref_id)); return true; } 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,array((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, array((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,array((int)$page_info["pos"], (int)$page_info["parent_id"])); if ($prefs['feature_user_watches'] == 'y') { include_once('lib/notifications/notificationemaillib.php'); sendStructureEmailNotification(array('action'=>'move_up', 'page_ref_id'=>$page_ref_id, 'parent_id'=>$page_info['parent_id'])); } } } 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,array((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,array((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, array((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,array((int)$page_info["pos"], (int)$page_info["parent_id"])); if ($prefs['feature_user_watches'] == 'y') { include_once('lib/notifications/notificationemaillib.php'); sendStructureEmailNotification(array('action'=>'move_down', 'page_ref_id'=>$page_ref_id, 'parent_id'=>$previous['page_ref_id'])); } } } 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,array((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,array((int)$page_info['pos'], (int)$res['page_ref_id']) ); $this->query($query,array((int)$res['pos'], (int)$page_info['page_ref_id']) ); } } 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,array((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,array((int)$res['pos'], (int)$page_info['page_ref_id']) ); $this->query($query,array((int)$page_info['pos'], (int)$res['page_ref_id']) ); } elseif ($page_info['pos'] > 1) { // a bug occured - try to fix $query = 'update `tiki_structures` set `pos`=? where `page_ref_id`=?'; $this->query($query,array($page_info['pos']-1, (int)$page_info['page_ref_id']) ); } } /** \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. */ function s_create_page($parent_id, $after_ref_id, $name, $alias='', $structure_id=null) { global $prefs; $ret = null; // If the page doesn't exist then create a new wiki page! $newpagebody = tra("Table of contents") . ":" . "{toc}"; $created = $this->create_page($name, 0, $newpagebody, $this->now, tra('created from structure'), 'system', '0.0.0.0', '', false, '', array('parent_id'=>$parent_id)); 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,array($name)); if (!empty($after_ref_id)) { $max = $this->getOne('select `pos` from `tiki_structures` where `page_ref_id`=?',array((int)$after_ref_id)); } else { $max = 0; } if ($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,array((int)$max, (int)$parent_id)); } } else if (!$created) { $max = $this->getOne('select max(`pos`) from `tiki_structures` where `parent_id`=?',array((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,array((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 = array((int)$page_id,$alias,(int)$max, (int)$parent_id); } else { $parent_check = ' and (`parent_id` is null or `parent_id`=0)'; $attributes = array((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, array($ret, $ret)); } if ($prefs['feature_user_watches'] == 'y') { include_once('lib/notifications/notificationemaillib.php'); sendStructureEmailNotification(array('action'=>'add', 'page_ref_id'=>$ret, 'name'=>$name)); } } return $ret; } function get_subtree($page_ref_id, $level = 0, $parent_pos = '') { global $tikilib; $ret = array(); $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']; global $wikilib; include_once('lib/wiki/wikilib.php'); $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,array((int)$page_ref_id)); $subs = array(); $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. */ function get_structure_path($page_ref_id) { $structure_path = array(); $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; return $structure_path; } /* get all the users that watches a page or a page above */ function get_watches($pageName='', $page_ref_id=0, $recurs=true) { global $tiki_p_watch_structure; if ($tiki_p_watch_structure != 'y') { return array(); } $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, array('structure_changed', $pageName)); } else { $query .= " WHERE ts.`page_ref_id`=?"; $result = $this->query($query, array('structure_changed', $page_ref_id)); } $ret = array(); 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 */ function s_get_structure_info($page_ref_id) { $parent_id = $this->getOne('select `parent_id` from `tiki_structures` where `page_ref_id`=?', array((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 */ 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`=?',array((int)$page_ref_id)); if (!$parent_id) return null; return ($this->s_get_page_info($parent_id)); } function use_user_language_preferences( $langContext = null ) { global $prefs, $multilinguallib; if( $prefs['feature_multilingual'] != 'y' ) return; if( $prefs['feature_multilingual_structures'] != 'y' ) return; if( !$multilinguallib ) include_once('lib/multilingual/multilinguallib.php'); $this->displayLanguageOrder = $multilinguallib->preferredLangs( $langContext ); } 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 */ 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,array((int)$page_ref_id)); } else { $args = array( (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) function build_subtree_toc($id,$slide=false,$order='asc',$tocPrefix='') { global $user, $tikilib; $ret = array(); $cant = $this->getOne('select count(*) from `tiki_structures` where `parent_id`=?',array((int)$id)); if ($cant) { // TODO : FIX $args = array(); 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; } $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; } function get_toc($page_ref_id,$order='asc',$showdesc=false,$numbering=true,$numberPrefix='',$type='plain',$page='',$maxdepth=0, $structurePageName='') { global $smarty; $structure_tree = $this->build_subtree_toc($page_ref_id,false,$order,$numberPrefix); return $this->fetch_toc($structure_tree,$showdesc,$numbering,$type,$page,$maxdepth,0,$structurePageName)."\n"; } function fetch_toc($structure_tree,$showdesc,$numbering,$type='plain',$page='',$maxdepth=0,$cur_depth=0,$structurePageName='') { global $smarty; $ret=''; if ($structure_tree != '') { if (($maxdepth <= 0) || ($cur_depth < $maxdepth)) { $smarty->assign('leafspace',str_repeat("\t",$cur_depth*2)); $ret.="<!--depth: $cur_depth-->\n".$smarty->fetch('structures_toc-startul.tpl')."\n"; foreach($structure_tree as $leaf) { if ($leaf["pageName"]==$page) { $smarty->assign('hilite',true); } else { $smarty->assign('hilite',false); } $smarty->assign('structurePageName',$structurePageName); $smarty->assign_by_ref('structure_tree',$leaf); $smarty->assign('showdesc',$showdesc); $smarty->assign('numbering',$numbering); $smarty->assign('toc_type',$type); $smarty->assign('leafspace',str_repeat("\t",$cur_depth*2)); $ret.=$smarty->fetch('structures_toc-leaf.tpl'); if(isset($leaf['sub']) && is_array($leaf['sub'])) { $ret.=$this->fetch_toc($leaf['sub'],$showdesc,$numbering,$type,$page,$maxdepth,$cur_depth+1, $structurePageName).str_repeat("\t",($cur_depth*2)+1)."</li>\n"; } else { $ret.=str_repeat("\t",($cur_depth*2)+1)."</li>\n"; } } $smarty->assign('leafspace',str_repeat("\t",$cur_depth*2)); $ret.=$smarty->fetch('structures_toc-endul.tpl')."\n"; } } return $ret; } // end of replacement function page_is_in_structure($pageName) { $query = 'select count(*) '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and `pageName`=?'; $cant = $this->getOne($query,array($pageName)); return $cant; } //Is this page the head page for a structure? function get_struct_ref_if_head($pageName) { $query = 'select `page_ref_id` '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and (`parent_id` is null or `parent_id`=0) and `pageName`=?'; $page_ref_id = $this->getOne($query,array($pageName)); if( $page_ref_id ) return $page_ref_id; if( !$this->displayLanguageOrder ) return null; $query = " SELECT page_ref_id FROM tiki_structures ts INNER JOIN tiki_translated_objects a ON ts.page_id = a.objId AND a.type = 'wiki page' INNER JOIN tiki_translated_objects b ON a.traId = b.traId AND b.type = 'wiki page' INNER JOIN tiki_pages tp ON b.objId = tp.page_id WHERE (parent_id IS NULL or parent_id = 0) AND pageName = ?"; $page_ref_id = $this->getOne($query,array($pageName)); return $page_ref_id; } //Get reference id for a page function get_struct_ref_id($pageName) { $query = 'select `page_ref_id` '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and `pageName`=?'; $page_ref_id = $this->getOne($query,array($pageName)); return $page_ref_id; } function get_next_page($page_ref_id, $deep = true) { // If we have children then get the first child if ($deep) { $query = 'select `page_ref_id` '; $query .= 'from `tiki_structures` ts '; $query .= 'where `parent_id`=? '; $query .= 'order by '.$this->convertSortMode('pos_asc'); $result1 = $this->query($query,array((int)$page_ref_id)); if ($result1->numRows()) { $res = $result1->fetchRow(); return $res['page_ref_id']; } } // Try to get the next page with the same parent as this $page_info = $this->s_get_page_info($page_ref_id); $parent_id = $page_info['parent_id']; $page_pos = $page_info['pos']; if (!$parent_id) return null; $query = 'select `page_ref_id` '; $query .= 'from `tiki_structures` ts '; $query .= 'where `parent_id`=? and `pos`>? '; $query .= 'order by '.$this->convertSortMode('pos_asc'); $result2 = $this->query($query,array((int)$parent_id, (int)$page_pos)); if ($result2->numRows()) { $res = $result2->fetchRow(); return $res['page_ref_id']; } else { return $this->get_next_page($parent_id, false); } } function get_prev_page($page_ref_id, $deep = false) { //Drill down to last child for this tree node if ($deep) { $query = 'select `page_ref_id` '; $query .= 'from `tiki_structures` ts '; $query .= 'where `parent_id`=? '; $query .= 'order by '.$this->convertSortMode('pos_desc'); $result = $this->query($query,array($page_ref_id)); if ($result->numRows()) { //There are more children $res = $result->fetchRow(); $page_ref_id = $this->get_prev_page($res['page_ref_id'], true); } return $page_ref_id; } // Try to get the previous page with the same parent as this $page_info = $this->s_get_page_info($page_ref_id); $parent_id = $page_info['parent_id']; $pos = $page_info['pos']; //At the top of the tree if (!isset($parent_id)) return null; $query = 'select `page_ref_id` '; $query .= 'from `tiki_structures` ts '; $query .= 'where `parent_id`=? and `pos`<? '; $query .= 'order by '.$this->convertSortMode('pos_desc'); $result = $this->query($query,array((int)$parent_id, (int)$pos)); if ($result->numRows()) { //There is a previous sibling $res = $result->fetchRow(); $page_ref_id = $this->get_prev_page($res['page_ref_id'], true); } else { //No previous siblings, just the parent $page_ref_id = $parent_id; } return $page_ref_id; } function get_navigation_info($page_ref_id) { $struct_nav_pages = array(); // Get structure info for this page $prev_page_ref_id = $this->get_prev_page($page_ref_id); $next_page_ref_id = $this->get_next_page($page_ref_id); $struct_nav_pages['prev'] = null; if (isset($prev_page_ref_id)) { $struct_nav_pages['prev'] = $this->s_get_page_info($prev_page_ref_id); } $struct_nav_pages['next'] = null; if (isset($next_page_ref_id)) { $struct_nav_pages['next'] = $this->s_get_page_info($next_page_ref_id); } $struct_nav_pages['parent'] = $this->s_get_parent_info($page_ref_id); $struct_nav_pages['home'] = $this->s_get_structure_info($page_ref_id); return $struct_nav_pages; } /** Return an array of subpages Used by the 'After Page' select box */ function s_get_pages($parent_id) { $ret = array(); $query = 'select `pos`, `page_ref_id`, `parent_id`, ts.`page_id`, `pageName`, `page_alias` '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and `parent_id`=? '; $query .= 'order by '.$this->convertSortMode('pos_asc'); $result = $this->query($query,array((int)$parent_id)); while ($res = $result->fetchRow()) { //$ret[] = $this->populate_page_info($res); $ret[] = $res; } return $ret; } /** Get a list of all structures this page is a member of */ function get_page_structures($pageName,$structure='') { $ret = array(); $structures_added = array(); if( empty( $this->displayLanguageOrder ) ) { $query = 'select `page_ref_id` '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and `pageName`=?'; } else { $query = " SELECT DISTINCT `page_ref_id` FROM tiki_structures ts LEFT JOIN tiki_translated_objects a ON a.objId = ts.page_id AND a.type = 'wiki page' LEFT JOIN tiki_translated_objects b ON a.traId = b.traId AND b.type = 'wiki page' LEFT JOIN tiki_pages tp ON ts.page_id = tp.page_id OR b.objId = tp.page_id WHERE pageName = ?"; } $result = $this->query($query,array($pageName)); while ($res = $result->fetchRow()) { $next_page = $this->s_get_structure_info($res['page_ref_id']); //Add each structure head only once if (!in_array($next_page['page_ref_id'], $structures_added)) { if(empty($structure) || $structure == $next_page['pageName']) { $structures_added[] = $next_page['page_ref_id']; $next_page['req_page_ref_id'] = $res['page_ref_id']; $ret[] = $next_page; } } } return $ret; } function get_max_children($page_ref_id) { $query = 'select `page_ref_id` from `tiki_structures` where `parent_id`=?'; $result = $this->query($query,array((int)$page_ref_id)); if (!$result->numRows()) { return ''; } $res = $result->fetchRow(); return $res; } /** Return a unique list of pages belonging to the structure \return An array of page_info arrays */ function s_get_structure_pages_unique($page_ref_id) { $ret = array(); // Add the structure page as well $ret[] = $this->s_get_page_info($page_ref_id); $ret2 = $this->s_get_structure_pages($page_ref_id); return array_unique(array_merge($ret, $ret2)); } /** Return all the pages belonging to a structure \param Page reference ID in struct table \return An array of page_info arrays */ function s_get_structure_pages($page_ref_id) { $ret = array(); if ($page_ref_id) { $ret[0] = $this->s_get_page_info($page_ref_id); $query = 'select `pos`, `page_ref_id`, `parent_id`, ts.`page_id`, `pageName`, `page_alias` '; $query .= 'from `tiki_structures` ts, `tiki_pages` tp '; $query .= 'where ts.`page_id`=tp.`page_id` and `parent_id`=? '; $query .= 'order by '.$this->convertSortMode('pos_asc'); $result = $this->query($query,array((int)$page_ref_id)); while ($res = $result->fetchRow()) { $ret = array_merge($ret,$this->s_get_structure_pages($res['page_ref_id'])); } } return $ret; } function list_structures($offset, $maxRecords, $sort_mode, $find='', $exact_match = true, $filter = '') { if ($find) { if (!$exact_match && $find) { $find = preg_replace("/(\w+)/","%\\1%",$find); $find = preg_split("/[\s]+/",$find,-1,PREG_SPLIT_NO_EMPTY); $mid = " where (`parent_id` is null or `parent_id`=0) and (tp.`pageName` like ".implode(' or tp.`pageName` like ',array_fill(0,count($find),'?')).")"; $bindvars = $find; } else { $mid = ' where (`parent_id` is null or `parent_id`=0) and (tp.`pageName` like ?)'; $findesc = '%' . $find . '%'; $bindvars=array($findesc); } } else { $mid = ' where (`parent_id` is null or `parent_id`=0) '; $bindvars=array(); } $join_tables = ' inner join `tiki_pages` tp on (tp.`page_id`= ts.`page_id`)'; $join_bindvars = array(); if (!empty($filter)) { foreach ($filter as $type=>$val) { if ($type == 'categId') { $join_tables .= " inner join `tiki_objects` as tob on (tob.`itemId`= tp.`pageName` and tob.`type`= ?) inner join `tiki_category_objects` as tc on (tc.`catObjectId`=tob.`objectId` and tc.`categId`=?) "; $join_bindvars = array('wiki page', $val); } elseif ($type == 'lang') { $mid .= empty($mid)? ' where ': ' and '; $mid .= '`lang`=? '; $bindvars[] = $val; } } } if (!empty($join_bindvars)) { $bindvars = empty($bindvars)? $join_bindvars : array_merge($join_bindvars, $bindvars); } $query = "select `page_ref_id`,`parent_id`,ts.`page_id`,`page_alias`,`pos`, `pageName`,tp.`hits`,`data`,tp.`description`,`lastModif`,`comment`,`version`, `user`,`ip`,`flag`,`points`,`votes`,`cache`,`wiki_cache`,`cache_timestamp`, `pageRank`,`creator`,`page_size` from `tiki_structures` as ts $join_tables $mid order by ".$this->convertSortMode($sort_mode); $query_cant = "select count(*) from `tiki_structures` ts $join_tables $mid"; $result = $this->query($query,$bindvars,$maxRecords,$offset); $cant = $this->getOne($query_cant,$bindvars); $ret = array(); while ($res = $result->fetchRow()) { global $user; if ( $this->user_has_perm_on_object($user,$res['pageName'],'wiki page','tiki_p_view') ) { if(file_exists('whelp/'.$res['pageName'].'/index.html')) { $res['webhelp']='y'; } else { $res['webhelp']='n'; } if ( $this->user_has_perm_on_object($user,$res['pageName'],'wiki page','tiki_p_edit') ) { $res['editable']='y'; } else { $res['editable']='n'; } $ret[] = $res; } // end check for perm if } $retval = array(); $retval['data'] = $ret; $retval['cant'] = $cant; return $retval; } function get_page_alias($page_ref_id) { $query = 'select `page_alias` from `tiki_structures` where `page_ref_id`=?'; $res = $this->getOne($query, array((int)$page_ref_id)); return $res; } function set_page_alias($page_ref_id, $pageAlias) { $query = 'update `tiki_structures` set `page_alias`=? where `page_ref_id`=?'; $this->query($query, array($pageAlias, (int)$page_ref_id)); } //This nifty function creates a static WebHelp version using a TikiStructure as //the base. function structure_to_webhelp($page_ref_id, $dir, $top) { global $style_base; global $prefs; //The first task is to convert the structure into an array with the //proper format to produce a WebHelp project. //We have to create something in the form //$pages=Array('root'=>Array('pag1'=>'','pag2'=>'','page3'=>Array(...))); //Where the name is the pageName|description and the other side is either '' //when the page is a leaf or an Array of pages when the page is a folder //Folders that are not TikiPages are known for having only a name instead //of name|description $tree = '$tree=Array('.$this->structure_to_tree($page_ref_id).');'; eval($tree); //Now we have the tree in $tree! $menucode="foldersTree = gFld(\"Contents\", \"content.html\")\n"; $menucode.=$this->traverse($tree); $base = "whelp/$dir"; copy("$base/menu/options.cfg","$base/menu/menuNodes.js"); $fw = fopen("$base/menu/menuNodes.js",'a+'); fwrite($fw,$menucode); fclose($fw); $docs = Array(); $words = Array(); $index = Array(); $first=true; $pages = $this->traverse2($tree); // Now loop the pages foreach($pages as $page) { $query = 'select * from `tiki_pages` where `pageName`=?'; $result = $this->query($query,array($page)); $res = $result->fetchRow(); $docs[] = $res['pageName']; if(empty($res['description'])) $res['description']=$res['pageName']; $pageName=$res['pageName'].'|'.$res['description']; $dat = $this->parse_data($res['data']); //Now dump the page $dat = preg_replace("/tiki-index.php\?page=([^\'\" ]+)/","$1.html",$dat); $dat = str_replace('?nocache=1','',$dat); $cs = ''; $data = "<html><head><script src=\"../js/highlight.js\"></script><link rel=\"StyleSheet\" href=\"../../../styles/$style_base.css\" type=\"text/css\" /><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>".$res["pageName"]."</title></head><body style=\"padding:10px\" onload=\"doProc();\">$cs<div id='tiki-center'><div class='wikitext'>".$dat.'</div></div></body></html>'; $fw=fopen("$base/pages/".$res['pageName'].'.html','wb+'); fwrite($fw,$data); fclose($fw); unset($dat); $page_words = preg_split("/[^A-Za-z0-9\-_]/",$res['data']); foreach($page_words as $word) { $word=strtolower($word); if(strlen($word)>3 && preg_match("/^[A-Za-z][A-Za-z0-9\_\-]*[A-Za-z0-9]$/",$word)) { if(!in_array($word,$words)) { $words[] = $word; $index[$word]=Array(); } if(!in_array($res['pageName'].'|'.$res['description'],$index[$word])) { $index[$word][] = $res['pageName'].'|'.$res['description']; } } } } sort($words); $i=0; $fw = fopen("$base/js/searchdata.js",'w'); fwrite($fw,"keywords = new Array();\n"); foreach($words as $word) { fwrite($fw,"keywords[$i] = Array(\"$word\",Array("); $first=true; foreach($index[$word] as $doc) { if(!$first) {fwrite($fw,',');} else {$first=false;} fwrite($fw,'"'.$doc.'"'); } fwrite($fw,"));\n"); $i++; } fclose($fw); // write the title page, using: // Browser Title, Logo, Site Title, Site subtitle $fw = fopen("$base/content.html",'w+'); $titlepage = "<h1>". $prefs['browsertitle'] . "</h1><p><img src='../../".$prefs['sitelogo_src']."' alt='".$prefs['sitelogo_alt']."' align='center' /></p><h2>". $prefs['sitetitle'] ."</h2><h3>". $prefs['sitesubtitle'] ."</h3>"; fwrite($fw, $titlepage); fclose($fw); } function structure_to_tree($page_ref_id) { $query = 'select * from `tiki_structures` ts,`tiki_pages` tp where tp.`page_id`=ts.`page_id` and `page_ref_id`=?'; $result = $this->query($query,array((int)$page_ref_id)); $res = $result->fetchRow(); if(empty($res['description'])) $res['description']=$res['pageName']; $name = str_replace("'","\'",$res['description'].'|'.$res['pageName']); $code = ''; $code.= "'$name'=>"; $query = 'select * from `tiki_structures` ts, `tiki_pages` tp where tp.`page_id`=ts.`page_id` and `parent_id`=?'; $result = $this->query($query,array((int)$page_ref_id)); if($result->numRows()) { $code.='Array('; $first = true; while($res=$result->fetchRow()) { if(!$first) { $code.=','; } else { $first = false; } $code.=$this->structure_to_tree($res['page_ref_id']); } $code.=')'; } else { $code.="''"; } return $code; } function traverse($tree,$parent='') { $code=''; foreach($tree as $name => $node) { list($name,$link) = explode('|',$name); if(is_array($node)) { //New folder node is parent++ folder parent is paren $new = $parent . 'A'; $code.='foldersTree'.$new."=insFld(foldersTree$parent,gFld(\"$name\",\"pages/$link.html\"));\n"; $code.=$this->traverse($node,$new); } else { $code.="insDoc(foldersTree$parent,gLnk(\"R\",\"$name\",\"pages/$link.html\"));\n"; } } return $code; } function traverse2($tree) { $pages = Array(); foreach($tree as $name => $node) { list($name,$link) = explode('|',$name); if(is_array($node)) { if(isset($name) && isset($link)) { $pageName = $link; $pages[] = $pageName; } $pages2 = $this->traverse2($node); foreach($pages2 as $elem) { $pages[] = $elem; } } else { $pages[] = $link; } } return $pages; } function move_to_structure($page_ref_id, $structure_id, $begin=true) { $page_info = $this->s_get_page_info($page_ref_id); $query = "update `tiki_structures` set `pos`=`pos`-1 where `pos`>? and `parent_id`=?"; $this->query($query, array((int)$page_info["pos"], (int)$page_info["parent_id"])); if ($begin) { $query = "update `tiki_structures` set `pos`=`pos`+1 where `parent_id`=?"; $this->query($query, array($structure_id)); $pos = 1; $query = "update `tiki_structures` set `parent_id`=?, `pos`=? where `page_ref_id`=?"; $this->query($query, array($structure_id, $pos+1, $page_ref_id)); } else { $query = "select max(`pos`) from `tiki_structures` where `parent_id`=?"; $pos = $this->getOne($query, array($structure_id)); $query = "update `tiki_structures` set `parent_id`=?, `pos`=? where `page_ref_id`=?"; $this->query($query, array($structure_id, $pos+1, $page_ref_id)); } } /* transform a structure into a menu */ function to_menu($channels, $structure, $sectionLevel=0, $cumul=0) { global $smarty; include_once('lib/smarty_tiki/function.sefurl.php'); $options = array(); $cant = 0; if (empty($channels)) { return array('cant'=>0, 'data'=>array()); } foreach ($channels as $channel) { if (empty($channel['sub'])) { if (isset($options[$cant-1]['sectionLevel'])) { $level = $options[$cant-1]['sectionLevel']; while ($level-- > $sectionLevel) { $options[]= array('type' => '-', 'sectionLevel'=>$level); ++$cant; } } } $option['name'] = empty($channel['page_alias'])? $channel['pageName']: $channel['page_alias']; $option['type'] = empty($channel['sub'])? 'o': ($sectionLevel?$sectionLevel:'s'); $option['url'] = smarty_function_sefurl(array('page'=>$channel['pageName'], 'structure'=>$structure, 'page_ref_id'=>$channel['page_ref_id'], 'sefurl'=>'n'), $smarty); $option['canonic'] = '(('.$channel['pageName'].'))'; $option['sefurl'] = smarty_function_sefurl(array('page'=>$channel['pageName'], 'structure'=>$structure, 'page_ref_id'=>$channel['page_ref_id']), $smarty); $option['position'] = $cant + $cumul; $option['sectionLevel'] = $sectionLevel; $option['url'] = str_replace('&', '&', $option['url']); // as of Tiki 7 menu items get encoded later $option['sefurl'] = str_replace('&', '&', $option['sefurl']); ++$cant; $options[] = $option; if (!empty($channel['sub'])) { $oSub = $this->to_menu($channel['sub'], $structure, $sectionLevel+1, $cant+$cumul); $cant += $oSub['cant']; $options = array_merge($options, $oSub['data']); } } return array('data'=>$options, 'cant'=>$cant); } } $structlib = new StructLib;