ZipResponse.php 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCP\AppFramework\Http;
  8. use OC\Streamer;
  9. use OCP\AppFramework\Http;
  10. use OCP\IRequest;
  11. /**
  12. * Public library to send several files in one zip archive.
  13. *
  14. * @since 15.0.0
  15. * @template S of int
  16. * @template H of array<string, mixed>
  17. * @template-extends Response<int, array<string, mixed>>
  18. */
  19. class ZipResponse extends Response implements ICallbackResponse {
  20. /** @var array{internalName: string, resource: resource, size: int, time: int}[] Files to be added to the zip response */
  21. private array $resources = [];
  22. /** @var string Filename that the zip file should have */
  23. private string $name;
  24. private IRequest $request;
  25. /**
  26. * @param S $status
  27. * @param H $headers
  28. * @since 15.0.0
  29. */
  30. public function __construct(IRequest $request, string $name = 'output', int $status = Http::STATUS_OK, array $headers = []) {
  31. parent::__construct($status, $headers);
  32. $this->name = $name;
  33. $this->request = $request;
  34. }
  35. /**
  36. * @since 15.0.0
  37. */
  38. public function addResource($r, string $internalName, int $size, int $time = -1) {
  39. if (!\is_resource($r)) {
  40. throw new \InvalidArgumentException('No resource provided');
  41. }
  42. $this->resources[] = [
  43. 'resource' => $r,
  44. 'internalName' => $internalName,
  45. 'size' => $size,
  46. 'time' => $time,
  47. ];
  48. }
  49. /**
  50. * @since 15.0.0
  51. */
  52. public function callback(IOutput $output) {
  53. $size = 0;
  54. $files = count($this->resources);
  55. foreach ($this->resources as $resource) {
  56. $size += $resource['size'];
  57. }
  58. $zip = new Streamer($this->request, $size, $files);
  59. $zip->sendHeaders($this->name);
  60. foreach ($this->resources as $resource) {
  61. $zip->addFileFromStream($resource['resource'], $resource['internalName'], $resource['size'], $resource['time']);
  62. }
  63. $zip->finalize();
  64. }
  65. }