Publier Globinours 1.0.0-rc.3
This commit is contained in:
parent
ea8c24d622
commit
9a2b4068da
325 changed files with 38230 additions and 20 deletions
82
app/Services/GlobalSearchService.php
Normal file
82
app/Services/GlobalSearchService.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
final class GlobalSearchService
|
||||
{
|
||||
public static function search(string $query, int $limit = 8): array
|
||||
{
|
||||
$query = trim(preg_replace('/\s+/u', ' ', $query) ?? '');
|
||||
if (mb_strlen($query) < 2) {
|
||||
return [];
|
||||
}
|
||||
$db = DB::pdo();
|
||||
$like = '%' . str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], $query) . '%';
|
||||
$out = [];
|
||||
if (PermissionService::can('animals')) {
|
||||
$out['animals'] = self::rows(
|
||||
$db,
|
||||
"SELECT id,name,internal_code,status,species FROM animals WHERE deleted_at IS NULL AND (name LIKE :q ESCAPE '\\' OR internal_code LIKE :q ESCAPE '\\' OR COALESCE(chip,'') LIKE :q ESCAPE '\\') ORDER BY name COLLATE NOCASE LIMIT :lim",
|
||||
$like,
|
||||
$limit,
|
||||
static fn($r) => [
|
||||
'title' => $r['name'],
|
||||
'detail' => implode(' · ', array_filter([$r['internal_code'], $r['species'], $r['status']])),
|
||||
'url' => '/animal?id=' . (int) $r['id'],
|
||||
],
|
||||
);
|
||||
}
|
||||
if (PermissionService::can('directory')) {
|
||||
$out['directory'] = self::rows(
|
||||
$db,
|
||||
"SELECT id,name,kind,phone,email,city FROM directory_contacts WHERE deleted_at IS NULL AND (name LIKE :q ESCAPE '\\' OR COALESCE(phone,'') LIKE :q ESCAPE '\\' OR COALESCE(email,'') LIKE :q ESCAPE '\\' OR COALESCE(city,'') LIKE :q ESCAPE '\\') ORDER BY name COLLATE NOCASE LIMIT :lim",
|
||||
$like,
|
||||
$limit,
|
||||
static fn($r) => [
|
||||
'title' => $r['name'],
|
||||
'detail' => implode(' · ', array_filter([$r['city'], $r['phone'], $r['email']])),
|
||||
'url' => '/directory/view?id=' . (int) $r['id'],
|
||||
],
|
||||
);
|
||||
}
|
||||
if (PermissionService::can('agenda')) {
|
||||
$out['agenda'] = self::rows(
|
||||
$db,
|
||||
"SELECT id,title,starts_at,location,status FROM agenda_items WHERE title LIKE :q ESCAPE '\\' OR COALESCE(description,'') LIKE :q ESCAPE '\\' OR COALESCE(location,'') LIKE :q ESCAPE '\\' ORDER BY starts_at DESC LIMIT :lim",
|
||||
$like,
|
||||
$limit,
|
||||
static fn($r) => [
|
||||
'title' => $r['title'],
|
||||
'detail' => implode(
|
||||
' · ',
|
||||
array_filter([substr((string) $r['starts_at'], 0, 16), $r['location'], $r['status']]),
|
||||
),
|
||||
'url' => '/agenda?q=' . rawurlencode($r['title']),
|
||||
],
|
||||
);
|
||||
}
|
||||
if (PermissionService::can('accounting')) {
|
||||
$out['accounting'] = self::rows(
|
||||
$db,
|
||||
"SELECT ai.id,ai.reference,ai.invoice_date,ai.status,dc.name vendor FROM accounting_invoices ai LEFT JOIN directory_contacts dc ON dc.id=ai.vendor_contact_id WHERE ai.deleted_at IS NULL AND (ai.reference LIKE :q ESCAPE '\\' OR COALESCE(ai.notes,'') LIKE :q ESCAPE '\\' OR COALESCE(dc.name,'') LIKE :q ESCAPE '\\') ORDER BY ai.invoice_date DESC LIMIT :lim",
|
||||
$like,
|
||||
$limit,
|
||||
static fn($r) => [
|
||||
'title' => $r['reference'],
|
||||
'detail' => implode(' · ', array_filter([$r['vendor'], $r['invoice_date'], $r['status']])),
|
||||
'url' => '/accounting/edit?id=' . (int) $r['id'],
|
||||
],
|
||||
);
|
||||
}
|
||||
return array_filter($out);
|
||||
}
|
||||
|
||||
private static function rows(PDO $db, string $sql, string $like, int $limit, callable $map): array
|
||||
{
|
||||
$s = $db->prepare($sql);
|
||||
$s->bindValue(':q', $like);
|
||||
$s->bindValue(':lim', max(1, min(20, $limit)), PDO::PARAM_INT);
|
||||
$s->execute();
|
||||
return array_map($map, $s->fetchAll(PDO::FETCH_ASSOC));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue