summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbitweaver.org <bitweaver@users.sourceforge.net>2005-06-19 04:57:03 +0000
committerbitweaver.org <bitweaver@users.sourceforge.net>2005-06-19 04:57:03 +0000
commit2608b4b3f9d1e5cf430a6c03019f24b9f136c4d5 (patch)
treeaa8478622110f4ee1df73bba4541a40120bf1f2d
downloadnexus-2608b4b3f9d1e5cf430a6c03019f24b9f136c4d5.tar.gz
nexus-2608b4b3f9d1e5cf430a6c03019f24b9f136c4d5.tar.bz2
nexus-2608b4b3f9d1e5cf430a6c03019f24b9f136c4d5.zip
IMPORT TikiPro CLYDE FINAL
-rw-r--r--Nexus.php790
-rw-r--r--NexusSystem.php133
-rw-r--r--admin/nexus_plugins.php12
-rw-r--r--admin/schema_inc.php60
-rw-r--r--bit_setup_inc.php10
-rw-r--r--icons/menu.gifbin0 -> 105 bytes
-rw-r--r--icons/organise.pngbin0 -> 545 bytes
-rw-r--r--icons/pkg_nexus.pngbin0 -> 1484 bytes
-rw-r--r--icons/remove_dead.pngbin0 -> 441 bytes
-rw-r--r--index.php3
-rw-r--r--insert_menu_item_inc.php31
-rw-r--r--menu_items.php102
-rw-r--r--menu_lookup_inc.php14
-rw-r--r--menu_sort.php37
-rw-r--r--menus.php70
-rw-r--r--plugins/menu.formelements.js12
-rw-r--r--plugins/menu.formelements.php126
-rw-r--r--plugins/menu.suckerfish.php94
-rw-r--r--plugins/menu.tikiwiki.php106
-rw-r--r--templates/insert_menu_item_inc.tpl69
-rw-r--r--templates/menu_details_inc.tpl45
-rw-r--r--templates/menu_items.tpl25
-rw-r--r--templates/menu_items_details_inc.tpl33
-rw-r--r--templates/menu_items_edit_inc.tpl113
-rw-r--r--templates/menu_items_organise_inc.tpl20
-rw-r--r--templates/menu_items_preview_inc.tpl7
-rw-r--r--templates/menu_nexus.tpl17
-rw-r--r--templates/menu_sort.tpl23
-rw-r--r--templates/menus.tpl128
-rw-r--r--templates/nexus_plugins.tpl39
-rw-r--r--templates/suckerfish/item.tpl1
-rw-r--r--templates/tikiwiki/item.tpl21
32 files changed, 2141 insertions, 0 deletions
diff --git a/Nexus.php b/Nexus.php
new file mode 100644
index 0000000..2ff3eea
--- /dev/null
+++ b/Nexus.php
@@ -0,0 +1,790 @@
+<?php
+/**
+* Nexus base class
+*
+* @abstract
+* @author xing <xing@synapse.plus.com>
+* @version $Revision: 1.1 $
+* @package Nexus
+*/
+
+require_once( NEXUS_PKG_PATH.'NexusSystem.php' );
+
+class Nexus extends NexusSystem {
+ /**
+ * Primary key for the menu
+ */
+ var $mMenuId;
+
+ /**
+ * Initialisation of this class
+ */
+ function Nexus( $pMenuId=NULL, $pAutoLoad=TRUE ) {
+ NexusSystem::NexusSystem();
+ $this->mMenuId = $pMenuId;
+ if ( $pAutoLoad ) {
+ $this->load();
+ }
+ }
+
+ /**
+ * Load the menu
+ */
+ function load() {
+ if( $this->mMenuId ) {
+ $this->mInfo = $this->getMenu( $this->mMenuId );
+ $this->mInfo['items'] = $this->getItemList( $this->mMenuId );
+ $this->mInfo['tree'] = $this->createMenuTree( $this->mInfo['items'] );
+ }
+ return( count( $this->mInfo ) );
+ }
+
+ /**
+ * Get menu information from database
+ * @param $pMenuId menu id of the menu we want information from
+ */
+ function getMenu( $pMenuId=NULL ) {
+ if( !$pMenuId && $this->isValid() ) {
+ $pMenuId = $this->mMenuId;
+ }
+ $bindVars = array();
+ $query = 'SELECT tnm.* FROM `'.BIT_DB_PREFIX.'tiki_nexus_menus` tnm';
+ if( is_numeric( $pMenuId ) ) {
+ $query .= ' WHERE tnm.`menu_id`=?';
+ $bindVars = array( $pMenuId );
+ }
+ if( $result = $this->query( $query, array( $bindVars ) ) ) {
+ $ret = $result->fields;
+ }
+ return $ret;
+ }
+
+ /**
+ * Get menu information from database
+ * @param $pMenuId menu id of the menu we want information from
+ */
+ function getMenuList( $pFindString=NULL, $pSortMode=NULL, $pOffset=NULL, $pMaxRows=NULL ) {
+ $bindVars = array();
+ $mid = '';
+ if( $pFindString ) {
+ $mid .= " WHERE UPPER(tnm.`title`) LIKE ? ";
+ $bindVars[] = '%'.strtoupper( $pFindString ).'%';
+ }
+ if( $pSortMode ) {
+ $mid .= " ORDER BY ".$this->convert_sortmode($pSortMode)." ";
+ }
+
+ $query = 'SELECT tnm.`menu_id` FROM `'.BIT_DB_PREFIX.'tiki_nexus_menus` tnm'.$mid;
+ if( $pMaxRows && is_numeric( $pMaxRows ) ) {
+ $result = $this->query( $query, $bindVars, $pOffset, $pMaxRows );
+ } else {
+ $result = $this->query( $query, $bindVars );
+ }
+ $menuIds = $result->getRows();
+ $menus = array();
+ foreach( $menuIds as $menuId ) {
+ $tmpMenu = new Nexus( $menuId['menu_id'] );
+ $menus[] = $tmpMenu->mInfo;
+ }
+
+ return $menus;
+ }
+
+ /**
+ * Create usable menu tree
+ * @param $pMenuHash full menu as supplied by '$this->getItemList( $pMenuId );'
+ * @param $pStripped if set to true, removes all permissions, user isn't part of
+ * @return menu with all menu items sorted with first and last items of each 'level' marked. items that contain siblings are marked with 'head' = TRUE;
+ */
+ function createMenuTree( $pMenuHash, $pStripped=FALSE, $parent_id=0 ) {
+ $ret = array();
+ if( $pStripped && $parent_id == 0 ) {
+ $pMenuHash = $this->checkUserPermission( $pMenuHash );
+ }
+ // get all child menu items for this item_id
+ $children = $this->getChildItems( $pMenuHash, $parent_id );
+ $pos = 1;
+ $row_max = count( $children );
+ foreach( $children as $item ) {
+ $aux = $item;
+ $aux['first'] = ( $pos == 1 );
+ $aux['last'] = FALSE;
+ $aux['head'] = FALSE;
+ $ret[] = $aux;
+ //Recursively add any children
+ $subs = $this->createMenuTree( $pMenuHash, $pStripped, $item['item_id'] );
+ if( !empty( $subs ) ) {
+ // mark items that have children
+ $row_last = count( $ret );
+ $ret[$row_last - 1]['head'] = TRUE;
+ $ret = array_merge( $ret, $subs );
+ }
+ if( $pos == $row_max ) {
+ if( !empty( $item['parent_id'] ) ) {
+ $tmpItem = $this->getItemList( NULL, $item['parent_id'] );
+ $aux = $tmpItem[$item['parent_id']];
+ } else {
+ $aux['item_id'] = $item['item_id'];
+ }
+ $aux['first'] = FALSE;
+ $aux['last'] = TRUE;
+ $ret[] = $aux;
+ }
+ $pos++;
+ }
+ return $ret;
+ }
+
+ /**
+ * Strip out all items a user doesn't have permission to view
+ * @param $pMenuHash full menu as supplied by '$this->getItemList( $pMenuId );'
+ * @return menu containing only items user is allowed to view
+ */
+ function checkUserPermission( $pMenuHash ) {
+ global $gBitUser;
+ $ret = array();
+ foreach( $pMenuHash as $item ) {
+ if( !empty( $item['perm'] ) ) {
+ if( $gBitUser->hasPermission( $item['perm'] ) ) {
+ $ret[] = $item;
+ }
+ } else {
+ $ret[] = $item;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Get all items in $pMenuHash that have a given parent_id
+ * @param $pMenuHash full menu as supplied by '$this->getItemList( $pMenuId );'
+ * @return array of items with a given parent_id
+ */
+ function getChildItems( $pMenuHash, $parent_id=0 ) {
+ $ret = array();
+ foreach( $pMenuHash as $item ) {
+ if( $item['parent_id'] == $parent_id ) {
+ $ret[] = $item;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Validate that a menu is being loaded and present
+ * @return TRUE if all is ok
+ */
+ function isValid() {
+ return( !empty( $this->mMenuId ) );
+ }
+
+ /**
+ * Check if all required items are present for menu creation / insertion
+ * @return number of errors encountered
+ */
+ function verifyMenu( &$pParamHash ) {
+ if( empty( $pParamHash['title'] ) ) {
+ $this->mErrors['error'] = 'Could not store menu because no title was given.';
+ }
+ if( empty( $pParamHash['description'] ) ) {
+ $pParamHash['description'] = NULL;
+ }
+ // set the default plugin_guid to suckerfish menus
+ if( empty( $pParamHash['plugin_guid'] ) ) {
+ $pParamHash['plugin_guid'] = NEXUS_PLUGIN_GUID_SUCKERFISH;
+ }
+ $type_name = 'type_' . $pParamHash['plugin_guid'];
+ if ( empty( $pParamHash[$type_name] )) {
+ $pParamHash['type'] = 'nor';
+ }
+ else {
+ $pParamHash['type'] = $pParamHash[$type_name];
+ }
+ if( empty( $pParamHash['editable'][0] ) || !is_numeric( $pParamHash['editable'][0] ) ) {
+ $pParamHash['editable'][0] = 0;
+ }
+ $pParamHash['editable'] = $pParamHash['editable'][0];
+ return( count( $this->mErrors ) == 0 );
+ }
+
+ /**
+ * Store menu in db
+ * @param menu_id if set, will update given menu - if not set, we create a new entry in the db
+ * @param title title of menu
+ * @param description description of menu
+ * @param type type of menu
+ * @param editable if menu is editable by other users - takes 0 or 1
+ * @return new menu menu_id or FALSE if not created
+ */
+ function storeMenu( &$pParamHash ) {
+ $ret = FALSE;
+ if( $this->verifyMenu( $pParamHash ) ) {
+ if( empty( $pParamHash['menu_id'] ) ) {
+ $query = "INSERT INTO `".BIT_DB_PREFIX."tiki_nexus_menus`( `title`,`description`,`type`,`plugin_guid`,`editable` ) VALUES(?,?,?,?,?)";
+ $result = $this->query( $query, array( $pParamHash['title'], $pParamHash['description'], $pParamHash['type'], $pParamHash['plugin_guid'], $pParamHash['editable'] ) );
+ $query = "SELECT MAX(`menu_id`) FROM `".BIT_DB_PREFIX."tiki_nexus_menus`";
+ $ret = $this->getOne( $query, array() );
+ } else {
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menus` SET `title`=?,`description`=?,`type`=?,`plugin_guid`=?,`editable`=? WHERE `".BIT_DB_PREFIX."tiki_nexus_menus`.`menu_id`=?";
+ $result = $this->query( $query, array( $pParamHash['title'], $pParamHash['description'], $pParamHash['type'], $pParamHash['plugin_guid'], $pParamHash['editable'], $pParamHash['menu_id'] ) );
+ $ret = $pParamHash['menu_id'];
+ }
+ $this->writeModuleCache( $ret );
+ $this->writeMsieJs();
+ } else {
+ vd( $this->mErrors );
+ }
+ return $ret;
+ }
+
+ /**
+ * Delete menu and associated menu items from db
+ * @return number of errors encountered
+ */
+ function expungeMenu( $pMenuId ) {
+ // first we remove the cache file
+ $delMenu = $this->getMenu( $pMenuId );
+ $menu_name = preg_replace( "/ +/", "_", trim( $delMenu['title'] ) );
+ if( !unlink( TEMP_PKG_PATH.'nexus/modules/mod_'.$menu_name.'_'.$pMenuId.'.tpl' ) ) {
+ $this->mErrors['error'] = "There was a problem removing the menu cache file.";
+ }
+ // delete menu items
+ $query = "DELETE FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `menu_id`=?";
+ $this->query( $query, array( $pMenuId ) );
+ // delete menu
+ $query = "DELETE FROM `".BIT_DB_PREFIX."tiki_nexus_menus` WHERE `menu_id`=?";
+ $this->query( $query, array( $pMenuId ) );
+ // now that the menu is gone, update the MSIE js file
+ $this->writeMsieJs( $pMenuId );
+ return( count( $this->mErrors ) == 0 );
+ }
+
+ /**
+ * Get menu items from the database
+ * @param $pItemId ID of menu item to get. if set, we only get this item.
+ * @param $pMenuId ID of menu to get
+ * @return all menu items with a given menu ID
+ */
+ function getItemList( $pMenuId=NULL, $pItemId=NULL ) {
+ $bindVars = array();
+ $ret = array();
+ $query = 'SELECT tnmi.* FROM `'.BIT_DB_PREFIX.'tiki_nexus_menu_items` tnmi';
+ if( is_numeric( $pItemId ) ) {
+ $query .= ' WHERE tnmi.`item_id`=?';
+ $bindVars = array( $pItemId );
+ } elseif( is_numeric( $pMenuId ) ) {
+ $query .= ' WHERE tnmi.`menu_id`=?';
+ $bindVars = array( $pMenuId );
+ }
+ $query .= ' ORDER BY tnmi.`pos`';
+ $result = $this->query( $query,array( $bindVars ) );
+ while( !$result->EOF ) {
+ $item = $result->fields;
+ $item['display_url'] = $this->printUrl( $item );
+ $ret[$item['item_id']] = $item;
+ $result->MoveNext();
+ }
+ // recursively add included menus
+/**/
+ // this version of the loop inserts the submenu at the point of choice
+ foreach( $ret as $item ) {
+ if( $item['rsrc_type'] == 'menu_id' ) {
+ $tmp = $this->getItemList( $item['rsrc'] );
+ foreach( $tmp as $i ) {
+ if( $i['parent_id'] == 0 ) {
+ $tmp[$i['item_id']]['parent_id'] = $item['item_id'];
+ }
+ // pass all items on to ret
+ $ret[$i['item_id']] = $tmp[$i['item_id']];
+ }
+ }
+ }
+/** /
+ // this version of the loop inserts the submenu at the point of choice but removes the insersion node and adjusts the pos accordingly
+ // this isn't working the way it should.
+ foreach( $ret as $item ) {
+ if( $item['rsrc_type'] == 'menu_id' ) {
+ $tmp = $this->getItemList( $item['rsrc'] );
+ // reposition items that are inserted in parent level
+ $pos = $item['pos'];
+ foreach( $tmp as $i ) {
+ if( $i['parent_id'] == 0 ) {
+// vd($i);
+ $tmp[$i['item_id']]['parent_id'] = $item['parent_id'];
+ $tmp[$i['item_id']]['pos'] = $pos++;
+// vd($pid);
+ }
+// vd($pid);
+ // pass all items on to ret using correct key
+ $ret[$i['item_id']] = $tmp[$i['item_id']];
+ // remove the item where we inserted the menu
+ unset( $ret[$item['item_id']] );
+ }
+ }
+ }
+/**/
+// vd($ret);
+ return $ret;
+ }
+
+ /**
+ * Create the correct url for a given item
+ * @param $pItemHash complete item hash
+ * @return url
+ */
+ function printUrl( $pItemHash ) {
+ $ret = NULL;
+ if( isset( $pItemHash['rsrc'] ) && isset( $pItemHash['rsrc_type'] ) ) {
+ switch( $pItemHash['rsrc_type'] ) {
+ case 'external':
+ case 'internal':
+ $ret .= $pItemHash['rsrc'];
+ break;
+ case 'content_id':
+ $ret .= BIT_ROOT_URL.'index.php?content_id='.$pItemHash['rsrc'];
+ break;
+ case 'structure_id':
+ $ret .= BIT_ROOT_URL.'index.php?structure_id='.$pItemHash['rsrc'];
+ break;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Verify rsrc handed to us and specify what type it is
+ * @return fixed rsrc and corresponding rsrc_type
+ */
+ function verifyRsrc( &$pParamHash ) {
+ $tiki_root_pattern = "/^".preg_replace( "/\//", "\/", BIT_ROOT_URL )."/i";
+ if( preg_match( "/^(http:\/\/)/i", $pParamHash['rsrc'] ) ) {
+ $pParamHash['rsrc_type'] = 'external';
+ } elseif( is_numeric( $pParamHash['rsrc'] ) ) {
+ // if the resource type is numeric but we don't know what type it is, assume that it's a content_id
+ if( !isset( $pParamHash['rsrc_type'] ) ) {
+ $pParamHash['rsrc_type'] = 'content_id';
+ }
+ } elseif( preg_match( $tiki_root_pattern, $pParamHash['rsrc'] ) ) {
+ // if BIT_ROOT_URL can be found at the beginning of the string, assume it's an internal link
+ // in most cases this will only be a '/' but hopefully that's enough
+ $pParamHash['rsrc_type'] = 'internal';
+ } else {
+ // if we haven't caught this resource yet, we just prepend it with BIT_ROOT_URL and hope for the best
+ $pParamHash['rsrc'] = BIT_ROOT_URL.$pParamHash['rsrc'];
+ $pParamHash['rsrc_type'] = 'internal';
+ }
+ }
+
+ /**
+ * Verify if a given menu item contains all required information and prepare menu_items table for item insertion.
+ * @return number of errors encountered
+ */
+ function verifyItem( &$pParamHash ) {
+ if( empty( $pParamHash['hint'] ) ) { $pParamHash['hint'] = NULL; }
+ if( empty( $pParamHash['perm'] ) ) { $pParamHash['perm'] = NULL; }
+ if( empty( $pParamHash['title'] ) ) {
+ $this->mErrors['error'] = 'Could not store menu item. No item title was given.';
+ }
+ if( empty( $pParamHash['menu_id'] ) || !is_numeric( $pParamHash['menu_id'] ) ) {
+ $this->mErrors['error'] = 'Could not store menu item. Invalid menu id. Menu id: '.$pParamHash['menu_id'];
+ } else {
+ $this->mDb->StartTrans();
+ if( empty( $pParamHash['parent_id'] ) || !is_numeric( $pParamHash['parent_id'] ) ) {
+ $pParamHash['parent_id'] = 0;
+ // if no parent_id is not known, but we have an after_ref_id, we use that to work out the parent_id
+ if( !empty( $pParamHash['after_ref_id'] ) ) {
+ $pParamHash['parent_id'] = $this->getOne("SELECT `parent_id` FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `item_id`=?", array( (int)$pParamHash['after_ref_id'] ) );
+ }
+ }
+ $pParamHash['max'] = 0;
+ if( !empty( $pParamHash['after_ref_id'] ) && is_numeric( $pParamHash['after_ref_id'] ) ) {
+ $pParamHash['max'] = $this->getOne("SELECT `pos` FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `item_id`=?", array( (int)$pParamHash['after_ref_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."tiki_nexus_menu_items` SET `pos`=`pos`+1 WHERE `pos`>? AND `parent_id`=?";
+ $result = $this->query( $query, array( (int)$pParamHash['max'], (int)$pParamHash['parent_id'] ) );
+ }
+ }
+ $this->mDb->CompleteTrans();
+ $pParamHash['max']++;
+ // if we get passed the position of where the item is to go, we pass it to 'max' -- used for importStructure()
+ if( !empty( $pParamHash['pos'] ) && is_numeric( $pParamHash['pos'] ) && empty( $pParamHash['after_ref_id'] ) ) {
+ $pParamHash['max'] = $pParamHash['pos'];
+ }
+ // work out what type of rsrc was passed in and fix
+ if( !empty( $pParamHash['rsrc'] ) ) {
+ $this->verifyRsrc( $pParamHash );
+ } else {
+ $pParamHash['rsrc'] = NULL;
+ $pParamHash['rsrc_type'] = NULL;
+ }
+ }
+ return( count( $this->mErrors ) == 0 );
+ }
+
+ /**
+ * Create a menu item entry
+ * @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 title The wiki page to reference
+ * @return the new entries item_id or FALSE if not created.
+ */
+ function storeItem( &$pParamHash ) {
+ $ret = FALSE;
+ if ( $this->verifyItem( $pParamHash ) ) {
+ $this->mDb->StartTrans();
+ if( empty( $pParamHash['item_id'] ) ) {
+ $query = "INSERT INTO `".BIT_DB_PREFIX."tiki_nexus_menu_items`( `menu_id`,`parent_id`,`pos`,`title`,`hint`,`rsrc`,`rsrc_type`,`perm` ) VALUES( ?,?,?,?,?,?,?,? )";
+ $result = $this->query( $query, array( (int)$pParamHash['menu_id'], (int)$pParamHash['parent_id'], (int)$pParamHash['max'], $pParamHash['title'], $pParamHash['hint'], $pParamHash['rsrc'], $pParamHash['rsrc_type'], $pParamHash['perm'] ) );
+ $query = "SELECT MAX(`item_id`) FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items`";
+ $ret = $this->getOne( $query, array() );
+ } else {
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `title`=?, `hint`=?, `rsrc`=?, `rsrc_type`=?, `perm`=? WHERE `item_id`=?";
+ $result = $this->query( $query, array( $pParamHash['title'], $pParamHash['hint'], $pParamHash['rsrc'], $pParamHash['rsrc_type'], $pParamHash['perm'], $pParamHash['item_id'] ) );
+ $ret = $pParamHash['item_id'];
+ }
+ $this->mDb->CompleteTrans();
+ $this->writeModuleCache( $pParamHash['menu_id'] );
+ } else {
+ return( count( $this->mErrors ) == 0 );
+ }
+ return $ret;
+ }
+
+ /**
+ * Delete item
+ * @param $pItemId item to be removed
+ * @return deleted item information
+ */
+ function expungeItem( $pItemId=NULL, $pWriteCache=TRUE ) {
+ if( isset( $pItemId ) && is_numeric( $pItemId ) ) {
+ // get full information of item that we are removing
+ $remItem = $this->getItemList( NULL, $pItemId );
+ $remItem = $remItem[$pItemId];
+ $this->mDb->StartTrans();
+ // get all items that are on the same level
+ $query = "SELECT * FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `parent_id`=? ORDER BY `pos`";
+ $result = $this->query( $query, array( $pItemId ) );
+ // this value is needed to correclty position items that are moved up a level
+ $pos_count = 0;
+ // first we move children up one level
+ while( !$result->EOF ) {
+ $item = $result->fields;
+ //Make a space for the item after its parent
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `pos`=`pos`+1 WHERE `pos`>?+".$pos_count." AND `parent_id`=? AND `menu_id`=?";
+ $res = $this->query( $query, array( (int)$remItem['pos'], (int)$remItem['parent_id'], (int)$remItem['menu_id'] ) );
+ // increase insertion count here
+ $pos_count++;
+ // move item up one level
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `parent_id`=?, `pos`=?+".$pos_count." WHERE `item_id`=?";
+ $this->query( $query, array( (int)$remItem['parent_id'], (int)$remItem['pos'], (int)$item['item_id'] ) );
+ $result->MoveNext();
+ }
+ // all items below remItem have to be shifted up by one
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `pos`=`pos`-1 WHERE `pos`>? AND `parent_id`=? AND `menu_id`=?";
+ $this->query( $query, array( (int)$remItem['pos'], (int)$remItem['parent_id'], (int)$remItem['menu_id'] ) );
+ // finally, we are ready do delete remItem
+ $query = "DELETE FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `item_id`=?";
+ $result = $this->query( $query, array( $pItemId ) );
+ $this->mDb->CompleteTrans();
+ return $remItem;
+ if( $pWriteCache ) {
+ $this->writeModuleCache( $remItem['menu_id'] );
+ }
+ } else {
+ $this->mErrors['error'] = "The menu item could not be removed because no valid item id was given";
+ return FALSE;
+ }
+ }
+
+ /**
+ * Remove items to content that has been removed
+ * @param $pMenuId menu from which we want to remove dead links
+ * @return titles of links removed
+ * @TODO check for items in structures. if they don't exist there, replace them with the appropriate content id
+ */
+ function expungeDeadItems( $pMenuId=NULL ) {
+ if( isset( $pMenuId ) && is_numeric( $pMenuId ) ) {
+ // get $contentList
+ include_once( LIBERTY_PKG_PATH.'get_content_list_inc.php' );
+ foreach( $contentList['data'] as $contentItem ) {
+ $contentIds[] = $contentItem['content_id'];
+ }
+ $deathList = FALSE;
+ foreach( $this->mInfo['items'] as $item ) {
+ if( $item['rsrc_type'] == 'content_id' && !in_array( $item['rsrc'], $contentIds ) ) {
+ $this->expungeItem( $item['item_id'], FALSE );
+ $deathList[] = $item['title'];
+ }
+ }
+ $this->writeModuleCache( $pMenuId );
+ }
+ return $deathList;
+ }
+
+ /**
+ * Move item west
+ * @param $pItemId item id of item to be moved
+ */
+ function moveItemWest( $pItemId=NULL ) {
+ if( $this->isValid() && $pItemId ) {
+ // pass current item into managable array
+ $item = $this->mInfo["items"][$pItemId];
+ // if there is a parent and the parent isnt the menu root item.
+ if( $item['parent_id'] > 0 ) {
+ $parentItem = $this->getItemList( $this->mMenuId, (int)$item["parent_id"] );
+ $parentItem = $parentItem[$item["parent_id"]];
+ $this->mDb->StartTrans();
+ if( empty( $parentItem["parent_id"] ) ) {
+ $max_row = $this->getOne("SELECT `pos` FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `item_id`=?", array( $item['parent_id'] ) );
+ $parent_item['pos'] = $max_row;
+ $parent_item['parent_id'] = 0;
+ }
+ //Make a space for the item after its parent
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `pos`=`pos`+1 WHERE `pos`>? AND `parent_id`=?";
+ $this->query( $query, array( (int)$parentItem["pos"], (int)$parentItem["parent_id"] ) );
+ //Move the item up one level
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `parent_id`=?, `pos`=(? + 1) WHERE `item_id`=?";
+ $this->query($query, array( (int)$parentItem["parent_id"], (int)$parentItem["pos"], $pItemId ) );
+ $this->mDb->CompleteTrans();
+ $this->writeModuleCache( $item['menu_id'] );
+ }
+ }
+ }
+
+ /**
+ * Move item east
+ * @param $pItemId item id of item to be moved
+ */
+ function moveItemEast( $pItemId=NULL ) {
+ if( $this->isValid() && $pItemId ) {
+ // pass current item into managable array
+ $item = $this->mInfo["items"][$pItemId];
+ $this->mDb->StartTrans();
+ $query = "SELECT `item_id`, `pos` FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `pos`<? AND `parent_id`=? AND `menu_id`=? ORDER BY `pos` DESC";
+ $result = $this->query( $query, array( (int)$item["pos"], (int)$item["parent_id"], (int)$item["menu_id"] ) );
+ if( $previous = $result->fetchRow() ) {
+ //Get last child item for previous sibling
+ $query = "SELECT `pos` FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `parent_id`=? AND `menu_id`=? ORDER BY `pos` DESC";
+ $result = $this->query( $query, array( (int)$previous["item_id"], (int)$item["menu_id"] ) );
+ if( $res = $result->fetchRow() ) {
+ $pos = $res["pos"];
+ } else {
+ $pos = 0;
+ }
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `parent_id`=?, `pos`=(? + 1) WHERE `item_id`=?";
+ $this->query( $query, array( (int)$previous["item_id"], (int)$pos, (int)$item["item_id"] ) );
+ //Move items up below that had previous parent and pos
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `pos`=`pos`-1 WHERE `pos`>? AND `parent_id`=? AND `menu_id`=?";
+ $this->query( $query, array( $item["pos"], $item["parent_id"], $item["menu_id"] ) );
+ $this->mDb->CompleteTrans();
+ $this->writeModuleCache( $item['menu_id'] );
+ }
+ }
+ }
+
+ /**
+ * Move item south
+ * @param $pItemId item id of item to be moved
+ */
+ function moveItemSouth( $pItemId=NULL ) {
+ if( $this->isValid() && $pItemId ) {
+ // pass current item into managable array
+ $item = $this->mInfo["items"][$pItemId];
+ $this->mDb->StartTrans();
+ $query = "SELECT `item_id`, `pos` FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `pos`>? AND `parent_id`=? ORDER BY `pos` ASC";
+ $result = $this->query( $query, array( (int)$item["pos"], (int)$item["parent_id"] ) );
+ if( $res = $result->fetchRow() ) {
+ //Swap position values
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `pos`=? WHERE `item_id`=?";
+ $this->query( $query, array( (int)$item["pos"], (int)$res["item_id"] ) );
+ $this->query( $query, array( (int)$res["pos"], (int)$item["item_id"] ) );
+ }
+ $this->mDb->CompleteTrans();
+ $this->writeModuleCache( $item['menu_id'] );
+ }
+ }
+
+ /**
+ * Move item north
+ * @param $pItemId item id of item to be moved
+ */
+ function moveItemNorth( $pItemId=NULL ) {
+ if( $this->isValid() && $pItemId ) {
+ // pass current item into managable array
+ $item = $this->mInfo["items"][$pItemId];
+ $this->mDb->StartTrans();
+ $query = "SELECT `item_id`, `pos` from `".BIT_DB_PREFIX."tiki_nexus_menu_items` WHERE `pos`<? AND `parent_id`=? ORDER BY `pos` desc";
+ $result = $this->query( $query, array((int)$item["pos"], (int)$item["parent_id"] ) );
+ if( $res = $result->fetchRow() ) {
+ //Swap position values
+ $query = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_menu_items` SET `pos`=? WHERE `item_id`=?";
+ $this->query( $query, array( (int)$res["pos"], (int)$item["item_id"] ) );
+ $this->query( $query, array( (int)$item["pos"], (int)$res["item_id"] ) );
+ }
+ $this->mDb->CompleteTrans();
+ $this->writeModuleCache( $item['menu_id'] );
+ }
+ }
+
+ /**
+ * Imports a structure from tiki_structures to nexus including hierarchy
+ * @return number of errors encountered
+ */
+ function importStructure( $pStructureId=NULL ) {
+ if( $pStructureId || !is_numeric( $pStructureId ) ) {
+ include_once( LIBERTY_PKG_PATH.'LibertyStructure.php');
+ $structure = new LibertyStructure( $pStructureId );
+ $structure->load();
+
+ // order matters for these conditionals
+ if( empty( $structure ) || !$structure->isValid() ) {
+ $this->mErrors['structure'] = 'Invalid structure';
+ }
+
+ if( $structure->mInfo['root_structure_id'] == $structure->mInfo['structure_id'] ) {
+ $rootStructure = &$structure;
+ } else {
+ $rootStructure = new LibertyStructure( $structure->mInfo['root_structure_id'] );
+ $rootStructure->load();
+ }
+ $structureList = $rootStructure->getSubTree( $rootStructure->mInfo['structure_id'] );
+ $menuHash['title'] = $rootStructure->mInfo['title'];
+ if( $menu_id = $this->storeMenu( $menuHash ) ) {
+ // we need to insert the structure title manually, as this is not part of the structure
+ $itemHash = array(
+ 'menu_id' => $menu_id,
+ 'title' => $rootStructure->mInfo['title'],
+ 'pos' => 1,
+ 'parent_id' => 0,
+ 'rsrc' => $rootStructure->mInfo['structure_id'],
+ 'rsrc_type' => 'structure_id'
+ );
+ $storedItem = $this->storeItem( $itemHash );
+
+ // insert all nodes in structure as menu items
+ foreach( $structureList as $structureItem ) {
+ if( $structureItem['first'] ) {
+ // get id of the current item
+ $query = "SELECT MAX(`item_id`) FROM `".BIT_DB_PREFIX."tiki_nexus_menu_items`";
+ $parentPath[] = $this->getOne( $query, array() );
+ $parent_id = end( $parentPath );
+ }
+ if( $structureItem['last'] ) {
+ // move up one step in the structure parentPath
+ array_pop( $parentPath );
+ $parent_id = end( $parentPath );
+ } else {
+ // save the item in the menu
+ $tmpItem = $rootStructure->getNode( $structureItem['structure_id'] );
+ $itemHash = array(
+ 'menu_id' => $menu_id,
+ 'title' => $structureItem['title'],
+ 'pos' => $tmpItem['pos'],
+ 'parent_id' => $parent_id,
+ 'rsrc' => isset( $structureItem['structure_id'] ) ? $structureItem['structure_id'] : NULL,
+ 'rsrc_type' => 'structure_id'
+ );
+ $storedItem = $this->storeItem( $itemHash );
+ }
+ }
+ } else {
+ $this->mErrors['menu'] = 'The menu could not be stored.';
+ }
+ } else {
+ $this->mErrors['structure'] = 'No valid structure id was given.';
+ }
+ return( count( $this->mErrors ) == 0 );
+ }
+
+ /**
+ * writes cache files to where the plugins determine
+ * @param $pMenuId menu id of the menu for which we want to create a cache file
+ * @return number of errors encountered
+ */
+ function writeModuleCache( $pMenuId=NULL ) {
+ if( $this->isValid() && !isset( $pMenuId ) ) {
+ $pMenuId = $this->mInfo['menu_id'];
+ }
+ // if the cache folder doesn't exist yet, create item
+ if( !is_dir( TEMP_PKG_PATH.'nexus' ) ) {
+ mkdir( TEMP_PKG_PATH.'nexus', 0777 );
+ mkdir( TEMP_PKG_PATH.'nexus/modules', 0777 );
+ }
+ // load the menu to make sure we have the latest version
+ $cacheMenu = new Nexus( $pMenuId );
+ if( !empty( $cacheMenu->mInfo['plugin_guid'] ) ) {
+ global $gNexusSystem;
+ if( $func = $gNexusSystem->getPluginFunction( $cacheMenu->mInfo['plugin_guid'], 'write_cache_function' ) ) {
+ $moduleCache = $func( $cacheMenu );
+ }
+ }
+ if( isset( $moduleCache ) ) {
+ foreach( $moduleCache as $cache_file => $cache_string ) {
+ $h = fopen( TEMP_PKG_PATH.'nexus/modules/'.$cache_file, 'w' );
+ if( isset( $h ) ) {
+ fwrite( $h, $cache_string );
+ fclose( $h );
+ } else {
+ $this->mErrors['error'][] = "Unable to write to ".realpath( $cache_file );
+ }
+ }
+ } else {
+ $this->mErrors['error'][] = "Unable to write the cache file because there was something wrong with the plugin: ".$cacheMenu->mInfo['plugin_guid'];
+ }
+ return( count( $this->mErrors ) == 0 );
+ }
+
+ /**
+ * function to write a js file with an array of menus that require the hoverfix for MSIE
+ * @return number of errors encountered
+ */
+ function writeMsieJs() {
+ global $gBitSystem;
+ $menuList = $this->getMenuList();
+ $jsMenuIds = array();
+ foreach( $menuList as $menu ) {
+ $jsMenuIds[] = $menu['menu_id'];
+ }
+ $cache_path = ( TEMP_PKG_PATH.'nexus/modules/hoverfix_array.js' );
+ $cache_file = fopen( $cache_path, 'w' );
+ if( isset( $cache_file ) ) {
+ $fw = 'nexusMenus.push(';
+ foreach( $jsMenuIds as $key => $menu_id ) {
+ $fw .= ( $key == 0 ) ? '' : ',';
+ $fw .= '"nexus'.$menu_id.'"';
+ }
+ $fw .= ');';
+ fwrite( $cache_file, $fw );
+ fclose( $cache_file );
+ } else {
+ $this->mErrors['chachefile'] = "Unable to write to ".realpath( $cache_path );
+ }
+ return( count( $this->mErrors ) == 0 );
+ }
+
+ /**
+ * This is not in use yet. would be good if this could be updated directly from the db
+ */
+ function getGalleryListMenu( $pParentId=NULL ) {
+ global $gBitSystem, $gFisheyeGallery;
+ require_once( FISHEYE_PKG_PATH.'FisheyeGallery.php');
+
+ $gFisheyeGallery = new FisheyeGallery();
+
+ $hash['root_only'] = TRUE;
+ $hash['get_thumbnails'] = FALSE;
+ $galleryList = $gFisheyeGallery->getList( $hash );
+
+ foreach( $galleryList as $key => $gal ) {
+ $itemHash['item_id'] = 'gl'.$key;
+ $itemHash['parent_id'] = $pParentId;
+ $itemHash['title'] = $gal['title'];
+ $itemHash['rsrc'] = $gal['content_id'];
+ $itemHash['rsrc_type'] = 'content_id';
+ $ret['gl'.$key] = $itemHash;
+ }
+ return $ret;
+ }
+}
+?>
diff --git a/NexusSystem.php b/NexusSystem.php
new file mode 100644
index 0000000..68489cd
--- /dev/null
+++ b/NexusSystem.php
@@ -0,0 +1,133 @@
+<?php
+/**
+* Nexus system class for handling the menu plugins
+*
+* @abstract
+* @author xing <xing@synapse.plus.com>
+* @copied copied from LibertySystem.php
+* @version $Revision: 1.1 $
+* @package Nexus
+*/
+
+// for menus that use regular HTML as output
+define( 'NEXUS_HTML_PLUGIN', 'nexushtml' );
+define( 'NEXUS_DEFAULT_GUID', 'suckerfish' );
+
+require_once( KERNEL_PKG_PATH.'BitBase.php' );
+
+class NexusSystem extends BitBase {
+
+ var $mPlugins;
+
+ function NexusSystem() {
+ BitBase::BitBase();
+ $this->loadPlugins();
+ }
+
+ function loadPlugins( $pCacheTime=BIT_QUERY_CACHE_TIME ) {
+ $rs = $this->query( "SELECT * FROM `".BIT_DB_PREFIX."tiki_nexus_plugins`", NULL, BIT_QUERY_DEFAULT, BIT_QUERY_DEFAULT );
+ while( $rs && !$rs->EOF ) {
+ $this->mPlugins[$rs->fields['plugin_guid']] = $rs->fields;
+ $rs->MoveNext();
+ }
+ }
+
+ function scanPlugins() {
+ $pluginsPath = NEXUS_PKG_PATH.'plugins/';
+ if( $pluginDir = opendir( $pluginsPath ) ) {
+ // Scan the plugins directory for plugins
+ while( FALSE !== ( $plugin = readdir( $pluginDir ) ) ) {
+ if( preg_match( '/\.php$/', $plugin ) ) {
+ include_once( $pluginsPath.$plugin );
+ }
+ }
+ }
+
+ // match up storage_type_id to plugin_guids. this _id varies from install to install, but guids are the same
+ foreach( array_keys( $this->mPlugins ) as $guid ) {
+ $handler = &$this->mPlugins[$guid]; //shorthand var alias
+ if( !isset( $handler['verified'] ) && $handler['is_active'] =='y' ) {
+ // We are missing a plugin!
+ $sql = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_plugins` SET `is_active`='x' WHERE `plugin_guid`=?";
+ $this->query( $sql, array( $guid ) );
+ $handler['is_active'] = 'n';
+ } elseif( !empty( $handler['verified'] ) && $handler['is_active'] =='x' ) {
+ //We found a formally missing plugin - re-enable it
+ $sql = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_plugins` SET `is_active`='y' WHERE `plugin_guid`=?";
+ $this->query( $sql, array( $guid ) );
+ $handler['is_active'] = 'y';
+ } elseif( empty( $handler['verified'] ) && !isset( $handler['is_active'] ) ) {
+ //We found a missing plugin - insert it
+ $sql = "INSERT INTO `".BIT_DB_PREFIX."tiki_nexus_plugins` ( `plugin_guid`, `plugin_type`, `plugin_description`, `is_active` ) VALUES ( ?, ?, ?, 'y' )";
+ $this->query( $sql, array( $guid, $handler['plugin_type'], $handler['description'] ) );
+ $handler['is_active'] = 'y';
+ }
+ }
+ if( !empty( $sql ) ) {
+ // we just ran some SQL - let's flush the loadPlugins query cache
+ $this->loadPlugins( 0 );
+ }
+ asort( $this->mPlugins );
+ }
+
+ function registerPlugin( $pGuid, $pPluginParams ) {
+ if( isset( $this->mPlugins[$pGuid] ) ) {
+ $this->mPlugins[$pGuid]['verified'] = TRUE;
+ } else {
+ $this->mPlugins[$pGuid]['verified'] = FALSE;
+ }
+ $this->mPlugins[$pGuid] = array_merge( $this->mPlugins[$pGuid], $pPluginParams );
+ }
+
+ // @parameter pPluginGuids an array of all the plugin guids that are active. Any left out are *inactive*!
+ function setActivePlugins( $pPluginGuids ) {
+ if( is_array( $pPluginGuids ) ) {
+ $sql = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_plugins` SET `is_active`='n' WHERE `is_active`!='x'";
+ $this->query( $sql );
+ foreach( array_keys( $this->mPlugins ) as $guid ) {
+ $this->mPlugins[$guid]['is_active'] = 'n';
+ }
+
+ foreach( array_keys( $pPluginGuids ) as $guid ) {
+ $sql = "UPDATE `".BIT_DB_PREFIX."tiki_nexus_plugins` SET `is_active`='y' WHERE `plugin_guid`=?";
+ $this->query( $sql, array( $guid ) );
+ $this->mPlugins[$guid]['is_active'] = 'y';
+ }
+ // we just ran some SQL - let's flush the loadPlugins query cache
+ $this->loadPlugins( 0 );
+ }
+ }
+
+ function getPluginFunction( $pGuid, $pFunctionName ) {
+ $ret = NULL;
+ if( !empty( $pGuid )
+ && !empty( $this->mPlugins[$pGuid] )
+ && !empty( $this->mPlugins[$pGuid][$pFunctionName] )
+ && function_exists( $this->mPlugins[$pGuid][$pFunctionName] )
+ ) {
+ $ret = $this->mPlugins[$pGuid][$pFunctionName];
+ }
+ return $ret;
+ }
+
+ /**
+ * fucntion to store pluging settings
+ * $param $pParamHash contains settings for any guid that require updating
+ * return TRUE
+ */
+ function storePluginSettings( $pParamHash ) {
+ // first get all values from tiki_nexus_plugin_settings to see which ones need updating and which ones are added for the first time
+ $rs = $this->query( "SELECT * FROM `".BIT_DB_PREFIX."tiki_nexus_plugin_settings`", NULL );
+ while( $rs && !$rs->EOF ) {
+ $settings[] = $rs->fields;
+ $rs->MoveNext();
+ }
+ vd($settings);
+ }
+}
+
+global $gNexusSystem;
+$gNexusSystem = new NexusSystem();
+$gNexusSystem->scanPlugins();
+$smarty->assign_by_ref( 'gNexusSystem', $gNexusSystem );
+?>
diff --git a/admin/nexus_plugins.php b/admin/nexus_plugins.php
new file mode 100644
index 0000000..194c4e8
--- /dev/null
+++ b/admin/nexus_plugins.php
@@ -0,0 +1,12 @@
+<?php
+require_once( '../../bit_setup_inc.php' );
+global $gBitSystem;
+require_once( NEXUS_PKG_PATH.'Nexus.php');
+
+if( isset( $_REQUEST['store_plugins'] ) ) {
+ $gNexusSystem->setActivePlugins( $_REQUEST['PLUGINS'] );
+}
+
+$gBitSystem->setBrowserTitle( 'Nexus Menus' );
+$gBitSystem->display( 'bitpackage:nexus/nexus_plugins.tpl' );
+?>
diff --git a/admin/schema_inc.php b/admin/schema_inc.php
new file mode 100644
index 0000000..5846db8
--- /dev/null
+++ b/admin/schema_inc.php
@@ -0,0 +1,60 @@
+<?php
+
+$tables = array(
+'tiki_nexus_plugins' => "
+ plugin_guid C(16) PRIMARY,
+ plugin_type C(16) NOTNULL,
+ is_active C(1) NOTNULL DEFAULT 'y',
+ plugin_description C(250),
+ maintainer_url C(250)
+",
+
+'tiki_nexus_menus' => "
+ menu_id I4 AUTO PRIMARY,
+ plugin_guid C(16) NOTNULL,
+ title C(128),
+ description C(255),
+ type C(16),
+ editable I4 DEFAULT 0
+",
+
+'tiki_nexus_menu_items' => "
+ item_id I4 AUTO PRIMARY,
+ menu_id I4 DEFAULT 0,
+ parent_id I4,
+ ext_menu I4,
+ pos I4,
+ title C(128),
+ hint C(255),
+ rsrc C(255),
+ rsrc_type C(16),
+ perm C(128)
+",
+);
+
+global $gBitInstaller;
+
+foreach( array_keys( $tables ) AS $tableName ) {
+ $gBitInstaller->registerSchemaTable( NEXUS_PKG_NAME, $tableName, $tables[$tableName] );
+}
+
+$gBitInstaller->registerPackageInfo( NEXUS_PKG_NAME, array(
+ 'description' => 'Nexus allows you to create multi level menus using a simple and intuitive interface. Menus can be of a dropdown style using css.',
+ 'license' => '<a href="http://www.gnu.org/licenses/licenses.html#LGPL">LGPL</a>',
+ 'version' => '0.1',
+ 'state' => 'experimental',
+ 'dependencies' => '',
+) );
+
+// ### Default UserPermissions
+$gBitInstaller->registerUserPermissions( NEXUS_PKG_NAME, array(
+ array('bit_p_insert_nexus_item', 'Can insert menu item in a menu while editing a page', 'editor', NEXUS_PKG_NAME),
+ array('bit_p_create_nexus_menus', 'Can create new menus using Nexus', 'editor', NEXUS_PKG_NAME),
+) );
+
+// ### Default Preferences
+$gBitInstaller->registerPreferences( NEXUS_PKG_NAME, array(
+// array(NEXUS_PKG_NAME, 'pref','value'),
+) );
+
+?>
diff --git a/bit_setup_inc.php b/bit_setup_inc.php
new file mode 100644
index 0000000..2e6a019
--- /dev/null
+++ b/bit_setup_inc.php
@@ -0,0 +1,10 @@
+<?php
+global $gBitSystem, $gBitUser;
+$gBitSystem->registerPackage( 'nexus', dirname( __FILE__).'/' );
+
+if( $gBitSystem->isPackageActive( 'nexus' ) ) {
+ if( $gBitUser->isAdmin() ) {
+ $gBitSystem->registerAppMenu( 'nexus', 'Nexus', NEXUS_PKG_URL.'index.php', 'bitpackage:nexus/menu_nexus.tpl', 'Nexus menus');
+ }
+}
+?>
diff --git a/icons/menu.gif b/icons/menu.gif
new file mode 100644
index 0000000..a063667
--- /dev/null
+++ b/icons/menu.gif
Binary files differ
diff --git a/icons/organise.png b/icons/organise.png
new file mode 100644
index 0000000..8df04ad
--- /dev/null
+++ b/icons/organise.png
Binary files differ
diff --git a/icons/pkg_nexus.png b/icons/pkg_nexus.png
new file mode 100644
index 0000000..5b39f3b
--- /dev/null
+++ b/icons/pkg_nexus.png
Binary files differ
diff --git a/icons/remove_dead.png b/icons/remove_dead.png
new file mode 100644
index 0000000..502ee62
--- /dev/null
+++ b/icons/remove_dead.png
Binary files differ
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..d121ea5
--- /dev/null
+++ b/index.php
@@ -0,0 +1,3 @@
+<?php
+header("location: menus.php");
+?>
diff --git a/insert_menu_item_inc.php b/insert_menu_item_inc.php
new file mode 100644
index 0000000..2c01fa2
--- /dev/null
+++ b/insert_menu_item_inc.php
@@ -0,0 +1,31 @@
+<?php
+require_once( NEXUS_PKG_PATH.'Nexus.php');
+include_once( NEXUS_PKG_PATH.'menu_lookup_inc.php' );
+
+$nexusList = $gNexus->getMenuList();
+$smarty->assign( 'nexusList', $nexusList );
+
+// nexusHash['title'] must already be set before calling this file
+if( isset( $nexusHash ) && !empty( $_REQUEST['nexus']['menu_id'] ) ) {
+ $nexusHash['menu_id'] = $_REQUEST['nexus']['menu_id'];
+ $nexusHash['after_ref_id'] = $_REQUEST['nexus']['after_ref_id'];
+ $nexusHash['rsrc'] = $gContent->mContentId;
+ $nexusHash['rsrc_type'] = 'content_id';
+ if( !$gNexus->storeItem( $nexusHash ) ) {
+ vd( $gNexus->mErrors );
+ }
+ $gNexus->load();
+} elseif( isset( $nexusHash ) && !empty( $_REQUEST['nexus']['remove_item'] ) ) {
+ $gNexus->expungeItem( $_REQUEST['nexus']['remove_item'] );
+} else {
+ // if the page is already present in a menu, don't allow users to add it again
+ foreach( $nexusList as $menu ) {
+ foreach( $menu['items'] as $item ) {
+ if( !empty( $item['rsrc'] ) && $item['rsrc'] == $gContent->mContentId && $item['rsrc_type'] == 'content_id' ) {
+ $smarty->assign( 'inNexusMenu', $menu );
+ $smarty->assign( 'inNexusMenuItem', $item['item_id'] );
+ }
+ }
+ }
+}
+?>
diff --git a/menu_items.php b/menu_items.php
new file mode 100644
index 0000000..cd85214
--- /dev/null
+++ b/menu_items.php
@@ -0,0 +1,102 @@
+<?php
+require_once( '../bit_setup_inc.php' );
+global $gBitSystem;
+require_once( NEXUS_PKG_PATH.'Nexus.php');
+include_once( NEXUS_PKG_PATH.'menu_lookup_inc.php' );
+
+$gBitSystem->verifyPermission( 'bit_p_create_nexus_menus' );
+
+if( empty( $_REQUEST['menu_id'] ) ) {
+ header( 'Location:'.NEXUS_PKG_URL.'index.php' );
+}
+
+// get content and pass it on
+include_once( LIBERTY_PKG_PATH.'get_content_list_inc.php' );
+$smarty->assign( 'contentSelect', $contentSelect );
+$smarty->assign( 'contentTypes', $contentTypes );
+
+$cList[''] = '';
+foreach( $contentList['data'] as $cItem ) {
+ $cList[$contentTypes[$cItem['content_type_guid']]][$cItem['content_id']] = $cItem['title'].' [id: '.$cItem['content_id'].']';
+}
+$smarty->assign( 'contentList', $cList );
+
+// store item
+if( isset( $_REQUEST['store_item'] ) ) {
+ if( $gNexus->storeItem( $_REQUEST ) ) {
+ $formfeedback['success'] = 'The menu item was saved successfully.';
+ } else {
+ $formfeedback = $gNexus->mErrors;
+ }
+ $gNexus->load();
+}
+
+if( isset( $_REQUEST['remove_item'] ) && is_array( $_REQUEST['remove_item'] ) ) {
+ $delList = '<ul>';
+ foreach( $_REQUEST['remove_item'] as $rem_id ) {
+ if( $delItem = $gNexus->expungeItem( $rem_id, FALSE ) ) {
+ $delList .= '<li>'.$delItem['title'].'</li>';
+ } else {
+ $formfeedback = $gNexus->mErrors;
+ }
+ }
+ $delList .= '</ul>';
+ if( isset( $delList ) ) {
+ $formfeedback['success'] = 'The following items were successfully removed from the menu'.$delList;
+ }
+ $gNexus->load();
+ $gNexus->writeModuleCache();
+}
+
+if( !empty( $_REQUEST['item_id'] ) ) {
+ $smarty->assign( 'editItem', $gNexus->mInfo['items'][$_REQUEST['item_id']] );
+}
+// when we use the content type dropdown or the filter, we need to pass back the information to the tpl
+if( isset( $_REQUEST['find_objects'] ) && !isset( $_REQUEST['store_item'] ) ) {
+ $smarty->assign( 'editItem', $_REQUEST );
+}
+if( isset( $_REQUEST['tab'] ) ) {
+ $smarty->assign( $_REQUEST['tab'].'TabSelect', 'tdefault' );
+}
+if( isset( $formfeedback ) ) {
+ $smarty->assign( 'formfeedback', $formfeedback );
+}
+
+// get all available perms only when the admin is visiting here.
+if( $gBitUser->isAdmin() ) {
+ $tmpPerms = $gBitUser->getGroupPermissions();
+} else {
+ $tmpPerms = $gBitUser->mPerms;
+}
+$perms['no permission'][''] = 'none';
+foreach( $tmpPerms as $perm => $info ) {
+ $perms[$info['package']][$perm] = $perm;
+}
+$smarty->assign( 'perms', $perms );
+
+// get a list of available resource types
+$rsrcTypes = array(
+ 'external' => 'URL',
+ 'content_id' => 'Content ID',
+ 'structure_id' => 'Structure ID',
+ 'menu_id' => 'Menu ID',
+// 'gallery_list' => 'Gallery List', // this is not in use yet - xing
+);
+$smarty->assign( 'rsrcTypes', $rsrcTypes );
+
+// get all available menus that can be included
+$menuHashList = array();
+$menuList[''] = '';
+$menuHashList = $gNexus->getMenuList();
+foreach( $menuHashList as $menu ) {
+ if( $menuId != $menu['menu_id'] ) {
+ $menuList[$menu['menu_id']] = $menu['title'].' [id: '.$menu['menu_id'].']';
+ }
+}
+if( count( $menuList ) > 1 ) {
+ $smarty->assign( 'menuList', $menuList );
+}
+
+$gBitSystem->setBrowserTitle( 'Nexus Menus' );
+$gBitSystem->display( 'bitpackage:nexus/menu_items.tpl' );
+?>
diff --git a/menu_lookup_inc.php b/menu_lookup_inc.php
new file mode 100644
index 0000000..b9b76f1
--- /dev/null
+++ b/menu_lookup_inc.php
@@ -0,0 +1,14 @@
+<?php
+global $gNexus;
+
+if ( !empty( $_REQUEST['menu_id'] ) && is_numeric( $_REQUEST['menu_id'] ) ) {
+ $menuId = $_REQUEST['menu_id'];
+ $gNexus = new Nexus( $menuId );
+} else {
+ $gNexus = new Nexus();
+ $menuId = NULL;
+}
+
+$smarty->assign_by_ref( 'gNexus', $gNexus );
+$smarty->assign_by_ref( 'menuId', $menuId );
+?>
diff --git a/menu_sort.php b/menu_sort.php
new file mode 100644
index 0000000..403792b
--- /dev/null
+++ b/menu_sort.php
@@ -0,0 +1,37 @@
+<?php
+require_once( '../bit_setup_inc.php' );
+global $gBitSystem;
+require_once( NEXUS_PKG_PATH.'Nexus.php');
+include_once( NEXUS_PKG_PATH.'menu_lookup_inc.php' );
+
+$gBitSystem->verifyPermission( 'bit_p_create_nexus_menus' );
+
+if( empty( $_REQUEST['menu_id'] ) ) {
+ header( 'Location:'.NEXUS_PKG_URL.'index.php' );
+}
+
+// if someone wants to move and item, move it.
+if( isset( $_REQUEST['move_item'] ) && isset( $_REQUEST['item_id'] ) ) {
+ if( $_REQUEST['move_item'] == 'w' ) {
+ $gNexus->moveItemWest( $_REQUEST['item_id'] );
+ } elseif( $_REQUEST['move_item'] == 'n' ) {
+ $gNexus->moveItemNorth( $_REQUEST['item_id'] );
+ } elseif( $_REQUEST['move_item'] == 's' ) {
+ $gNexus->moveItemSouth( $_REQUEST['item_id'] );
+ } elseif( $_REQUEST['move_item'] == 'e' ) {
+ $gNexus->moveItemEast( $_REQUEST['item_id'] );
+ }
+ header( 'Location: '.NEXUS_PKG_URL.'menu_sort.php?menu_id='.$_REQUEST['sort_menu'].'&tab='.$_REQUEST['tab'] );
+ die;
+}
+
+if( isset( $_REQUEST['tab'] ) ) {
+ $smarty->assign( $_REQUEST['tab'].'TabSelect', 'tdefault' );
+}
+
+// this is the module filename
+$smarty->assign( 'nexus_file', strtolower( 'mod_'.preg_replace( "/ /", "_", $gNexus->mInfo['title'] ).'_'.$gNexus->mInfo['menu_id'].'.tpl' ) );
+
+$gBitSystem->setBrowserTitle( 'Nexus Menus' );
+$gBitSystem->display( 'bitpackage:nexus/menu_sort.tpl' );
+?>
diff --git a/menus.php b/menus.php
new file mode 100644
index 0000000..6a35d70
--- /dev/null
+++ b/menus.php
@@ -0,0 +1,70 @@
+<?php
+require_once( '../bit_setup_inc.php' );
+global $gBitSystem;
+require_once( NEXUS_PKG_PATH.'Nexus.php');
+include_once( NEXUS_PKG_PATH.'menu_lookup_inc.php' );
+
+$gBitSystem->verifyPermission( 'bit_p_create_nexus_menus' );
+
+if( isset( $_REQUEST['action'] ) ) {
+ if( $_REQUEST['action'] == 'edit' ) {
+ $smarty->assign( 'editMenu', $gNexus->getMenu() );
+ }
+ if( $_REQUEST['action'] == 'remove' ) {
+ $formHash['remove'] = TRUE;
+ $formHash['menu_id'] = $menuId;
+ $msgHash = array(
+ 'label' => 'Delete Menu',
+ 'confirm_item' => $gNexus->mInfo['title'],
+ 'warning' => 'This will remove this menu including all menu items associated with it.<br />This cannot be undone!',
+ );
+ $gBitSystem->confirmDialog( $formHash,$msgHash );
+ }
+ if( $_REQUEST['action'] == 'remove_dead' ) {
+ if( $deadLinks = $gNexus->expungeDeadItems( $menuId ) ) {
+ $deadHtml = '<ul>';
+ foreach( $deadLinks as $dead ) {
+ $deadHtml .= '<li>'.$dead.'</li>';
+ }
+ $deadHtml .= '</ul>';
+ $formfeedback['warning'] = 'Links that were dead and removed from '.$gNexus->mInfo['title'].$deadHtml;
+ } else {
+ $formfeedback['success'] = 'No dead links were found for this menu.';
+ }
+ }
+ if( $_REQUEST['action'] == 'convert_structure' ) {
+ if( $gNexus->importStructure( $_REQUEST['structure_id'] ) ) {
+ $formfeedback['success'] = 'The structure was successfully imported as menu.';
+ } else {
+ vd( $gNexus->mErrors );
+ }
+ }
+}
+if( isset( $_REQUEST['confirm'] ) ) {
+ if( $gNexus->expungeMenu( $menuId ) ) {
+ header ("Location: ".NEXUS_PKG_URL."menus.php");
+ die;
+ } else {
+ vd( $gNexus->mErrors );
+ }
+}
+
+if( isset( $_REQUEST['store_menu'] ) ) {
+ $menu_id = $gNexus->storeMenu( $_REQUEST );
+ // redirect to menu items page if this is a new menu
+ if( empty( $menuId ) ) {
+ header( 'Location: '.NEXUS_PKG_URL.'menu_items.php?menu_id='.$menu_id.'&tab=edit' );
+ die;
+ }
+ $gNexus->load();
+ $formfeedback['success'] = 'The menu \''.$gNexus->mInfo['title'].'\' was updated successfully.';
+}
+
+$smarty->assign( 'menuList', $gNexus->getMenuList() );
+if( isset( $formfeedback ) ) {
+ $smarty->assign( 'formfeedback', $formfeedback );
+}
+
+$gBitSystem->setBrowserTitle( 'Nexus Menus' );
+$gBitSystem->display( 'bitpackage:nexus/menus.tpl' );
+?>
diff --git a/plugins/menu.formelements.js b/plugins/menu.formelements.js
new file mode 100644
index 0000000..dbf9562
--- /dev/null
+++ b/plugins/menu.formelements.js
@@ -0,0 +1,12 @@
+AlertMsg = "Sorry, that\'\s not a valid page."
+
+function MenuNavSelect(form,elt) {
+ if (form != null) {
+ if(form.elements[elt].selectedIndex.value == 0) {
+ alert(AlertMsg);
+ form.elements[elt].selected='true';
+ } else {
+ window.location = form.elements[elt].options[form.elements[elt].selectedIndex].value;
+ }
+ }
+}
diff --git a/plugins/menu.formelements.php b/plugins/menu.formelements.php
new file mode 100644
index 0000000..1808cc8
--- /dev/null
+++ b/plugins/menu.formelements.php
@@ -0,0 +1,126 @@
+<?php
+/**
+* Plugin for Nexus for handling menus that are based on form elements
+* such as drop-down menu using select
+*
+* @abstract implements javascript menu using form elements
+* @author william@elan.net
+* @copied copied from menu.suckerfish.php originally by xing
+* @version $Revision: 1.1 $
+* @package Nexus Plugin
+*/
+
+global $gNexusSystem;
+
+define( 'NEXUS_PLUGIN_GUID_FORMELEMENTSMENU', 'formelements' );
+
+$pluginParams = array(
+ 'write_cache_function' => 'writeFormMenuCache',
+ 'description' => 'Menus using form elements',
+ 'web_link' => '',
+ 'browser_requirements' => 'This menu should work in all browsers that support javascript',
+ 'edit_label' => 'Menus using form elements',
+ 'menu_types' => array(
+ 'sdd' => array( 'label' => 'Standard DropDown', 'note' => 'drop-down menu using select with menu name on top' ),
+ 'qdd' => array( 'label' => 'Quick DropDown', 'note' => 'drop-down menu using select with menu name in drop-down select box'),
+ 's3' => array( 'label' => '3-Line Box', 'note' => 'select menu with 3 lines showing' ),
+ 's5' => array( 'label' => '5-Line Box', 'note' => 'select menu with 5 lines showing' ),
+ 'sal' => array( 'label' => 'Full Text Box', 'note' => 'select menu with all menu items showing' ),
+ ),
+ 'plugin_type' => NEXUS_HTML_PLUGIN,
+ 'include_js_in_head' => '/nexus/plugins/menu.formelements.js',
+);
+
+$gNexusSystem->registerPlugin( NEXUS_PLUGIN_GUID_FORMELEMENTSMENU, $pluginParams );
+
+/**
+* bloody mad function to write a custom cache file for an individual menu
+* @param $pMenuId menu id of the menu for which we want to create a cache file
+* @return number of errors encountered
+* @public
+*/
+function writeFormMenuCache( $pMenuHash ) {
+ global $smarty;
+ $menu_name = preg_replace( "/ +/", "_", trim( $pMenuHash->mInfo['title'] ) );
+ $menu_name = strtolower( $menu_name );
+ $menu_file = 'mod_'.$menu_name.'_'.$pMenuHash->mInfo['menu_id'].'.tpl';
+ if ( $pMenuHash->mInfo['type'] != 'qdd' ) {
+ $data = '{bitmodule title="{tr}'.$pMenuHash->mInfo['title'].'{/tr}" name="'.$menu_name.'"}';
+ }
+ else {
+ $data = '{bitmodule name="'.$menu_name.'"}';
+ }
+ // if a permission has been set, we need to work out when to close the {if} clause
+ $permCloseIds = array();
+ $perm_close = FALSE;
+ $next_cycle = FALSE;
+ foreach( $pMenuHash->mInfo['tree'] as $key => $item ) {
+ if( !empty( $item['perm'] ) ) {
+ $perm_open = '{if $gBitUser->hasPermission("'.$item['perm'].'")}';
+ }
+ if( $item['first'] ) {
+ $data .= '<form id="menu_nexus'.$pMenuHash->mInfo['menu_id'].'" action="">';
+ if ( $pMenuHash->mInfo['type'] == 'qdd' ) {
+ $data .= $smarty->fetch( NEXUS_PKG_PATH.'templates/formelements/start_center.tpl' );
+ }
+ $data .= '<select ';
+ if ( $pMenuHash->mInfo['type'] == 's3' ) {
+ $data .= 'size="3" ';
+ }
+ if ( $pMenuHash->mInfo['type'] == 's5' ) {
+ $data .= 'size="5" ';
+ }
+ if ( $pMenuHash->mInfo['type'] == 'sal' ) {
+ $data .= 'size="$pMenuHash->sizeof()" ';
+ }
+ if( $key == 0 ) {
+ $data .= ' onchange="go(this.form.elements[0]);" ';
+ $data .= ' name="menu_nexus'.$pMenuHash->mInfo['menu_id'].'" >';
+ if ( $pMenuHash->mInfo['type'] == 'sdd' ) {
+ $data .= '<option value=""></option>';
+ }
+ if ( $pMenuHash->mInfo['type'] == 'qdd' ) {
+ $data .= '<option value="">'.$pMenuHash->mInfo['title'].'</option>' ;
+ }
+ } else {
+ $data .= '>';
+ }
+ } else {
+ // close permission clauses
+ if( $next_cycle ) {
+ $data .= '{/if}';
+ $next_cycle = FALSE;
+ }
+ if( in_array( $item['item_id'], $permCloseIds ) ) {
+ $next_cycle = TRUE;
+ }
+ if( $perm_close ) {
+ $data .= '{/if}';
+ $perm_close = FALSE;
+ }
+ }
+ if( $item['last'] ) {
+ $data .= '</select>' ;
+ if ( $pMenuHash->mInfo['type'] == 'qdd' ) {
+ $data .= $smarty->fetch( NEXUS_PKG_PATH.'templates/formelements/finish_center.tpl' );
+ }
+ $data .= '</form>' ;
+ } else {
+ if( !empty( $item['perm'] ) ) {
+ // open permission if clause
+ $data .= $perm_open;
+ if( !$item['head'] ) {
+ $perm_close = TRUE;
+ } else {
+ $permCloseIds[] = $item['item_id'];
+ }
+ }
+ $smarty->assign( 'item', $item );
+ $data .= $smarty->fetch( NEXUS_PKG_PATH.'templates/formelements/item.tpl' );
+ }
+ }
+ $data .= '{/bitmodule}';
+ $ret[$menu_file] = $data;
+ return $ret;
+}
+?>
diff --git a/plugins/menu.suckerfish.php b/plugins/menu.suckerfish.php
new file mode 100644
index 0000000..e058ec8
--- /dev/null
+++ b/plugins/menu.suckerfish.php
@@ -0,0 +1,94 @@
+<?php
+/**
+* Plugin for Nexus creating a hierarchial set of items using <ul> and <li> items.
+* using the appropriate css settings, this can be transformed into a dropdown menu
+*
+* @abstract creates a simple <ul> and <li> based list of items
+* @author xing@synapse.plus.com
+* @version $Revision: 1.1 $
+* @package Nexus Plugin
+*/
+global $gNexusSystem;
+
+// GUID should be a maximum of 16 chars
+define( 'NEXUS_PLUGIN_GUID_SUCKERFISH', 'suckerfish' );
+
+$pluginParams = array(
+ 'write_cache_function' => 'writeSuckerfishCache',
+ 'description' => 'Sophisticated and flexible CSS driven dropdown menus',
+ 'web_link' => '<a class="external" href="http://www.htmldog.com/articles/suckerfish/">Sons of Suckerfish Menus</a>',
+ 'browser_requirements' => 'Many modern browsers support suckerfish menus inherently using CSS. MSIE requires javascript to be ON for them to work.',
+ 'edit_label' => 'CSS based menus',
+ 'menu_types' => array(
+ 'nor' => array( 'label' => 'Normal', 'note' => 'Nested list of menu items using "ul" and "li" HTML tags.' ),
+ 'ver' => array( 'label' => 'Vertical', 'note' => 'Vertical dropdown menu that usually resides in one of the side modules.' ),
+ 'hor' => array( 'label' => 'Horizontal', 'note' => 'Horizontal menu with dropdowns similar to the top bar menu (positioning of this hasn\'t been implemented yet).' ),
+ ),
+ 'plugin_type' => NEXUS_HTML_PLUGIN,
+ 'include_js_in_head' => FALSE,
+);
+
+$gNexusSystem->registerPlugin( NEXUS_PLUGIN_GUID_SUCKERFISH, $pluginParams );
+
+/**
+* bloody mad function to write a custom cache file for an individual menu
+* @param $pMenuHash full menu hash
+* @return full menu string ready for printing (key serves as cache file path)
+*/
+function writeSuckerfishCache( $pMenuHash ) {
+ global $smarty;
+ $menu_name = preg_replace( "/ +/", "_", trim( $pMenuHash->mInfo['title'] ) );
+ $menu_name = strtolower( $menu_name );
+ $menu_file = 'mod_'.$menu_name.'_'.$pMenuHash->mInfo['menu_id'].'.tpl';
+ $data = '{bitmodule title="{tr}'.$pMenuHash->mInfo['title'].'{/tr}" name="'.$menu_name.'"}';
+ // if a permission has been set, we need to work out when to close the {if} clause
+ $permCloseIds = array();
+ $perm_close = FALSE;
+ $next_cycle = FALSE;
+ foreach( $pMenuHash->mInfo['tree'] as $key => $item ) {
+ if( $item['first'] ) {
+ if( $key == 0 ) {
+ $data .= '<ul id="nexus'.$pMenuHash->mInfo['menu_id'].'" class="menu '.$pMenuHash->mInfo['type'].'">';
+ } else {
+ $data .= '<ul>';
+ }
+ } else {
+ $data .= '</li>';
+ // close permission clauses
+ if( $next_cycle ) {
+ $data .= '{/if}';
+ $next_cycle = FALSE;
+ }
+ if( in_array( $item['item_id'], $permCloseIds ) ) {
+ $next_cycle = TRUE;
+ }
+ if( $perm_close ) {
+ $data .= '{/if}';
+ $perm_close = FALSE;
+ }
+ }
+ if( $item['last'] ) {
+ $data .= '</ul>';
+ } else {
+ if( !empty( $item['perm'] ) ) {
+ // open permission if clause
+ $data .= '{if $gBitUser->hasPermission("'.$item['perm'].'")}';
+ if( !$item['head'] ) {
+ $perm_close = TRUE;
+ } else {
+ $permCloseIds[] = $item['item_id'];
+ }
+ }
+ $data .= '<li>';
+ $smarty->assign( 'item', $item );
+ $data .= $smarty->fetch( NEXUS_PKG_PATH.'templates/'.NEXUS_PLUGIN_GUID_SUCKERFISH.'/item.tpl' );
+ }
+ }
+ if( $pMenuHash->mInfo['type'] == 'ver' || $pMenuHash->mInfo['type'] == 'hor' ) {
+ $data .= '<div class="clear"></div>';
+ }
+ $data .= '{/bitmodule}';
+ $ret[$menu_file] = $data;
+ return $ret;
+}
+?>
diff --git a/plugins/menu.tikiwiki.php b/plugins/menu.tikiwiki.php
new file mode 100644
index 0000000..f81d56f
--- /dev/null
+++ b/plugins/menu.tikiwiki.php
@@ -0,0 +1,106 @@
+<?php
+/**
+* Plugin for Nexus creating a tikiwiki style menu with the difference of multiple levels being available
+*
+* @abstract creates a javascript expandable menu
+* @author xing@synapse.plus.com
+* @version $Revision: 1.1 $
+* @package Nexus Plugin
+*/
+global $gNexusSystem;
+
+// GUID should be a maximum of 16 chars
+define( 'NEXUS_PLUGIN_GUID_TIKIWIKI', 'tikiwiki' );
+
+$pluginParams = array(
+ 'write_cache_function' => 'writeTikiWikiCache',
+ 'description' => 'expandable menu reminiscent of the tikiwiki menu',
+ 'web_link' => '<a class="external" href="http://www.tikiwiki.org">TikiWiki</a>',
+ 'browser_requirements' => 'Most browsers that support javascript should support these menus.',
+ 'edit_label' => 'TikiWiki menus',
+ 'menu_types' => array(
+ 'heo' => array( 'label' => 'head expands - open', 'note' => 'Head item serves merely as container and clicking on it will expand the underlying items (initial setting is open).' ),
+ 'hec' => array( 'label' => 'head expands - closed', 'note' => 'Initial setting is closed' ),
+ 'ieo' => array( 'label' => 'icon expands - open', 'note' => 'Menu head item serves as link and there is an icon to expand the menu (initial setting is open).' ),
+ 'iec' => array( 'label' => 'icon expands - closed', 'note' => 'Initial setting is closed' ),
+ ),
+ 'plugin_type' => NEXUS_HTML_PLUGIN,
+ 'include_js_in_head' => FALSE,
+);
+
+$gNexusSystem->registerPlugin( NEXUS_PLUGIN_GUID_TIKIWIKI, $pluginParams );
+
+/**
+* exports tikiwiki style menu
+* @param $pMenuHash full menu hash
+* @return full menu string ready for printing (key serves as cache file path)
+*/
+function writeTikiWikiCache( $pMenuHash ) {
+ global $smarty;
+ $menu_name = preg_replace( "/ +/", "_", trim( $pMenuHash->mInfo['title'] ) );
+ $menu_name = strtolower( $menu_name );
+ $menu_file = 'mod_'.$menu_name.'_'.$pMenuHash->mInfo['menu_id'].'.tpl';
+ $data = '{bitmodule title="{tr}'.$pMenuHash->mInfo['title'].'{/tr}" name="'.$menu_name.'"}';
+ $data .= '<div class="tikiwiki menu">';
+ // if a permission has been set, we need to work out when to close the {if} clause
+ $permCloseIds = array();
+ $perm_close = FALSE;
+ $perm_cycle = FALSE;
+ $type = $pMenuHash->mInfo['type'];
+ foreach( $pMenuHash->mInfo['tree'] as $key => $item ) {
+ if( $item['first'] ) {
+ $togid = 'togid'.$item['item_id'];
+ $data .= '<div id="'.$togid.'" ';
+ $data .= 'style="display:{if $smarty.cookies.'.$togid.' eq \'c\'}none{elseif $smarty.cookies.'.$togid.' eq \'o\'}block{else}';
+ if( $key != 0 && preg_match( "/c$/", $type ) ) {
+ $data .= 'none';
+ } else {
+ $data .= 'block';
+ }
+ $data .= '{/if};">';
+ } else {
+ // close permission clauses
+ if( $perm_cycle ) {
+ $data .= '{/if}';
+ $perm_cycle = FALSE;
+ }
+ if( in_array( $item['item_id'], $permCloseIds ) ) {
+ $perm_cycle = TRUE;
+ }
+ if( $perm_close ) {
+ $data .= '{/if}';
+ $perm_close = FALSE;
+ }
+ }
+ if( $item['last'] ) {
+ $data .= '</div>';
+ } else {
+ if( !empty( $item['perm'] ) ) {
+ // open permission if clause
+ $data .= '{if $gBitUser->hasPermission("'.$item['perm'].'")}';
+ if( !$item['head'] ) {
+ $perm_close = TRUE;
+ } else {
+ $permCloseIds[] = $item['item_id'];
+ }
+ }
+ if( $item['head'] ) {
+ $tog_next = 'togid'.$pMenuHash->mInfo['tree'][$key+1]['item_id'];
+ if( $type == 'heo' || $type == 'hec' ) {
+ $item['display_url'] = "javascript:toggle('".$tog_next."');";
+ } elseif( $type == 'ieo' || $type == 'iec' ) {
+ $item['expand_url'] = "javascript:icntoggle('".$tog_next."');";
+ }
+ $smarty->assign( 'tog_next', $tog_next );
+ }
+ $smarty->assign( 'item', $item );
+ $smarty->assign( 'type', $type );
+ $data .= $smarty->fetch( NEXUS_PKG_PATH.'templates/'.NEXUS_PLUGIN_GUID_TIKIWIKI.'/item.tpl' );
+ }
+ }
+ $data .= '</div><!-- end .menu -->';
+ $data .= '{/bitmodule}';
+ $ret[$menu_file] = $data;
+ return $ret;
+}
+?>
diff --git a/templates/insert_menu_item_inc.tpl b/templates/insert_menu_item_inc.tpl
new file mode 100644
index 0000000..78ccced
--- /dev/null
+++ b/templates/insert_menu_item_inc.tpl
@@ -0,0 +1,69 @@
+{strip}
+{if $gBitUser->hasPermission( 'bit_p_insert_nexus_item' ) }
+ {if !$inNexusMenu}
+ {foreach from=$nexusList item=menu}
+ {if $menu.editable}
+ {assign var=nexusAssign value=TRUE}
+
+ <div class="row">
+ {formlabel label="Menu"}
+ {forminput}
+ {$menu.title}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Menu description"}
+ {forminput}
+ {$menu.description}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Insert in this menu" for="nexus`$menu.menu_id`"}
+ {forminput}
+ <input type="radio" value="{$menu.menu_id}" name="nexus[menu_id]" id="nexus{$menu.menu_id}" />
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Insert after" for="after_ref_id`$menu.menu_id`"}
+ {forminput}
+ <select name="nexus[after_ref_id]" id="after_ref_id{$menu.menu_id}">
+ {foreach from=$menu.tree item=item}
+ {if !$item.last}<option {if $item.head}style="font-weight:bold;" {/if}value="{$item.item_id}">{$item.title}</option>{/if}
+ {foreachelse}
+ <option value="">{tr}no items found{/tr}</option>
+ {/foreach}
+ </select>
+ {/forminput}
+ </div>
+
+ <hr class="clear" />
+ {/if}
+ {/foreach}
+ {else}
+ <div class="row">
+ {formfeedback note="This `$gContent->mType.content_description` is already part of the menu <strong>`$inNexusMenu.title`</strong>."}
+ {formlabel label="Remove" for="nexusRemove"}
+ {forminput}
+ <input type="checkbox" name="nexus[remove_item]" id="nexusRemove" value="{$inNexusMenuItem.item_id}" />
+ {formhelp note="Check thib box if you wish to remove this page from the menu. This will also allow you to insert the menu item in a different menu when editing the menu next time."}
+ {/forminput}
+ </div>
+ {/if}
+
+ {if $nexusList and $nexusAssign}
+ <div class="row">
+ {formlabel label="Don't insert into any menu" for="nexus-no-insert"}
+ {forminput}
+ <input type="radio" value="" name="nexus[menu_id]" id="nexus-no-insert" checked="checked" />
+ {/forminput}
+ </div>
+ {elseif !$inNexusMenu}
+ <div class="row">
+ {formfeedback note="Currently there is no menu available where you can insert this `$gContent->mType.content_description`."}
+ </div>
+ {/if}
+{/if}
+{/strip}
diff --git a/templates/menu_details_inc.tpl b/templates/menu_details_inc.tpl
new file mode 100644
index 0000000..4b0b308
--- /dev/null
+++ b/templates/menu_details_inc.tpl
@@ -0,0 +1,45 @@
+{strip}
+{legend legend="Menu settings"}
+ <div class="row">
+ {formlabel label="Title"}
+ {forminput}
+ {formfeedback note=$gNexus->mInfo.title}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Description"}
+ {forminput}
+ {formfeedback note=$gNexus->mInfo.description}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Editable"}
+ {forminput}
+ {if $gNexus->mInfo.editable}
+ {formfeedback note='yes'}
+ {else}
+ {formfeedback note='no'}
+ {/if}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Menu Type"}
+ {forminput}
+ {formfeedback note=$gNexus->mInfo.plugin_guid}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Menu subtype"}
+ {forminput}
+ {assign var=plugin_guid value=$gNexus->mInfo.plugin_guid}
+ {foreach from=$gNexusSystem->mPlugins.$plugin_guid.menu_types item=menu_type key=m_type}
+ {if $m_type eq $gNexus->mInfo.type}{$menu_type.label}{/if}
+ {/foreach}
+ {/forminput}
+ </div>
+{/legend}
+{/strip}
diff --git a/templates/menu_items.tpl b/templates/menu_items.tpl
new file mode 100644
index 0000000..6dc1da0
--- /dev/null
+++ b/templates/menu_items.tpl
@@ -0,0 +1,25 @@
+{strip}
+{if $editItem.menu_id}
+ <div class="floaticon"><a href="{$gBitLoc.PKG_NEXUS_URL}menu_items.php?tab=edit&amp;menu_id={$editItem.menu_id}">{biticon ipackage=liberty iname=new iexplain="create new menu"}</a></div>
+{/if}
+
+<div class="display nexus">
+ <div class="header">
+ <h1>{tr}Create / Edit Menu Items{/tr}</h1>
+ </div>
+
+ <div class="body">
+ {jstabs}
+ {jstab title="Edit Menu Items"}
+ {include file="bitpackage:nexus/menu_items_edit_inc.tpl"}
+ {/jstab}
+
+ {jstab title="Menu Details"}
+ {include file="bitpackage:nexus/menu_details_inc.tpl"}
+ {/jstab}
+ {/jstabs}
+
+ {include file="bitpackage:nexus/menu_items_details_inc.tpl"}
+ </div><!-- end .body -->
+</div><!-- end .nexus -->
+{/strip}
diff --git a/templates/menu_items_details_inc.tpl b/templates/menu_items_details_inc.tpl
new file mode 100644
index 0000000..d973023
--- /dev/null
+++ b/templates/menu_items_details_inc.tpl
@@ -0,0 +1,33 @@
+{strip}
+{form legend="Item Details"}
+ {foreach from=$gNexus->mInfo.tree item=item key=key}
+ {if $item.first}<ul>{else}</li>{/if}
+ {if $item.last}</ul>{else}
+ <li>
+ <div class="{cycle values='even,odd'}">
+ {html_checkboxes values=$item.item_id name=remove_item id="item_`$item.item_id`" style="float:right;"}
+ <a href="{$gBitLoc.NEXUS_PKG_URL}menu_items.php?menu_id={$item.menu_id}&amp;item_id={$item.item_id}">{biticon ipackage=liberty iname="edit" iexplain="edit item" style="float:right" iforce=icon}</a>
+
+ <label for="item_{$item.item_id}">
+ <strong>{$item.title}</strong>
+ {if $item.hint}&nbsp;&bull;&nbsp;{$item.hint}{/if}
+ </label>
+
+ <br />
+
+ <small>
+ {foreach from=$rsrcTypes key=key item=rsrc_type}
+ {if $item.rsrc_type eq $key}{$rsrc_type}{/if}
+ {/foreach}
+ : {$item.rsrc}
+ {if $item.perm}&nbsp;&bull;&nbsp;{tr}Permission{/tr}: {$item.perm}{/if}
+ </small>
+ </div>
+ {/if}
+ {/foreach}
+ {if $gNexus->mInfo.tree}
+ <input type="hidden" name="menu_id" value="{$gNexus->mInfo.menu_id}" />
+ <input type="image" src="{biticon ipackage=liberty iname=delete iexplain='remove item' url=TRUE}" title="remove selected items" style="float:right" />
+ {/if}
+{/form}
+{/strip}
diff --git a/templates/menu_items_edit_inc.tpl b/templates/menu_items_edit_inc.tpl
new file mode 100644
index 0000000..9d17608
--- /dev/null
+++ b/templates/menu_items_edit_inc.tpl
@@ -0,0 +1,113 @@
+{strip}
+{form legend="Add / Edit menu items"}
+ <input type="hidden" name="menu_id" value="{$gNexus->mInfo.menu_id}" />
+ <input type="hidden" name="item_id" value="{$editItem.item_id}" />
+ <input type="hidden" name="tab" value="edit" />
+
+ {formfeedback hash=$formfeedback}
+
+ <div class="row">
+ {formlabel label="Link to content" for="content"}
+ {forminput}
+ <select name="content_type" onchange="submit();">
+ <option {if !$contentSelect}selected="selected"{/if} value="">All Content</option>
+ {foreach from=$contentTypes key=guid item=description}
+ <option value="{$guid}" {if $contentSelect eq $guid}selected="selected"{assign var=selectDescription value=$description}{/if}>{$description}</option>
+ {/foreach}
+ </select>
+ <noscript>
+ <div><input type="submit" name="content_switch" value="{tr}change content type{/tr}" /></div>
+ </noscript>
+ {/forminput}
+
+ {forminput}
+ {html_options name="content" options=$contentList onchange="document.getElementById('rsrc').value=options[selectedIndex].value;document.getElementById('title').value=options[selectedIndex].label.replace(/ \[id.*?\]/,'');document.getElementById('rsrc_type').value='content_id';"}
+ <noscript>
+ {formhelp note="Since you don't have javascript (enabled), please insert the appropriate information from the dropdown manually. The content ID is the number associated with the item in the dropdown list."}
+ </noscript>
+ {/forminput}
+
+ {forminput}
+ <input type="text" name="find_objects" />
+ <input type="submit" value="{tr}filter{/tr}" name="search_objects" />
+ {formhelp note=""}
+ {/forminput}
+ </div>
+
+ {if $menuList}
+ <div class="row">
+ {formlabel label="Insert menu" for="menu_list"}
+ {forminput}
+ {html_options name="menu_list" options=$menuList onchange="document.getElementById('rsrc').value=options[selectedIndex].value;document.getElementById('title').value=options[selectedIndex].label.replace(/ \[id.*?\]/,'');document.getElementById('rsrc_type').value='menu_id';"}
+ <noscript>
+ {formhelp note="Since you don't have javascript (enabled), please insert the appropriate information from the dropdown manually. The content ID is the number associated with the item in the dropdown list."}
+ </noscript>
+ {/forminput}
+ </div>
+ {/if}
+
+ <div class="row">
+ <hr />
+ </div>
+
+ <div class="row">
+ {formlabel label="Title" for="title"}
+ {forminput}
+ <input type="text" name="title" id="title" size="54" value="{$editItem.title}" />
+ {formhelp note="Enter a title for your menu item."}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Hint" for="hint"}
+ {forminput}
+ <textarea name="hint" id="hint" cols="80" rows="2">{$editItem.hint}</textarea>
+ {formhelp note="A hint for this item. This hint is visible when you hover over the menu item - hint is set as 'title' attribute for link (for menu plugins that support this feature)."}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Resource type" for="rsrc_type"}
+ {forminput}
+ {html_options name="rsrc_type" id="rsrc_type" options=$rsrcTypes selected=`$editItem.rsrc_type`}
+ {formhelp note="Here you can pick the resource type you wish to link to."}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Resource link" for="rsrc"}
+ {forminput}
+ <input type="text" name="rsrc" id="rsrc" size="54" value="{$editItem.rsrc}" />
+ {formhelp note="<dl><dt>External URL</dt><dd>enter full link. e.g.: <strong>http://www.example.com</strong></dd><dt>Internal URL</dt><dd>enter link beginning from your bitweaver installation directory. e.g.: <strong>wiki/rankings.php</strong></dd><dt>Content ID</dt><dd>enter the number referring to some content (e.g. the number assoctiated with each item in the content dropdown is a content ID). e.g.: <strong>3</strong></dd><dt>Menu ID</dt><dd>Enter the menu ID of the menu you wish to insert.</dd></dl>"}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Permission" for="perm"}
+ {forminput}
+ {html_options name="perm" id="perm" options=$perms selected=`$editItem.perm`}
+ {formhelp note="Permission required to view this item and any children associated with it. If no permission is selected, the menu is visible to all users."}
+ {/forminput}
+ </div>
+
+ {if !$editItem.item_id}
+ <div class="row">
+ {formlabel label="Insert after" for="after_ref_id"}
+ {forminput}
+ <select name="after_ref_id" id="after_ref_id">
+ {foreach from=$gNexus->mInfo.items item=item}
+ <option value="{$item.item_id}">{$item.title}</option>
+ {foreachelse}
+ <option value="">{tr}no items found{/tr}</option>
+ {/foreach}
+ </select>
+ {formhelp note="Pick the position after which you want to add the item."}
+ {/forminput}
+ </div>
+ {/if}
+
+ <div class="row submit">
+ <input type="submit" name="store_item" value="{tr}Save Item{/tr}" />
+ </div>
+{/form}
+{/strip}
diff --git a/templates/menu_items_organise_inc.tpl b/templates/menu_items_organise_inc.tpl
new file mode 100644
index 0000000..79c2a1a
--- /dev/null
+++ b/templates/menu_items_organise_inc.tpl
@@ -0,0 +1,20 @@
+{strip}
+{foreach from=$gNexus->mInfo.tree item=item key=key}
+ {if $item.first}<ul{if $key eq 0} class="toc"{/if}>{else}</li>{/if}
+ {if $item.last}</ul>{else}
+ <li>
+ <div class="{cycle values='even,odd'}">
+ <a href="{$gBitLoc.NEXUS_PKG_URL}menu_items.php?sort_menu={$menuId}&amp;menu_id={$item.menu_id}&amp;item_id={$item.item_id}&amp;tab=edit">{biticon iforce=icon ipackage=liberty iname="edit" iexplain="edit item" style="float:right"}</a>
+ {biticon iforce=icon ipackage=liberty iname="spacer" iexplain="" style="float:right"}
+
+ <a href="{$gBitLoc.NEXUS_PKG_URL}menu_sort.php?sort_menu={$menuId}&amp;menu_id={$item.menu_id}&amp;item_id={$item.item_id}&amp;move_item=e&amp;tab=organise">{biticon iforce=icon ipackage=liberty iname="nav_next" iexplain="move right" style="float:right"}</a>
+ <a href="{$gBitLoc.NEXUS_PKG_URL}menu_sort.php?sort_menu={$menuId}&amp;menu_id={$item.menu_id}&amp;item_id={$item.item_id}&amp;move_item=s&amp;tab=organise">{biticon iforce=icon ipackage=liberty iname="nav_down" iexplain="move down" style="float:right"}</a>
+ <a href="{$gBitLoc.NEXUS_PKG_URL}menu_sort.php?sort_menu={$menuId}&amp;menu_id={$item.menu_id}&amp;item_id={$item.item_id}&amp;move_item=n&amp;tab=organise">{biticon iforce=icon ipackage=liberty iname="nav_up" iexplain="move up" style="float:right"}</a>
+ <a href="{$gBitLoc.NEXUS_PKG_URL}menu_sort.php?sort_menu={$menuId}&amp;menu_id={$item.menu_id}&amp;item_id={$item.item_id}&amp;move_item=w&amp;tab=organise">{biticon iforce=icon ipackage=liberty iname="nav_prev" iexplain="move left" style="float:right"}</a>
+
+ {$item.title}
+ {biticon iforce=icon ipackage=liberty iname="spacer" iexplain=""}
+ </div>
+ {/if}
+{/foreach}
+{/strip}
diff --git a/templates/menu_items_preview_inc.tpl b/templates/menu_items_preview_inc.tpl
new file mode 100644
index 0000000..3ae60e8
--- /dev/null
+++ b/templates/menu_items_preview_inc.tpl
@@ -0,0 +1,7 @@
+{strip}
+{formfeedback warning="This is a rough approximation of what the menu might look like. Depending on the CSS file settings, it might appear quite differently once in position."}
+<div class="preview" style="width:200px;margin-left:auto;margin-right:auto;">
+ {include file="bitpackage:temp/nexus/$nexus_file"}
+</div><!-- end .preview -->
+<div class="clear"></div>
+{/strip}
diff --git a/templates/menu_nexus.tpl b/templates/menu_nexus.tpl
new file mode 100644
index 0000000..40a4ebf
--- /dev/null
+++ b/templates/menu_nexus.tpl
@@ -0,0 +1,17 @@
+{strip}
+<ul>
+ {if $gNexus->mInfo.menu_id}
+ <li><a class="head" href="{$gBitLoc.NEXUS_PKG_URL}menus.php">{biticon ipackage="nexus" iname="menu" iexplain="menus"} Menus</a>
+ <ul>
+ <li><a class="item" href="{$gBitLoc.NEXUS_PKG_URL}menu_items.php?menu_id={$gNexus->mInfo.menu_id}">{biticon ipackage="liberty" iname="edit" iexplain="edit items" iforce=icon} {tr}Add/Edit items{/tr}</a></li>
+ <li><a class="item" href="{$gBitLoc.NEXUS_PKG_URL}menu_sort.php?menu_id={$gNexus->mInfo.menu_id}">{biticon ipackage="nexus" iname="organise" iexplain="organise items" iforce=icon} {tr}Organise items{/tr}</a></li>
+ </ul>
+ </li>
+ {else}
+ <li><a class="item" href="{$gBitLoc.NEXUS_PKG_URL}menus.php">{biticon ipackage="nexus" iname="menu" iexplain="menus" iforce=icon} Menus</a></li>
+ {/if}
+ {if $gBitUser->hasPermission('bit_p_admin')}
+ <li><a class="item" href="{$gBitLoc.NEXUS_PKG_URL}admin/nexus_plugins.php">{biticon ipackage="liberty" iname="plugin" iexplain="menus" iforce=icon} Nexus Plugins</a></li>
+ {/if}
+</ul>
+{/strip}
diff --git a/templates/menu_sort.tpl b/templates/menu_sort.tpl
new file mode 100644
index 0000000..87ebd99
--- /dev/null
+++ b/templates/menu_sort.tpl
@@ -0,0 +1,23 @@
+{strip}
+{if $editItem.menu_id}
+ <div class="floaticon"><a href="{$gBitLoc.PKG_NEXUS_URL}menu_items.php?tab=edit&amp;menu_id={$editItem.menu_id}">{biticon ipackage=liberty iname=new iexplain="create new menu"}</a></div>
+{/if}
+
+<div class="display nexus">
+ <div class="header">
+ <h1>{tr}Organise Menu Items{/tr}</h1>
+ </div>
+
+ <div class="body">
+ {jstabs}
+ {jstab title="Organise Items"}
+ {include file="bitpackage:nexus/menu_items_organise_inc.tpl"}
+ {/jstab}
+
+ {jstab title="Preview Menu"}
+ {include file="bitpackage:nexus/menu_items_preview_inc.tpl"}
+ {/jstab}
+ {/jstabs}
+ </div><!-- end .body -->
+</div><!-- end .nexus -->
+{/strip}
diff --git a/templates/menus.tpl b/templates/menus.tpl
new file mode 100644
index 0000000..bc58fe4
--- /dev/null
+++ b/templates/menus.tpl
@@ -0,0 +1,128 @@
+{strip}
+{if $editMenu.menu_id}
+ <div class="floaticon"><a href="{$gBitLoc.PKG_NEXUS_URL}menus.php">{biticon ipackage=liberty iname=new iexplain="create new menu"}</a></div>
+{/if}
+<div class="display nexus">
+ <div class="header">
+ <h1>{tr}Menu Administration{/tr}</h1>
+ </div>
+
+ <div class="body">
+
+ {form legend="Create / Edit Menus"}
+ <input type="hidden" name="menu_id" value="{$editMenu.menu_id}" />
+
+ {formfeedback hash=$formfeedback}
+
+ <div class="row">
+ {formlabel label="Title" for="title"}
+ {forminput}
+ <input type="text" name="title" id="title" size="50" value="{$editMenu.title}" />
+ {formhelp note="Enter a name for your menu."}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Description" for="description"}
+ {forminput}
+ <textarea name="description" id="description" cols="80" rows="3">{$editMenu.description}</textarea>
+ {formhelp note="A description of this menu. This description is visible to users that can add items to this menu."}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Editable menu" for="editable"}
+ {forminput}
+ {html_checkboxes name="editable" values="1" checked=`$editMenu.editable` labels=false id="editable"}
+ {formhelp note="Checking this will allow users with the correct permission (bit_p_insert_nexus_item) to add menu items when they are editing content such as a wiki page or a fisheye gallery."}
+ {/forminput}
+ </div>
+
+ <div class="row">
+ {formlabel label="Pick menu type"}
+ {forminput}
+ {foreach from=$gNexusSystem->mPlugins item=plugin}
+ {if $plugin.is_active eq 'y'}
+ <div class="row">
+ <label>
+ <input type="radio" name="plugin_guid" value="{$plugin.plugin_guid}"
+ {if $editMenu.plugin_guid eq $plugin.plugin_guid or ( $editMenu.plugin_guid eq '' and $plugin.plugin_guid eq 'suckerfish' )}
+ checked="checked"
+ {/if}
+ />
+ &nbsp;{$plugin.plugin_guid}
+ </label>
+ <br />
+ &nbsp;
+ <select name="type_{$plugin.plugin_guid}" id="type_{$plugin.plugin_guid}">
+ {foreach from=$plugin.menu_types key=type item=menu_type}
+ <option value="{$type}"{if $type eq $editMenu.type} selected="selected"{/if}>{$menu_type.label}</option>
+ {/foreach}
+ </select>
+ {formhelp note=$plugin.plugin_description}
+ <div class="formhelp">
+ <dl>
+ {foreach from=$plugin.menu_types item=menu_type}
+ <dt>{$menu_type.label}</dt><dd>{$menu_type.note}</dd>
+ {/foreach}
+ </dl>
+ </div>
+ </div>
+ {/if}
+ {/foreach}
+ {/forminput}
+ </div>
+
+ <div class="row submit">
+ <input type="submit" name="store_menu" value="Save Settings" />
+ </div>
+ {/form}
+
+ <table class="data" summary="{tr}List of menus that can be used on this site{/tr}">
+ <caption>{tr}Existing menus{/tr}</caption>
+ <tr>
+ <th scope="col">{tr}Title{/tr}</th>
+ <th scope="col">{tr}Description{/tr}</th>
+ <th scope="col">{tr}GUID{/tr}</th>
+ <th scope="col">{tr}Type{/tr}</th>
+ <th scope="col">{tr}# of Items{/tr}</th>
+ <th scope="col">{tr}Editable{/tr}</th>
+ <th scope="col">{tr}Actions{/tr}</th>
+ </tr>
+ {foreach from=$menuList item=menu}
+ <tr class="{cycle values="even,odd"}">
+ <td>{$menu.title}</td>
+ <td>{$menu.description}</td>
+ <td>{$menu.plugin_guid}</td>
+ <td>
+ {assign var=plugin_guid value=$menu.plugin_guid}
+ {foreach from=$gNexusSystem->mPlugins.$plugin_guid.menu_types item=menu_type key=m_type}
+ {if $m_type eq $menu.type}{$menu_type.label}{/if}
+ {/foreach}
+ </td>
+ <td style="text-align:right;">{$menu.items|@count}</td>
+ <td style="text-align:center;">
+ {if $menu.editable}
+ {biticon ipackage=liberty iname=active iexplain="menu is editable"}
+ {else}
+ {biticon ipackage=liberty iname=inactive iexplain="menu is not editable"}
+ {/if}
+ </td>
+ <td class="actionicon">
+ <a href="{$gBitLoc.PKG_NEXUS_URL}menu_sort.php?menu_id={$menu.menu_id}">{biticon ipackage=nexus iname=organise iexplain='sort menu items'}</a>
+ <a href="{$gBitLoc.PKG_NEXUS_URL}menu_items.php?menu_id={$menu.menu_id}">{biticon ipackage=liberty iname=edit iexplain='create and edit menu items'}</a>
+ <a href="{$gBitLoc.KERNEL_PKG_URL}admin/index.php?page=layout&amp;module_name=WhatGoesInHere">{biticon ipackage=liberty iname=assign iexplain=assign}</a>
+ <a href="{$gBitLoc.PKG_NEXUS_URL}menus.php?action=remove_dead&amp;menu_id={$menu.menu_id}">{biticon ipackage=nexus iname=remove_dead iexplain='remove dead links'}</a>
+ <a href="{$gBitLoc.PKG_NEXUS_URL}menus.php?action=edit&amp;menu_id={$menu.menu_id}">{biticon ipackage=liberty iname=config iexplain='configure menu'}</a>
+ <a href="{$gBitLoc.PKG_NEXUS_URL}menus.php?action=remove&amp;menu_id={$menu.menu_id}">{biticon ipackage=liberty iname=delete iexplain='remove menu'}</a>
+ </td>
+ </tr>
+ {foreachelse}
+ <tr>
+ <td class="norecords" colspan="7">{tr}No Records Found{/tr}</td>
+ </tr>
+ {/foreach}
+ </table>
+ </div><!-- end .body -->
+</div><!-- end .nexus -->
+{/strip}
diff --git a/templates/nexus_plugins.tpl b/templates/nexus_plugins.tpl
new file mode 100644
index 0000000..32ba8e9
--- /dev/null
+++ b/templates/nexus_plugins.tpl
@@ -0,0 +1,39 @@
+{strip}
+<div class="admin nexus">
+ <div class="header">
+ <h1>{tr}Nexus Menu Plugins{/tr}</h1>
+ </div>
+
+ <div class="body">
+ {form legend="Nexus Menu Plugins"}
+ <ul class="data">
+ {foreach from=$gNexusSystem->mPlugins item=plugin}
+ {if $plugin.verified}
+ <li class="item {cycle values='even,odd'}">
+ <div class="floaticon">
+ <input type="checkbox" name="PLUGINS[{$plugin.plugin_guid}]" id="{$plugin.plugin_guid}" value="y" {if $plugin.is_active eq 'y'}checked="checked"{/if} />
+ </div>
+ <h3><label for="{$plugin.plugin_guid}">{$plugin.plugin_guid}</label></h3>
+ {$plugin.plugin_description}<br />
+ {tr}Menu subtypes{/tr}
+ <ul class="small">
+ {foreach from=$plugin.menu_types item=menu_type}
+ <li>{$menu_type.note}</li>
+ {/foreach}
+ </ul>
+ <small>
+ {if $plugin.web_link}<strong>{tr}Online Resource{/tr}:</strong> {$plugin.web_link}<br />{/if}
+ <strong>{tr}Browser Requirements{/tr}:</strong> {$plugin.browser_requirements}
+ </small>
+ </li>
+ {/if}
+ {/foreach}
+ </ul>
+
+ <div class="row submit">
+ <input type="submit" name="store_plugins" value="{tr}Save Plugin Settings{/tr}" />
+ </div>
+ {/form}
+ </div><!-- end .body -->
+</div><!-- end .nexus -->
+{/strip}
diff --git a/templates/suckerfish/item.tpl b/templates/suckerfish/item.tpl
new file mode 100644
index 0000000..b3c6fe5
--- /dev/null
+++ b/templates/suckerfish/item.tpl
@@ -0,0 +1 @@
+<a class="{if $item.head}head{else}item{/if}{if $item.rsrc_type eq 'ext'} external{/if}" title="{$item.hint}"{if $item.display_url} href="{$item.display_url}"{/if}>{$item.title}</a> \ No newline at end of file
diff --git a/templates/tikiwiki/item.tpl b/templates/tikiwiki/item.tpl
new file mode 100644
index 0000000..cacd822
--- /dev/null
+++ b/templates/tikiwiki/item.tpl
@@ -0,0 +1,21 @@
+ {strip}
+{if $item.head and ( $type eq 'ieo' or $type eq 'iec' )}
+ <span style="display:block;">
+{/if}
+{if $item.expand_url}
+ <a style="float:left;padding:0 3px;" href="{$item.expand_url}">
+ {biticon ipackage=liberty iname=folder id="`$tog_next`img" iexplain="expand menu"}
+ </a>
+{/if}
+<a class="{if $item.head}head{else}item{/if}{if $item.rsrc_type eq 'ext'} external{/if}" title="{$item.hint}" {if $item.display_url}href="{$item.display_url}{/if}">
+ {$item.title}
+</a>
+{if $item.head and ( $type eq 'ieo' or $type eq 'iec' )}
+ </span>
+{/if}
+{if $item.head and ( $type eq 'ieo' or $type eq 'iec' )}
+ <script type="text/javascript">
+ setfoldericonstate('{$tog_next}');
+ </script>
+{/if}
+{/strip}