1<?php 2/** 3 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 4 * @author Myron Turner <turnermm02@shaw.ca> 5 * 6 */ 7if(!defined('DOKU_INC')) die(); 8 9if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 10require_once(DOKU_PLUGIN.'action.php'); 11define ("TOC_URL", DOKU_BASE ."doku.php?id="); 12define ("TOCSEL_IMGDIR", DOKU_BASE . 'lib/plugins/tocselect/img/'); 13 14class action_plugin_tocselect extends DokuWiki_Action_Plugin { 15 private $retv; 16 private $ul_count; 17 private $ul_open; 18 private $ul_closed; 19 private $up; 20 function register(Doku_Event_Handler $controller){ 21 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this,'_ajax_call'); 22 $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this,'handle_started'); 23 } 24 25 function handle_started(Doku_Event $event, $param) { 26 global $conf; 27 if($this->getConf('notoc')) { 28 $conf['tocminheads'] = 0; 29 } 30 31 } 32 function _ajax_call(Doku_Event $event, $param) { 33 34 global $INPUT; 35 36 if ($event->data == 'tocselect') { 37 $event->stopPropagation(); 38 $event->preventDefault(); 39 $wikifn = rawurldecode($INPUT->str('seltoc_val')); 40 $regex = preg_quote(':*'); 41 if(preg_match('/^(.*?)' . $regex . '\s*$/',$wikifn,$matches)) 42 { 43 $wikifn = $matches[1]; 44 $ns = getNS($wikifn . ':file'); 45 $pathinf = pathinfo(wikiFN($wikifn . ':file') ); 46 if($matches[1]) { 47 $this->up = $this->get_up_dir($pathinf ); //inserted in get_dir_list() 48 } 49 $list = $this->get_dir_list($pathinf['dirname'], $ns); 50 echo $list; 51 return; 52 } 53 else $file = wikiFN($wikifn) ; 54 55 $exists = file_exists($file); 56 if($exists && auth_quickaclcheck( $wikifn) ) { 57 setcookie('tocselect',$wikifn,0,DOKU_BASE); 58 $this->ul_count = $this->ul_open = $this->ul_closed = 0; 59 $this->get_toc($wikifn); 60 if($this->retv) { 61 echo $this->retv; 62 } 63 else { 64 $up = $this->get_up_dir(pathinfo("$file/file")); 65 66 } 67 } 68 else { 69 if($exists && !auth_quickaclcheck( $wikifn) ) { 70 echo $this->getLang('perm'); 71 } 72 } 73 74 } 75 } 76 77 function get_toc($id) { 78 $this->retv = ""; 79 $toc = p_get_metadata($id,'description tableofcontents'); 80 if(!$toc) return ""; 81 $current=0; 82 $start_level = 0; 83 $this->ulcount('open'); 84 85 $up = $this->get_up_dir(pathinfo(wikiFN("$id:file"))); 86 $this->retv .= "<UL class='tocsel_li1'>$up\n"; 87 88 foreach ($toc as $head) { 89 $level = $this->format_item($head, $current,$id); 90 if($start_level==0) $start_level = $level; 91 } 92 if($start_level != $level) { 93 $this->retv .= "</UL>\n"; 94 $this->ulcount('closed'); 95 } 96 $this->retv .= "</UL>\n"; 97 $this->ulcount('closed'); 98 if($this->ul_open > $this->ul_closed) { 99 $this->retv .= "</UL>\n"; 100 } 101 102 } 103 104 function format_item($h, &$n,$id){ 105 if($n==0) $n=$h['level']; 106 107 if($n < $h['level'] ) { 108 $this->ulcount('open'); 109 $this->retv .= "<UL>\n"; 110 111 } 112 else if ($n != $h['level']) { 113 $this->retv .= "</UL>\n"; 114 $this->ulcount('closed'); 115 } 116 117 $this->retv .= '<li>' . $this->format_link($h['title'], $h['hid'],$id) . "</li>\n"; 118 $n = $h['level']; 119 return $n; 120 } 121 function format_link($title,$anchor,$id) { 122 $link = "<a href ='". TOC_URL . $id. '#'. $anchor."'>" . "$title</a>"; 123 return $link; 124 } 125 126 function ulcount($which) { 127 128 if ($which == "open") { 129 if($this->ul_open> 0) $this->retv .="\n" .'<li class="ihidden">'; 130 $this->ul_count++; 131 $this->ul_open++; 132 } 133 else if ($which == "closed") { 134 $this->ul_count --; 135 if($this->ul_closed> 0) $this->retv .="</li>\n"; 136 $this->ul_closed ++; 137 } 138 } 139 140 private function get_dir_list($dir, $namespace){ 141 $retdir = "<UL>"; 142 if(!empty($this->up)) $retdir .= $this->up; 143 $retfile = ""; 144 $dir_ar = array(); 145 $file_ar = array(); 146 147 $dh = opendir($dir); 148 if(!$dh) return; 149 while (($file = readdir($dh)) !== false) { 150 if($file == '.' || $file == '..') continue; # cur and upper dir 151 if(is_dir("$dir/$file")) { 152 $dir_ar[$file] = $this->handle_directory($file, $namespace); 153 } 154 else { 155 if(!preg_match("/\.txt$/",$file)|| preg_match("/^_/",$file) ) continue; //exclude non .txt files and templates 156 $file_ar[$file] = $this->handle_file($file, $namespace); 157 } 158 } 159 closedir($dh); 160 ksort($dir_ar); 161 ksort($file_ar); 162 foreach ($dir_ar as $key=>$val) { 163 $retdir .= $val; 164 } 165 foreach ($file_ar as $key=>$val) { 166 $retfile .= $val; 167 } 168 $ret = $retdir . $retfile . "</UL>"; 169 return $ret; 170 } 171 172 private function handle_directory($curdir, $namespace) { 173 return "<li><span class='clickerdir tocselb' onclick=\"tocsel_updatetoc('$namespace:$curdir:*');\">$namespace:$curdir:*</span></li>"; 174 } 175 176 private function handle_file($file, $namespace) { 177 $file = preg_replace("/\.txt$/","", $file); 178 return "<li><span class='clickerfile' onclick=\"tocsel_updatetoc('$namespace:$file');\">$namespace:$file</span></li>"; 179 } 180 181 private function handle_up($namespace) { 182 if(empty($namespace)) 183 $title = 'Root NS'; 184 else $title = $namespace; 185 $png = '<img title = "' . $title. '"src = "' . TOCSEL_IMGDIR.'up.png' . '" />'; 186 return "<li class= 'tocsel_up'><span class='clicker tocselb' onclick=\"tocsel_updatetoc('$namespace:*');\">$png</span></li> "; 187 } 188 189 private function get_up_dir($pathinf) { 190 $up = dirname($pathinf['dirname']); 191 $up = preg_replace("#.*?/data/pages#","",$up); 192 $up = str_replace('/', ':', $up); 193 return $this-> handle_up($up); // empty $up = root ns 194 } 195 } 196 197 198 199