ImageExportPlugin.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\DAV\CardDAV;
  8. use OCP\AppFramework\Http;
  9. use OCP\Files\NotFoundException;
  10. use Sabre\CardDAV\Card;
  11. use Sabre\DAV\Server;
  12. use Sabre\DAV\ServerPlugin;
  13. use Sabre\HTTP\RequestInterface;
  14. use Sabre\HTTP\ResponseInterface;
  15. class ImageExportPlugin extends ServerPlugin {
  16. /** @var Server */
  17. protected $server;
  18. /**
  19. * ImageExportPlugin constructor.
  20. *
  21. * @param PhotoCache $cache
  22. */
  23. public function __construct(
  24. private PhotoCache $cache,
  25. ) {
  26. }
  27. /**
  28. * Initializes the plugin and registers event handlers
  29. *
  30. * @param Server $server
  31. * @return void
  32. */
  33. public function initialize(Server $server) {
  34. $this->server = $server;
  35. $this->server->on('method:GET', [$this, 'httpGet'], 90);
  36. }
  37. /**
  38. * Intercepts GET requests on addressbook urls ending with ?photo.
  39. *
  40. * @param RequestInterface $request
  41. * @param ResponseInterface $response
  42. * @return bool
  43. */
  44. public function httpGet(RequestInterface $request, ResponseInterface $response) {
  45. $queryParams = $request->getQueryParameters();
  46. // TODO: in addition to photo we should also add logo some point in time
  47. if (!array_key_exists('photo', $queryParams)) {
  48. return true;
  49. }
  50. $size = isset($queryParams['size']) ? (int)$queryParams['size'] : -1;
  51. $path = $request->getPath();
  52. $node = $this->server->tree->getNodeForPath($path);
  53. if (!$node instanceof Card) {
  54. return true;
  55. }
  56. $this->server->transactionType = 'carddav-image-export';
  57. // Checking ACL, if available.
  58. if ($aclPlugin = $this->server->getPlugin('acl')) {
  59. /** @var \Sabre\DAVACL\Plugin $aclPlugin */
  60. $aclPlugin->checkPrivileges($path, '{DAV:}read');
  61. }
  62. // Fetch addressbook
  63. $addressbookpath = explode('/', $path);
  64. array_pop($addressbookpath);
  65. $addressbookpath = implode('/', $addressbookpath);
  66. /** @var AddressBook $addressbook */
  67. $addressbook = $this->server->tree->getNodeForPath($addressbookpath);
  68. $response->setHeader('Cache-Control', 'private, max-age=3600, must-revalidate');
  69. $response->setHeader('Etag', $node->getETag());
  70. try {
  71. $file = $this->cache->get($addressbook->getResourceId(), $node->getName(), $size, $node);
  72. $response->setHeader('Content-Type', $file->getMimeType());
  73. $fileName = $node->getName() . '.' . PhotoCache::ALLOWED_CONTENT_TYPES[$file->getMimeType()];
  74. $response->setHeader('Content-Disposition', "attachment; filename=$fileName");
  75. $response->setStatus(Http::STATUS_OK);
  76. $response->setBody($file->getContent());
  77. } catch (NotFoundException $e) {
  78. $response->setStatus(Http::STATUS_NO_CONTENT);
  79. }
  80. return false;
  81. }
  82. }