xref: /webtrees/app/Http/RequestHandlers/AbstractTomSelectHandler.php (revision e873f434551745f888937263ff89e80db3b0f785)
1c8d78f19SGreg Roach<?php
2c8d78f19SGreg Roach
3c8d78f19SGreg Roach/**
4c8d78f19SGreg Roach * webtrees: online genealogy
5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
6c8d78f19SGreg Roach * This program is free software: you can redistribute it and/or modify
7c8d78f19SGreg Roach * it under the terms of the GNU General Public License as published by
8c8d78f19SGreg Roach * the Free Software Foundation, either version 3 of the License, or
9c8d78f19SGreg Roach * (at your option) any later version.
10c8d78f19SGreg Roach * This program is distributed in the hope that it will be useful,
11c8d78f19SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12c8d78f19SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c8d78f19SGreg Roach * GNU General Public License for more details.
14c8d78f19SGreg Roach * You should have received a copy of the GNU General Public License
15c8d78f19SGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
16c8d78f19SGreg Roach */
17c8d78f19SGreg Roach
18c8d78f19SGreg Roachdeclare(strict_types=1);
19c8d78f19SGreg Roach
20c8d78f19SGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers;
21c8d78f19SGreg Roach
22c8d78f19SGreg Roachuse Fisharebest\Webtrees\Tree;
23c8d78f19SGreg Roachuse Fisharebest\Webtrees\Validator;
24c8d78f19SGreg Roachuse Illuminate\Support\Collection;
25c8d78f19SGreg Roachuse Psr\Http\Message\ResponseInterface;
26c8d78f19SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
27c8d78f19SGreg Roachuse Psr\Http\Server\RequestHandlerInterface;
28c8d78f19SGreg Roach
29c8d78f19SGreg Roachuse function response;
30c8d78f19SGreg Roach
31c8d78f19SGreg Roach/**
32c8d78f19SGreg Roach * Autocomplete for TomSelect based controls.
33c8d78f19SGreg Roach */
34c8d78f19SGreg Roachabstract class AbstractTomSelectHandler implements RequestHandlerInterface
35c8d78f19SGreg Roach{
36c8d78f19SGreg Roach    // For clients that request one page of data at a time.
37*e873f434SGreg Roach    private const int RESULTS_PER_PAGE = 50;
38c8d78f19SGreg Roach
39c8d78f19SGreg Roach    /**
40c8d78f19SGreg Roach     * @param ServerRequestInterface $request
41c8d78f19SGreg Roach     *
42c8d78f19SGreg Roach     * @return ResponseInterface
43c8d78f19SGreg Roach     */
44c8d78f19SGreg Roach    public function handle(ServerRequestInterface $request): ResponseInterface
45c8d78f19SGreg Roach    {
46b55cbc6bSGreg Roach        $tree  = Validator::attributes($request)->tree();
47110d87e5SGreg Roach        $at    = Validator::queryParams($request)->isInArray(['', '@'])->string('at');
481e60ebf4SGreg Roach        $page  = Validator::queryParams($request)->integer('page', 1);
49b55cbc6bSGreg Roach        $query = Validator::queryParams($request)->string('query');
50c8d78f19SGreg Roach
51c8d78f19SGreg Roach        // Fetch one more row than we need, so we can know if more rows exist.
52c8d78f19SGreg Roach        $offset = ($page - 1) * self::RESULTS_PER_PAGE;
53c8d78f19SGreg Roach        $limit  = self::RESULTS_PER_PAGE + 1;
54c8d78f19SGreg Roach
55c8d78f19SGreg Roach        // Perform the search.
56c8d78f19SGreg Roach        if ($query !== '') {
57c8d78f19SGreg Roach            $results = $this->search($tree, $query, $offset, $limit, $at ? '@' : '');
58c8d78f19SGreg Roach        } else {
59c8d78f19SGreg Roach            $results = new Collection();
60c8d78f19SGreg Roach        }
61c8d78f19SGreg Roach
62c8d78f19SGreg Roach        if ($results->count() > self::RESULTS_PER_PAGE) {
63c8d78f19SGreg Roach            $next_url = route(static::class, ['tree' => $tree->name(), 'at' => $at ? '@' : '', 'page' => $page + 1]);
64c8d78f19SGreg Roach        } else {
65c8d78f19SGreg Roach            $next_url = null;
66c8d78f19SGreg Roach        }
67c8d78f19SGreg Roach
68c8d78f19SGreg Roach        return response([
69c8d78f19SGreg Roach            'data'    => $results->slice(0, self::RESULTS_PER_PAGE)->all(),
70c8d78f19SGreg Roach            'nextUrl' => $next_url,
71c8d78f19SGreg Roach        ]);
72c8d78f19SGreg Roach    }
73c8d78f19SGreg Roach
74c8d78f19SGreg Roach    /**
75c8d78f19SGreg Roach     * Perform the search
76c8d78f19SGreg Roach     *
77c8d78f19SGreg Roach     * @param Tree   $tree
78c8d78f19SGreg Roach     * @param string $query
79c8d78f19SGreg Roach     * @param int    $offset
80c8d78f19SGreg Roach     * @param int    $limit
81c8d78f19SGreg Roach     * @param string $at    "@" or ""
82c8d78f19SGreg Roach     *
83110d87e5SGreg Roach     * @return Collection<int,array{text:string,value:string}>
84c8d78f19SGreg Roach     */
85c8d78f19SGreg Roach    abstract protected function search(Tree $tree, string $query, int $offset, int $limit, string $at): Collection;
86c8d78f19SGreg Roach}
87