*/
/**
* required setup
*/
require_once( LIBERTY_PKG_PATH.'LibertyBase.php' );
/**
* System class for handling the liberty package
*
* @package liberty
*/
class LibertyStructure extends LibertyBase {
var $mStructureId;
function LibertyStructure ( $pStructureId=NULL, $pContentId=NULL ) {
// we need to init our database connection early
LibertyBase::LibertyBase();
$this->mStructureId = $pStructureId;
$this->mContentId = $pContentId;
}
function load() {
if( $this->mStructureId || $this->mContentId ) {
if( $this->mInfo = $this->getNode( $this->mStructureId, $this->mContentId ) ) {
global $gLibertySystem;
$this->mStructureId = $this->mInfo['structure_id'];
$this->mContentId = $this->mInfo['content_id'];
$this->mInfo['content_type'] = $gLibertySystem->mContentTypes[$this->mInfo['content_type_guid']];
}
}
return( $this->mInfo && count( $this->mInfo ) );
}
/**
* get the details to a given node
*
* @param array $pStructureId Structure ID of the node
* @param array $pContentId Content ID of the node
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getNode( $pStructureId=NULL, $pContentId=NULL ) {
global $gLibertySystem, $gBitSystem;
$contentTypes = $gLibertySystem->mContentTypes;
$ret = NULL;
$query = 'SELECT ls.*, lc.`user_id`, lc.`title`, lc.`content_type_guid`, uu.`login`, uu.`real_name`
FROM `'.BIT_DB_PREFIX.'liberty_structures` ls
INNER JOIN `'.BIT_DB_PREFIX.'liberty_content` lc ON (ls.`content_id`=lc.`content_id`)
LEFT JOIN `'.BIT_DB_PREFIX.'users_users` uu ON ( uu.`user_id` = lc.`user_id` )';
if( @$this->verifyId( $pStructureId ) ) {
$query .= ' WHERE ls.`structure_id`=?';
$bindVars = array( $pStructureId );
} elseif( @$this->verifyId( $pContentId ) ) {
$query .= ' WHERE ls.`content_id`=?';
$bindVars = array( $pContentId );
}
if( $result = $this->mDb->query( $query, $bindVars ) ) {
$ret = $result->fetchRow();
}
if( !empty( $contentTypes[$ret['content_type_guid']] ) ) {
// quick alias for code readability
$type = &$contentTypes[$ret['content_type_guid']];
if( empty( $type['content_object'] ) ) {
// create *one* object for each object *type* to call virtual methods.
include_once( $gBitSystem->mPackages[$type['handler_package']]['path'].$type['handler_file'] );
$type['content_object'] = new $type['handler_class']();
}
$ret['title'] = $type['content_object']->getTitle( $ret );
}
return $ret;
}
/**
* Check if a node is a root node
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function isRootNode() {
$ret = FALSE;
if( @$this->verifyId( $this->mInfo['structure_id'] ) ) {
$ret = $this->mInfo['root_structure_id'] == $this->mInfo['structure_id'];
}
return $ret;
}
/**
* get the title of the root node
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getRootTitle() {
$ret = NULL;
if( isset( $this->mInfo['structure_path'][0]['title'] ) ) {
$ret = $this->mInfo['structure_path'][0]['title'];
}
return $ret;
}
/**
* if you only have a structure id and you want to figure out the root structure id, use this
*
* @param array $pParamHash['structure_id'] is the structure id from which you want to figure out the root structure id
* @access public
* @return none. updates $pParamHash['root_structure_id'] by reference
*/
function getRootStructureId( &$pParamHash ) {
if( @BitBase::verifyId( $pParamHash['root_structure_id'] ) ) {
$pParamHash['root_structure_id'] = $pParamHash['root_structure_id'];
} elseif( @BitBase::verifyId( $this->mInfo['root_structure_id'] ) ) {
$pParamHash['root_structure_id'] = $this->mInfo['root_structure_id'];
} elseif( @BitBase::verifyId( $pParamHash['structure_id'] ) ) {
$pParamHash['root_structure_id'] = $this->mDb->getOne( "SELECT `root_structure_id` FROM `".BIT_DB_PREFIX."liberty_structures` WHERE `structure_id` = ?", array( $pParamHash['structure_id'] ) );
} else {
$pParamHash['root_structure_id'] = NULL;
}
}
// This is a utility function mainly used for upgrading sites.
function setTreeRoot( $pRootId, $pTree ) {
foreach( $pTree as $structRow ) {
$this->mDb->query( "UPDATE `".BIT_DB_PREFIX."liberty_structures` SET `root_structure_id`=? WHERE `structure_id`=?", array( $pRootId, $structRow["structure_id"] ) );
if( !empty( $structRow["sub"] ) ) {
$this->setTreeRoot( $pRootId, $structRow["sub"] );
}
}
}
function isValid() {
return( $this->verifyId( $this->mStructureId ) );
}
/**
* loadNavigation
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function loadNavigation() {
if( $this->isValid() ) {
$this->mInfo["prev"] = null;
// Get structure info for this page
if( !$this->isRootNode() && ($prev_structure_id = $this->getPrevStructureNode( $this->mStructureId )) ) {
$this->mInfo["prev"] = $this->getNode($prev_structure_id);
}
$next_structure_id = $this->getNextStructureNode( $this->mStructureId );
$this->mInfo["next"] = null;
if (isset($next_structure_id)) {
$this->mInfo["next"] = $this->getNode( $next_structure_id) ;
}
$this->mInfo["parent"] = $this->getStructureParentInfo( $this->mStructureId );
$this->mInfo["home"] = $this->getNode( $this->mStructureId );
}
return TRUE;
}
function loadPath() {
if( $this->isValid() ) {
$this->mInfo['structure_path'] = $this->getPath( $this->mStructureId );
}
return( !empty( $this->mInfo['structure_path'] ) );
}
/**
* This can be used to construct a path from the structure head to the requested page.
* @returns an array of page_info arrays.
*/
function getPath( $pStructureId ) {
$structure_path = array();
$page_info = $this->getNode($pStructureId);
if ($page_info["parent_id"]) {
$structure_path = $this->getPath($page_info["parent_id"]);
}
$structure_path[] = $page_info;
return $structure_path;
}
/**
* Get full structure from database
* @param $pStructureId structure for which we want structure
* @return full structure
*/
function getStructure( &$pParamHash ) {
global $gBitSystem, $gLibertySystem;
// make sure we have the correct id to get the entire structure
LibertyStructure::getRootStructureId( $pParamHash );
$ret = FALSE;
if( @BitBase::verifyId( $pParamHash['root_structure_id'] ) ) {
// Get all nodes for this structure
$query = "SELECT ls.*, lc.`user_id`, lc.`title`, lc.`content_type_guid`, uu.`login`, uu.`real_name`
FROM `".BIT_DB_PREFIX."liberty_structures` ls
INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON ( ls.`content_id` = lc.`content_id` )
INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON ( uu.`user_id` = lc.`user_id` )
WHERE ls.`root_structure_id` = ? ORDER BY `pos` ASC";
$result = $this->mDb->query( $query, array( $pParamHash['root_structure_id'] ) );
$subs = array();
$row_max = $result->numRows();
$contentTypes = $gLibertySystem->mContentTypes;
while( $res = $result->fetchRow() ) {
$aux = array();
$aux = $res;
if( !empty( $contentTypes[$res['content_type_guid']] ) ) {
// quick alias for code readability
$type = &$contentTypes[$res['content_type_guid']];
if( empty( $type['content_object'] ) ) {
// create *one* object for each object *type* to call virtual methods.
include_once( $gBitSystem->mPackages[$type['handler_package']]['path'].$type['handler_file'] );
$type['content_object'] = new $type['handler_class']();
}
if( !empty( $pParamHash['thumbnail_size'] ) ) {
$aux['content_object'] = new $type['handler_class']( NULL, $aux['content_id'] );
if( $aux['content_object']->load() ) {
$aux['thumbnail_url'] = $aux['content_object']->getThumbnailUrl( $pParamHash['thumbnail_size'] );
}
}
$aux['title'] = $type['content_object']->getTitle( $aux );
$ret[] = $aux;
}
}
}
return $ret;
}
/**
* Get all structures in $pStructureHash that have a given parent_id
* @param $pStructureHash full menu as supplied by '$this->getItemList( $pMenuId );'
* @return array of nodes with a given parent_id
*/
function getChildNodes( $pStructureHash, $pParentId = 0 ) {
$ret = array();
if( !empty( $pStructureHash ) ) {
foreach( $pStructureHash as $node ) {
if( $node['parent_id'] == $pParentId ) {
$ret[] = $node;
}
}
}
return $ret;
}
/**
* Create a usable array from the data in the database from getStructure()
* @param $pStructureHash raw structure data from database
* @return nicely formatted and cleaned up structure array
*/
function createSubTree( $pStructureHash, $pParentId = 0, $pParentPos = '', $pLevel = 0 ) {
$ret = array();
// get all child menu Nodes for this structure_id
$children = LibertyStructure::getChildNodes( $pStructureHash, $pParentId );
$pos = 1;
$row_max = count( $children );
// we need to insert the root structure item first
if (!$pLevel) {
foreach( $pStructureHash as $node ) {
if( ( $pParentId == 0 && $node['structure_id'] == $node['root_structure_id'] ) || $node['structure_id'] == $pParentId) {
$aux = $node;
$aux["first"] = true;
$aux["last"] = true;
$aux["pos"] = '';
$aux["level"] = $pLevel++;
$ret[] = $aux;
}
}
}
foreach( $children as $node ) {
$aux = $node;
$aux['level'] = $pLevel;
$aux['first'] = ( $pos == 1 );
$aux['last'] = FALSE;
$aux['has_children'] = FALSE;
if( strlen( $pParentPos ) == 0 ) {
$aux["pos"] = "$pos";
} else {
$aux["pos"] = $pParentPos . '.' . "$pos";
}
$ret[] = $aux;
//Recursively add any children
$subs = LibertyStructure::createSubTree( $pStructureHash, $node['structure_id'], $aux['pos'], ( $pLevel + 1 ) );
if( !empty( $subs ) ) {
$r = array_pop( $ret );
$r['has_children'] = TRUE;
array_push( $ret, $r );
$ret = array_merge( $ret, $subs );
}
if( $pos == $row_max ) {
$aux['structure_id'] = $node['structure_id'];
$aux['first'] = FALSE;
$aux['last'] = TRUE;
$ret[] = $aux;
}
$pos++;
}
return $ret;
}
// get sub tree of $pStructureId
function getSubTree( $pStructureId, $pRootTree = FALSE, $pListHash=NULL ) {
global $gLibertySystem, $gBitSystem;
$ret = array();
if( @BitBase::verifyId( $pStructureId ) ) {
$pListHash['structure_id'] = $pStructureId;
$structureHash = $this->getStructure( $pListHash );
$ret = $this->createSubTree( $structureHash, ( ( $pRootTree ) ? $pListHash['root_structure_id'] : $pStructureId ) );
}
return $ret;
}
/**
* getList
*
* @param array $pListHash
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getList( &$pListHash ) {
global $gBitSystem, $gBitUser;
$this->prepGetList( $pListHash );
if( !empty( $pListHash['find'] ) ) {
$findesc = '%' . $pListHash['find'] . '%';
$mid = " (`parent_id` is null or `parent_id`=0) and (lc.`title` like ?)";
$bindVars=array($findesc);
} else {
$mid = " (`parent_id` is null or `parent_id`=0) ";
$bindVars=array();
}
if( @$this->verifyId( $pListHash['user_id'] ) ) {
$mid .= " AND lc.`user_id` = ? ";
array_push( $bindVars, $pListHash['user_id'] );
}
if( !empty( $pListHash['content_type_guid'] ) ) {
$mid .= " AND lc.`content_type_guid`=? ";
array_push( $bindVars, $pListHash['content_type_guid'] );
}
$query = "SELECT ls.`structure_id`, ls.`parent_id`, ls.`content_id`, `page_alias`, `pos`, lc.`title`, `data`, `last_modified`, lc.`modifier_user_id`, `ip`, lc.`user_id` AS `creator_user_id`, uu.`login` AS `creator_user`, uu.`real_name` , uu.`email`
FROM `".BIT_DB_PREFIX."liberty_structures` ls INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON ( ls.`content_id` = lc.`content_id` ) INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON ( lc.`user_id` = uu.`user_id` )
WHERE $mid
ORDER BY ".$this->mDb->convertSortmode($pListHash['sort_mode']);
$query_cant = "SELECT count(*)
FROM `".BIT_DB_PREFIX."liberty_structures` ls INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON ( ls.`content_id` = lc.`content_id` )
WHERE $mid";
$result = $this->mDb->query($query,$bindVars,$pListHash['max_records'],$pListHash['offset']);
$cant = $this->mDb->getOne($query_cant,$bindVars);
$ret = array();
while ($res = $result->fetchRow()) {
if( $gBitSystem->isPackageActive( 'bithelp' ) && file_exists(BITHELP_PKG_PATH.$res['title'].'/index.html')) {
$res['webhelp']='y';
} else {
$res['webhelp']='n';
}
$ret[] = $res;
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/**
* prepare a structure node for storage in the database
* @param $pParamHash contains various settings for the node to be stored
* @return TRUE on success, FALSE on failure where $this->mErrors will contain the reason why it failed
*/
function verifyNode( &$pParamHash ) {
if( !@$this->verifyId( $pParamHash['content_id'] ) ) {
$this->mErrors['content'] = 'Could not store structure. Invalid content id. '.$pParamHash['content_id'];
} else {
if( !@$this->verifyId( $pParamHash['parent_id'] ) ) {
$pParamHash['parent_id'] = 0;
}
if( empty( $pParamHash['alias'] ) ) {
$pParamHash['alias'] = '';
}
if( isset( $pParamHash['after_ref_id'] ) ) {
$pParamHash['max'] = $this->mDb->getOne("select `pos` from `".BIT_DB_PREFIX."liberty_structures` where `structure_id`=?",array((int)$pParamHash['after_ref_id']));
} else {
$pParamHash['max'] = $this->mDb->getOne("select max(`pos`) from `".BIT_DB_PREFIX."liberty_structures` where `parent_id`=?",array((int)$pParamHash['parent_id']));
}
if( $pParamHash['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 `".BIT_DB_PREFIX."liberty_structures` set `pos`=`pos`+1 where `pos`>? and `parent_id`=?";
$result = $this->mDb->query($query,array((int)$pParamHash['max'], (int)$pParamHash['parent_id']));
}
$pParamHash['max']++;
}
return( count( $this->mErrors ) == 0 );
}
/**
* clean up and prepare a complete structure in the form of arrays about to be stored
* @param $pParamHash is a set of arrays generated by the DynamicTree javascript tree builder
* @return TRUE on success, FALSE on failure where $this->mErrors will contain the reason why it failed
*/
function verifyStructure( &$pParamHash ) {
if( !empty( $pParamHash['structure_string'] ) ) {
eval( $pParamHash['structure_string'] );
$pParamHash = array_merge( $pParamHash, $tree );
}
if( !empty( $pParamHash['structure'] ) && @BitBase::verifyId( $pParamHash['root_structure_id'] ) ) {
LibertyStructure::embellishStructureHash( $pParamHash['structure'] );
$structureHash = LibertyStructure::flattenStructureHash( $pParamHash['structure'] );
// replace the 'tree' in the data array with the root_structure_id
foreach( $pParamHash['data'] as $structure_id => $node ) {
if( !@BitBase::verifyId( $pParamHash['data'][$structure_id]['parent_id'] ) ) {
$pParamHash['data'][$structure_id]['parent_id'] = $pParamHash['root_structure_id'];
}
}
foreach( $structureHash as $node ) {
if( @BitBase::verifyId( $node['structure_id'] ) ) {
$pParamHash['structure_store'][$node['structure_id']] = array_merge( $node, $pParamHash['data'][$node['structure_id']] );
$pParamHash['structure_store'][$node['structure_id']]['root_structure_id'] = $pParamHash['root_structure_id'];
}
}
} else {
$this->mErrors['verify_structure'] = tra( "The structure could not be stored because of missing data." );
}
// clear up some memory
if( !empty( $pParamHash['structure_string'] ) ) { unset( $pParamHash['structure_string'] ); }
if( !empty( $pParamHash['structure'] ) ) { unset( $pParamHash['structure'] ); }
if( !empty( $pParamHash['data'] ) ) { unset( $pParamHash['data'] ); }
return( count( $this->mErrors ) == 0 );
}
/**
* store a complete structure where ever subarray contains a complete node as it should go into the database
* @param $pParamHash is an array with subarrays, each representing a structure node ready to associativley inserted into the database
* @return TRUE on success, FALSE on failure where $this->mErrors will contain the reason why it failed
*/
function storeStructure( $pParamHash ) {
if( $this->verifyStructure( $pParamHash ) ) {
// now that the structure is ready to be stored, we remove the old structure first and then insert the new one.
$query = "DELETE FROM `".BIT_DB_PREFIX."liberty_structures` WHERE `root_structure_id`=? AND `structure_id`<>?";
$result = $this->mDb->query( $query, array( (int)$pParamHash['root_structure_id'], (int)$pParamHash['root_structure_id'] ) );
$query = "";
$this->mDb->StartTrans();
foreach( $pParamHash['structure_store'] as $node ) {
$this->mDb->associateInsert( BIT_DB_PREFIX."liberty_structures", $node );
}
$this->mDb->CompleteTrans();
}
return( count( $this->mErrors ) == 0 );
}
/**
* make sure the array only contains one level depth
* @param $pParamHash contains a nested set of arrays with structure_id and pos values set
* @return flattened array
*/
function flattenStructureHash( $pParamHash, $i = -10000 ) {
$ret = array();
foreach( $pParamHash as $key => $node ) {
if( !empty( $node ) && count( $node ) > 2 ) {
$ret = array_merge( $ret, LibertyStructure::flattenStructureHash( $node, $i ) );
$i++;
} elseif( count( $node ) == 2 ) {
$ret[] = $node;
$i++;
} else {
$ret[$i][$key] = $node;
}
}
return $ret;
}
/**
* cleans up and reorganises data in nested array where keys are structure_id
* @param $pParamHash contains a nested set of arrays with structure_id as key
* @return reorganised array
*/
function embellishStructureHash( &$pParamHash ) {
$pos = 1;
foreach( $pParamHash as $structure_id => $node ) {
if( !empty( $node ) ) {
LibertyStructure::embellishStructureHash( $node );
}
$node['pos'] = $pos++;
$node['structure_id'] = $structure_id;
$pParamHash[$structure_id] = $node;
}
}
/** 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 structure_id or null if not created.
*/
function storeNode( &$pParamHash ) {
global $gBitSystem;
$ret = null;
// If the page doesn't exist then create a new wiki page!
$now = $gBitSystem->getUTCTime();
// $created = $this->create_page($name, 0, '', $now, tra('created from structure'), 'system', '0.0.0.0', '');
// if were not trying to add a duplicate structure head
if ( $this->verifyNode( $pParamHash ) ) {
$this->mDb->StartTrans();
//Create a new structure entry
$pParamHash['structure_id'] = $this->mDb->GenID( 'liberty_structures_id_seq' );
if( !@$this->verifyId( $pParamHash['root_structure_id'] ) ) {
$pParamHash['root_structure_id'] = $pParamHash['structure_id'];
}
$query = "INSERT INTO `".BIT_DB_PREFIX."liberty_structures`( `structure_id`, `parent_id`,`content_id`, `root_structure_id`, `page_alias`, `pos` ) values(?,?,?,?,?,?)";
$result = $this->mDb->query( $query, array( $pParamHash['structure_id'], $pParamHash['parent_id'], (int)$pParamHash['content_id'], (int)$pParamHash['root_structure_id'], $pParamHash['alias'], $pParamHash['max'] ) );
$this->mDb->CompleteTrans();
$ret = $pParamHash['structure_id'];
} else {
//vd( $this->mErrors );
}
return $ret;
}
/**
* moveNodeWest
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function moveNodeWest() {
if( $this->isValid() ) {
//If there is a parent and the parent isnt the structure root node.
$this->mDb->StartTrans();
if( @$this->verifyId( $this->mInfo["parent_id"] ) ) {
$parentNode = $this->getNode( $this->mInfo["parent_id"] );
if( @$this->verifyId( $parentNode['parent_id'] ) ) {
//Make a space for the node after its parent
$query = "update `".BIT_DB_PREFIX."liberty_structures` set `pos`=`pos`+1 where `pos`>? and `parent_id`=?";
$this->mDb->query( $query, array( $parentNode['pos'], $parentNode['parent_id'] ) );
//Move the node up one level
$query = "update `".BIT_DB_PREFIX."liberty_structures` set `parent_id`=?, `pos`=(? + 1) where `structure_id`=?";
$this->mDb->query($query, array( $parentNode['parent_id'], $parentNode['pos'], $this->mStructureId ) );
}
}
$this->mDb->CompleteTrans();
}
}
/**
* moveNodeEast
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function moveNodeEast() {
if( $this->isValid() ) {
$this->mDb->StartTrans();
$query = "select `structure_id`, `pos` from `".BIT_DB_PREFIX."liberty_structures` where `pos` and `parent_id`=? order by `pos` desc";
$result = $this->mDb->query($query,array($this->mInfo["pos"], (int)$this->mInfo["parent_id"]));
if ($previous = $result->fetchRow()) {
//Get last child nodes for previous sibling
$query = "select `pos` from `".BIT_DB_PREFIX."liberty_structures` where `parent_id`=? order by `pos` desc";
$result = $this->mDb->query($query,array((int)$previous["structure_id"]));
if ($res = $result->fetchRow()) {
$pos = $res["pos"];
} else{
$pos = 0;
}
$query = "update `".BIT_DB_PREFIX."liberty_structures` set `parent_id`=?, `pos`=(? + 1) where `structure_id`=?";
$this->mDb->query( $query, array((int)$previous["structure_id"], (int)$pos, (int)$this->mStructureId) );
//Move nodes up below that had previous parent and pos
$query = "update `".BIT_DB_PREFIX."liberty_structures` set `pos`=`pos`-1 where `pos`>? and `parent_id`=?";
$this->mDb->query( $query, array( $this->mInfo['pos'], $this->mInfo['parent_id'] ) );
}
$this->mDb->CompleteTrans();
}
}
/**
* moveNodeSouth
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function moveNodeSouth() {
if( $this->isValid() ) {
$this->mDb->StartTrans();
$query = "select `structure_id`, `pos` from `".BIT_DB_PREFIX."liberty_structures` where `pos`>? and `parent_id`=? order by `pos` asc";
$result = $this->mDb->query($query,array((int)$this->mInfo["pos"], (int)$this->mInfo["parent_id"]));
$res = $result->fetchRow();
if ($res) {
//Swap position values
$query = "update `".BIT_DB_PREFIX."liberty_structures` set `pos`=? where `structure_id`=?";
$this->mDb->query($query,array((int)$this->mInfo["pos"], (int)$res["structure_id"]) );
$this->mDb->query($query,array((int)$res["pos"], (int)$this->mInfo["structure_id"]) );
}
$this->mDb->CompleteTrans();
}
}
/**
* moveNodeNorth
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function moveNodeNorth() {
if( $this->isValid() ) {
$this->mDb->StartTrans();
$query = "select `structure_id`, `pos` from `".BIT_DB_PREFIX."liberty_structures` where `pos` and `parent_id`=? order by `pos` desc";
$result = $this->mDb->query($query,array((int)$this->mInfo["pos"], (int)$this->mInfo["parent_id"]));
$res = $result->fetchRow();
if ($res) {
//Swap position values
$query = "update `".BIT_DB_PREFIX."liberty_structures` set `pos`=? where `structure_id`=?";
$this->mDb->query($query,array((int)$res["pos"], (int)$this->mInfo["structure_id"]) );
$this->mDb->query($query,array((int)$this->mInfo["pos"], (int)$res["structure_id"]) );
}
$this->mDb->CompleteTrans();
}
}
// ============== OLD struct_lib STUFF
function removeStructureNode( $structure_id, $delete=FALSE ) {
// Now recursively remove
if( @$this->verifyId( $structure_id ) ) {
$query = "SELECT *
FROM `".BIT_DB_PREFIX."liberty_structures`
WHERE `parent_id`=?";
$result = $this->mDb->query( $query, array( (int)$structure_id ) );
// Iterate down through the child nodes
while( $res = $result->fetchRow() ) {
$this->removeStructureNode( $res["structure_id"], $delete );
}
// Only delete a page if other structures arent referencing it
if( $delete ) {
$page_info = $this->getNode( $structure_id );
$query = "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."liberty_structures` WHERE `content_id`=?";
$count = $this->mDb->getOne( $query, array( (int)$page_info["page_id"] ) );
if( $count = 1 ) {
$this->remove_all_versions( $page_info["page_id"] );
}
}
// If we are removing the root node, remove the entry in liberty_content as well
$query = "SELECT `content_id`
FROM `".BIT_DB_PREFIX."liberty_structures`
WHERE `structure_id`=? AND `structure_id`=`root_structure_id`";
$content_id = $this->mDb->getOne( $query, array( (int)$structure_id ) );
// Delete the liberty_content stuff
$lc = new LibertyContent($content_id);
$lc->expunge();
// Remove the structure node
$query = "DELETE FROM `".BIT_DB_PREFIX."liberty_structures` WHERE `structure_id`=?";
$result = $this->mDb->query( $query, array( (int)$structure_id) );
return true;
}
}
/**
* Returns an array of info about the parent
*
* @param array $structure_id
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getStructureParentInfo($structure_id) {
$parent_id = $this->mDb->getOne( "SELECT `parent_id` FROM `".BIT_DB_PREFIX."liberty_structures` WHERE `structure_id`=?", array( (int)$structure_id ) );
if( !@BitBase::verifyId( $parent_id ) ) {
return null;
}
return( $this->getNode( $parent_id ) );
}
/**
* getContentIds
*
* @param array $pStructureId
* @param array $pToc
* @param float $pLevel
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getContentIds( $pStructureId, &$pToc, $pLevel=0 ) {
$ret = array();
$query = "SELECT * from `".BIT_DB_PREFIX."liberty_structures` where `parent_id`=? ORDER BY pos, page_alias, content_id";
$result = $this->mDb->query( $query, array( (int)$pStructureId ) );
while ( $row = $result->fetchRow() ) {
array_push( $pToc, $row['content_id'] );
$this->getContentIds( $row['structure_id'], $pToc, ++$pLevel );
}
}
/**
* getContentArray
*
* @param array $pStructureId
* @param array $pToc
* @param float $pLevel
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getContentArray( $pStructureId, &$pToc, $pLevel=0 ) {
$query = "SELECT * from `".BIT_DB_PREFIX."liberty_structures` where `structure_id`=?";
$result = $this->mDb->query( $query, array( (int)$pStructureId ) );
while ( $row = $result->fetchRow() ) {
array_push( $pToc, $row['content_id'] );
$this->getContentIds( $pStructureId, $pToc, $pLevel );
}
}
/**
* exportHtml
*
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function exportHtml() {
$ret = array();
$toc = array();
$this->getContentArray( $this->mStructureId, $toc );
if( count( $toc ) ) {
foreach( $toc as $conId ) {
if( $viewContent = $this->getLibertyObject( $conId ) ) {
$ret[] = array(
'type' => $viewContent->mContentTypeGuid,
'landscape' => FALSE,
'url' => $viewContent->getDisplayUrl(),
'content_id' => $viewContent->mContentId,
);
}
}
}
return $ret;
}
/**
* buildSubtreeToc
*
* @param array $id
* @param array $slide
* @param string $order
* @param string $tocPrefix can be used to Prefix a subtree as it would start from a given number (e.g. 2.1.3)
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function buildSubtreeToc($id,$slide=false,$order='asc',$tocPrefix='') {
global $gLibertySystem, $gBitSystem;
$back = array();
$cant = $this->mDb->getOne("select count(*) from `".BIT_DB_PREFIX."liberty_structures` where `parent_id`=?",array((int)$id));
if ($cant) {
$query = "SELECT `structure_id`, `page_alias`, lc.`user_id`, lc.`title`, lc.`content_type_guid`, uu.`login`, uu.`real_name`
FROM `".BIT_DB_PREFIX."liberty_structures` ls INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON ( lc.`content_id`=ls.`content_id` )
LEFT JOIN `".BIT_DB_PREFIX."users_users` uu ON ( uu.`user_id` = lc.`user_id` )
WHERE `parent_id`=?
ORDER BY ".$this->mDb->convertSortmode("pos_".$order);
$result = $this->mDb->query($query,array((int)$id));
$prefix=1;
$contentTypes = $gLibertySystem->mContentTypes;
while ($res = $result->fetchRow()) {
$res['prefix']=($tocPrefix=='')?'':"$tocPrefix.";
$res['prefix'].=$prefix;
$prefix++;
if( !empty( $contentTypes[$res['content_type_guid']] ) ) {
// quick alias for code readability
$type = &$contentTypes[$res['content_type_guid']];
if( empty( $type['content_object'] ) ) {
// create *one* object for each object *type* to call virtual methods.
include_once( $gBitSystem->mPackages[$type['handler_package']]['path'].$type['handler_file'] );
$type['content_object'] = new $type['handler_class']();
}
$res['title'] = $type['content_object']->getTitle( $res );
if ($res['structure_id'] != $id) {
$sub = $this->buildSubtreeToc($res['structure_id'],$slide,$order,$res['prefix']);
if (is_array($sub)) {
$res['sub'] = $sub;
}
}
}
$back[] = $res;
}
} else {
return false;
}
return $back;
}
/**
* getToc
*
* @param array $pStructureId
* @param string $order
* @param array $showdesc
* @param array $numbering
* @param string $numberPrefix
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getToc($pStructureId=NULL,$order='asc',$showdesc=false,$numbering=true,$numberPrefix='') {
if( !@$this->verifyId( $pStructureId ) ) {
$pStructureId = $this->mStructureId;
}
$structure_tree = $this->buildSubtreeToc($pStructureId,false,$order,$numberPrefix);
return $this->fetchToc($structure_tree,$showdesc,$numbering);
}
/**
* fetchToc
*
* @param array $structure_tree
* @param array $showdesc
* @param array $numbering
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function fetchToc($structure_tree,$showdesc,$numbering) {
global $gBitSmarty;
$ret='';
if ($structure_tree != '') {
$gBitSmarty->verifyCompileDir();
$ret.=$gBitSmarty->fetch( "bitpackage:wiki/book_toc_startul.tpl");
foreach($structure_tree as $leaf) {
//echo "
";print_r($leaf);echo "
";
$gBitSmarty->assign_by_ref('structure_tree',$leaf);
$gBitSmarty->assign('showdesc',$showdesc);
$gBitSmarty->assign('numbering',$numbering);
$ret.=$gBitSmarty->fetch( "bitpackage:wiki/book_toc_leaf.tpl");
if(isset($leaf["sub"]) && is_array($leaf["sub"])) {
$ret.=$this->fetchToc($leaf["sub"],$showdesc,$numbering);
}
}
$ret.=$gBitSmarty->fetch( "bitpackage:wiki/book_toc_endul.tpl");
}
return $ret;
}
/**
* getNextStructureNode
*
* @param array $structure_id
* @param array $deep
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getNextStructureNode($structure_id, $deep = true) {
// If we have children then get the first child
if ($deep) {
$query = "SELECT `structure_id`
FROM `".BIT_DB_PREFIX."liberty_structures` ls
WHERE `parent_id`=?
ORDER BY ".$this->mDb->convertSortmode("pos_asc");
$result1 = $this->mDb->query($query,array((int)$structure_id));
if ($result1->numRows()) {
$res = $result1->fetchRow();
return $res["structure_id"];
}
}
// Try to get the next page with the same parent as this
$page_info = $this->getNode($structure_id);
$parent_id = $page_info["parent_id"];
$page_pos = $page_info["pos"];
if (!$parent_id)
return null;
$query = "SELECT `structure_id`
FROM `".BIT_DB_PREFIX."liberty_structures` ls
WHERE `parent_id`=? and `pos`>?
ORDER BY ".$this->mDb->convertSortmode("pos_asc");
$result2 = $this->mDb->query($query,array((int)$parent_id, (int)$page_pos));
if ($result2->numRows()) {
$res = $result2->fetchRow();
return $res["structure_id"];
}
else {
return $this->getNextStructureNode($parent_id, false);
}
}
/**
* getPrevStructureNode
*
* @param array $structure_id
* @param array $deep
* @access public
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
*/
function getPrevStructureNode($structure_id, $deep = false) {
//Drill down to last child for this tree node
if ($deep) {
$query = "select `structure_id` ";
$query .= "from `".BIT_DB_PREFIX."liberty_structures` ls ";
$query .= "where `parent_id`=? ";
$query .= "order by ".$this->mDb->convertSortmode("pos_desc");
$result = $this->mDb->query($query,array($structure_id));
if ($result->numRows()) {
//There are more children
$res = $result->fetchRow();
$structure_id = $this->getPrevStructureNode($res["structure_id"], true);
}
return $structure_id;
}
// Try to get the previous page with the same parent as this
$page_info = $this->getNode($structure_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 `structure_id` ";
$query .= "from `".BIT_DB_PREFIX."liberty_structures` ls ";
$query .= "where `parent_id`=? and `pos` ";
$query .= "order by ".$this->mDb->convertSortmode("pos_desc");
$result = $this->mDb->query($query,array((int)$parent_id, (int)$pos));
if ($result->numRows()) {
//There is a previous sibling
$res = $result->fetchRow();
$structure_id = $this->getPrevStructureNode($res["structure_id"], true);
}
else {
//No previous siblings, just the parent
$structure_id = $parent_id;
}
return $structure_id;
}
/**
* Return an array of subpages
*
* @param array $pParentId
* @access public
* @return array of child structure pages
*/
function getStructureNodes( $pParentId ) {
$ret = array();
$query = "SELECT `pos`, `structure_id`, `parent_id`, ls.`content_id`, lc.`title`, `page_alias`
FROM `".BIT_DB_PREFIX."liberty_structures` ls, `".BIT_DB_PREFIX."liberty_content` lc
WHERE ls.`content_id` = lc.`content_id` AND `parent_id`=? ";
$query .= "order by ".$this->mDb->convertSortmode("pos_asc");
$result = $this->mDb->query($query,array((int)$pParentId));
while ($res = $result->fetchRow()) {
//$ret[] = $this->populate_page_info($res);
$ret[] = $res;
}
return $ret;
}
// {{{ the following is just for the transition phase...
function s_remove_page() { deprecated( 'Please use removeStructureNode() instead' ); }
function s_get_pages() { deprecated( 'Please use getStructureNodes() instead' ); }
function get_prev_page() { deprecated( 'Please use getPrevStructureNode() instead' ); }
function get_next_page() { deprecated( 'Please use getNextStructureNode() instead' ); }
function get_toc() { deprecated( 'Please use getToc() instead' ); }
function fetch_toc() { deprecated( 'Please use fetchToc() instead' ); }
function s_get_parent_info() { deprecated( 'Please use getStructureParentInfo() instead' ); }
function build_subtree_toc() { deprecated( 'Please use buildSubtreeToc() instead' ); }
// }}}
}
?>