Files
xamxam/docs/search.md
T

99 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Search & Répertoire — Documentation
Two public browsing surfaces, both handled by `app/src/Controllers/SearchController.php`
and routed by `app/src/Dispatcher.php`:
| Route | Handler | Purpose |
|-------|---------|---------|
| `/search`, `/search.php` | `handleSearch()` | Full-text query + classic single filters |
| `/repertoire`, `/repertoire.php` | `handleRepertoire()` | Browseable directory with multi-select filters |
Both only ever expose **published** theses (`is_published = 1`).
---
## HandleSearch (`/search`)
`handleSearch()` reads from `$_GET` and renders `app/templates/public/search.php`
with the results fragment (`app/templates/partials/search-results.php`).
Searchable text fields (via `Database::searchTheses()`):
- Title, subtitle, synopsis, author names, supervisor names, tags/keywords.
Single-value filters (`collectSearchParams()`):
- `query` — free text
- `year` — exact year
- `orientation` — artistic orientation
- `ap_program` — AP program
- `finality` — finality type
- `format` — format
- `keyword` — tag/keyword
Results are paginated (`limit = 20` default); the **search bar**
(`app/templates/partials/search-bar.php`) submits a GET form to `/search`.
---
## HandleRepertoire (`/repertoire`)
`handleRepertoire()` reads multi-select filter arrays from `$_GET` and renders
`app/templates/public/repertoire.php`, which uses the shared results partial
and `app/templates/partials/repertoire-index.php`.
Multi-select filters (`collectFilterParams()`, each an array, `_GET` keys):
- `fy[]` — years (validated to 1900–2100)
- `ap[]` — AP program names
- `or[]` — orientations
- `fi[]` — finalities
- `kw[]` — keywords/tags
Each value is trimmed, length-capped (≤ 100), de-duplicated, and passed through
as sanitised strings — no direct user input reaches SQL.
There is also an HTMX **student preview** popover at
`/repertoire/student-preview` (`handleStudentPreview()` → `student-preview.php`).
---
## Rate limiting
Search is rate-limited via `app/src/RateLimit.php`. See the nginx config
(`nginx/xamxam.conf`) for the matching server-side limits.
---
## Database access
- **Full-text + single filters:** `Database::searchTheses(array $params, $limit, $offset)`
and `Database::countSearchResults(array $params)`.
- **Keyword/tag autocomplete:** `Database::searchTags(string $query)`.
- **Supervisor autocomplete:** `Database::searchSupervisors($query, $role)`.
- **Language autocomplete:** `Database::searchLanguages(string $query)`.
Queries operate on `v_theses_public`; keyword matching joins the `thesis_tags` /
`tags` tables (keywords are stored as lowercase-normalised **tags**, not a
`keywords`/`thesis_keywords` set — see [database.md](database.md)).
All queries use PDO prepared statements and escape `%`/`_` for `LIKE`
(`Database::escapeLikeString`) to prevent wildcard injection.
---
## Performance notes
- Critical text/filter columns and the junction tables are indexed
(`idx_theses_pub_year`, `idx_theses_*`, `idx_thesis_tags_*`, …).
- `v_theses_public` pre-computes the joins for the common read path.
- The repertoire filters operate on indexed lookup columns.
---
## Future enhancements (not yet implemented)
The historical `search.md` listed potential automplete/faceted-search/export
ideas. Status:
- Auto-complete for tags exists at the form level (`searchTags`)
- Faceted counts, saved searches, result export, and advanced boolean operators
are **not** implemented