array( 'page_selected_cb' => null, 'ns_selected_cb' => null, 'page_selected_js' => null, 'ns_selected_js' => null, ), 'vars'=>array( 'id'=> null, 'class' => 'explorertree', ), 'init_plugin' => null, ); function cache(){ if ($this->memcache === false){ // we will use memcache even it's emulated, as we building a tree requires to search filesystem (multiple fs I/O) and emulated cache only graps one compressed wile from disk (one optimized fs I/O) $this->memcache = plugin_load('helper','memcache'); } return $this->memcahce; } function getMethods() { $result = array(); $result[] = array( 'name' => 'registerRoute', 'desc' => 'registers a route: the tree will be created by the options and ajax will be routed to the caller class.', 'parameters' => array( 'name' => "string unique name, usually the registerer plugin's name (with suffix, if the plugin uses more trees).", 'options' => "array of options, that replace the original options (see getOptions)", ) ); $result[] = array( 'name' => 'getOptions', 'desc' => 'returns a registered route options or the default options', 'parameters' => array( 'name' => "string unique name for the registered options. if omitted, the default options are returned." ), 'return' => array('options'=>'array of options or null if the name does not exists.'), ); $result[] = array( 'name' => 'getTree', 'desc' => 'gets the tree of NS and pages ', 'parameters' => array( 'folder' => 'string a folder of the current namespace', ), 'return' => array('tree'=>'array'), ); $result[] = array( 'name' => 'htmlExplorer', 'desc' => 'gets html explorer of the whole wiki.', 'parameters' => array( 'name' => 'string unique name of a callback/data store.', 'base' => 'string ID of the root node', 'current' => 'string ID of the current node', ), 'return' => array('tree'=>'array'), ); return $result; } function registerRoute($name,array $options){ $this->routes[$name] = array_replace_recursive ($this->options,$options); } function getOptions($name = null){ if (!$name) return $this->options; return @$this->routes[$name][$options]; } function loadRoute($name,array $reg = null){ if (!$name) return $this->options; if ((! @$this->routes[$name]) && $reg){ if (($p = plugin_load($reg['type'],$reg['plugin'])) && $met = $reg['method']){ call_user_func(array($p,$met),array()); } } return @$this->routes[$name]; } /** * get a list of namespace / page files * * @param string $folder an already converted filesystem folder of the current namespace */ function getTree($folder=':'){ global $conf; global $ID; // read tree structure from pages and media $ofolder = $folder; if ($folder == '*' || $folder == '') $folder = ':'; if ($folder[0] != ':') $folder = resolve_id($folder,$ID); $dir = strtr(cleanID($folder),':','/'); if (!($this->cache() && is_array($data = $this->cache()->get('explorertree_cache_'.$dir)))){ $data = array(); search($data,$conf['datadir'],'search_index',array('ns'=>getNS($ID)),$dir,$dir == '' ? 1 : count(explode('/',$dir))+1); $count = count($data); if($count>0) for($i=1; $i<$count; $i++){ if($data[$i-1]['id'] == $data[$i]['id'] && $data[$i-1]['type'] == $data[$i]['type']) { unset($data[$i]); $i++; // duplicate found, next $i can't be a duplicate, so skip forward one } } if ($this->cache()) { $this->cache()->set($cache_id = 'explorertree_cache_'.$dir,$data,60); // store the data itself (cache for one minute) } } return $data; } /** * Display a tree menu to select a page or namespace * */ function htmlExplorer($name,$base = '',$current = null){ global $lang; if ($base == '' || $base == '*') $base = ':'; if (!($o = $this->loadRoute($name))){ return "
Invalid explorertree route!
"; //TODO: replace with lang... } $data = $this->getTree($base); // wrap a list with the root level around the other namespaces if ($base == ':'){ array_unshift($data, array( 'level' => 0, 'id' => ':', 'type' => 'd', 'open' =>'true', 'label' => '['.$lang['mediaroot'].']')); } $list = html_buildlist($data, $class = $o['vars']['class'], array($this,'_html_list_tree'), array($this,'_html_li_tree') ); if (strncasecmp(trim($list),'