@@ -54,7 +54,11 @@ class AmazonS3 extends Common {
5454
5555 private bool $ serverSideCopyEnabled ;
5656
57- /** Failure counter keyed by endpoint fingerprint. Static so sibling mounts share state within a request. */
57+ /**
58+ * Keyed by endpoint fingerprint. Static because sibling mounts share state within a request.
59+ *
60+ * @psalm-suppress ImpureStaticProperty MUST persist across per-mount instances within a request.
61+ */
5862 private static array $ serverSideCopyFailureCounter = [];
5963
6064 /** Fast path MUST stay disabled for the remainder of the request after this many consecutive S3Exceptions per endpoint. */
@@ -813,7 +817,7 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
813817 return $ size ;
814818 }
815819
816- #[Override]
820+ #[\ Override]
817821 public function getDirectDownload (string $ path ): array |false {
818822 if (!$ this ->isUsePresignedUrl ()) {
819823 return false ;
@@ -843,7 +847,7 @@ public function getDirectDownload(string $path): array|false {
843847 ];
844848 }
845849
846- #[Override]
850+ #[\ Override]
847851 public function getDirectDownloadById (string $ fileId ): array |false {
848852 if (!$ this ->isUsePresignedUrl ()) {
849853 return false ;
@@ -853,7 +857,7 @@ public function getDirectDownloadById(string $fileId): array|false {
853857 return $ this ->getDirectDownload ($ entry ->getPath ());
854858 }
855859
856- #[Override]
860+ #[\ Override]
857861 public function copyFromStorage (IStorage $ sourceStorage , string $ sourceInternalPath , string $ targetInternalPath , bool $ preserveMtime = false ): bool {
858862 if ($ preserveMtime === true ) {
859863 return parent ::copyFromStorage ($ sourceStorage , $ sourceInternalPath , $ targetInternalPath , $ preserveMtime );
@@ -882,7 +886,7 @@ public function copyFromStorage(IStorage $sourceStorage, string $sourceInternalP
882886 }
883887 }
884888
885- #[Override]
889+ #[\ Override]
886890 public function moveFromStorage (IStorage $ sourceStorage , string $ sourceInternalPath , string $ targetInternalPath ): bool {
887891 $ eligibility = $ this ->evaluateFastPathEligibility ($ sourceStorage , $ sourceInternalPath );
888892 if ($ eligibility === null ) {
@@ -959,10 +963,7 @@ private function handleFastPathFailure(S3Exception $exception, string $targetKey
959963 }
960964
961965 /**
962- * Returns null when the terminal storage is not an AmazonS3. Otherwise returns the
963- * unwrapped storage plus the Jail-translated path.
964- *
965- * @return array{0: self, 1: string}|null
966+ * @return array{0: self, 1: string}|null Unwrapped storage and Jail-translated path, or null when the terminal storage is not AmazonS3.
966967 */
967968 private function unwrapSource (IStorage $ sourceStorage , string $ sourceInternalPath ): ?array {
968969 $ current = $ sourceStorage ;
@@ -986,10 +987,7 @@ private function isSameS3Endpoint(self $other): bool {
986987 }
987988
988989 /**
989- * Normalised endpoint identity tuple. Two AmazonS3 instances with identical fingerprints
990- * target the same S3 endpoint under the same access-key ID.
991- *
992- * @return list<string>
990+ * @return list<string> Endpoint identity tuple including access-key ID so distinct credentials against the same host do not collide.
993991 */
994992 private function endpointFingerprint (): array {
995993 return [
@@ -1086,8 +1084,7 @@ private function copyObjectFromForeignBucket(
10861084 }
10871085
10881086 /**
1089- * Delete the source after a successful server-side copy. Roll back the destination on
1090- * cleanup failure to mirror AmazonS3::rename() semantics and to let the caller retry.
1087+ * Roll back the destination on cleanup failure to mirror AmazonS3::rename() semantics and let the caller retry.
10911088 */
10921089 private function deleteSourceAfterMove (self $ source , string $ sourcePath , string $ targetPath ): bool {
10931090 $ deleted = $ source ->is_dir ($ sourcePath ) ? $ source ->rmdir ($ sourcePath ) : $ source ->unlink ($ sourcePath );
0 commit comments