1<?php 2/* 3 * To change this template, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 7function formatXml($data) 8{ 9 $xmlFormat = ' 10<sphinx:document id="{id}"> 11<title><![CDATA[[{title}]]></title> 12<body><![CDATA[[{body}]]></body> 13<namespace><![CDATA[[{namespace}]]></namespace> 14<pagename><![CDATA[[{pagename}]]></pagename> 15<level>{level}</level> 16<modified>{modified}</modified> 17</sphinx:document> 18 19'; 20 21 return str_replace( array('{id}', '{title}', '{body}', '{namespace}', '{pagename}', '{level}', '{modified}'), 22 array($data['id'], escapeTextValue($data['title_to_index']), 23 escapeTextValue($data['body']), 24 escapeTextValue($data['namespace']), 25 escapeTextValue($data['pagename']), 26 $data['level'], $data['modified']), 27 $xmlFormat 28 ); 29} 30 31function escapeTextValue($value) 32{ 33 if ("" === $value) 34 { 35 return ""; 36 } 37 //$value = mb_convert_encoding($value,'UTF-8','ISO-8859-1'); 38 $value = str_replace('<?php', 'PHPTAGSTART', $value); 39 $value = str_replace('?>', 'PHPTAGEND', $value); 40 $value = strip_tags($value); 41 $value = stripInvalidXml($value); 42 return str_replace("]]>", "]]><![CDATA[]]]]><![CDATA[>]]><![CDATA[", $value); 43 } 44 45function stripInvalidXml($value) 46{ 47 $ret = ""; 48 if (empty($value)) 49 { 50 return $ret; 51 } 52 53 $current = null; 54 $length = strlen($value); 55 for ($i=0; $i < $length; $i++) 56 { 57 $current = ord($value{$i}); 58 if (($current == 0x9) || 59 ($current == 0xA) || 60 ($current == 0xD) || 61 (($current >= 0x20) && ($current <= 0xD7FF)) || 62 (($current >= 0xE000) && ($current <= 0xFFFD)) || 63 (($current >= 0x10000) && ($current <= 0x10FFFF))) 64 { 65 $ret .= chr($current); 66 } 67 else 68 { 69 $ret .= " "; 70 } 71 } 72 return $ret; 73 } 74 75function getDocumentsByHeadings($id, $metadata) 76{ 77 if (empty($metadata) || empty($metadata['description']['tableofcontents'])) return false; 78 79 $sections = array(); 80 $level = 1; 81 $previouse_title = ''; 82 $firstSection = true; 83 foreach($metadata['description']['tableofcontents'] as $row){ 84 if ($firstSection){ 85 $zerocontent = getZeroSectionContent($id, $row['title']); 86 if ($zerocontent){ 87 $sections[$id] = array( 88 'section' => $zerocontent, 89 'level' => 0, 90 'title' => $id, 91 'title_to_index' => $id 92 ); 93 } 94 $firstSection = false; 95 } 96 $sections[$row['hid']] = array( 97 'section' => getSectionByTitleLevel($id, $row['title'], false), 98 'level' => $row['level'], 99 'title' => $row['title'] 100 ); 101 if ($row['level'] > $level && !empty($previouse_title)){ 102 $sections[$row['hid']]['title_text'] = $previouse_title . " » ".$row['title']; 103 } else { 104 $sections[$row['hid']]['title_text'] = $row['title']; 105 $previouse_title = $row['title']; 106 } 107 $sections[$row['hid']]['title_to_index'] = $row['title']; 108 } 109 return $sections; 110} 111 112function getZeroSectionContent($id, $header) 113{ 114 $headerReg = preg_quote($header, '/'); 115 $regex = "(={1,6})\s*({$headerReg})\s*(={1,6})"; 116 $doc = io_readFile(wikiFN($id)); 117 $matches = array(); 118 if (!preg_match("/$regex/i",$doc,$matches)) { 119 return false; 120 } 121 if (empty($matches[1])){ 122 return false; 123 } 124 $end = strpos($doc, $matches[1]); 125 if (!$end){ 126 return false; 127 } 128 $zerocontent = substr($doc, 0, $end); 129 return $zerocontent; 130} 131 132function getSectionByTitleLevel($id, $header, $extended=false) 133{ 134 $headerReg = preg_quote($header, '/'); 135 $doc = io_readFile(wikiFN($id)); 136 $regex = "(={1,6})\s*({$headerReg})\s*(={1,6})"; 137 $section = ''; 138 if (preg_match("/$regex/i",$doc,$matches)) { 139 $startHeader = $matches[0]; 140 $startHeaderPos = strpos($doc, $startHeader) + strlen($startHeader); 141 $endDoc = substr($doc, $startHeaderPos); 142 143 $regex = '(={4,6})(.*?)(={4,6})'; 144 if (preg_match("/$regex/i",$endDoc,$matches)) { 145 $endHeader = $matches[0]; 146 $endHeaderPos = strpos($doc, $endHeader); 147 } else { 148 $endHeaderPos = 0; 149 } 150 if ($endHeaderPos){ 151 $section = substr($doc, $startHeaderPos, $endHeaderPos - $startHeaderPos); 152 } else { 153 $section = substr($doc, $startHeaderPos); 154 } 155 } 156 $section = trim($section); 157 //trying to get next section content if body for first section is empty 158 //working only for extended mode 159 if ($extended && empty($section)){ 160 $startHeaderPos = $endHeaderPos + strlen($endHeader); 161 $endDoc = substr($endDoc, $startHeaderPos); 162 $regex = '(={4,6})(.*?)(={4,6})'; 163 if (preg_match("/$regex/i",$endDoc,$matches)) { 164 $endHeader = $matches[0]; 165 $endHeaderPos = strpos($doc, $endHeader); 166 } else { 167 $endHeaderPos = 0; 168 } 169 if ($endHeaderPos){ 170 $section = substr($doc, $startHeaderPos, $endHeaderPos - $startHeaderPos); 171 } else { 172 $section = substr($doc, $startHeaderPos); 173 } 174 } 175 $section = trim($section); 176 return $section; 177} 178 179function getSection($id, $header) 180{ 181 static $cacheInstructions = null; 182 static $cacheDoc = null; 183 184 if (empty($cacheDoc[$id])){ 185 // Create the parser 186 $Parser = & new Doku_Parser(); 187 188 // Add the Handler 189 $Parser->Handler = & new Doku_Handler(); 190 191 // Load the header mode to find headers 192 $Parser->addMode('header',new Doku_Parser_Mode_Header()); 193 $Parser->addMode('listblock',new Doku_Parser_Mode_ListBlock()); 194 195 // Loads the raw wiki document 196 $doc = io_readFile(wikiFN($id)); 197 198 // Get a list of instructions 199 $instructions = $Parser->parse($doc); 200 201 unset($Parser->Handler); 202 unset($Parser); 203 204 //free old cache 205 $cacheInstructions = null; 206 $cacheDoc = null; 207 208 //initialize new cache 209 $cacheInstructions[$id] = $instructions; 210 $cacheDoc[$id] = $doc; 211 } else { 212 $instructions = $cacheInstructions[$id]; 213 $doc = $cacheDoc[$id]; 214 } 215 216 217 218 // Use this to watch when we're inside the section we want 219 $inSection = FALSE; 220 $startPos = 0; 221 $endPos = 0; 222 223 // Loop through the instructions 224 foreach ( $instructions as $instruction ) { 225 226 if ( !$inSection ) { 227 228 // Look for the header for the "Lists" heading 229 if ( $instruction[0] == 'header' && 230 trim($instruction[1][0]) == $header ) { 231 232 $startPos = $instruction[2]; 233 $inSection = TRUE; 234 } 235 } else { 236 237 // Look for the end of the section 238 if ( $instruction[0] == 'section_close' ) { 239 $endPos = $instruction[2]; 240 break; 241 } 242 } 243 } 244 245 // Normalize and pad the document in the same way the parse does 246 // so that byte indexes with match 247 $doc = "\n".str_replace("\r\n","\n",$doc)."\n"; 248 $section = substr($doc, $startPos, ($endPos-$startPos)); 249 250 return $section; 251} 252 253function getCategories($id) 254{ 255 if (empty($id)) return ''; 256 257 if (false === strpos($id, ":")){ 258 return ''; 259 } 260 261 $ns = explode(":", $id); 262 $nsCount = count($ns) - 1; 263 264 $result = ''; 265 do{ 266 for($i = 0; $i < $nsCount; $i++){ 267 $name = $ns[$i]; 268 $result .= $name; 269 if ($i < $nsCount - 1){ 270 $result .= ':'; 271 } 272 } 273 $result .= ' '; 274 }while($nsCount--); 275 return $result; 276} 277 278function getPagename($id) 279{ 280 if (empty($id)) return ''; 281 282 if (false === strpos($id, ":")){ 283 return $id; 284 } 285 286 $ns = explode(":", $id); 287 return $ns[count($ns) - 1]; 288} 289 290 291 292 /** 293 * Method return all wiki page names 294 * @global array $conf 295 * @return array 296 */ 297 function getPagesList() 298 { 299 global $conf; 300 301 $data = array(); 302 sort($data); 303 search($data,$conf['datadir'],'search_allpages',array('skipacl'=>1),''); 304 305 return $data; 306} 307 308function getNsLinks($id, $keywords, $search) 309{ 310 global $conf; 311 $parts = explode(':', $id); 312 $count = count($parts); 313 314 // print intermediate namespace links 315 $part = ''; 316 $data = array(); 317 $titles = array(); 318 for($i=0; $i<$count; $i++){ 319 $part .= $parts[$i].':'; 320 $page = $part; 321 resolve_pageid('',$page,$exists); 322 323 if (preg_match("#:start$#", $page) && !preg_match("#:start:$#", $part)) { 324 $page = substr($page, 0, strpos($page, ":start")); 325 }; 326 327 // output 328 if ($exists){ 329 $titles[wl($page)] = $parts[$i]; 330 } else { 331 $titles[wl($page)] = $parts[$i]; 332 } 333 $data[] = array('link' => "?do=search&id={$keywords}".urlencode(" @ns $page")); 334 } 335 $titleExcerpt = $search->getExcerpt($titles, $search->starQuery($keywords)); 336 $i = 0; 337 foreach ($data as $key => $notused){ 338 $data[$key]['title'] = $titleExcerpt[$i++]; 339 } 340 return $data; 341} 342 343function printNamespaces($query) 344{ 345 $data = array(); 346 $query = str_replace(" ", "_", $query); 347 $data = ft_pageLookup($query, false); 348 349 if(!count($data)) return false; 350 351 print '<h3>Matching pagenames</h3>'; 352 print '<ul>'; 353 $counter = 0; 354 foreach($data as $id){ 355 print '<li>'; 356 $ns = getNS($id); 357 if($ns){ 358 $name = shorten(noNS($id), ' ('.$ns.')',30); 359 }else{ 360 $name = $id; 361 } 362 $href = wl($id); 363 364 tpl_link($href,$id, "class='wikilink1'"); 365 print '</li>'; 366 if(++$counter == 20){ 367 break; 368 } 369 } 370 print '</ul>'; 371} 372 373function printNamespacesNew($pageNames) 374{ 375 if(empty($pageNames)) return false; 376 377 $limit = 10; 378 print '<h3>Matching pagenames</h3>'; 379 print '<ul>'; 380 $counter = 0; 381 foreach($pageNames as $id => $header){ 382 $ns = getNS($id); 383 if($ns){ 384 $name = shorten(noNS($id), ' ('.$ns.')',30); 385 }else{ 386 $name = $id; 387 } 388 print '<li>'; 389 /*if (!empty($header)){ 390 print '<a href="'.wl($id).'#'.$header.'" '. "class='wikilink1'>".$id."</a>".'#'.$header; 391 } else { 392 print '<a href="'.wl($id).'" '. "class='wikilink1'>".$id."</a>"; 393 }*/ 394 print '<a href="'.wl($id).'" '. "class='wikilink1'>".$id."</a>"; 395 print '</li>'; 396 if (++$counter == $limit){ 397 break; 398 } 399 } 400 print '</ul>'; 401} 402 403if(!function_exists('shorten')){ 404 /** 405 * Shorten a given string by removing data from the middle 406 * 407 * You can give the string in two parts, teh first part $keep 408 * will never be shortened. The second part $short will be cut 409 * in the middle to shorten but only if at least $min chars are 410 * left to display it. Otherwise it will be left off. 411 * 412 * @param string $keep the part to keep 413 * @param string $short the part to shorten 414 * @param int $max maximum chars you want for the whole string 415 * @param int $min minimum number of chars to have left for middle shortening 416 * @param string $char the shortening character to use 417 */ 418 function shorten($keep,$short,$max,$min=9,$char='⌇'){ 419 $max = $max - utf8_strlen($keep); 420 if($max < $min) return $keep; 421 $len = utf8_strlen($short); 422 if($len <= $max) return $keep.$short; 423 $half = floor($max/2); 424 return $keep.utf8_substr($short,0,$half-1).$char.utf8_substr($short,$len-$half); 425 } 426} 427