1<?php 2 3 4/** 5 * All DokuWiki plugins to extend the parser/rendering mechanism 6 * need to inherit from this class 7 */ 8class action_plugin_dtable extends DokuWiki_Action_Plugin { 9 10 function register(Doku_Event_Handler $controller) { 11 $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'add_php_data'); 12 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax'); 13 $controller->register_hook('PARSER_WIKITEXT_PREPROCESS', 'AFTER', $this, 'parser_preprocess_handler'); 14 $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insert_button', array ()); 15 16 } 17 18 public function insert_button (Doku_Event $event, $param) { 19 $event->data[] = array ( 20 'type' => 'format', 21 'title' => $this->getLang('toolbar_insert_button'), 22 'icon' => '../../plugins/dtable/images/add_table.png', 23 'open' => '<dtable>', 24 'close' => '</dtable>', 25 'sample' => "\n^ ^ ^\n| | |\n| | |\n| | |\n" 26 ); 27 } 28 function parser_preprocess_handler(&$event, $parm) 29 { 30 global $ID, $INFO; 31 $lines = explode("\n", $event->data); 32 $new_lines = array(); 33 //determine dtable page 34 35 //only 100 dtables per page 36 $i = 0; 37 $dtable_pages = array(); 38 foreach($lines as $line) 39 { 40 if(strpos($line, '<dtable>') === 0) { 41 $new_lines[] = '<dtab'.( $i < 10 ? '0'.$i : $i ).'>'; 42 $dtable_pages[$i] = $ID; 43 $i++; 44 } else 45 { 46 $new_lines[] = $line; 47 } 48 } 49 50 //it will make include plugin behaves correctly 51 p_set_metadata($INFO['id'] ?? null, array('dtable_pages' => $dtable_pages), false, false); 52 53 //mark dtables 54 //it will not work becouse section editing in dokuwiki needs no modified content. 55 if($this->getConf('all_tables')) 56 { 57 $new_lines = array(); 58 59 $in_tab = 0; 60 $in_dtable_tag = 0; 61 62 foreach($lines as $line) 63 { 64 if(strpos($line, '<dtable>') === 0) 65 $in_dtable_tag = 1; 66 if(strpos($line, '</dtable>') === 0) 67 $in_dtable_tag = 0; 68 69 if(strpos($line, '|') !== 0 && $in_tab == 1 && $in_dtable_tag == 0) 70 { 71 $new_lines[] = '</dtable>'; 72 $in_tab = 0; 73 } 74 75 if(strpos($line, '^') === 0 && $in_tab == 0 && $in_dtable_tag == 0) 76 { 77 $new_lines[] = '<dtable>'; 78 $in_tab = 1; 79 } 80 81 $new_lines[] = $line; 82 } 83 $lines = $new_lines; 84 } 85 $event->data = implode("\n", $new_lines); 86 } 87 function add_php_data(&$event, $param) { 88 global $JSINFO, $ID; 89 90 if (auth_quickaclcheck($ID) >= AUTH_EDIT) 91 $JSINFO['write'] = true; 92 else 93 $JSINFO['write'] = false; 94 95 $JSINFO['disabled'] = explode(',', $this->getConf('disabled')); 96 97 98 $JSINFO['lang']['insert_before'] = $this->getLang('insert_before'); 99 $JSINFO['lang']['insert_after'] = $this->getLang('insert_after'); 100 $JSINFO['lang']['edit'] = $this->getLang('edit'); 101 $JSINFO['lang']['remove'] = $this->getLang('remove'); 102 $JSINFO['lang']['insert_col_left'] = $this->getLang('insert_col_left'); 103 $JSINFO['lang']['insert_col_right'] = $this->getLang('insert_col_right'); 104 $JSINFO['lang']['mark_row_as_header'] = $this->getLang('mark_row_as_header'); 105 $JSINFO['lang']['mark_col_as_header'] = $this->getLang('mark_col_as_header'); 106 $JSINFO['lang']['mark_cell_as_header'] = $this->getLang('mark_cell_as_header'); 107 108 $JSINFO['lang']['mark_row_as_cell'] = $this->getLang('mark_row_as_cell'); 109 $JSINFO['lang']['mark_col_as_cell'] = $this->getLang('mark_col_as_cell'); 110 $JSINFO['lang']['mark_cell_as_cell'] = $this->getLang('mark_cell_as_cell'); 111 112 $JSINFO['lang']['show_merged_rows'] = $this->getLang('show_merged_rows'); 113 114 $JSINFO['lang']['lock_notify'] = str_replace( 115 array('%u', '%t'), 116 array('<span class="who"></span>', '<span class="time_left"></span>'), 117 $this->getLang('lock_notify')); 118 $JSINFO['lang']['unlock_notify'] = $this->getLang('unlock_notify'); 119 } 120 function handle_ajax(&$event, $param) 121 { 122 global $conf; 123 124 switch($event->data) 125 { 126 case 'dtable': 127 $event->preventDefault(); 128 $event->stopPropagation(); 129 130 list($dtable_start_line, $dtable_page_id) = explode('_', $_POST['table'], 2); 131 $file = wikiFN( $dtable_page_id ); 132 if( ! @file_exists( $file ) ) 133 { 134 echo json_encode( array('type' => 'error', 'msg' => 'This page does not exist.') ); 135 exit(0); 136 } 137 138 $dtable = plugin_load('helper', 'dtable'); 139 140 $page_lines = explode( "\n", io_readFile( $file ) ); 141 142 if(isset($_POST['remove'])) 143 { 144 $scope = json_decode($_POST['remove'], true); 145 146 $lines_to_remove = array(); 147 for ($i = $scope[0]; $i <= $scope[1]; $i++) 148 $lines_to_remove[] = $i; 149 150 $removed_line = ''; 151 foreach ($lines_to_remove as $line) { 152 $removed_line .= $page_lines[ $line ]." "; 153 } 154 155 array_splice($page_lines, $scope[0], $scope[1] - $scope[0] + 1); 156 157 $new_cont = implode( "\n", $page_lines ); 158 159 saveWikiText($dtable_page_id, $new_cont, $this->getLang('summary_remove').' '.$removed_line); 160 161 162 163 echo json_encode( array('type' => 'success', 'spans' => 164 $dtable->get_spans($dtable_start_line, $page_lines, $dtable_page_id) ) ); 165 166 } else 167 { 168 $cols = array(); 169 $new_table_line = array(); 170 foreach( $_POST as $k => $v ) 171 { 172 if( strpos( $k, 'col' ) === 0) 173 { 174 //remove col from col12, col1 etc. to be 12 1 175 $cols[(int)substr($k, 3)] = json_decode($v, true); 176 } 177 } 178 ksort($cols); 179 180 //reset index 181 $cols = array_values($cols); 182 183 $j = 0; 184 for($i = 0; $i < count($cols); $i++) { 185 $class = $cols[$i][0]; 186 $value = $cols[$i][1]; 187 188 if ($value == '' && $j >= 1) 189 $new_table_line[$j-1][1]++; 190 else { 191 $type = $class == 'tablecell_open' ? '|' : '^'; 192 $new_table_line[$j] = array(1, 1, $type, $value); 193 $j++; 194 } 195 } 196 $new_line = $dtable->format_row($cols); 197 198 if( isset( $_POST['add'] ) ) 199 { 200 $action = 'add'; 201 202 /*$table_line = (int) $_POST['add'] + 1; 203 $line_to_add = $dtable_start_line + $table_line;*/ 204 $line_to_add = (int) $_POST['add'] + 1; 205 206 array_splice($page_lines, $line_to_add, 0, $new_line ); 207 $line_nr = $line_to_add; 208 209 $info = $this->getLang('summary_add').' '.$new_line; 210 211 } elseif( isset( $_POST['edit'] ) ) 212 { 213 $action = 'edit'; 214 215 $scope = json_decode($_POST['edit'], true); 216 217 $lines_to_change = array(); 218 for ($i = $scope[0]; $i <= $scope[1]; $i++) 219 $lines_to_change[] = $i; 220 221 $old_line= ''; 222 foreach ($lines_to_change as $line) { 223 $old_line .= $page_lines[ $line ]." "; 224 } 225 226 //$old_line = $page_lines[ $line_to_change ]; 227 228 array_splice($page_lines, $scope[0], $scope[1] - $scope[0] + 1, $new_line); 229 $line_nr = $scope[0]; 230 231 $new_cont = implode( "\n", $page_lines ); 232 233 $info = str_replace( array('%o', '%n'), array($old_line, $new_line), $this->getLang('summary_edit') ); 234 } 235 236 $new_cont = implode( "\n", $page_lines ); 237 saveWikiText($dtable_page_id, $new_cont, $info); 238 239 echo json_encode( array('type' => 'success', 'action' => $action, 'new_row' => $dtable->parse_line($new_line, $dtable_page_id), 'raw_row' => array($new_table_line, array($line_nr, $line_nr)), 'spans' => $dtable->get_spans($dtable_start_line, $page_lines, $dtable_page_id) ) ); 240 241 } 242 break; 243 case 'dtable_page_lock': 244 $event->preventDefault(); 245 $event->stopPropagation(); 246 247 $ID = $_POST['page']; 248 lock($ID); 249 break; 250 case 'dtable_page_unlock': 251 $event->preventDefault(); 252 $event->stopPropagation(); 253 254 $ID = $_POST['page']; 255 unlock($ID); 256 break; 257 case 'dtable_is_page_locked': 258 $event->preventDefault(); 259 $event->stopPropagation(); 260 261 $ID = $_POST['page']; 262 $checklock = checklock($ID); 263 264 //check when lock expire 265 $lock_file = wikiLockFN($ID); 266 if(file_exists($lock_file)) 267 { 268 $locktime = filemtime(wikiLockFN($ID)); 269 //dokuwiki uses dformat here but we will use raw unix timesamp 270 $expire = $locktime + $conf['locktime'] - time(); 271 } else 272 $expire = $conf['locktime']; 273 274 if($checklock === false) 275 echo json_encode(array('locked' => 0, 'time_left' => $expire)); 276 else 277 echo json_encode(array('locked' => 1, 'who' => $checklock, 'time_left' => $expire)); 278 279 break; 280 } 281 } 282} 283