@@ -61,9 +61,31 @@ public function initialize(Server $server): void {
6161 $ this ->server ->on ('afterMethod:GET ' , $ this ->afterDownload (...), 999 );
6262 }
6363
64+ /**
65+ * @return iterable<NcNode>
66+ */
67+ protected function createIterator (array $ rootNodes ): iterable {
68+ foreach ($ rootNodes as $ rootNode ) {
69+ yield from $ this ->iterateNodes ($ rootNode );
70+ }
71+ }
72+
73+ /**
74+ * Recursively iterate over all nodes in a folder.
75+ * @return iterable<NcNode>
76+ */
77+ protected function iterateNodes (NcNode $ node ): iterable {
78+ yield $ node ;
79+
80+ if ($ node instanceof NcFolder) {
81+ foreach ($ node ->getDirectoryListing () as $ childNode ) {
82+ yield from $ this ->iterateNodes ($ childNode );
83+ }
84+ }
85+ }
86+
6487 /**
6588 * Adding a node to the archive streamer.
66- * This will recursively add new nodes to the stream if the node is a directory.
6789 */
6890 protected function streamNode (Streamer $ streamer , NcNode $ node , string $ rootPath ): void {
6991 // Remove the root path from the filename to make it relative to the requested folder
@@ -79,10 +101,6 @@ protected function streamNode(Streamer $streamer, NcNode $node, string $rootPath
79101 $ streamer ->addFileFromStream ($ resource , $ filename , $ node ->getSize (), $ mtime );
80102 } elseif ($ node instanceof NcFolder) {
81103 $ streamer ->addEmptyDir ($ filename , $ mtime );
82- $ content = $ node ->getDirectoryListing ();
83- foreach ($ content as $ subNode ) {
84- $ this ->streamNode ($ streamer , $ subNode , $ rootPath );
85- }
86104 }
87105 }
88106
@@ -137,7 +155,14 @@ public function handleDownload(Request $request, Response $response): ?bool {
137155 }
138156
139157 $ folder = $ node ->getNode ();
140- $ event = new BeforeZipCreatedEvent ($ folder , $ files );
158+ $ rootNodes = empty ($ files ) ? $ folder ->getDirectoryListing () : [];
159+ foreach ($ files as $ path ) {
160+ $ child = $ node ->getChild ($ path );
161+ assert ($ child instanceof Node);
162+ $ rootNodes [] = $ child ->getNode ();
163+ }
164+
165+ $ event = new BeforeZipCreatedEvent ($ folder , $ files , $ this ->createIterator ($ rootNodes ));
141166 $ this ->eventDispatcher ->dispatchTyped ($ event );
142167 if ((!$ event ->isSuccessful ()) || $ event ->getErrorMessage () !== null ) {
143168 $ errorMessage = $ event ->getErrorMessage ();
@@ -150,13 +175,6 @@ public function handleDownload(Request $request, Response $response): ?bool {
150175 throw new Forbidden ($ errorMessage );
151176 }
152177
153- $ content = empty ($ files ) ? $ folder ->getDirectoryListing () : [];
154- foreach ($ files as $ path ) {
155- $ child = $ node ->getChild ($ path );
156- assert ($ child instanceof Node);
157- $ content [] = $ child ->getNode ();
158- }
159-
160178 $ archiveName = $ folder ->getName ();
161179 if (count (explode ('/ ' , trim ($ folder ->getPath (), '/ ' ), 3 )) === 2 ) {
162180 // this is a download of the root folder
@@ -169,13 +187,13 @@ public function handleDownload(Request $request, Response $response): ?bool {
169187 $ rootPath = dirname ($ folder ->getPath ());
170188 }
171189
172- $ streamer = new Streamer ($ tarRequest , -1 , count ($ content ), $ this ->timezoneFactory );
190+ $ streamer = new Streamer ($ tarRequest , -1 , count ($ rootNodes ), $ this ->timezoneFactory );
173191 $ streamer ->sendHeaders ($ archiveName );
174192 // For full folder downloads we also add the folder itself to the archive
175193 if (empty ($ files )) {
176194 $ streamer ->addEmptyDir ($ archiveName );
177195 }
178- foreach ($ content as $ node ) {
196+ foreach ($ event -> getNodes () as $ node ) {
179197 $ this ->streamNode ($ streamer , $ node , $ rootPath );
180198 }
181199 $ streamer ->finalize ();
0 commit comments