|
4 | 4 |
|
5 | 5 | use Doku_Renderer_xhtml; |
6 | 6 | use dokuwiki\ChangeLog\PageChangeLog; |
| 7 | +use dokuwiki\ChangeLog\MediaChangeLog; |
7 | 8 | use dokuwiki\Extension\AuthPlugin; |
8 | 9 | use dokuwiki\Extension\Event; |
9 | 10 | use dokuwiki\Remote\Response\Link; |
|
22 | 23 | class ApiCore |
23 | 24 | { |
24 | 25 | /** @var int Increased whenever the API is changed */ |
25 | | - public const API_VERSION = 13; |
| 26 | + public const API_VERSION = 14; |
26 | 27 |
|
27 | 28 | /** |
28 | 29 | * Returns details about the core methods |
@@ -65,7 +66,7 @@ public function getMethods() |
65 | 66 | 'core.getMedia' => new ApiCall([$this, 'getMedia'], 'media'), |
66 | 67 | 'core.getMediaInfo' => new ApiCall([$this, 'getMediaInfo'], 'media'), |
67 | 68 | 'core.getMediaUsage' => new ApiCall([$this, 'getMediaUsage'], 'media'), |
68 | | - // todo: implement getMediaHistory |
| 69 | + 'core.getMediaHistory' => new ApiCall([$this, 'getMediaHistory'], 'media'), |
69 | 70 |
|
70 | 71 | 'core.saveMedia' => new ApiCall([$this, 'saveMedia'], 'media'), |
71 | 72 | 'core.deleteMedia' => new ApiCall([$this, 'deleteMedia'], 'media'), |
@@ -463,7 +464,7 @@ public function getPageInfo($page, $rev = 0, $author = false, $hash = false) |
463 | 464 | /** |
464 | 465 | * Returns a list of available revisions of a given wiki page |
465 | 466 | * |
466 | | - * The number of returned pages is set by `$conf['recent']`, but non accessible revisions pages |
| 467 | + * The number of returned pages is set by `$conf['recent']`, but non accessible revisions |
467 | 468 | * are skipped, so less than that may be returned. |
468 | 469 | * |
469 | 470 | * @link https://www.dokuwiki.org/config:recent |
@@ -834,6 +835,11 @@ public function getMedia($media, $rev = 0) |
834 | 835 | throw new AccessDeniedException('You are not allowed to read this media file', 211); |
835 | 836 | } |
836 | 837 |
|
| 838 | + // was the current revision requested? |
| 839 | + if ($this->isCurrentMediaRev($media, $rev)) { |
| 840 | + $rev = 0; |
| 841 | + } |
| 842 | + |
837 | 843 | $file = mediaFN($media, $rev); |
838 | 844 | if (!@ file_exists($file)) { |
839 | 845 | throw new RemoteException('The requested media file (revision) does not exist', 221); |
@@ -865,6 +871,12 @@ public function getMediaInfo($media, $rev = 0, $author = false, $hash = false) |
865 | 871 | if (auth_quickaclcheck($media) < AUTH_READ) { |
866 | 872 | throw new AccessDeniedException('You are not allowed to read this media file', 211); |
867 | 873 | } |
| 874 | + |
| 875 | + // was the current revision requested? |
| 876 | + if ($this->isCurrentMediaRev($media, $rev)) { |
| 877 | + $rev = 0; |
| 878 | + } |
| 879 | + |
868 | 880 | if (!media_exists($media, $rev)) { |
869 | 881 | throw new RemoteException('The requested media file does not exist', 221); |
870 | 882 | } |
@@ -903,6 +915,62 @@ public function getMediaUsage($media) |
903 | 915 | return ft_mediause($media); |
904 | 916 | } |
905 | 917 |
|
| 918 | + /** |
| 919 | + * Returns a list of available revisions of a given media file |
| 920 | + * |
| 921 | + * The number of returned files is set by `$conf['recent']`, but non accessible revisions |
| 922 | + * are skipped, so less than that may be returned. |
| 923 | + * |
| 924 | + * Since API Version 14 |
| 925 | + * |
| 926 | + * @link https://www.dokuwiki.org/config:recent |
| 927 | + * @param string $media file id |
| 928 | + * @param int $first skip the first n changelog lines, 0 starts at the current revision |
| 929 | + * @return MediaChange[] |
| 930 | + * @throws AccessDeniedException |
| 931 | + * @throws RemoteException |
| 932 | + * @author |
| 933 | + */ |
| 934 | + public function getMediaHistory($media, $first = 0) |
| 935 | + { |
| 936 | + global $conf; |
| 937 | + |
| 938 | + $media = cleanID($media); |
| 939 | + // check that this media exists |
| 940 | + if (auth_quickaclcheck($media) < AUTH_READ) { |
| 941 | + throw new AccessDeniedException('You are not allowed to read this media file', 211); |
| 942 | + } |
| 943 | + if (!media_exists($media, 0)) { |
| 944 | + throw new RemoteException('The requested media file does not exist', 221); |
| 945 | + } |
| 946 | + |
| 947 | + $medialog = new MediaChangeLog($media); |
| 948 | + $medialog->setChunkSize(1024); |
| 949 | + // old revisions are counted from 0, so we need to subtract 1 for the current one |
| 950 | + $revisions = $medialog->getRevisions($first - 1, $conf['recent']); |
| 951 | + |
| 952 | + $result = []; |
| 953 | + foreach ($revisions as $rev) { |
| 954 | + // the current revision needs to be checked against the current file path |
| 955 | + $check = $this->isCurrentMediaRev($media, $rev) ? '' : $rev; |
| 956 | + if (!media_exists($media, $check)) continue; // skip non-existing revisions |
| 957 | + |
| 958 | + $info = $medialog->getRevisionInfo($rev); |
| 959 | + |
| 960 | + $result[] = new MediaChange( |
| 961 | + $media, |
| 962 | + $rev, |
| 963 | + $info['user'], |
| 964 | + $info['ip'], |
| 965 | + $info['sum'], |
| 966 | + $info['type'], |
| 967 | + $info['sizechange'] |
| 968 | + ); |
| 969 | + } |
| 970 | + |
| 971 | + return $result; |
| 972 | + } |
| 973 | + |
906 | 974 | /** |
907 | 975 | * Uploads a file to the wiki |
908 | 976 | * |
@@ -987,6 +1055,20 @@ public function deleteMedia($media) |
987 | 1055 | } |
988 | 1056 | } |
989 | 1057 |
|
| 1058 | + /** |
| 1059 | + * Check if the given revision is the current revision of this file |
| 1060 | + * |
| 1061 | + * @param string $id |
| 1062 | + * @param int $rev |
| 1063 | + * @return bool |
| 1064 | + */ |
| 1065 | + protected function isCurrentMediaRev(string $id, int $rev) |
| 1066 | + { |
| 1067 | + $current = @filemtime(mediaFN($id)); |
| 1068 | + if ($current === $rev) return true; |
| 1069 | + return false; |
| 1070 | + } |
| 1071 | + |
990 | 1072 | // endregion |
991 | 1073 |
|
992 | 1074 |
|
|
0 commit comments