diff --git a/CHANGELOG.md b/CHANGELOG.md index 89614e07d..ed3c51475 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## [Unreleased] +### Added +- Make recipes searchable through unified search + [#611](https://github.com/nextcloud/cookbook/pull/611) @PFischbeck + ### Fixed - Calling reindex [#653](https://github.com/nextcloud/cookbook/pull/653) @seyfeb diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php new file mode 100644 index 000000000..e3256ba6e --- /dev/null +++ b/lib/AppInfo/Application.php @@ -0,0 +1,39 @@ += 20 +// Remove conditional once we end support for NC 19 +if (Util::getVersion()[0] >= 20) { + class Application extends App implements IBootstrap +{ + public const APP_ID = 'cookbook'; + + public function __construct(array $urlParams = []) { + parent::__construct(self::APP_ID, $urlParams); + } + + public function register(IRegistrationContext $context): void { + $context->registerSearchProvider(Provider::class); + } + + public function boot(IBootContext $context): void { + } + } +} else { + class Application extends App +{ + public const APP_ID = 'cookbook'; + + public function __construct(array $urlParams = []) { + parent::__construct(self::APP_ID, $urlParams); + } + } +} diff --git a/lib/Search/Provider.php b/lib/Search/Provider.php new file mode 100644 index 000000000..26bb5c73c --- /dev/null +++ b/lib/Search/Provider.php @@ -0,0 +1,96 @@ += 20 +// Remove conditional once we end support for NC 19 +if (Util::getVersion()[0] >= 20) { + class Provider implements IProvider +{ + + /** @var IL10N */ + private $l; + + /** @var IURLGenerator */ + private $urlGenerator; + + /** @var RecipeDb */ + private $recipeDb; + + /** @var RecipeService */ + private $recipeService; + + public function __construct(IL10n $il10n, IURLGenerator $urlGenerator, + RecipeDb $recipeDb, RecipeService $recipeService) { + $this->l = $il10n; + $this->urlGenerator = $urlGenerator; + $this->recipeDb = $recipeDb; + $this->recipeService = $recipeService; + } + + public function getId(): string { + return Application::APP_ID; + } + + public function getName(): string { + return $this->l->t('Recipes'); + } + + public function getOrder(string $route, array $routeParameters): int { + if (strpos($route, 'files' . '.') === 0) { + return 25; + } elseif (strpos($route, Application::APP_ID . '.') === 0) { + return -1; + } + return 4; + } + + public function search(IUser $user, ISearchQuery $query): SearchResult { + $recipes = $this->recipeService->findRecipesInSearchIndex($query->getTerm()); + $result = array_map( + function (array $recipe) use ($user) : SearchResultEntry { + $id = $recipe['recipe_id']; + + $subline = ''; + $category = $this->recipeDb->getCategoryOfRecipe($id, $user->getUID()); + if ($category !== null) { + // TRANSLATORS Will be shown in search results, listing the recipe category, e.g., 'in Salads' + $subline = $this->l->t('in %s', [$category]); + } + + return new SearchResultEntry( + // Thumb image + $this->urlGenerator->linkToRoute('cookbook.recipe.image', ['id' => $id, 'size' => 'thumb']), + // Name as title + $recipe['name'], + // Category as subline + $subline, + // Link to Vue route of recipe + $this->urlGenerator->linkToRouteAbsolute('cookbook.main.index') . '#/recipe/' . $id + ); + }, $recipes + ); + + return SearchResult::complete( + $this->getName(), + $result + ); + } + } +} else { + class Provider +{ + } +}