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
12class BatcheditRequest {
13
14    const COMMAND_WELCOME = 'welcome';
15    const COMMAND_PREVIEW = 'preview';
16    const COMMAND_APPLY = 'apply';
17
18    private $command;
19    private $sessionId;
20    private $namespace;
21    private $regexp;
22    private $replacement;
23    private $summary;
24    private $minorEdit;
25    private $appliedMatches;
26
27    /**
28     *
29     */
30    public function __construct($config) {
31        $this->command = $this->parseCommand();
32
33        if ($this->command == self::COMMAND_WELCOME) {
34            return;
35        }
36
37        $config->update($this->parseOptions());
38
39        $this->sessionId = $this->parseSessionId();
40        $this->namespace = $this->parseNamespace();
41        $this->regexp = $this->parseRegexp($config);
42        $this->replacement = $this->parseReplacement();
43        $this->summary = $this->parseSummary();
44        $this->minorEdit = isset($_REQUEST['minor']);
45
46        if ($this->command == self::COMMAND_APPLY || $config->getConf('keepmarks')) {
47            $this->appliedMatches = $this->parseAppliedMatches();
48        }
49    }
50
51    /**
52     *
53     */
54    public function getCommand() {
55        return $this->command;
56    }
57
58    /**
59     *
60     */
61    public function getSessionId() {
62        return $this->sessionId;
63    }
64
65    /**
66     *
67     */
68    public function getNamespace() {
69        return $this->namespace;
70    }
71
72    /**
73     *
74     */
75    public function getRegexp() {
76        return $this->regexp;
77    }
78
79    /**
80     *
81     */
82    public function getReplacement() {
83        return $this->replacement;
84    }
85
86    /**
87     *
88     */
89    public function getSummary() {
90        return $this->summary;
91    }
92
93    /**
94     *
95     */
96    public function getMinorEdit() {
97        return $this->minorEdit;
98    }
99
100    /**
101     *
102     */
103    public function getAppliedMatches() {
104        return $this->appliedMatches;
105    }
106
107    /**
108     *
109     */
110    private function parseCommand() {
111        if (!isset($_REQUEST['cmd'])) {
112            return self::COMMAND_WELCOME;
113        }
114
115        if (!is_array($_REQUEST['cmd'])) {
116            throw new BatcheditException('err_invreq');
117        }
118
119        $command = key($_REQUEST['cmd']);
120
121        if (($command != 'preview') && ($command != 'apply')) {
122            throw new BatcheditException('err_invreq');
123        }
124
125        return $command;
126    }
127
128    /**
129     *
130     */
131    private function parseOptions() {
132        if (!isset($_REQUEST['searchmode'])) {
133            throw new BatcheditException('err_invreq');
134        }
135
136        $options = array();
137
138        $options['searchmode'] = $_REQUEST['searchmode'];
139        $options['matchcase'] = isset($_REQUEST['matchcase']);
140        $options['multiline'] = isset($_REQUEST['multiline']);
141        $options['advregexp'] = isset($_REQUEST['advregexp']);
142        $options['matchctx'] = isset($_REQUEST['matchctx']);
143        $options['ctxchars'] = isset($_REQUEST['ctxchars']) ? $_REQUEST['ctxchars'] : '';
144        $options['ctxlines'] = isset($_REQUEST['ctxlines']) ? $_REQUEST['ctxlines'] : '';
145        $options['searchlimit'] = isset($_REQUEST['searchlimit']);
146        $options['searchmax'] = isset($_REQUEST['searchmax']) ? $_REQUEST['searchmax'] : '';
147        $options['keepmarks'] = isset($_REQUEST['keepmarks']);
148        $options['markpolicy'] = isset($_REQUEST['markpolicy']) ? $_REQUEST['markpolicy'] : '';
149        $options['checksummary'] = isset($_REQUEST['checksummary']);
150
151        return $options;
152    }
153
154    /**
155     *
156     */
157    private function parseSessionId() {
158        if (!isset($_REQUEST['session'])) {
159            return '';
160        }
161
162        return $_REQUEST['session'];
163    }
164
165    /**
166     *
167     */
168    private function parseNamespace() {
169        if (!isset($_REQUEST['namespace'])) {
170            throw new BatcheditException('err_invreq');
171        }
172
173        $namespace = trim($_REQUEST['namespace']);
174
175        if ($namespace != '') {
176            global $ID;
177
178            $namespace = resolve_id(getNS($ID), $namespace . ':') . ':';
179        }
180
181        return $namespace;
182    }
183
184    /**
185     *
186     */
187    private function parseRegexp($config) {
188        if (!isset($_REQUEST['search'])) {
189            throw new BatcheditException('err_invreq');
190        }
191
192        $regexp = trim($_REQUEST['search']);
193
194        if ($regexp == '') {
195            throw new BatcheditException('err_nosearch');
196        }
197
198        if ($config->getConf('searchmode') == 'regexp') {
199            if ($config->getConf('advregexp')) {
200                if (preg_match('/^([^\w\\\\]|_).+?\1[imsxADSUXJu]*$/s', $regexp) != 1) {
201                    throw new BatcheditException('err_invregexp');
202                }
203            }
204            else {
205                $regexp = "\033" . $regexp . "\033um";
206            }
207        }
208        else {
209            $regexp = "\033" . preg_quote($regexp) . "\033";
210        }
211
212        $regexp = str_replace("\r\n", "\n", $regexp);
213
214        if (!$config->getConf('matchcase')) {
215            $regexp .= 'i';
216        }
217
218        return $regexp;
219    }
220
221    /**
222     *
223     */
224    private function parseReplacement() {
225        if (!isset($_REQUEST['replace'])) {
226            throw new BatcheditException('err_invreq');
227        }
228
229        $replace = str_replace("\r\n", "\n", $_REQUEST['replace']);
230
231        $unescape = function($matches) {
232            static $unescaped = array('n' => "\n", 'r' => "\r", 't' => "\t");
233
234            if (strlen($matches[1]) % 2) {
235                return substr($matches[1], 1) . $unescaped[$matches[2]];
236            }
237            else {
238                return $matches[0];
239            }
240        };
241
242        return preg_replace_callback('/(\\\\+)([nrt])/', $unescape, $replace);
243    }
244
245    /**
246     *
247     */
248    private function parseSummary() {
249        if (!isset($_REQUEST['summary'])) {
250            throw new BatcheditException('err_invreq');
251        }
252
253        return $_REQUEST['summary'];
254    }
255
256    /**
257     *
258     */
259    private function parseAppliedMatches() {
260        if (!isset($_REQUEST['apply'])) {
261            return array();
262        }
263
264        $matchIds = json_decode($_REQUEST['apply']);
265
266        if (!is_array($matchIds)) {
267            throw new BatcheditException('err_invreq');
268        }
269
270        return $matchIds;
271    }
272}
273