1<?php
2/**
3 *
4 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
5 * @author     Andreas Gohr <andi@splitbrain.org>
6 */
7
8/**
9 * Class action_plugin_data
10 */
11class action_plugin_data extends DokuWiki_Action_Plugin {
12
13    /**
14     * will hold the data helper plugin
15     * @var helper_plugin_data
16     */
17    var $dthlp = null;
18
19    /**
20     * Constructor. Load helper plugin
21     */
22    function __construct(){
23        $this->dthlp = plugin_load('helper', 'data');
24    }
25
26    /**
27     * Registers a callback function for a given event
28     */
29    function register(Doku_Event_Handler $controller) {
30        $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, '_handle');
31        $controller->register_hook('HTML_SECEDIT_BUTTON', 'BEFORE', $this, '_editbutton');
32        $controller->register_hook('HTML_EDIT_FORMSELECTION', 'BEFORE', $this, '_editform'); // deprecated
33        $controller->register_hook('EDIT_FORM_ADDTEXTAREA', 'BEFORE', $this, '_editform'); // replacement
34        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, '_handle_edit_post');
35        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_handle_ajax');
36    }
37
38    /**
39     * Handles the page write event and removes the database info
40     * when the plugin code is no longer in the source
41     *
42     * @param Doku_Event $event
43     * @param null       $param
44     */
45    function _handle(Doku_Event $event, $param){
46        $data = $event->data;
47        if(strpos($data[0][1],'dataentry') !== false) return; // plugin seems still to be there
48
49        $sqlite = $this->dthlp->_getDB();
50        if(!$sqlite) return;
51        $id = ltrim($data[1].':'.$data[2],':');
52
53        // get page id
54        $res = $sqlite->query('SELECT pid FROM pages WHERE page = ?',$id);
55        $pid = (int) $sqlite->res2single($res);
56        if(!$pid) return; // we have no data for this page
57
58        $sqlite->query('DELETE FROM data WHERE pid = ?',$pid);
59        $sqlite->query('DELETE FROM pages WHERE pid = ?',$pid);
60    }
61
62    /**
63     * @param Doku_Event $event
64     * @param null       $param
65     */
66    function _editbutton($event, $param) {
67        if ($event->data['target'] !== 'plugin_data') {
68            return;
69        }
70
71        $event->data['name'] = $this->getLang('dataentry');
72    }
73
74    /**
75     * @param Doku_Event $event
76     * @param null       $param
77     */
78    function _editform(Doku_Event $event, $param) {
79        global $TEXT;
80        if ($event->data['target'] !== 'plugin_data') {
81            // Not a data edit
82            return;
83        }
84
85        $event->stopPropagation();
86        $event->preventDefault();
87        unset($event->data['intro_locale']);
88        $event->data['media_manager'] = false;
89
90        echo $this->locale_xhtml('edit_intro' . ($this->getConf('edit_content_only') ? '_contentonly' : ''));
91
92        require_once 'renderer_data_edit.php';
93        $Renderer = new Doku_Renderer_plugin_data_edit();
94        $Renderer->form = $event->data['form'];
95
96        // Loop through the instructions
97        $instructions = p_get_instructions($TEXT);
98        foreach ( $instructions as $instruction ) {
99            // Execute the callback against the Renderer
100            call_user_func_array(array($Renderer, $instruction[0]),$instruction[1]);
101        }
102    }
103
104    /**
105     * @param Doku_Event $event
106     */
107    function _handle_edit_post(Doku_Event $event) {
108        if (!isset($_POST['data_edit'])) {
109            return;
110        }
111        global $TEXT;
112
113        require_once 'syntax/entry.php';
114        $TEXT = syntax_plugin_data_entry::editToWiki($_POST['data_edit']);
115    }
116
117    /**
118     * @param Doku_Event $event
119     */
120    function _handle_ajax(Doku_Event $event) {
121        if ($event->data !== 'data_page') {
122            return;
123        }
124
125        $event->stopPropagation();
126        $event->preventDefault();
127
128        $type = substr($_REQUEST['aliastype'], 10);
129        $aliases = $this->dthlp->_aliases();
130
131        if (!isset($aliases[$type])) {
132            echo 'Unknown type';
133            return;
134        }
135
136        if ($aliases[$type]['type'] !== 'page') {
137            echo 'AutoCompletion is only supported for page types';
138            return;
139        }
140
141        if (substr($aliases[$type]['postfix'], -1, 1) === ':') {
142            // Resolve namespace start page ID
143            global $conf;
144            $aliases[$type]['postfix'] .= $conf['start'];
145        }
146
147        $search = $_REQUEST['search'];
148
149        $c_search = $search;
150        $in_ns = false;
151        if (!$search) {
152            // No search given, so we just want all pages in the prefix
153            $c_search = $aliases[$type]['prefix'];
154            $in_ns = true;
155        }
156        $pages = ft_pageLookup($c_search, $in_ns, false);
157
158        $regexp = '/^';
159        if ($aliases[$type]['prefix'] !== '') {
160            $regexp .= preg_quote($aliases[$type]['prefix'], '/');
161        }
162        $regexp .= '([^:]+)';
163        if ($aliases[$type]['postfix'] !== '') {
164            $regexp .= preg_quote($aliases[$type]['postfix'], '/');
165        }
166        $regexp .= '$/';
167
168        $result = array();
169        foreach ($pages as $page => $title) {
170            $id = array();
171            if (!preg_match($regexp, $page, $id)) {
172                // Does not satisfy the postfix and prefix criteria
173                continue;
174            }
175
176            $id = $id[1];
177
178            if ($search !== '' &&
179                stripos($id, cleanID($search)) === false &&
180                stripos($title, $search) === false) {
181                // Search string is not in id part or title
182                continue;
183            }
184
185            if ($title === '') {
186                $title = utf8_ucwords(str_replace('_', ' ', $id));
187            }
188            $result[hsc($id)] = hsc($title);
189        }
190
191        $json = new JSON();
192        header('Content-Type: application/json');
193        echo $json->encode($result);
194    }
195}
196