FilesSearchProvider.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
  5. *
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author John Molakvoæ <skjnldsv@protonmail.com>
  9. * @author Robin Appelman <robin@icewind.nl>
  10. * @author Roeland Jago Douma <roeland@famdouma.nl>
  11. *
  12. * @license GNU AGPL version 3 or any later version
  13. *
  14. * This program is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Affero General Public License as
  16. * published by the Free Software Foundation, either version 3 of the
  17. * License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU Affero General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Affero General Public License
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  26. *
  27. */
  28. namespace OCA\Files\Search;
  29. use OC\Files\Search\SearchComparison;
  30. use OC\Files\Search\SearchOrder;
  31. use OC\Files\Search\SearchQuery;
  32. use OCP\Files\FileInfo;
  33. use OCP\Files\IMimeTypeDetector;
  34. use OCP\Files\IRootFolder;
  35. use OCP\Files\Search\ISearchComparison;
  36. use OCP\Files\Node;
  37. use OCP\Files\Search\ISearchOrder;
  38. use OCP\IL10N;
  39. use OCP\IURLGenerator;
  40. use OCP\IUser;
  41. use OCP\Search\IProvider;
  42. use OCP\Search\ISearchQuery;
  43. use OCP\Search\SearchResult;
  44. use OCP\Search\SearchResultEntry;
  45. class FilesSearchProvider implements IProvider {
  46. /** @var IL10N */
  47. private $l10n;
  48. /** @var IURLGenerator */
  49. private $urlGenerator;
  50. /** @var IMimeTypeDetector */
  51. private $mimeTypeDetector;
  52. /** @var IRootFolder */
  53. private $rootFolder;
  54. public function __construct(
  55. IL10N $l10n,
  56. IURLGenerator $urlGenerator,
  57. IMimeTypeDetector $mimeTypeDetector,
  58. IRootFolder $rootFolder
  59. ) {
  60. $this->l10n = $l10n;
  61. $this->urlGenerator = $urlGenerator;
  62. $this->mimeTypeDetector = $mimeTypeDetector;
  63. $this->rootFolder = $rootFolder;
  64. }
  65. /**
  66. * @inheritDoc
  67. */
  68. public function getId(): string {
  69. return 'files';
  70. }
  71. /**
  72. * @inheritDoc
  73. */
  74. public function getName(): string {
  75. return $this->l10n->t('Files');
  76. }
  77. /**
  78. * @inheritDoc
  79. */
  80. public function getOrder(string $route, array $routeParameters): int {
  81. if ($route === 'files.View.index') {
  82. // Before comments
  83. return -5;
  84. }
  85. return 5;
  86. }
  87. /**
  88. * @inheritDoc
  89. */
  90. public function search(IUser $user, ISearchQuery $query): SearchResult {
  91. $userFolder = $this->rootFolder->getUserFolder($user->getUID());
  92. $fileQuery = new SearchQuery(
  93. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query->getTerm() . '%'),
  94. $query->getLimit(),
  95. (int)$query->getCursor(),
  96. $query->getSortOrder() === ISearchQuery::SORT_DATE_DESC ? [
  97. new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'mtime'),
  98. ] : [],
  99. $user
  100. );
  101. return SearchResult::paginated(
  102. $this->l10n->t('Files'),
  103. array_map(function (Node $result) use ($userFolder) {
  104. // Generate thumbnail url
  105. $thumbnailUrl = $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreviewByFileId', ['x' => 32, 'y' => 32, 'fileId' => $result->getId()]);
  106. $path = $userFolder->getRelativePath($result->getPath());
  107. // Use shortened link to centralize the various
  108. // files/folder url redirection in files.View.showFile
  109. $link = $this->urlGenerator->linkToRoute(
  110. 'files.View.showFile',
  111. ['fileid' => $result->getId()]
  112. );
  113. $searchResultEntry = new SearchResultEntry(
  114. $thumbnailUrl,
  115. $result->getName(),
  116. $this->formatSubline($path),
  117. $this->urlGenerator->getAbsoluteURL($link),
  118. $result->getMimetype() === FileInfo::MIMETYPE_FOLDER ? 'icon-folder' : $this->mimeTypeDetector->mimeTypeIcon($result->getMimetype())
  119. );
  120. $searchResultEntry->addAttribute('fileId', (string)$result->getId());
  121. $searchResultEntry->addAttribute('path', $path);
  122. return $searchResultEntry;
  123. }, $userFolder->search($fileQuery)),
  124. $query->getCursor() + $query->getLimit()
  125. );
  126. }
  127. /**
  128. * Format subline for files
  129. *
  130. * @param string $path
  131. * @return string
  132. */
  133. private function formatSubline(string $path): string {
  134. // Do not show the location if the file is in root
  135. if (strrpos($path, '/') > 0) {
  136. $path = ltrim(dirname($path), '/');
  137. return $this->l10n->t('in %s', [$path]);
  138. } else {
  139. return '';
  140. }
  141. }
  142. }