1<?php 2/** 3 * Move Plugin Page Rename Functionality 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <gohr@cosmocode.de> 7 */ 8// must be run within Dokuwiki 9if(!defined('DOKU_INC')) die(); 10 11/** 12 * Class action_plugin_move_rename 13 */ 14class action_plugin_move_rename extends DokuWiki_Action_Plugin { 15 16 /** 17 * Register event handlers. 18 * 19 * @param Doku_Event_Handler $controller The plugin controller 20 */ 21 public function register(Doku_Event_Handler $controller) { 22 $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'handle_init'); 23 24 // TODO: DEPRECATED JAN 2018 25 $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'handle_pagetools'); 26 27 $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addsvgbutton', array()); 28 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax'); 29 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxMediaManager'); 30 } 31 32 /** 33 * set JavaScript info if renaming of current page is possible 34 */ 35 public function handle_init() { 36 global $JSINFO; 37 global $INFO; 38 global $INPUT; 39 global $USERINFO; 40 41 if (isset($INFO['id'])) { 42 $JSINFO['move_renameokay'] = $this->renameOkay($INFO['id']); 43 } else { 44 $JSINFO['move_renameokay'] = false; 45 } 46 47 $JSINFO['move_allowrename'] = auth_isMember( 48 $this->getConf('allowrename'), 49 $INPUT->server->str('REMOTE_USER'), 50 $USERINFO['grps'] ?? [] 51 ); 52 } 53 54 /** 55 * Adds a button to the default template 56 * 57 * TODO: DEPRECATED JAN 2018 58 * 59 * @param Doku_Event $event 60 */ 61 public function handle_pagetools(Doku_Event $event) { 62 if($event->data['view'] != 'main') return; 63 if (!$this->getConf('pagetools_integration')) { 64 return; 65 } 66 67 $newitem = '<li class="plugin_move_page"><a href=""><span>' . $this->getLang('renamepage') . '</span></a></li>'; 68 $offset = count($event->data['items']) - 1; 69 $event->data['items'] = 70 array_slice($event->data['items'], 0, $offset, true) + 71 array('plugin_move' => $newitem) + 72 array_slice($event->data['items'], $offset, null, true); 73 } 74 75 /** 76 * Add 'rename' button to page tools, new SVG based mechanism 77 * 78 * @param Doku_Event $event 79 */ 80 public function addsvgbutton(Doku_Event $event) { 81 global $INFO, $JSINFO; 82 if( 83 $event->data['view'] !== 'page' || 84 !$this->getConf('pagetools_integration') || 85 empty($JSINFO['move_renameokay']) 86 ) { 87 return; 88 } 89 if(!$INFO['exists']) { 90 return; 91 } 92 array_splice($event->data['items'], -1, 0, array(new \dokuwiki\plugin\move\MenuItem())); 93 } 94 95 /** 96 * Rename a single page 97 */ 98 public function handle_ajax(Doku_Event $event) { 99 if($event->data != 'plugin_move_rename') return; 100 $event->preventDefault(); 101 $event->stopPropagation(); 102 103 global $MSG; 104 global $INPUT; 105 106 $src = cleanID($INPUT->str('id')); 107 $dst = cleanID($INPUT->str('newid')); 108 109 /** @var helper_plugin_move_op $MoveOperator */ 110 $MoveOperator = plugin_load('helper', 'move_op'); 111 112 $JSON = new JSON(); 113 114 header('Content-Type: application/json'); 115 116 if($this->renameOkay($src) && $MoveOperator->movePage($src, $dst)) { 117 // all went well, redirect 118 echo $JSON->encode(array('redirect_url' => wl($dst, '', true, '&'))); 119 } else { 120 if(isset($MSG[0])) { 121 $error = $MSG[0]; // first error 122 } else { 123 $error = $this->getLang('cantrename'); 124 } 125 echo $JSON->encode(array('error' => $error)); 126 } 127 } 128 129 /** 130 * Handle media renames in media manager 131 * 132 * @param Doku_Event $event 133 * @return void 134 */ 135 public function handleAjaxMediaManager(Doku_Event $event) 136 { 137 if ($event->data !== 'plugin_move_rename_mediamanager') return; 138 139 if (!checkSecurityToken()) { 140 throw new \Exception('Security token did not match'); 141 } 142 143 $event->preventDefault(); 144 $event->stopPropagation(); 145 146 global $INPUT; 147 global $MSG; 148 global $USERINFO; 149 150 $src = cleanID($INPUT->str('src')); 151 $dst = cleanID($INPUT->str('dst')); 152 153 /** @var helper_plugin_move_op $moveOperator */ 154 $moveOperator = plugin_load('helper', 'move_op'); 155 156 if ($src && $dst) { 157 header('Content-Type: application/json'); 158 159 $response = []; 160 161 // check user/group restrictions 162 if ( 163 !auth_isMember($this->getConf('allowrename'), $INPUT->server->str('REMOTE_USER'), (array) $USERINFO['grps']) 164 ) { 165 $response['error'] = $this->getLang('notallowed'); 166 echo json_encode($response); 167 return; 168 } 169 170 $response['success'] = $moveOperator->moveMedia($src, $dst); 171 172 if ($response['success']) { 173 $ns = getNS($dst); 174 $response['redirect_url'] = wl($dst, ['do' => 'media', 'ns' => $ns], true, '&'); 175 } else { 176 $response['error'] = sprintf($this->getLang('mediamoveerror'), $src); 177 if (isset($MSG)) { 178 foreach ($MSG as $msg) { 179 $response['error'] .= ' ' . $msg['msg']; 180 } 181 } 182 } 183 184 echo json_encode($response); 185 } 186 } 187 188 /** 189 * Determines if it would be okay to show a rename page button for the given page and current user 190 * 191 * @param $id 192 * @return bool 193 */ 194 public function renameOkay($id) { 195 global $conf; 196 global $ACT; 197 global $USERINFO; 198 if(!($ACT == 'show' || empty($ACT))) return false; 199 if(!page_exists($id)) return false; 200 if(auth_quickaclcheck($id) < AUTH_EDIT) return false; 201 if(checklock($id) !== false || @file_exists(wikiLockFN($id))) return false; 202 if(!$conf['useacl']) return true; 203 if(!isset($_SERVER['REMOTE_USER'])) return false; 204 if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], (array) $USERINFO['grps'])) return false; 205 206 return true; 207 } 208 209 /** 210 * Use this in your template to add a simple "move this page" link 211 * 212 * Alternatively give anything the class "plugin_move_page" - it will automatically be hidden and shown and 213 * trigger the page move dialog. 214 */ 215 public function tpl() { 216 echo '<a href="" class="plugin_move_page">'; 217 echo $this->getLang('renamepage'); 218 echo '</a>'; 219 } 220 221} 222