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