Fix/#32861#9
Merged
Merged
Conversation
The legacy /wiki/download servlet no longer accepts API-token
authentication (HTTP 401). Download attachments via the supported
REST endpoint /wiki/rest/api/content/{pageId}/child/attachment/{id}/download
instead; pageId is now passed through downloadAttachment().
Also replace the silent echo+return on folder/exception errors with a
RuntimeException (download folder) and PSR-3 logger->error() (page
download), so failures are no longer swallowed. Adds psr/log dependency
and ConfluenceAttachment::getId().
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…wnload URL findDownloadPath() was the only consumer of the broken legacy /wiki/download path and is now unused — remove it so the 401-prone path cannot be reused by accident. Normalize the attachment download URL to a relative path (no leading slash) to match findChildAttachments(); both resolve identically against the host-root base_uri. Clarify the comment: auth is unchanged (same email + API token), only the endpoint moved to the REST API. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e to English Align the attachment-retrieval exception message with the other two messages in Content.php, which are already English. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the missing @throws annotations (GuzzleException from the HTTP client, Exception on non-200 responses) to findPagesInSpace, findPageContent and findChildAttachments. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nts doc blocks Describe what each method does, its $pageId parameter, return value and error cases. Correct the findChildAttachments summary: it uses the child/attachment endpoint, not descendants.attachment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…riable name Add doc blocks (description, @param, @throws) to ensureDownloadFolder, downloadPageContent, downloadAttachment and shouldAttachmentBeUpdated, and import GuzzleException so the @throws reference resolves. Rename the local $filemtime to $fileModificationTime for readability. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-add phpunit/phpunit (^11.5, compatible with the >=8.2 floor) and phpstan/phpstan-phpunit, plus a phpunit.xml and a 'composer test' script. Add 21 unit tests covering the #32861 fix, all served by a Guzzle MockHandler so no build ever calls the live Confluence API: - DownloadTest: REST attachment URL, Basic-auth header, skip/re-download by mtime, download-folder creation and RuntimeException on failure - ContentTest: JSON-to-DTO parsing, non-200 guard, 5xx GuzzleException, pagination termination - ConfluenceAttachmentTest: id/title and lastUpdated parsing - ConfluencePageContentDownloaderTest: macro replacers, withAttachments and null-pageId guards, and the new error-logging path Add a self-contained PHPUnit GitHub Actions workflow (PHP 8.2 + 8.3, mirroring the PHPStan matrix) so the tests run on every build; the shared workflows repo has no phpunit workflow to reuse. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sidler
approved these changes
Jun 9, 2026
f-kuechler
approved these changes
Jun 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#32861 — Fix Confluence-Attachment-Download (REST-Endpoint) + Tests & CI
Problem
Attachments (z. B. die „Schnellhilfe"-Bilder) wurden nicht mehr heruntergeladen und
erschienen in der synchronisierten Dokumentation als 404. Ursache: Das Paket hat Attachments
über das Legacy-Servlet
/wiki/downloadgeladen, das API-Token-Authentifizierung nicht mehrakzeptiert und HTTP 401 zurückgibt. Da der Fehler verschluckt wurde (ein bloßes
echo+return), wirkte der Sync erfolgreich, während jedes Attachment still übersprungen wurde.Fix
Attachments werden stattdessen über den unterstützten REST-Endpoint geladen:
/wiki/rest/api/content/{pageId}/child/attachment/{attachmentId}/download
(E-Mail + API-Token) gesendet wie bei jedem anderen Aufruf; nur der Endpoint wurde auf die
REST-API umgestellt.
downloadAttachment()erhält jetzt diepageId, undConfluenceAttachment::getId()wurdeergänzt, um die REST-URL zu bauen.
Fehlerbehandlung (keine stillen Fehlschläge mehr)
ensureDownloadFolder()wirft jetzt eineRuntimeException, wenn der Download-Ordner nichtangelegt werden kann, statt auf stdout auszugeben und weiterzulaufen.
ConfluencePageContentDownloaderfängt Exceptions und meldet sie über einen injiziertenPSR-3-
LoggerInterface(Default:NullLogger, das Verhalten bleibt also unverändert, wennkein Logger übergeben wird). Fügt eine
psr/log-Abhängigkeit hinzu.Cleanup / Aufräumen
ConfluenceAttachment::findDownloadPath()entfernt (einziger Nutzer des kaputtenLegacy-Pfads), damit der 401-anfällige Pfad nicht versehentlich wiederverwendet werden kann.
konsistent mit den übrigen Content-API-Aufrufen.
anderen).
@throws-Annotationen an denContent- undDownload-Methoden ergänzt/erweitertund eine lokale Variable
$filemtime→$fileModificationTimeumbenannt.Tests & CI
die Skip-/Re-Download-Entscheidung (Datei-mtime vs. Attachment-
lastUpdated), das Anlegen desDownload-Ordners und die neue
RuntimeException, das JSON→DTO-Parsing, die Non-200-/5xx-Behandlungsowie den neuen Error-Logging-Pfad.
MockHandlerbedient — kein Test ruft jemals die Live-Confluence-API auf, Builds bleiben damit netzwerkfrei.
phpunit/phpunit,phpstan/phpstan-phpunit), einephpunit.xmlund eincomposer test-Script wieder hinzugefügt.PHPStan-Matrix), da der geteilte Workflows-Repo keinen wiederverwendbaren phpunit-Workflow hat.
Die Tests laufen jetzt in jedem Build.
Warum PHPUnit 11 (und nicht 12)
Wir sind bewusst auf
phpunit/phpunit ^11.5geblieben statt auf dem zuvor entfernten^12.5.6:phpunit12 benötigt PHP ≥ 8.3, der Floor dieser Library ist aberphp: >=8.2und die CIfährt einen 8.2-Matrix-Leg. Mit phpunit 12 würde
composer installauf PHP 8.2 fehlschlagen und denBuild brechen. PHPUnit 11.5 unterstützt PHP 8.2–8.4 und behält damit den 8.2-Support, ohne die
Runtime-Constraint
require.phpanzufassen (Consumer sind nicht betroffen — Dev-Abhängigkeitenwerden nicht transitiv installiert).
Verifikation
End-to-End in einer echten AGP-Installation über einen erzwungenen Voll-Sync verifiziert: Alle
Attachments wurden korrekt heruntergeladen, inklusive des Bildes, das zuvor 404 lieferte; Text und
Bilder werden in der UI gerendert. PHPUnit (21 Tests) und PHPStan Level 8 (über
src+tests) sindgrün.