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