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 header('Content-Type: application/json'); 113 114 if($this->renameOkay($src) && $MoveOperator->movePage($src, $dst)) { 115 // all went well, redirect 116 echo json_encode(array('redirect_url' => wl($dst, '', true, '&'))); 117 } else { 118 if(isset($MSG[0])) { 119 $error = $MSG[0]; // first error 120 } else { 121 $error = $this->getLang('cantrename'); 122 } 123 echo json_encode(array('error' => $error)); 124 } 125 } 126 127 /** 128 * Handle media renames in media manager 129 * 130 * @param Doku_Event $event 131 * @return void 132 */ 133 public function handleAjaxMediaManager(Doku_Event $event) 134 { 135 if ($event->data !== 'plugin_move_rename_mediamanager') return; 136 137 if (!checkSecurityToken()) { 138 throw new \Exception('Security token did not match'); 139 } 140 141 $event->preventDefault(); 142 $event->stopPropagation(); 143 144 global $INPUT; 145 global $MSG; 146 global $USERINFO; 147 148 $src = cleanID($INPUT->str('src')); 149 $dst = cleanID($INPUT->str('dst')); 150 151 /** @var helper_plugin_move_op $moveOperator */ 152 $moveOperator = plugin_load('helper', 'move_op'); 153 154 if ($src && $dst) { 155 header('Content-Type: application/json'); 156 157 $response = []; 158 159 // check user/group restrictions 160 if ( 161 !auth_isMember($this->getConf('allowrename'), $INPUT->server->str('REMOTE_USER'), (array) $USERINFO['grps']) 162 ) { 163 $response['error'] = $this->getLang('notallowed'); 164 echo json_encode($response); 165 return; 166 } 167 168 $response['success'] = $moveOperator->moveMedia($src, $dst); 169 170 if ($response['success']) { 171 $ns = getNS($dst); 172 $response['redirect_url'] = wl($dst, ['do' => 'media', 'ns' => $ns], true, '&'); 173 } else { 174 $response['error'] = sprintf($this->getLang('mediamoveerror'), $src); 175 if (isset($MSG)) { 176 foreach ($MSG as $msg) { 177 $response['error'] .= ' ' . $msg['msg']; 178 } 179 } 180 } 181 182 echo json_encode($response); 183 } 184 } 185 186 /** 187 * Determines if it would be okay to show a rename page button for the given page and current user 188 * 189 * @param $id 190 * @return bool 191 */ 192 public function renameOkay($id) { 193 global $conf; 194 global $ACT; 195 global $USERINFO; 196 if(!($ACT == 'show' || empty($ACT))) return false; 197 if(!page_exists($id)) return false; 198 if(auth_quickaclcheck($id) < AUTH_EDIT) return false; 199 if(checklock($id) !== false || @file_exists(wikiLockFN($id))) return false; 200 if(!$conf['useacl']) return true; 201 if(!isset($_SERVER['REMOTE_USER'])) return false; 202 if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], (array) $USERINFO['grps'])) return false; 203 204 return true; 205 } 206 207 /** 208 * Use this in your template to add a simple "move this page" link 209 * 210 * Alternatively give anything the class "plugin_move_page" - it will automatically be hidden and shown and 211 * trigger the page move dialog. 212 */ 213 public function tpl() { 214 echo '<a href="" class="plugin_move_page">'; 215 echo $this->getLang('renamepage'); 216 echo '</a>'; 217 } 218 219} 220