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 echo "<ul>$up"; 66 echo "<li><span class='ten__ptb'>" . $this->getLang('notoc') ." $wikifn</span></li></ul>"; 67 } 68 } 69 else { 70 if($exists && !auth_quickaclcheck( $wikifn) ) { 71 echo $this->getLang('perm'); 72 } 73 } 74 75 } 76 } 77 78 function get_toc($id) { 79 $this->retv = ""; 80 $toc = p_get_metadata($id,'description tableofcontents'); 81 if(!$toc) return ""; 82 $current=0; 83 $start_level = 0; 84 $this->ulcount('open'); 85 86 $up = $this->get_up_dir(pathinfo(wikiFN("$id:file"))); 87 $this->retv .= "<UL class='tocsel_li1'>$up\n"; 88 89 foreach ($toc as $head) { 90 $level = $this->format_item($head, $current,$id); 91 if($start_level==0) $start_level = $level; 92 } 93 if($start_level != $level) { 94 $this->retv .= "</UL>\n"; 95 $this->ulcount('closed'); 96 } 97 $this->retv .= "</UL>\n"; 98 $this->ulcount('closed'); 99 if($this->ul_open > $this->ul_closed) { 100 $this->retv .= "</UL>\n"; 101 } 102 103 } 104 105 function format_item($h, &$n,$id){ 106 if($n==0) $n=$h['level']; 107 108 if($n < $h['level'] ) { 109 $this->ulcount('open'); 110 $this->retv .= "<UL>\n"; 111 112 } 113 else if ($n != $h['level']) { 114 $this->retv .= "</UL>\n"; 115 $this->ulcount('closed'); 116 } 117 118 $this->retv .= '<li>' . $this->format_link($h['title'], $h['hid'],$id) . "</li>\n"; 119 $n = $h['level']; 120 return $n; 121 } 122 function format_link($title,$anchor,$id) { 123 $link = "<a href ='". TOC_URL . $id. '#'. $anchor."'>" . "$title</a>"; 124 return $link; 125 } 126 127 function ulcount($which) { 128 129 if ($which == "open") { 130 if($this->ul_open> 0) $this->retv .="\n" .'<li class="ihidden">'; 131 $this->ul_count++; 132 $this->ul_open++; 133 } 134 else if ($which == "closed") { 135 $this->ul_count --; 136 if($this->ul_closed> 0) $this->retv .="</li>\n"; 137 $this->ul_closed ++; 138 } 139 } 140 141 private function get_dir_list($dir, $namespace){ 142 $retdir = "<UL>"; 143 if(!empty($this->up)) $retdir .= $this->up; 144 $retfile = ""; 145 $dir_ar = array(); 146 $file_ar = array(); 147 148 $dh = opendir($dir); 149 if(!$dh) return; 150 while (($file = readdir($dh)) !== false) { 151 if($file == '.' || $file == '..') continue; # cur and upper dir 152 if(is_dir("$dir/$file")) { 153 $dir_ar[$file] = $this->handle_directory($file, $namespace); 154 } 155 else { 156 if(!preg_match("/\.txt$/",$file)|| preg_match("/^_/",$file) ) continue; //exclude non .txt files and templates 157 $file_ar[$file] = $this->handle_file($file, $namespace); 158 } 159 } 160 closedir($dh); 161 ksort($dir_ar); 162 ksort($file_ar); 163 foreach ($dir_ar as $key=>$val) { 164 $retdir .= $val; 165 } 166 foreach ($file_ar as $key=>$val) { 167 $retfile .= $val; 168 } 169 $ret = $retdir . $retfile . "</UL>"; 170 return $ret; 171 } 172 173 private function handle_directory($curdir, $namespace) { 174 return "<li><span class='clickerdir tocselb' onclick=\"tocsel_updatetoc('$namespace:$curdir:*');\">$namespace:$curdir:*</span></li>"; 175 } 176 177 private function handle_file($file, $namespace) { 178 $file = preg_replace("/\.txt$/","", $file); 179 return "<li><span class='clickerfile' onclick=\"tocsel_updatetoc('$namespace:$file');\">$namespace:$file</span></li>"; 180 } 181 182 private function handle_up($namespace) { 183 if(empty($namespace)) 184 $title = 'Root NS'; 185 else $title = $namespace; 186 $png = '<img title = "' . $title. '"src = "' . TOCSEL_IMGDIR.'up.png' . '" />'; 187 return "<li class= 'tocsel_up'><span class='clicker tocselb' onclick=\"tocsel_updatetoc('$namespace:*');\">$png</span></li> "; 188 } 189 190 private function get_up_dir($pathinf) { 191 $up = dirname($pathinf['dirname']); 192 $up = preg_replace("#.*?/data/pages#","",$up); 193 $up = str_replace('/', ':', $up); 194 return $this-> handle_up($up); // empty $up = root ns 195 } 196 } 197 198 199 200