1<?php 2 3/** 4 * Plugin BatchEdit: User request 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Mykola Ostrovskyy <dwpforge@gmail.com> 8 */ 9 10require_once(DOKU_PLUGIN . 'batchedit/engine.php'); 11 12/** 13 * As of DW 2023-04-04 the \dokuwiki\File\Resolver class is abstact with only 14 * two concrete implementations (PageResolver, MediaResolver). This child class 15 * is used to access basic namespace resolution from the abstract base. 16 */ 17class BatcheditNamespaceResolver extends \dokuwiki\File\Resolver { 18} 19 20class BatcheditRequest { 21 22 const COMMAND_WELCOME = 'welcome'; 23 const COMMAND_PREVIEW = 'preview'; 24 const COMMAND_APPLY = 'apply'; 25 26 private $command; 27 private $sessionId; 28 private $namespace; 29 private $regexp; 30 private $replacement; 31 private $summary; 32 private $minorEdit; 33 private $appliedMatches; 34 35 /** 36 * 37 */ 38 public function __construct($config) { 39 $this->command = $this->parseCommand(); 40 41 if ($this->command == self::COMMAND_WELCOME) { 42 return; 43 } 44 45 $config->update($this->parseOptions()); 46 47 $this->sessionId = $this->parseSessionId(); 48 $this->namespace = $this->parseNamespace(); 49 $this->regexp = $this->parseRegexp($config); 50 $this->replacement = $this->parseReplacement(); 51 $this->summary = $this->parseSummary(); 52 $this->minorEdit = isset($_REQUEST['minor']); 53 54 if ($this->command == self::COMMAND_APPLY || $config->getConf('keepmarks')) { 55 $this->appliedMatches = $this->parseAppliedMatches(); 56 } 57 } 58 59 /** 60 * 61 */ 62 public function getCommand() { 63 return $this->command; 64 } 65 66 /** 67 * 68 */ 69 public function getSessionId() { 70 return $this->sessionId; 71 } 72 73 /** 74 * 75 */ 76 public function getNamespace() { 77 return $this->namespace; 78 } 79 80 /** 81 * 82 */ 83 public function getRegexp() { 84 return $this->regexp; 85 } 86 87 /** 88 * 89 */ 90 public function getReplacement() { 91 return $this->replacement; 92 } 93 94 /** 95 * 96 */ 97 public function getSummary() { 98 return $this->summary; 99 } 100 101 /** 102 * 103 */ 104 public function getMinorEdit() { 105 return $this->minorEdit; 106 } 107 108 /** 109 * 110 */ 111 public function getAppliedMatches() { 112 return $this->appliedMatches; 113 } 114 115 /** 116 * 117 */ 118 private function parseCommand() { 119 if (!isset($_REQUEST['cmd'])) { 120 return self::COMMAND_WELCOME; 121 } 122 123 if (!is_array($_REQUEST['cmd'])) { 124 throw new BatcheditException('err_invreq'); 125 } 126 127 $command = key($_REQUEST['cmd']); 128 129 if (($command != 'preview') && ($command != 'apply')) { 130 throw new BatcheditException('err_invreq'); 131 } 132 133 return $command; 134 } 135 136 /** 137 * 138 */ 139 private function parseOptions() { 140 if (!isset($_REQUEST['searchmode'])) { 141 throw new BatcheditException('err_invreq'); 142 } 143 144 $options = array(); 145 146 $options['searchmode'] = $_REQUEST['searchmode']; 147 $options['matchcase'] = isset($_REQUEST['matchcase']); 148 $options['multiline'] = isset($_REQUEST['multiline']); 149 $options['advregexp'] = isset($_REQUEST['advregexp']); 150 $options['matchctx'] = isset($_REQUEST['matchctx']); 151 $options['ctxchars'] = isset($_REQUEST['ctxchars']) ? $_REQUEST['ctxchars'] : ''; 152 $options['ctxlines'] = isset($_REQUEST['ctxlines']) ? $_REQUEST['ctxlines'] : ''; 153 $options['searchlimit'] = isset($_REQUEST['searchlimit']); 154 $options['searchmax'] = isset($_REQUEST['searchmax']) ? $_REQUEST['searchmax'] : ''; 155 $options['keepmarks'] = isset($_REQUEST['keepmarks']); 156 $options['markpolicy'] = isset($_REQUEST['markpolicy']) ? $_REQUEST['markpolicy'] : ''; 157 $options['tplpatterns'] = isset($_REQUEST['tplpatterns']); 158 $options['checksummary'] = isset($_REQUEST['checksummary']); 159 160 return $options; 161 } 162 163 /** 164 * 165 */ 166 private function parseSessionId() { 167 if (!isset($_REQUEST['session'])) { 168 return ''; 169 } 170 171 return $_REQUEST['session']; 172 } 173 174 /** 175 * 176 */ 177 private function parseNamespace() { 178 if (!isset($_REQUEST['namespace'])) { 179 throw new BatcheditException('err_invreq'); 180 } 181 182 $namespace = trim($_REQUEST['namespace']); 183 184 if ($namespace != '') { 185 global $ID; 186 $resolver = new BatcheditNamespaceResolver($ID); 187 $resolved = array(); 188 189 foreach (explode(',', $namespace) as $ns) { 190 $ns = trim($ns) . ':'; 191 192 if ($ns[0] == '-') { 193 $resolved[] = '-' . $resolver->resolveId(substr($ns, 1)); 194 } 195 else { 196 $resolved[] = $resolver->resolveId($ns); 197 } 198 } 199 200 $namespace = implode(',', $resolved); 201 } 202 203 return $namespace; 204 } 205 206 /** 207 * 208 */ 209 private function parseRegexp($config) { 210 if (!isset($_REQUEST['search'])) { 211 throw new BatcheditException('err_invreq'); 212 } 213 214 $regexp = trim($_REQUEST['search']); 215 216 if ($regexp == '') { 217 throw new BatcheditException('err_nosearch'); 218 } 219 220 if ($config->getConf('searchmode') == 'regexp') { 221 if ($config->getConf('advregexp')) { 222 if (preg_match('/^([^\w\\\\]|_).+?\1[imsxADSUXJu]*$/s', $regexp) != 1) { 223 throw new BatcheditException('err_invregexp'); 224 } 225 } 226 else { 227 $regexp = "\033" . $regexp . "\033um"; 228 } 229 } 230 else { 231 $regexp = "\033" . preg_quote($regexp) . "\033"; 232 } 233 234 $regexp = str_replace("\r\n", "\n", $regexp); 235 236 if (!$config->getConf('matchcase')) { 237 $regexp .= 'i'; 238 } 239 240 return $regexp; 241 } 242 243 /** 244 * 245 */ 246 private function parseReplacement() { 247 if (!isset($_REQUEST['replace'])) { 248 throw new BatcheditException('err_invreq'); 249 } 250 251 $replace = str_replace("\r\n", "\n", $_REQUEST['replace']); 252 253 $unescape = function($matches) { 254 static $unescaped = array('n' => "\n", 'r' => "\r", 't' => "\t"); 255 256 if (strlen($matches[1]) % 2) { 257 return substr($matches[1], 1) . $unescaped[$matches[2]]; 258 } 259 else { 260 return $matches[0]; 261 } 262 }; 263 264 return preg_replace_callback('/(\\\\+)([nrt])/', $unescape, $replace); 265 } 266 267 /** 268 * 269 */ 270 private function parseSummary() { 271 if (!isset($_REQUEST['summary'])) { 272 throw new BatcheditException('err_invreq'); 273 } 274 275 return $_REQUEST['summary']; 276 } 277 278 /** 279 * 280 */ 281 private function parseAppliedMatches() { 282 if (!isset($_REQUEST['apply'])) { 283 return array(); 284 } 285 286 $matchIds = json_decode($_REQUEST['apply']); 287 288 if (!is_array($matchIds)) { 289 throw new BatcheditException('err_invreq'); 290 } 291 292 return $matchIds; 293 } 294} 295