1
+ <?php
2
+
3
+ declare (strict_types=1 );
4
+
5
+ namespace Artemeon \Confluence ;
6
+
7
+ use Artemeon \Confluence \MacroReplacer \MacroReplacerInterface ;
8
+ use Exception ;
9
+ use GuzzleHttp \Client ;
10
+
11
+ class ConfluencePageDownloader
12
+ {
13
+ private string $ confluenceUrl ;
14
+
15
+ private string $ username ;
16
+
17
+ private string $ password ;
18
+
19
+ private string $ pageId ;
20
+
21
+ private string $ downloadFolder ;
22
+
23
+ private array $ macroReplacers ;
24
+
25
+ public function __construct (string $ confluenceUrl , string $ username , string $ password , string $ pageId , string $ downloadFolder , array $ macroReplacers = [])
26
+ {
27
+ $ this ->confluenceUrl = $ confluenceUrl ;
28
+ $ this ->username = $ username ;
29
+ $ this ->password = $ password ;
30
+ $ this ->pageId = $ pageId ;
31
+ $ this ->downloadFolder = $ downloadFolder . '/ ' . $ this ->pageId ;
32
+ $ this ->macroReplacers = $ macroReplacers ;
33
+ }
34
+
35
+ public function downloadPageWithAttachments (): void
36
+ {
37
+ $ client = new Client ();
38
+
39
+ if (!$ this ->checkDownloadFolder ()) {
40
+ echo 'Fehler: Der Download-Ordner existiert nicht oder konnte nicht erstellt werden. ' ;
41
+
42
+ return ;
43
+ }
44
+
45
+ try {
46
+ $ pageData = $ this ->downloadPageContent ($ client );
47
+ $ htmlContent = $ pageData ['body ' ]['storage ' ]['value ' ];
48
+
49
+ foreach ($ this ->macroReplacers as $ macroReplacer ) {
50
+ if ($ macroReplacer instanceof MacroReplacerInterface) {
51
+ $ htmlContent = $ macroReplacer ->replace ($ htmlContent );
52
+ }
53
+ }
54
+
55
+ $ this ->savePageContent ($ htmlContent );
56
+
57
+ // Herunterladen von Attachments über "descendants.attachment"
58
+ $ attachments = $ this ->getDescendantAttachments ($ this ->pageId , $ client );
59
+ foreach ($ attachments as $ attachment ) {
60
+ $ this ->downloadAttachment ($ client , $ attachment );
61
+ }
62
+
63
+ echo 'Der Seiteninhalt und die Attachments wurden erfolgreich heruntergeladen und im Ordner " ' . $ this ->downloadFolder . '" gespeichert. ' ;
64
+ } catch (Exception $ e ) {
65
+ echo 'Ein Fehler ist aufgetreten: ' . $ e ->getMessage ();
66
+ }
67
+ }
68
+
69
+ private function downloadPageContent (Client $ client ): array
70
+ {
71
+ // Verwende die Confluence Content API, um den Seiteninhalt abzurufen
72
+ $ apiUrl = $ this ->confluenceUrl . '/wiki/rest/api/content/ ' . $ this ->pageId . '?expand=body.storage,version,space,metadata.labels ' ;
73
+ $ response = $ client ->request ('GET ' , $ apiUrl , ['auth ' => [$ this ->username , $ this ->password ]]);
74
+
75
+ if ($ response ->getStatusCode () === 200 ) {
76
+ return json_decode ($ response ->getBody ()->getContents (), true );
77
+ } else {
78
+ throw new Exception ('Fehler beim Abrufen des Seiteninhalts. HTTP-Statuscode: ' . $ response ->getStatusCode ());
79
+ }
80
+ }
81
+
82
+ private function getDescendantAttachments (string $ pageId , Client $ client ): array
83
+ {
84
+ // Verwende "descendants.attachment" in der Content API, um Attachments zu erhalten
85
+ $ apiUrl = $ this ->confluenceUrl . '/wiki/rest/api/content/ ' . $ pageId . '/child/attachment ' ;
86
+ $ response = $ client ->request ('GET ' , $ apiUrl , ['auth ' => [$ this ->username , $ this ->password ]]);
87
+
88
+ if ($ response ->getStatusCode () === 200 ) {
89
+ $ attachmentsData = json_decode ($ response ->getBody ()->getContents (), true );
90
+ $ attachments = $ attachmentsData ['results ' ];
91
+
92
+ return $ attachments ;
93
+ } else {
94
+ throw new Exception ('Fehler beim Abrufen der Attachments. HTTP-Statuscode: ' . $ response ->getStatusCode ());
95
+ }
96
+ }
97
+
98
+ private function checkDownloadFolder (): bool
99
+ {
100
+ if (!is_dir ($ this ->downloadFolder )) {
101
+ return mkdir ($ this ->downloadFolder , 0755 , true );
102
+ }
103
+
104
+ return true ;
105
+ }
106
+
107
+ private function savePageContent (string $ htmlContent ): void
108
+ {
109
+ $ htmlFile = $ this ->downloadFolder . '/page.html ' ;
110
+ file_put_contents ($ htmlFile , $ htmlContent );
111
+ }
112
+
113
+ private function downloadAttachment (Client $ client , array $ attachment ): void
114
+ {
115
+ // Verwende den relativen Pfad aus der API, um das Attachment herunterzuladen
116
+ $ attachmentPath = $ this ->confluenceUrl . '/wiki ' . $ attachment ['_links ' ]['download ' ];
117
+ $ attachmentContent = $ client ->request ('GET ' , $ attachmentPath , ['auth ' => [$ this ->username , $ this ->password ]])->getBody ()->getContents ();
118
+
119
+ $ attachmentFolder = $ this ->downloadFolder ;
120
+
121
+ if (!is_dir ($ attachmentFolder )) {
122
+ mkdir ($ attachmentFolder , 0755 , true );
123
+ }
124
+
125
+ $ attachmentFilePath = $ attachmentFolder . '/ ' . $ attachment ['title ' ];
126
+ file_put_contents ($ attachmentFilePath , $ attachmentContent );
127
+ }
128
+ }
0 commit comments