Office.php 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 OC\Preview;
  8. use OCP\Files\File;
  9. use OCP\Files\FileInfo;
  10. use OCP\IImage;
  11. use OCP\ITempManager;
  12. use OCP\Server;
  13. use Psr\Log\LoggerInterface;
  14. abstract class Office extends ProviderV2 {
  15. /**
  16. * {@inheritDoc}
  17. */
  18. public function isAvailable(FileInfo $file): bool {
  19. return is_string($this->options['officeBinary']);
  20. }
  21. /**
  22. * {@inheritDoc}
  23. */
  24. public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
  25. if (!$this->isAvailable($file)) {
  26. return null;
  27. }
  28. $tempManager = Server::get(ITempManager::class);
  29. // The file to generate the preview for.
  30. $absPath = $this->getLocalFile($file);
  31. if ($absPath === false) {
  32. Server::get(LoggerInterface::class)->error(
  33. 'Failed to get local file to generate thumbnail for: ' . $file->getPath(),
  34. ['app' => 'core']
  35. );
  36. return null;
  37. }
  38. // The destination for the LibreOffice user profile.
  39. // LibreOffice can rune once per user profile and therefore instance id and file id are included.
  40. $profile = $tempManager->getTemporaryFolder(
  41. 'nextcloud-office-profile-' . \OC_Util::getInstanceId() . '-' . $file->getId()
  42. );
  43. // The destination for the LibreOffice convert result.
  44. $outdir = $tempManager->getTemporaryFolder(
  45. 'nextcloud-office-preview-' . \OC_Util::getInstanceId() . '-' . $file->getId()
  46. );
  47. if ($profile === false || $outdir === false) {
  48. $this->cleanTmpFiles();
  49. return null;
  50. }
  51. $parameters = [
  52. $this->options['officeBinary'],
  53. '-env:UserInstallation=file://' . escapeshellarg($profile),
  54. '--headless',
  55. '--nologo',
  56. '--nofirststartwizard',
  57. '--invisible',
  58. '--norestore',
  59. '--convert-to png',
  60. '--outdir ' . escapeshellarg($outdir),
  61. escapeshellarg($absPath),
  62. ];
  63. $cmd = implode(' ', $parameters);
  64. exec($cmd, $output, $returnCode);
  65. if ($returnCode !== 0) {
  66. $this->cleanTmpFiles();
  67. return null;
  68. }
  69. $preview = $outdir . pathinfo($absPath, PATHINFO_FILENAME) . '.png';
  70. $image = new \OCP\Image();
  71. $image->loadFromFile($preview);
  72. $this->cleanTmpFiles();
  73. if ($image->valid()) {
  74. $image->scaleDownToFit($maxX, $maxY);
  75. return $image;
  76. }
  77. return null;
  78. }
  79. }