1<?php
2/**
3 * DokuWiki Plugin log (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Adrian Lang <lang@cosmocode.de>
7 */
8
9require_once DOKU_PLUGIN.'log/common.php';
10require_once DOKU_PLUGIN.'syntax.php';
11
12class syntax_plugin_log extends DokuWiki_Syntax_Plugin {
13
14    function getType() {
15        return 'substition';
16    }
17
18    function getPType() {
19        return 'block';
20    }
21
22    function getSort() {
23        return 55;
24    }
25
26    function connectTo($mode) {
27        $this->Lexer->addSpecialPattern('{{log(?:>[^}]+)?}}',$mode,'plugin_log');
28    }
29
30    function handle($match, $state, $pos, Doku_Handler $handler){
31        global $ID;
32
33        if (preg_match('/{{log(?:>(\d+))?}}/', $match, $match) === 0) {
34            return $this->getLang('e_syntax');
35        }
36        $maxcount = count($match) > 1 ? $match[1] : 5;
37
38        $empty_list = array(array('listitem_open', array(1)),
39                       array('listcontent_open', array()),
40                       array('cdata', array($this->getLang('no_entry'))),
41                       array('listcontent_close', array()),
42                       array('listitem_close', array()));
43
44        try {
45            $logpage = log_get_log_page($this, $ID);
46        } catch (Exception $e) {
47            return $e->getMessage();
48        }
49        if (!page_exists($logpage)) {
50            return array($empty_list, 'u', $logpage);
51        }
52
53        $instructions = p_cached_instructions(wikiFN($logpage),false,$logpage);
54
55        // prepare some vars
56        $max = count($instructions);
57        $start = -1;
58        $end = -1;
59        $lvl = 0;
60        $cnt = $maxcount;
61
62        // build a lookup table
63        for($i=0; $i<$max; $i++){
64            switch ($instructions[$i][0]) {
65            case 'listu_open': case 'listo_open':
66                if ($lvl === 0) {
67                    $start = $i + 1;
68                    $type = substr($instructions[$i][0], 4, 1);
69                }
70                ++$lvl;
71                break;
72            case 'listitem_close':
73                if ($lvl === 1 && --$cnt === 0) {
74                    $instructions = array_slice($instructions, $start, $i - $start + 1);
75                    break 2;
76                }
77                break;
78            case 'listu_close': case 'listo_close':
79                if (--$lvl === 0) {
80                    $instructions = array_slice($instructions, $start, $i - $start);
81                    break 2;
82                }
83            }
84        }
85        if ($start === -1) {
86            $type = 'u';
87            $instructions = $empty_list;
88        }
89
90        return array(array_merge($instructions,
91                                 array(array('listitem_open', array(1)),
92                                       array('listcontent_open', array()),
93                                       array('internallink', array($logpage, $this->getLang('fulllog'))),
94                                       array('listcontent_close', array()),
95                                       array('listitem_close', array()))),
96                     $type, $logpage, $maxcount);
97    }
98
99    function render($mode, Doku_Renderer $renderer, $data) {
100        if($mode === 'metadata'){
101            $renderer->meta['relation']['logplugin'] = true;
102            return true;
103        }
104
105        if($mode !== 'xhtml') return false;
106
107        if (!is_array($data)) {
108            // Show error
109            $renderer->doc .= hsc($data);
110            return true;
111        }
112
113        // Disable cache for the security token (it is not necessary for the
114        // log inclusion, this is managed via metadata dependencies)
115        $renderer->info['cache'] = false;
116
117        global $ID;
118
119        call_user_func(array(&$renderer, 'list' . $data[1] . '_open'));
120        if (auth_quickaclcheck($data[2]) >= AUTH_EDIT) {
121            call_user_func(array(&$renderer, 'listitem_open'), 1);
122            call_user_func(array(&$renderer, 'listcontent_open'));
123            $form = new Doku_Form(array('action' => wl($ID,array('do'=>'log_new'), false, '&'),
124                                        'class' => 'plugin_log'));
125            $form->addElement(form_makeTextField('log_text', '', $this->getLang('newentry')));
126            $form->addHidden('id', $ID);
127            $form->addHidden('maxcount', $data[3]);
128            $form->addElement(form_makeButton('submit', null, $this->getLang('save')));
129
130            $renderer->doc .= $form->getForm();
131            call_user_func(array(&$renderer, 'listcontent_close'));
132            call_user_func(array(&$renderer, 'listitem_close'));
133        }
134
135        foreach ($data[0] as $instruction ) {
136            // Execute the callback against the Renderer
137            call_user_func_array(array(&$renderer, $instruction[0]),$instruction[1]);
138        }
139
140        call_user_func(array(&$renderer, 'list' . $data[1] . '_close'));
141        return true;
142    }
143}
144
145// vim:ts=4:sw=4:et:enc=utf-8:
146