@@ -61,9 +61,22 @@ public function initialize(Server $server): void {
6161 $ this ->server ->on ('afterMethod:GET ' , $ this ->afterDownload (...), 999 );
6262 }
6363
64+ /**
65+ * Recursively iterate over all nodes in a folder.
66+ */
67+ protected function iterateNodes (NcNode $ node ): iterable {
68+ if ($ node instanceof NcFile) {
69+ yield $ node ;
70+ } elseif ($ node instanceof NcFolder) {
71+ yield $ node ;
72+ foreach ($ node ->getDirectoryListing () as $ childNode ) {
73+ yield from $ this ->iterateNodes ($ childNode );
74+ }
75+ }
76+ }
77+
6478 /**
6579 * Adding a node to the archive streamer.
66- * This will recursively add new nodes to the stream if the node is a directory.
6780 */
6881 protected function streamNode (Streamer $ streamer , NcNode $ node , string $ rootPath ): void {
6982 // Remove the root path from the filename to make it relative to the requested folder
@@ -79,10 +92,6 @@ protected function streamNode(Streamer $streamer, NcNode $node, string $rootPath
7992 $ streamer ->addFileFromStream ($ resource , $ filename , $ node ->getSize (), $ mtime );
8093 } elseif ($ node instanceof NcFolder) {
8194 $ streamer ->addEmptyDir ($ filename , $ mtime );
82- $ content = $ node ->getDirectoryListing ();
83- foreach ($ content as $ subNode ) {
84- $ this ->streamNode ($ streamer , $ subNode , $ rootPath );
85- }
8695 }
8796 }
8897
@@ -137,14 +146,20 @@ public function handleDownload(Request $request, Response $response): ?bool {
137146 }
138147
139148 $ folder = $ node ->getNode ();
140- $ nodes = empty ($ files ) ? $ folder ->getDirectoryListing () : [];
149+ $ rootNodes = empty ($ files ) ? $ folder ->getDirectoryListing () : [];
141150 foreach ($ files as $ path ) {
142151 $ child = $ node ->getChild ($ path );
143152 assert ($ child instanceof Node);
144- $ nodes [] = $ child ->getNode ();
153+ $ rootNodes [] = $ child ->getNode ();
154+ }
155+ $ allNodes = [];
156+ foreach ($ rootNodes as $ rootNode ) {
157+ foreach ($ this ->iterateNodes ($ rootNode ) as $ node ) {
158+ $ allNodes [] = $ node ;
159+ }
145160 }
146161
147- $ event = new BeforeZipCreatedEvent ($ folder , $ files , $ nodes );
162+ $ event = new BeforeZipCreatedEvent ($ folder , $ files , $ allNodes );
148163 $ this ->eventDispatcher ->dispatchTyped ($ event );
149164 if ((!$ event ->isSuccessful ()) || $ event ->getErrorMessage () !== null ) {
150165 $ errorMessage = $ event ->getErrorMessage ();
@@ -156,8 +171,7 @@ public function handleDownload(Request $request, Response $response): ?bool {
156171 // Downloading was denied by an app
157172 throw new Forbidden ($ errorMessage );
158173 }
159-
160- $ nodes = $ event ->getNodes ();
174+ $ allNodes = $ event ->getNodes ();
161175
162176 $ archiveName = $ folder ->getName ();
163177 if (count (explode ('/ ' , trim ($ folder ->getPath (), '/ ' ), 3 )) === 2 ) {
@@ -171,13 +185,13 @@ public function handleDownload(Request $request, Response $response): ?bool {
171185 $ rootPath = dirname ($ folder ->getPath ());
172186 }
173187
174- $ streamer = new Streamer ($ tarRequest , -1 , count ($ nodes ), $ this ->timezoneFactory );
188+ $ streamer = new Streamer ($ tarRequest , -1 , count ($ rootNodes ), $ this ->timezoneFactory );
175189 $ streamer ->sendHeaders ($ archiveName );
176190 // For full folder downloads we also add the folder itself to the archive
177191 if (empty ($ files )) {
178192 $ streamer ->addEmptyDir ($ archiveName );
179193 }
180- foreach ($ nodes as $ node ) {
194+ foreach ($ allNodes as $ node ) {
181195 $ this ->streamNode ($ streamer , $ node , $ rootPath );
182196 }
183197 $ streamer ->finalize ();
0 commit comments