10Syaroslav@ivinco.com<?php 20Syaroslav@ivinco.com/** 30Syaroslav@ivinco.com * XML feed export 40Syaroslav@ivinco.com * 50Syaroslav@ivinco.com * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 60Syaroslav@ivinco.com * @author Andreas Gohr <andi@splitbrain.org> 70Syaroslav@ivinco.com */ 80Syaroslav@ivinco.com 90Syaroslav@ivinco.com 100Syaroslav@ivinco.com/* Initialization */ 110Syaroslav@ivinco.com 121Syaroslav@ivinco.comif(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../../'); 130Syaroslav@ivinco.comif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 140Syaroslav@ivinco.com 150Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/init.php'); 160Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/common.php'); 170Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/events.php'); 180Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/parserutils.php'); 190Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/feedcreator.class.php'); 200Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/auth.php'); 210Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/pageutils.php'); 220Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/search.php'); 23*4Syaroslav@ivinco.comrequire_once(DOKU_INC.'inc/parser/parser.php'); 24*4Syaroslav@ivinco.com 250Syaroslav@ivinco.com 260Syaroslav@ivinco.comrequire_once(DOKU_PLUGIN.'sphinxsearch/PageMapper.php'); 270Syaroslav@ivinco.com 281Syaroslav@ivinco.comif (!file_exists(DOKU_INC.$conf['savedir']."/sphinxsearch/")){ 291Syaroslav@ivinco.com mkdir(DOKU_INC.$conf['savedir']."/sphinxsearch/"); 301Syaroslav@ivinco.com} 311Syaroslav@ivinco.com 320Syaroslav@ivinco.com$pagesList = getPagesList(); 330Syaroslav@ivinco.com 340Syaroslav@ivinco.comecho '<?xml version="1.0" encoding="utf-8"?> 350Syaroslav@ivinco.com<sphinx:docset> 360Syaroslav@ivinco.com 370Syaroslav@ivinco.com<sphinx:schema> 380Syaroslav@ivinco.com<sphinx:field name="title"/> 390Syaroslav@ivinco.com<sphinx:field name="body"/> 400Syaroslav@ivinco.com<sphinx:field name="categories"/> 41*4Syaroslav@ivinco.com<sphinx:field name="level"/> 420Syaroslav@ivinco.com<sphinx:field name="modified"/> 430Syaroslav@ivinco.com<sphinx:field name="creator"/> 44*4Syaroslav@ivinco.com<sphinx:attr name="level" type="int" bits="8" default="1"/> 450Syaroslav@ivinco.com</sphinx:schema> 460Syaroslav@ivinco.com'; 470Syaroslav@ivinco.com 480Syaroslav@ivinco.com$pageMapper = new PageMapper(); 490Syaroslav@ivinco.com 500Syaroslav@ivinco.comforeach($pagesList as $row){ 510Syaroslav@ivinco.com $dokuPageId = $row['id']; 520Syaroslav@ivinco.com //get meta data 53*4Syaroslav@ivinco.com $metadata = p_get_metadata($dokuPageId); 54*4Syaroslav@ivinco.com $sections = getDocumentsByHeadings($dokuPageId, $metadata); 55*4Syaroslav@ivinco.com if (!empty($sections)){ 56*4Syaroslav@ivinco.com foreach($sections as $hid => $section){ 57*4Syaroslav@ivinco.com //parse meta data for headers, abstract, date, authors 58*4Syaroslav@ivinco.com $data = array(); 59*4Syaroslav@ivinco.com $data['id'] = crc32($dokuPageId.$hid); 60*4Syaroslav@ivinco.com $data['categories'] = getCategories($dokuPageId) . '#' . $hid; 61*4Syaroslav@ivinco.com $data['level'] = $section['level']; 62*4Syaroslav@ivinco.com $data['modified'] = $metadata['date']['modified']; 63*4Syaroslav@ivinco.com $data['creator'] = $metadata['creator']; 64*4Syaroslav@ivinco.com $data['title'] = strip_tags($section['title']); 65*4Syaroslav@ivinco.com $data['body'] = strip_tags(p_render('xhtml',p_get_instructions($section['section']),$info)); 660Syaroslav@ivinco.com 67*4Syaroslav@ivinco.com echo formatXml($data)."\n"; 68*4Syaroslav@ivinco.com $pageMapper->add($dokuPageId, $section['title'], $hid); 69*4Syaroslav@ivinco.com } 70*4Syaroslav@ivinco.com } else { 71*4Syaroslav@ivinco.com //parse meta data for headers, abstract, date, authors 72*4Syaroslav@ivinco.com $data = array(); 73*4Syaroslav@ivinco.com $data['id'] = crc32($dokuPageId); 74*4Syaroslav@ivinco.com $data['categories'] = getCategories($dokuPageId); 75*4Syaroslav@ivinco.com $data['level'] = 1; 76*4Syaroslav@ivinco.com $data['modified'] = $metadata['date']['modified']; 77*4Syaroslav@ivinco.com $data['creator'] = $metadata['creator']; 78*4Syaroslav@ivinco.com $data['title'] = strip_tags($metadata['title']); 79*4Syaroslav@ivinco.com $data['body'] = strip_tags(p_wiki_xhtml($dokuPageId,$metadata['date']['modified'],false)); 800Syaroslav@ivinco.com 81*4Syaroslav@ivinco.com echo formatXml($data)."\n"; 82*4Syaroslav@ivinco.com $pageMapper->add($dokuPageId, $metadata['title']); 83*4Syaroslav@ivinco.com } 840Syaroslav@ivinco.com} 850Syaroslav@ivinco.com 860Syaroslav@ivinco.comecho '</sphinx:docset>'; 870Syaroslav@ivinco.com 880Syaroslav@ivinco.com 890Syaroslav@ivinco.com 900Syaroslav@ivinco.comfunction formatXml($data) 910Syaroslav@ivinco.com{ 920Syaroslav@ivinco.com $xmlFormat = ' 930Syaroslav@ivinco.com<sphinx:document id="{id}"> 940Syaroslav@ivinco.com<title><![CDATA[[{title}]]></title> 950Syaroslav@ivinco.com<body><![CDATA[[{body}]]></body> 960Syaroslav@ivinco.com<categories><![CDATA[[{categories}]]></categories> 97*4Syaroslav@ivinco.com<level>{level}</level> 980Syaroslav@ivinco.com<modified>{modified}</modified> 990Syaroslav@ivinco.com<creator>{creator}</creator> 1000Syaroslav@ivinco.com</sphinx:document> 1010Syaroslav@ivinco.com 1020Syaroslav@ivinco.com'; 1030Syaroslav@ivinco.com 104*4Syaroslav@ivinco.com return str_replace( array('{id}', '{title}', '{body}', '{categories}', '{level}', '{modified}', '{creator}'), 105*4Syaroslav@ivinco.com array($data['id'], $data['title'], $data['body'], $data['categories'], 106*4Syaroslav@ivinco.com $data['level'], $data['modified'], $data['creator']), 1070Syaroslav@ivinco.com $xmlFormat 1080Syaroslav@ivinco.com ); 1090Syaroslav@ivinco.com} 1100Syaroslav@ivinco.com 111*4Syaroslav@ivinco.comfunction getDocumentsByHeadings($id, $metadata) 1120Syaroslav@ivinco.com{ 113*4Syaroslav@ivinco.com if (empty($metadata) || empty($metadata['description']['tableofcontents'])) return false; 114*4Syaroslav@ivinco.com 115*4Syaroslav@ivinco.com $sections = array(); 116*4Syaroslav@ivinco.com foreach($metadata['description']['tableofcontents'] as $row){ 117*4Syaroslav@ivinco.com $sections[$row['hid']] = array( 118*4Syaroslav@ivinco.com 'section' => getSection($id, $row['title']), 119*4Syaroslav@ivinco.com 'title' => $row['title'], 120*4Syaroslav@ivinco.com 'level' => $row['level'] 121*4Syaroslav@ivinco.com ); 122*4Syaroslav@ivinco.com } 123*4Syaroslav@ivinco.com return $sections; 124*4Syaroslav@ivinco.com} 125*4Syaroslav@ivinco.com 126*4Syaroslav@ivinco.comfunction getSection($id, $header) 127*4Syaroslav@ivinco.com{ 128*4Syaroslav@ivinco.com // Create the parser 129*4Syaroslav@ivinco.com $Parser = & new Doku_Parser(); 130*4Syaroslav@ivinco.com 131*4Syaroslav@ivinco.com // Add the Handler 132*4Syaroslav@ivinco.com $Parser->Handler = & new Doku_Handler(); 133*4Syaroslav@ivinco.com 134*4Syaroslav@ivinco.com // Load the header mode to find headers 135*4Syaroslav@ivinco.com $Parser->addMode('header',new Doku_Parser_Mode_Header()); 1360Syaroslav@ivinco.com 137*4Syaroslav@ivinco.com // Load the modes which could contain markup that might be 138*4Syaroslav@ivinco.com // mistaken for a header 139*4Syaroslav@ivinco.com $Parser->addMode('listblock',new Doku_Parser_Mode_ListBlock()); 140*4Syaroslav@ivinco.com $Parser->addMode('preformatted',new Doku_Parser_Mode_Preformatted()); 141*4Syaroslav@ivinco.com $Parser->addMode('table',new Doku_Parser_Mode_Table()); 142*4Syaroslav@ivinco.com $Parser->addMode('unformatted',new Doku_Parser_Mode_Unformatted()); 143*4Syaroslav@ivinco.com $Parser->addMode('php',new Doku_Parser_Mode_PHP()); 144*4Syaroslav@ivinco.com $Parser->addMode('html',new Doku_Parser_Mode_HTML()); 145*4Syaroslav@ivinco.com $Parser->addMode('code',new Doku_Parser_Mode_Code()); 146*4Syaroslav@ivinco.com $Parser->addMode('file',new Doku_Parser_Mode_File()); 147*4Syaroslav@ivinco.com $Parser->addMode('quote',new Doku_Parser_Mode_Quote()); 148*4Syaroslav@ivinco.com $Parser->addMode('footnote',new Doku_Parser_Mode_Footnote()); 149*4Syaroslav@ivinco.com $Parser->addMode('internallink',new Doku_Parser_Mode_InternalLink()); 150*4Syaroslav@ivinco.com $Parser->addMode('media',new Doku_Parser_Mode_Media()); 151*4Syaroslav@ivinco.com $Parser->addMode('externallink',new Doku_Parser_Mode_ExternalLink()); 152*4Syaroslav@ivinco.com $Parser->addMode('windowssharelink',new Doku_Parser_Mode_WindowsShareLink()); 153*4Syaroslav@ivinco.com $Parser->addMode('filelink',new Doku_Parser_Mode_FileLink()); 154*4Syaroslav@ivinco.com 155*4Syaroslav@ivinco.com // Loads the raw wiki document 156*4Syaroslav@ivinco.com $doc = io_readFile(wikiFN($id)); 157*4Syaroslav@ivinco.com 158*4Syaroslav@ivinco.com // Get a list of instructions 159*4Syaroslav@ivinco.com $instructions = $Parser->parse($doc); 160*4Syaroslav@ivinco.com 161*4Syaroslav@ivinco.com unset($Parser); 162*4Syaroslav@ivinco.com 163*4Syaroslav@ivinco.com // Use this to watch when we're inside the section we want 164*4Syaroslav@ivinco.com $inSection = FALSE; 165*4Syaroslav@ivinco.com $startPos = 0; 166*4Syaroslav@ivinco.com $endPos = 0; 167*4Syaroslav@ivinco.com 168*4Syaroslav@ivinco.com // Loop through the instructions 169*4Syaroslav@ivinco.com foreach ( $instructions as $instruction ) { 170*4Syaroslav@ivinco.com 171*4Syaroslav@ivinco.com if ( !$inSection ) { 172*4Syaroslav@ivinco.com 173*4Syaroslav@ivinco.com // Look for the header for the "Lists" heading 174*4Syaroslav@ivinco.com if ( $instruction[0] == 'header' && 175*4Syaroslav@ivinco.com trim($instruction[1][0]) == $header ) { 176*4Syaroslav@ivinco.com 177*4Syaroslav@ivinco.com $startPos = $instruction[2]; 178*4Syaroslav@ivinco.com $inSection = TRUE; 179*4Syaroslav@ivinco.com } 180*4Syaroslav@ivinco.com } else { 181*4Syaroslav@ivinco.com 182*4Syaroslav@ivinco.com // Look for the end of the section 183*4Syaroslav@ivinco.com if ( $instruction[0] == 'section_close' ) { 184*4Syaroslav@ivinco.com $endPos = $instruction[2]; 185*4Syaroslav@ivinco.com break; 186*4Syaroslav@ivinco.com } 187*4Syaroslav@ivinco.com } 1880Syaroslav@ivinco.com } 189*4Syaroslav@ivinco.com 190*4Syaroslav@ivinco.com // Normalize and pad the document in the same way the parse does 191*4Syaroslav@ivinco.com // so that byte indexes with match 192*4Syaroslav@ivinco.com $doc = "\n".str_replace("\r\n","\n",$doc)."\n"; 193*4Syaroslav@ivinco.com $section = substr($doc, $startPos, ($endPos-$startPos)); 194*4Syaroslav@ivinco.com 195*4Syaroslav@ivinco.com return $section; 1960Syaroslav@ivinco.com} 1970Syaroslav@ivinco.com 1980Syaroslav@ivinco.comfunction getCategories($id) 1990Syaroslav@ivinco.com{ 2000Syaroslav@ivinco.com if (empty($id)) return ''; 2010Syaroslav@ivinco.com 2020Syaroslav@ivinco.com if (false === strpos($id, ":")){ 2030Syaroslav@ivinco.com return $id; 2040Syaroslav@ivinco.com } 2050Syaroslav@ivinco.com 2060Syaroslav@ivinco.com $ns = explode(":", $id); 2070Syaroslav@ivinco.com $nsCount = count($ns); 2080Syaroslav@ivinco.com 2090Syaroslav@ivinco.com $result = ''; 2100Syaroslav@ivinco.com do{ 2110Syaroslav@ivinco.com for($i = 0; $i < $nsCount; $i++){ 2120Syaroslav@ivinco.com $name = $ns[$i]; 2130Syaroslav@ivinco.com $result .= $name; 2140Syaroslav@ivinco.com if ($i < $nsCount - 1){ 2150Syaroslav@ivinco.com $result .= ':'; 2160Syaroslav@ivinco.com } 2170Syaroslav@ivinco.com } 2180Syaroslav@ivinco.com $result .= ' '; 2190Syaroslav@ivinco.com }while($nsCount--); 2200Syaroslav@ivinco.com return $result; 2210Syaroslav@ivinco.com} 2220Syaroslav@ivinco.com 2230Syaroslav@ivinco.com 2240Syaroslav@ivinco.com /** 2250Syaroslav@ivinco.com * Method return all wiki page names 2260Syaroslav@ivinco.com * @global array $conf 2270Syaroslav@ivinco.com * @return array 2280Syaroslav@ivinco.com */ 2290Syaroslav@ivinco.com function getPagesList() 2300Syaroslav@ivinco.com { 2310Syaroslav@ivinco.com global $conf; 2320Syaroslav@ivinco.com 2330Syaroslav@ivinco.com $data = array(); 2340Syaroslav@ivinco.com sort($data); 2350Syaroslav@ivinco.com search($data,$conf['datadir'],'search_allpages','',''); 2360Syaroslav@ivinco.com 2370Syaroslav@ivinco.com return $data; 2380Syaroslav@ivinco.com} 2390Syaroslav@ivinco.com 2400Syaroslav@ivinco.com/** 2410Syaroslav@ivinco.com * Array 2420Syaroslav@ivinco.com( 2430Syaroslav@ivinco.com [date] => Array 2440Syaroslav@ivinco.com ( 2450Syaroslav@ivinco.com [created] => 1239181434 2460Syaroslav@ivinco.com [modified] => 1239202933 2470Syaroslav@ivinco.com ) 2480Syaroslav@ivinco.com 2490Syaroslav@ivinco.com [creator] => Sergey Nikolaev 2500Syaroslav@ivinco.com [last_change] => Array 2510Syaroslav@ivinco.com ( 2520Syaroslav@ivinco.com [date] => 1239202933 2530Syaroslav@ivinco.com [ip] => 85.118.229.162 2540Syaroslav@ivinco.com [type] => E 2550Syaroslav@ivinco.com [id] => cal:minutes:boardreader:200904:20090408 2560Syaroslav@ivinco.com [user] => snikolaev 2570Syaroslav@ivinco.com [sum] => 2580Syaroslav@ivinco.com [extra] => 2590Syaroslav@ivinco.com ) 2600Syaroslav@ivinco.com 2610Syaroslav@ivinco.com [contributor] => Array 2620Syaroslav@ivinco.com ( 2630Syaroslav@ivinco.com [snikolaev] => Sergey Nikolaev 2640Syaroslav@ivinco.com ) 2650Syaroslav@ivinco.com 2660Syaroslav@ivinco.com [title] => BoardReader call of Apr 8 2009 2670Syaroslav@ivinco.com [description] => Array 2680Syaroslav@ivinco.com ( 2690Syaroslav@ivinco.com [tableofcontents] => Array 2700Syaroslav@ivinco.com ( 2710Syaroslav@ivinco.com [0] => Array 2720Syaroslav@ivinco.com ( 2730Syaroslav@ivinco.com [hid] => boardreader_call_of_apr_8_2009 2740Syaroslav@ivinco.com [title] => BoardReader call of Apr 8 2009 2750Syaroslav@ivinco.com [type] => ul 2760Syaroslav@ivinco.com [level] => 1 2770Syaroslav@ivinco.com ) 2780Syaroslav@ivinco.com 2790Syaroslav@ivinco.com [1] => Array 2800Syaroslav@ivinco.com ( 2810Syaroslav@ivinco.com [hid] => sergey 2820Syaroslav@ivinco.com [title] => Sergey 2830Syaroslav@ivinco.com [type] => ul 2840Syaroslav@ivinco.com [level] => 2 2850Syaroslav@ivinco.com ) 2860Syaroslav@ivinco.com 2870Syaroslav@ivinco.com [2] => Array 2880Syaroslav@ivinco.com ( 2890Syaroslav@ivinco.com [hid] => slava 2900Syaroslav@ivinco.com [title] => Slava 2910Syaroslav@ivinco.com [type] => ul 2920Syaroslav@ivinco.com [level] => 2 2930Syaroslav@ivinco.com ) 2940Syaroslav@ivinco.com 2950Syaroslav@ivinco.com [3] => Array 2960Syaroslav@ivinco.com ( 2970Syaroslav@ivinco.com [hid] => roman 2980Syaroslav@ivinco.com [title] => Roman 2990Syaroslav@ivinco.com [type] => ul 3000Syaroslav@ivinco.com [level] => 2 3010Syaroslav@ivinco.com ) 3020Syaroslav@ivinco.com 3030Syaroslav@ivinco.com [4] => Array 3040Syaroslav@ivinco.com ( 3050Syaroslav@ivinco.com [hid] => nikita 3060Syaroslav@ivinco.com [title] => Nikita 3070Syaroslav@ivinco.com [type] => ul 3080Syaroslav@ivinco.com [level] => 2 3090Syaroslav@ivinco.com ) 3100Syaroslav@ivinco.com 3110Syaroslav@ivinco.com [5] => Array 3120Syaroslav@ivinco.com ( 3130Syaroslav@ivinco.com [hid] => discussion 3140Syaroslav@ivinco.com [title] => Discussion 3150Syaroslav@ivinco.com [type] => ul 3160Syaroslav@ivinco.com [level] => 2 3170Syaroslav@ivinco.com ) 3180Syaroslav@ivinco.com 3190Syaroslav@ivinco.com ) 3200Syaroslav@ivinco.com 3210Syaroslav@ivinco.com [abstract] => Participants: Mindaugas, Sergey, Slava, Roman, Nikita 3220Syaroslav@ivinco.com 3230Syaroslav@ivinco.comDuration: 23 min 3240Syaroslav@ivinco.com 3250Syaroslav@ivinco.comSergey 3260Syaroslav@ivinco.com 3270Syaroslav@ivinco.comStatus: 3280Syaroslav@ivinco.com 3290Syaroslav@ivinco.com * published Roman's changes 3300Syaroslav@ivinco.com * started reviewing Slava's changes 3310Syaroslav@ivinco.com 3320Syaroslav@ivinco.com 3330Syaroslav@ivinco.comPlans: 3340Syaroslav@ivinco.com 3350Syaroslav@ivinco.com * start altering (singature field) 3360Syaroslav@ivinco.com * select server error handling 3370Syaroslav@ivinco.com * publish Slava's and Roman's changes 3380Syaroslav@ivinco.com ) 3390Syaroslav@ivinco.com 3400Syaroslav@ivinco.com [internal] => Array 3410Syaroslav@ivinco.com ( 3420Syaroslav@ivinco.com [cache] => 1 3430Syaroslav@ivinco.com [toc] => 1 3440Syaroslav@ivinco.com ) 3450Syaroslav@ivinco.com 3460Syaroslav@ivinco.com) 3470Syaroslav@ivinco.com 3480Syaroslav@ivinco.com */ 3490Syaroslav@ivinco.com 350