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['tplpatterns'] = isset($_REQUEST['tplpatterns']);
150        $options['checksummary'] = isset($_REQUEST['checksummary']);
151
152        return $options;
153    }
154
155    /**
156     *
157     */
158    private function parseSessionId() {
159        if (!isset($_REQUEST['session'])) {
160            return '';
161        }
162
163        return $_REQUEST['session'];
164    }
165
166    /**
167     *
168     */
169    private function parseNamespace() {
170        if (!isset($_REQUEST['namespace'])) {
171            throw new BatcheditException('err_invreq');
172        }
173
174        $namespace = trim($_REQUEST['namespace']);
175
176        if ($namespace != '') {
177            global $ID;
178
179            $namespace = resolve_id(getNS($ID), $namespace . ':') . ':';
180        }
181
182        return $namespace;
183    }
184
185    /**
186     *
187     */
188    private function parseRegexp($config) {
189        if (!isset($_REQUEST['search'])) {
190            throw new BatcheditException('err_invreq');
191        }
192
193        $regexp = trim($_REQUEST['search']);
194
195        if ($regexp == '') {
196            throw new BatcheditException('err_nosearch');
197        }
198
199        if ($config->getConf('searchmode') == 'regexp') {
200            if ($config->getConf('advregexp')) {
201                if (preg_match('/^([^\w\\\\]|_).+?\1[imsxADSUXJu]*$/s', $regexp) != 1) {
202                    throw new BatcheditException('err_invregexp');
203                }
204            }
205            else {
206                $regexp = "\033" . $regexp . "\033um";
207            }
208        }
209        else {
210            $regexp = "\033" . preg_quote($regexp) . "\033";
211        }
212
213        $regexp = str_replace("\r\n", "\n", $regexp);
214
215        if (!$config->getConf('matchcase')) {
216            $regexp .= 'i';
217        }
218
219        return $regexp;
220    }
221
222    /**
223     *
224     */
225    private function parseReplacement() {
226        if (!isset($_REQUEST['replace'])) {
227            throw new BatcheditException('err_invreq');
228        }
229
230        $replace = str_replace("\r\n", "\n", $_REQUEST['replace']);
231
232        $unescape = function($matches) {
233            static $unescaped = array('n' => "\n", 'r' => "\r", 't' => "\t");
234
235            if (strlen($matches[1]) % 2) {
236                return substr($matches[1], 1) . $unescaped[$matches[2]];
237            }
238            else {
239                return $matches[0];
240            }
241        };
242
243        return preg_replace_callback('/(\\\\+)([nrt])/', $unescape, $replace);
244    }
245
246    /**
247     *
248     */
249    private function parseSummary() {
250        if (!isset($_REQUEST['summary'])) {
251            throw new BatcheditException('err_invreq');
252        }
253
254        return $_REQUEST['summary'];
255    }
256
257    /**
258     *
259     */
260    private function parseAppliedMatches() {
261        if (!isset($_REQUEST['apply'])) {
262            return array();
263        }
264
265        $matchIds = json_decode($_REQUEST['apply']);
266
267        if (!is_array($matchIds)) {
268            throw new BatcheditException('err_invreq');
269        }
270
271        return $matchIds;
272    }
273}
274