You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

559 lines
16 KiB

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