Plugin.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\Files_Versions\Sabre;
  8. use OC\AppFramework\Http\Request;
  9. use OCA\DAV\Connector\Sabre\FilesPlugin;
  10. use OCP\IPreview;
  11. use OCP\IRequest;
  12. use Sabre\DAV\Exception\NotFound;
  13. use Sabre\DAV\INode;
  14. use Sabre\DAV\PropFind;
  15. use Sabre\DAV\PropPatch;
  16. use Sabre\DAV\Server;
  17. use Sabre\DAV\ServerPlugin;
  18. use Sabre\HTTP\RequestInterface;
  19. use Sabre\HTTP\ResponseInterface;
  20. class Plugin extends ServerPlugin {
  21. private Server $server;
  22. public const VERSION_LABEL = '{http://nextcloud.org/ns}version-label';
  23. public const VERSION_AUTHOR = '{http://nextcloud.org/ns}version-author'; // dav property for author
  24. public function __construct(
  25. private IRequest $request,
  26. private IPreview $previewManager,
  27. ) {
  28. $this->request = $request;
  29. }
  30. public function initialize(Server $server) {
  31. $this->server = $server;
  32. $server->on('afterMethod:GET', [$this, 'afterGet']);
  33. $server->on('propFind', [$this, 'propFind']);
  34. $server->on('propPatch', [$this, 'propPatch']);
  35. }
  36. public function afterGet(RequestInterface $request, ResponseInterface $response) {
  37. $path = $request->getPath();
  38. if (!str_starts_with($path, 'versions')) {
  39. return;
  40. }
  41. try {
  42. $node = $this->server->tree->getNodeForPath($path);
  43. } catch (NotFound $e) {
  44. return;
  45. }
  46. if (!($node instanceof VersionFile)) {
  47. return;
  48. }
  49. $filename = $node->getVersion()->getSourceFileName();
  50. if ($this->request->isUserAgent(
  51. [
  52. Request::USER_AGENT_IE,
  53. Request::USER_AGENT_ANDROID_MOBILE_CHROME,
  54. Request::USER_AGENT_FREEBOX,
  55. ])) {
  56. $response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
  57. } else {
  58. $response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
  59. . '; filename="' . rawurlencode($filename) . '"');
  60. }
  61. }
  62. public function propFind(PropFind $propFind, INode $node): void {
  63. if ($node instanceof VersionFile) {
  64. $propFind->handle(self::VERSION_LABEL, fn () => $node->getMetadataValue('label'));
  65. $propFind->handle(self::VERSION_AUTHOR, fn () => $node->getMetadataValue('author'));
  66. $propFind->handle(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, fn () => $this->previewManager->isMimeSupported($node->getContentType()));
  67. }
  68. }
  69. public function propPatch($path, PropPatch $propPatch): void {
  70. $node = $this->server->tree->getNodeForPath($path);
  71. if ($node instanceof VersionFile) {
  72. $propPatch->handle(self::VERSION_LABEL, fn (string $label) => $node->setMetadataValue('label', $label));
  73. }
  74. }
  75. }