Failed Conditions
Push — psr2 ( 2140e7...2ed72d )
by Andreas
03:11
created

Ajax::call_draftdel()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki;
4
5
/**
6
 * Manage all builtin AJAX calls
7
 *
8
 * @todo The calls should be refactored out to their own proper classes
9
 * @package dokuwiki
10
 */
11
class Ajax {
12
13
    /**
14
     * Execute the given call
15
     *
16
     * @param string $call name of the ajax call
17
     */
18
    public function __construct($call) {
19
        $callfn = 'call' . ucfirst($call);
20
        if(method_exists($this, $callfn)) {
21
            $this->$callfn();
22
        } else {
23
            $evt = new \Doku_Event('AJAX_CALL_UNKNOWN', $call);
24
            if($evt->advise_before()) {
25
                print "AJAX call '" . hsc($call) . "' unknown!\n";
26
            } else {
27
                $evt->advise_after();
28
                unset($evt);
29
            }
30
        }
31
    }
32
33
    /**
34
     * Searches for matching pagenames
35
     *
36
     * @author Andreas Gohr <[email protected]>
37
     */
38
    protected function callQsearch() {
39
        global $lang;
40
        global $INPUT;
41
42
        $maxnumbersuggestions = 50;
43
44
        $query = $INPUT->post->str('q');
45
        if(empty($query)) $query = $INPUT->get->str('q');
46
        if(empty($query)) return;
47
48
        $query = urldecode($query);
49
50
        $data = ft_pageLookup($query, true, useHeading('navigation'));
51
52
        if(!count($data)) return;
53
54
        print '<strong>' . $lang['quickhits'] . '</strong>';
55
        print '<ul>';
56
        $counter = 0;
57
        foreach($data as $id => $title) {
58
            if(useHeading('navigation')) {
59
                $name = $title;
60
            } else {
61
                $ns = getNS($id);
62
                if($ns) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ns of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
63
                    $name = noNS($id) . ' (' . $ns . ')';
64
                } else {
65
                    $name = $id;
66
                }
67
            }
68
            echo '<li>' . html_wikilink(':' . $id, $name) . '</li>';
69
70
            $counter++;
71
            if($counter > $maxnumbersuggestions) {
72
                echo '<li>...</li>';
73
                break;
74
            }
75
        }
76
        print '</ul>';
77
    }
78
79
    /**
80
     * Support OpenSearch suggestions
81
     *
82
     * @link   http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0
83
     * @author Mike Frysinger <[email protected]>
84
     */
85
    protected function callSuggestions() {
86
        global $INPUT;
87
88
        $query = cleanID($INPUT->post->str('q'));
89
        if(empty($query)) $query = cleanID($INPUT->get->str('q'));
90
        if(empty($query)) return;
91
92
        $data = ft_pageLookup($query);
93
        if(!count($data)) return;
94
        $data = array_keys($data);
95
96
        // limit results to 15 hits
97
        $data = array_slice($data, 0, 15);
98
        $data = array_map('trim', $data);
99
        $data = array_map('noNS', $data);
100
        $data = array_unique($data);
101
        sort($data);
102
103
        /* now construct a json */
104
        $suggestions = array(
105
            $query,  // the original query
106
            $data,   // some suggestions
107
            array(), // no description
108
            array()  // no urls
109
        );
110
111
        header('Content-Type: application/x-suggestions+json');
112
        print json_encode($suggestions);
113
    }
114
115
    /**
116
     * Refresh a page lock and save draft
117
     *
118
     * Andreas Gohr <[email protected]>
119
     */
120
    protected function callLock() {
121
        global $ID;
122
        global $INFO;
123
        global $INPUT;
124
125
        $ID = cleanID($INPUT->post->str('id'));
126
        if(empty($ID)) return;
127
128
        $INFO = pageinfo();
129
130
        $response = [
131
            'errors' => [],
132
            'lock' => '0',
133
            'draft' => '',
134
        ];
135
        if(!$INFO['writable']) {
136
            $response['errors'][] = 'Permission to write this page has been denied.';
137
            echo json_encode($response);
138
            return;
139
        }
140
141
        if(!checklock($ID)) {
142
            lock($ID);
143
            $response['lock'] = '1';
144
        }
145
146
        $draft = new Draft($ID, $INFO['client']);
147
        if ($draft->saveDraft()) {
148
            $response['draft'] = $draft->getDraftMessage();
149
        } else {
150
            $response['errors'] = array_merge($response['errors'], $draft->getErrors());
151
        }
152
        echo json_encode($response);
153
    }
154
155
    /**
156
     * Delete a draft
157
     *
158
     * @author Andreas Gohr <[email protected]>
159
     */
160
    protected function callDraftdel() {
161
        global $INPUT;
162
        $id = cleanID($INPUT->str('id'));
163
        if(empty($id)) return;
164
165
        $client = $_SERVER['REMOTE_USER'];
166
        if(!$client) $client = clientIP(true);
167
168
        $cname = getCacheName($client . $id, '.draft');
169
        @unlink($cname);
170
    }
171
172
    /**
173
     * Return subnamespaces for the Mediamanager
174
     *
175
     * @author Andreas Gohr <[email protected]>
176
     */
177
    protected function callMedians() {
178
        global $conf;
179
        global $INPUT;
180
181
        // wanted namespace
182
        $ns = cleanID($INPUT->post->str('ns'));
183
        $dir = utf8_encodeFN(str_replace(':', '/', $ns));
184
185
        $lvl = count(explode(':', $ns));
186
187
        $data = array();
188
        search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir);
189
        foreach(array_keys($data) as $item) {
190
            $data[$item]['level'] = $lvl + 1;
191
        }
192
        echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li');
193
    }
194
195
    /**
196
     * Return list of files for the Mediamanager
197
     *
198
     * @author Andreas Gohr <[email protected]>
199
     */
200
    protected function callMedialist() {
201
        global $NS;
202
        global $INPUT;
203
204
        $NS = cleanID($INPUT->post->str('ns'));
205
        $sort = $INPUT->post->bool('recent') ? 'date' : 'natural';
206
        if($INPUT->post->str('do') == 'media') {
207
            tpl_mediaFileList();
208
        } else {
209
            tpl_mediaContent(true, $sort);
210
        }
211
    }
212
213
    /**
214
     * Return the content of the right column
215
     * (image details) for the Mediamanager
216
     *
217
     * @author Kate Arzamastseva <[email protected]>
218
     */
219
    protected function callMediadetails() {
220
        global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT;
221
        $fullscreen = true;
222
        require_once(DOKU_INC . 'lib/exe/mediamanager.php');
223
224
        $image = '';
225
        if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
226
        if(isset($IMG)) $image = $IMG;
227
        if(isset($JUMPTO)) $image = $JUMPTO;
228
        $rev = false;
229
        if(isset($REV) && !$JUMPTO) $rev = $REV;
230
231
        html_msgarea();
232
        tpl_mediaFileDetails($image, $rev);
233
    }
234
235
    /**
236
     * Returns image diff representation for mediamanager
237
     *
238
     * @author Kate Arzamastseva <[email protected]>
239
     */
240
    protected function callMediadiff() {
241
        global $NS;
242
        global $INPUT;
243
244
        $image = '';
245
        if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
246
        $NS = getNS($image);
247
        $auth = auth_quickaclcheck("$NS:*");
248
        media_diff($image, $NS, $auth, true);
0 ignored issues
show
Security Bug introduced by
It seems like $NS defined by getNS($image) on line 246 can also be of type false; however, media_diff() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
249
    }
250
251
    /**
252
     * Manages file uploads
253
     *
254
     * @author Kate Arzamastseva <[email protected]>
255
     */
256
    protected function callMediaupload() {
257
        global $NS, $MSG, $INPUT;
258
259
        $id = '';
260
        if($_FILES['qqfile']['tmp_name']) {
261
            $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']);
262
        } elseif($INPUT->get->has('qqfile')) {
263
            $id = $INPUT->get->str('qqfile');
264
        }
265
266
        $id = cleanID($id);
267
268
        $NS = $INPUT->str('ns');
269
        $ns = $NS . ':' . getNS($id);
270
271
        $AUTH = auth_quickaclcheck("$ns:*");
272
        if($AUTH >= AUTH_UPLOAD) {
273
            io_createNamespace("$ns:xxx", 'media');
274
        }
275
276
        if($_FILES['qqfile']['error']) unset($_FILES['qqfile']);
277
278
        $res = false;
279
        if($_FILES['qqfile']['tmp_name']) $res = media_upload($NS, $AUTH, $_FILES['qqfile']);
280
        if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH);
281
282
        if($res) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $res of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
283
            $result = array(
284
                'success' => true,
285
                'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'),
286
                'id' => $NS . ':' . $id,
287
                'ns' => $NS
288
            );
289
        } else {
290
            $error = '';
291
            if(isset($MSG)) {
292
                foreach($MSG as $msg) {
293
                    $error .= $msg['msg'];
294
                }
295
            }
296
            $result = array(
297
                'error' => $error,
298
                'ns' => $NS
299
            );
300
        }
301
302
        header('Content-Type: application/json');
303
        echo json_encode($result);
304
    }
305
306
    /**
307
     * Return sub index for index view
308
     *
309
     * @author Andreas Gohr <[email protected]>
310
     */
311
    protected function callIndex() {
312
        global $conf;
313
        global $INPUT;
314
315
        // wanted namespace
316
        $ns = cleanID($INPUT->post->str('idx'));
317
        $dir = utf8_encodeFN(str_replace(':', '/', $ns));
318
319
        $lvl = count(explode(':', $ns));
320
321
        $data = array();
322
        search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir);
323
        foreach(array_keys($data) as $item) {
324
            $data[$item]['level'] = $lvl + 1;
325
        }
326
        echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index');
327
    }
328
329
    /**
330
     * List matching namespaces and pages for the link wizard
331
     *
332
     * @author Andreas Gohr <[email protected]>
333
     */
334
    protected function callLinkwiz() {
335
        global $conf;
336
        global $lang;
337
        global $INPUT;
338
339
        $q = ltrim(trim($INPUT->post->str('q')), ':');
340
        $id = noNS($q);
341
        $ns = getNS($q);
342
343
        $ns = cleanID($ns);
0 ignored issues
show
Security Bug introduced by
It seems like $ns can also be of type false; however, cleanID() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
344
        $id = cleanID($id);
345
346
        $nsd = utf8_encodeFN(str_replace(':', '/', $ns));
347
348
        $data = array();
349
        if($q && !$ns) {
350
351
            // use index to lookup matching pages
352
            $pages = ft_pageLookup($id, true);
353
354
            // result contains matches in pages and namespaces
355
            // we now extract the matching namespaces to show
356
            // them seperately
357
            $dirs = array();
358
359
            foreach($pages as $pid => $title) {
360
                if(strpos(noNS($pid), $id) === false) {
361
                    // match was in the namespace
362
                    $dirs[getNS($pid)] = 1; // assoc array avoids dupes
363
                } else {
364
                    // it is a matching page, add it to the result
365
                    $data[] = array(
366
                        'id' => $pid,
367
                        'title' => $title,
368
                        'type' => 'f',
369
                    );
370
                }
371
                unset($pages[$pid]);
372
            }
373
            foreach($dirs as $dir => $junk) {
374
                $data[] = array(
375
                    'id' => $dir,
376
                    'type' => 'd',
377
                );
378
            }
379
380
        } else {
381
382
            $opts = array(
383
                'depth' => 1,
384
                'listfiles' => true,
385
                'listdirs' => true,
386
                'pagesonly' => true,
387
                'firsthead' => true,
388
                'sneakyacl' => $conf['sneaky_index'],
389
            );
390
            if($id) $opts['filematch'] = '^.*\/' . $id;
391
            if($id) $opts['dirmatch'] = '^.*\/' . $id;
392
            search($data, $conf['datadir'], 'search_universal', $opts, $nsd);
393
394
            // add back to upper
395
            if($ns) {
396
                array_unshift(
397
                    $data, array(
398
                             'id' => getNS($ns),
399
                             'type' => 'u',
400
                         )
401
                );
402
            }
403
        }
404
405
        // fixme sort results in a useful way ?
406
407
        if(!count($data)) {
408
            echo $lang['nothingfound'];
409
            exit;
410
        }
411
412
        // output the found data
413
        $even = 1;
414
        foreach($data as $item) {
415
            $even *= -1; //zebra
416
417
            if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':';
418
            $link = wl($item['id']);
419
420
            echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">';
421
422
            if($item['type'] == 'u') {
423
                $name = $lang['upperns'];
424
            } else {
425
                $name = hsc($item['id']);
426
            }
427
428
            echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>';
429
430
            if(!blank($item['title'])) {
431
                echo '<span>' . hsc($item['title']) . '</span>';
432
            }
433
            echo '</div>';
434
        }
435
436
    }
437
438
}
439