Office.php 2.0 KB

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