xref: /dokuwiki/inc/Remote/LegacyApiCore.php (revision 73dc0a8919857718a3b64a4c0741b57580a34b2a)
1<?php
2
3namespace dokuwiki\Remote;
4
5use dokuwiki\MailUtils;
6use dokuwiki\Utf8\PhpString;
7use IXR\DataType\Base64;
8use IXR\DataType\Date;
9
10/**
11 * Provides wrappers for the API calls as they existed in API Version 11
12 *
13 * No guarantees are made about the exact compatibility of the return values.
14 *
15 * @deprecated
16 */
17class LegacyApiCore extends ApiCore
18{
19    /** @inheritdoc */
20    public function getMethods()
21    {
22        $methods = parent::getMethods();
23
24        return array_merge(
25            $methods,
26            [
27                'dokuwiki.getVersion' => new ApiCall($this->legacyGetVersion(...), 'legacy'),
28                'dokuwiki.login' => (new ApiCall($this->legacyLogin(...), 'legacy'))->setPublic(),
29                'dokuwiki.logoff' => new ApiCall($this->legacyLogoff(...), 'legacy'),
30                'dokuwiki.getPagelist' => new ApiCall($this->legacyGetPagelist(...), 'legacy'),
31                'dokuwiki.search' => new ApiCall($this->legacySearch(...), 'legacy'),
32                'dokuwiki.getTime' => new ApiCall($this->legacyGetTime(...), 'legacy'),
33                'dokuwiki.setLocks' => new ApiCall($this->legacySetLocks(...), 'legacy'),
34                'dokuwiki.getTitle' => (new ApiCall($this->legacyGetTitle(...), 'legacy'))->setPublic(),
35                'dokuwiki.appendPage' => new ApiCall($this->legacyAppendPage(...), 'legacy'),
36                'dokuwiki.createUser' => new ApiCall($this->legacyCreateUser(...), 'legacy'),
37                'dokuwiki.deleteUsers' => new ApiCall($this->legacyDeleteUsers(...), 'legacy'),
38                'wiki.getPage' => new ApiCall($this->legacyGetPage(...), 'legacy'),
39                'wiki.getPageVersion' => new ApiCall($this->legacyGetPageVersion(...), 'legacy'),
40                'wiki.getPageHTML' => new ApiCall($this->legacyGetPageHTML(...), 'legacy'),
41                'wiki.getPageHTMLVersion' => new ApiCall($this->legacyGetPageHTMLVersion(...), 'legacy'),
42                'wiki.getAllPages' => new ApiCall($this->legacyGetAllPages(...), 'legacy'),
43                'wiki.getAttachments' => new ApiCall($this->legacyGetAttachments(...), 'legacy'),
44                'wiki.getBackLinks' => new ApiCall($this->legacyGetBackLinks(...), 'legacy'),
45                'wiki.getPageInfo' => new ApiCall($this->legacyGetPageInfo(...), 'legacy'),
46                'wiki.getPageInfoVersion' => new ApiCall($this->legacyGetPageInfoVersion(...), 'legacy'),
47                'wiki.getPageVersions' => new ApiCall($this->legacyGetPageVersions(...), 'legacy'),
48                'wiki.putPage' => new ApiCall($this->legacyPutPage(...), 'legacy'),
49                'wiki.listLinks' => new ApiCall($this->legacyListLinks(...), 'legacy'),
50                'wiki.getRecentChanges' => new ApiCall($this->legacyGetRecentChanges(...), 'legacy'),
51                'wiki.getRecentMediaChanges' => new ApiCall($this->legacyGetRecentMediaChanges(...), 'legacy'),
52                'wiki.aclCheck' => new ApiCall($this->legacyAclCheck(...), 'legacy'),
53                'wiki.putAttachment' => new ApiCall($this->legacyPutAttachment(...), 'legacy'),
54                'wiki.deleteAttachment' => new ApiCall($this->legacyDeleteAttachment(...), 'legacy'),
55                'wiki.getAttachment' => new ApiCall($this->legacyGetAttachment(...), 'legacy'),
56                'wiki.getAttachmentInfo' => new ApiCall($this->legacyGetAttachmentInfo(...), 'legacy'),
57                'dokuwiki.getXMLRPCAPIVersion' => (new ApiCall($this->legacyGetXMLRPCAPIVersion(...), 'legacy'))
58                    ->setPublic(),
59                'wiki.getRPCVersionSupported' => (new ApiCall($this->legacyGetRPCVersionSupported(...), 'legacy'))
60                    ->setPublic(),
61            ]
62        );
63    }
64
65    /**
66     * This returns a XMLRPC object that will not work for the new JSONRPC API
67     *
68     * @param int $ts
69     * @return Date
70     */
71    protected function toDate($ts)
72    {
73        return new Date($ts);
74    }
75
76
77    /**
78     * @deprecated use core.getWikiVersion instead
79     */
80    public function legacyGetVersion()
81    {
82        return getVersion();
83    }
84
85    /**
86     * @deprecated use core.getWikiTime instead
87     */
88    public function legacyGetTime()
89    {
90        return $this->getWikiTime();
91    }
92
93
94    /**
95     * @deprecated use core.getPage instead
96     */
97    public function legacyGetPage($id)
98    {
99        try {
100            return $this->getPage($id);
101        } catch (RemoteException $e) {
102            if ($e->getCode() === 121) {
103                return '';
104            }
105            throw $e;
106        }
107    }
108
109    /**
110     * @deprecated use core.getPage instead
111     */
112    public function legacyGetPageVersion($id, $rev = '')
113    {
114        try {
115            return $this->getPage($id, $rev);
116        } catch (RemoteException $e) {
117            if ($e->getCode() === 121) {
118                return '';
119            }
120            throw $e;
121        }
122    }
123
124    /**
125     * @deprecated use core.getMedia instead
126     */
127    public function legacyGetAttachment($id)
128    {
129        return new Base64(base64_decode($this->getMedia($id)));
130    }
131
132    /**
133     * @deprecated use core.getMediaInfo instead
134     */
135    public function legacygetAttachmentInfo($id)
136    {
137        $info = $this->getMediaInfo($id);
138        return [
139            'lastModified' => $this->toDate($info->revision),
140            'size' => $info->size,
141        ];
142    }
143
144    /**
145     * @deprecated use core.getPageHTML instead
146     */
147    public function legacyGetPageHTML($id)
148    {
149        try {
150            return $this->getPageHTML($id);
151        } catch (RemoteException $e) {
152            if ($e->getCode() === 121) {
153                return '';
154            }
155            throw $e;
156        }
157    }
158
159    /**
160     * @deprecated use core.getPageHTML instead
161     */
162    public function legacyGetPageHTMLVersion($id, $rev = '')
163    {
164        try {
165            return $this->getPageHTML($id, (int)$rev);
166        } catch (RemoteException $e) {
167            if ($e->getCode() === 121) {
168                return '';
169            }
170            throw $e;
171        }
172    }
173
174    /**
175     * @deprecated use core.listPages instead
176     */
177    public function legacyGetAllPages()
178    {
179        $pages = $this->listPages('', 0);
180
181        $result = [];
182        foreach ($pages as $page) {
183            $result[] = [
184                'id' => $page->id,
185                'perms' => $page->permission,
186                'size' => $page->size,
187                'lastModified' => $this->toDate($page->revision),
188            ];
189        }
190        return $result;
191    }
192
193    /**
194     * @deprecated use core.listPages instead
195     */
196    public function legacyGetPagelist($ns, $opts = [])
197    {
198        $data = $this->listPages($ns, $opts['depth'] ?? 0, $opts['hash'] ?? false);
199        $result = [];
200
201        foreach ($data as $page) {
202            $result[] = [
203                'id' => $page->id,
204                'perms' => $page->permission,
205                'size' => $page->size,
206                'rev' => $page->revision,
207                'mtime' => $page->revision,
208                'hash' => $page->hash,
209
210            ];
211        }
212
213        return $result;
214    }
215
216    /**
217     * @deprecated use core.searchPages instead
218     */
219    public function legacySearch($query)
220    {
221        $this->searchPages($query);
222        $pages = [];
223
224        foreach ($this->searchPages($query) as $page) {
225            $pages[] = [
226                'id' => $page->id,
227                'score' => $page->score,
228                'rev' => $page->revision,
229                'lastModified' => $this->toDate($page->revision),
230                'size' => $page->size,
231                'snippet' => $page->snippet,
232                'title' => $page->title
233            ];
234        }
235
236        return $pages;
237    }
238
239    /**
240     * @deprecated use core.getWikiTitle instead
241     */
242    public function legacyGetTitle()
243    {
244        return $this->getWikiTitle();
245    }
246
247    /**
248     * @deprecated use core.listMedia instead
249     */
250    public function legacyGetAttachments($ns, $options = [])
251    {
252        $files = $this->listMedia($ns, $options['pattern'] ?? '', $options['depth'] ?? 0, $options['hash'] ?? false);
253        $result = [];
254        foreach ($files as $file) {
255            $result[] = [
256                'id' => $file->id,
257                'perms' => $file->permission,
258                'size' => $file->size,
259                'rev' => $file->revision,
260                'lastModified' => $this->toDate($file->revision),
261                'mtime' => $this->toDate($file->revision),
262                'hash' => $file->hash,
263                'file' => PhpString::basename(mediaFN($file->id)),
264                'writable' => is_writable(mediaFN($file->id)),
265                'isimg' => $file->isimage,
266
267            ];
268        }
269        return $result;
270    }
271
272    /**
273     * @deprecated use core.getPageBackLinks instead
274     */
275    public function legacyGetBackLinks($id)
276    {
277        return $this->getPageBackLinks($id);
278    }
279
280    /**
281     * @deprecated use core.getPageInfo instead
282     */
283    public function legacyGetPageInfo($id)
284    {
285        $info = $this->getPageInfo($id, 0);
286        return [
287            'name' => $info->id,
288            'lastModified' => $this->toDate($info->revision),
289            'author' => $info->author,
290            'version' => $info->revision,
291        ];
292    }
293
294    /**
295     * @deprecated use core.getPageInfo instead
296     */
297    public function legacyGetPageInfoVersion($id, $rev = '')
298    {
299        $info = $this->getPageInfo($id, $rev);
300        return [
301            'name' => $info->id,
302            'lastModified' => $this->toDate($info->revision),
303            'author' => $info->author,
304            'version' => $info->revision,
305        ];
306    }
307
308    /**
309     * @deprecated use core.savePage instead
310     */
311    public function legacyPutPage($id, $text, $params = [])
312    {
313        return $this->savePage($id, $text, $params['sum'] ?? '', $params['minor'] ?? false);
314    }
315
316    /**
317     * @deprecated use core.appendPage instead
318     */
319    public function legacyAppendPage($id, $text, $params = [])
320    {
321        $ok = $this->appendPage($id, $text, $params['sum'] ?? '', $params['minor'] ?? false);
322        if ($ok === true) {
323            return cleanID($id);
324        } else {
325            return $ok;
326        }
327    }
328
329    /**
330     * @deprecated use plugin.usermanager.createUser instead
331     */
332    public function legacyCreateUser($userStruct)
333    {
334        if (!auth_isadmin()) {
335            throw new AccessDeniedException('Only admins are allowed to create users', 114);
336        }
337
338        /** @var AuthPlugin $auth */
339        global $auth;
340
341        if (!$auth->canDo('addUser')) {
342            throw new AccessDeniedException(
343                sprintf('Authentication backend %s can\'t do addUser', $auth->getPluginName()),
344                114
345            );
346        }
347
348        $user = trim($auth->cleanUser($userStruct['user'] ?? ''));
349        $password = $userStruct['password'] ?? '';
350        $name = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $userStruct['name'] ?? ''));
351        $mail = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $userStruct['mail'] ?? ''));
352        $groups = $userStruct['groups'] ?? [];
353
354        $notify = (bool)$userStruct['notify'] ?? false;
355
356        if ($user === '') throw new RemoteException('empty or invalid user', 401);
357        if ($name === '') throw new RemoteException('empty or invalid user name', 402);
358        if (!MailUtils::isValid($mail)) throw new RemoteException('empty or invalid mail address', 403);
359
360        if ((string)$password === '') {
361            $password = auth_pwgen($user);
362        }
363
364        if (!is_array($groups) || $groups === []) {
365            $groups = null;
366        }
367
368        $ok = $auth->triggerUserMod('create', [$user, $password, $name, $mail, $groups]);
369
370        if ($ok !== false && $ok !== null) {
371            $ok = true;
372        }
373
374        if ($ok) {
375            if ($notify) {
376                auth_sendPassword($user, $password);
377            }
378        }
379
380        return $ok;
381    }
382
383
384    /**
385     * @deprecated use plugin.usermanager.deleteUser instead
386     */
387    public function legacyDeleteUsers($usernames)
388    {
389        if (!auth_isadmin()) {
390            throw new AccessDeniedException('Only admins are allowed to delete users', 114);
391        }
392        /** @var AuthPlugin $auth */
393        global $auth;
394        return (bool)$auth->triggerUserMod('delete', [$usernames]);
395    }
396
397    /**
398     * @deprecated use core.saveMedia instead
399     */
400    public function legacyPutAttachment($id, $file, $params = [])
401    {
402        $ok = $this->saveMedia($id, base64_encode($file), $params['ow'] ?? false);
403        if ($ok === true) {
404            return cleanID($id);
405        } else {
406            return $ok;
407        }
408    }
409
410    /**
411     * @deprecated use core.deleteMedia instead
412     */
413    public function legacyDeleteAttachment($id)
414    {
415        $ok = $this->deleteMedia($id);
416        if ($ok === true) {
417            return 0;
418        } else {
419            return $ok;
420        }
421    }
422
423    /**
424     * @deprecated use core.aclCheck instead
425     */
426    public function legacyAclCheck($id, $user = null, $groups = null)
427    {
428        return $this->aclCheck($id, (string)$user, (string)$groups);
429    }
430
431    /**
432     * @deprecated use core.listLinks instead
433     */
434    public function legacyListLinks($id)
435    {
436        $links = $this->getPageLinks($id);
437        $result = [];
438        foreach ($links as $link) {
439            $result[] = [
440                'type' => $link['type'],
441                'page' => $link['page'],
442                'href' => $link['href'],
443            ];
444        }
445        return $result;
446    }
447
448    /**
449     * @deprecated use core.getRecentChanges instead
450     */
451    public function legacyGetRecentChanges($timestamp)
452    {
453        $recents = $this->getRecentPageChanges($timestamp);
454        $result = [];
455        foreach ($recents as $recent) {
456            $result[] = [
457                'name' => $recent->id,
458                'lastModified' => $this->toDate($recent->revision),
459                'author' => $recent->author,
460                'version' => $recent->revision,
461                'perms' => auth_quickaclcheck($recent->id),
462                'size' => @filesize(wikiFN($recent->id)),
463            ];
464        }
465        return $result;
466    }
467
468    /**
469     * @deprecated use core.getRecentMediaChanges instead
470     */
471    public function legacyGetRecentMediaChanges($timestamp)
472    {
473        $recents = $this->getRecentMediaChanges($timestamp);
474        $result = [];
475        foreach ($recents as $recent) {
476            $result[] = [
477                'name' => $recent->id,
478                'lastModified' => $this->toDate($recent->revision),
479                'author' => $recent->author,
480                'version' => $recent->revision,
481                'perms' => auth_quickaclcheck($recent->id),
482                'size' => @filesize(mediaFN($recent->id)),
483            ];
484        }
485        return $result;
486    }
487
488    /**
489     * @deprecated use core.getPageHistory instead
490     */
491    public function legacyGetPageVersions($id, $first = 0)
492    {
493        $revisions = $this->getPageHistory($id, $first);
494        $result = [];
495
496        foreach ($revisions as $revision) {
497            $result[] = [
498                'user' => $revision->author,
499                'ip' => $revision->ip,
500                'type' => $revision->type,
501                'sum' => $revision->summary,
502                'modified' => $this->toDate($revision->revision),
503                'version' => $revision->revision,
504            ];
505        }
506        return $result;
507    }
508
509    /**
510     * @deprecated Wiki RPC spec is no longer supported
511     */
512    public function legacyGetRPCVersionSupported()
513    {
514        return 2;
515    }
516
517    /**
518     * @deprecated use core.lockPages and core.unlockPages instead
519     */
520    public function legacySetLocks($set)
521    {
522        $locked = $this->lockPages($set['lock']);
523        $lockfail = array_diff($set['lock'], $locked);
524
525        $unlocked = $this->unlockPages($set['unlock']);
526        $unlockfail = array_diff($set['unlock'], $unlocked);
527
528        return [
529            'locked' => $locked,
530            'lockfail' => $lockfail,
531            'unlocked' => $unlocked,
532            'unlockfail' => $unlockfail
533        ];
534    }
535
536    /**
537     * @deprecated use core.getAPIVersion instead
538     */
539    public function legacyGetXMLRPCAPIVersion()
540    {
541        return $this->getAPIVersion();
542    }
543
544    /**
545     * @deprecated use core.login instead
546     */
547    public function legacyLogin($user, $pass)
548    {
549        return parent::login($user, $pass);
550    }
551
552    /**
553     * @deprecated use core.logoff instead
554     */
555    public function legacyLogoff()
556    {
557        return parent::logoff();
558    }
559}
560