add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MintyPHP\Support\Search;
|
|
|
|
|
|
|
|
|
|
use MintyPHP\Service\User\UserAvatarService;
|
|
|
|
|
|
|
|
|
|
class SearchItemMapperProvider
|
|
|
|
|
{
|
2026-03-04 15:56:58 +01:00
|
|
|
/** @var (callable(): UserAvatarService)|null */
|
|
|
|
|
private static $userAvatarServiceResolver = null;
|
|
|
|
|
|
|
|
|
|
public static function configure(callable $userAvatarServiceResolver): void
|
|
|
|
|
{
|
|
|
|
|
self::$userAvatarServiceResolver = $userAvatarServiceResolver;
|
|
|
|
|
}
|
2026-02-23 12:58:19 +01:00
|
|
|
|
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
|
|
|
public static function mapPreviewItem(string $key, array $data, string $query): ?array
|
|
|
|
|
{
|
|
|
|
|
if ($key === 'users') {
|
|
|
|
|
$label = trim(($data['first_name'] ?? '') . ' ' . ($data['last_name'] ?? ''));
|
|
|
|
|
$email = trim((string) ($data['email'] ?? ''));
|
|
|
|
|
if ($email !== '') {
|
|
|
|
|
$label = $label === '' ? $email : ($label . ' — ' . $email);
|
|
|
|
|
}
|
|
|
|
|
$url = lurl('admin/users/edit/' . ($data['uuid'] ?? '')) . '?search=' . urlencode($query);
|
|
|
|
|
} elseif ($key === 'address-book') {
|
|
|
|
|
$label = trim(($data['first_name'] ?? '') . ' ' . ($data['last_name'] ?? ''));
|
|
|
|
|
$email = trim((string) ($data['email'] ?? ''));
|
|
|
|
|
if ($email !== '') {
|
|
|
|
|
$label = $label === '' ? $email : ($label . ' — ' . $email);
|
|
|
|
|
}
|
|
|
|
|
$url = lurl('address-book/view/' . ($data['uuid'] ?? '')) . '?search=' . urlencode($query);
|
|
|
|
|
} elseif ($key === 'permissions') {
|
|
|
|
|
$label = (string) ($data['description'] ?? '');
|
|
|
|
|
$url = lurl('admin/permissions/edit/' . ($data['id'] ?? '')) . '?search=' . urlencode($query);
|
|
|
|
|
} elseif ($key === 'scheduled-jobs') {
|
|
|
|
|
$jobLabel = trim((string) ($data['label'] ?? ''));
|
|
|
|
|
$jobKey = trim((string) ($data['job_key'] ?? ''));
|
|
|
|
|
$status = trim((string) ($data['last_run_status'] ?? ''));
|
|
|
|
|
$label = $jobLabel !== '' ? $jobLabel : $jobKey;
|
|
|
|
|
if ($status !== '') {
|
|
|
|
|
$label = trim($label . ' — ' . strtoupper($status));
|
|
|
|
|
}
|
|
|
|
|
$url = lurl('admin/scheduled-jobs/edit/' . ($data['id'] ?? '')) . '?search=' . urlencode($query);
|
|
|
|
|
} elseif ($key === 'mail-log') {
|
|
|
|
|
$toEmail = trim((string) ($data['to_email'] ?? ''));
|
|
|
|
|
$subject = trim((string) ($data['subject'] ?? ''));
|
|
|
|
|
$status = trim((string) ($data['status'] ?? ''));
|
|
|
|
|
$label = $subject !== '' ? $subject : $toEmail;
|
|
|
|
|
if ($status !== '') {
|
|
|
|
|
$label = trim($label . ' — ' . strtoupper($status));
|
|
|
|
|
}
|
|
|
|
|
$url = lurl('admin/mail-log/view/' . ($data['id'] ?? '')) . '?search=' . urlencode($query);
|
|
|
|
|
} elseif ($key === 'api-audit') {
|
|
|
|
|
$method = strtoupper(trim((string) ($data['method'] ?? '')));
|
|
|
|
|
$path = trim((string) ($data['path'] ?? ''));
|
|
|
|
|
$statusCode = (int) ($data['status_code'] ?? 0);
|
|
|
|
|
$requestId = trim((string) ($data['request_id'] ?? ''));
|
|
|
|
|
$label = trim($method . ' ' . $path);
|
|
|
|
|
if ($statusCode > 0) {
|
|
|
|
|
$label = trim($label . ' — ' . $statusCode);
|
|
|
|
|
}
|
|
|
|
|
if ($label === '' && $requestId !== '') {
|
|
|
|
|
$label = $requestId;
|
|
|
|
|
}
|
|
|
|
|
$url = lurl('admin/api-audit/view/' . ($data['id'] ?? '')) . '?search=' . urlencode($query);
|
2026-03-04 15:56:58 +01:00
|
|
|
} elseif ($key === 'system-audit') {
|
|
|
|
|
$eventType = trim((string) ($data['event_type'] ?? ''));
|
|
|
|
|
$outcome = strtolower(trim((string) ($data['outcome'] ?? '')));
|
|
|
|
|
$requestId = trim((string) ($data['request_id'] ?? ''));
|
|
|
|
|
$label = $eventType !== '' ? $eventType : $requestId;
|
|
|
|
|
if ($outcome !== '') {
|
|
|
|
|
$label = trim($label . ' — ' . $outcome);
|
|
|
|
|
}
|
|
|
|
|
$url = lurl('admin/system-audit/view/' . ($data['id'] ?? '')) . '?search=' . urlencode($query);
|
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
|
|
|
} elseif ($key === 'pages') {
|
|
|
|
|
$label = (string) ($data['slug'] ?? '');
|
|
|
|
|
$url = lurl('page/' . $label) . '?search=' . urlencode($query);
|
|
|
|
|
} else {
|
|
|
|
|
$label = (string) ($data['description'] ?? '');
|
|
|
|
|
$url = lurl('admin/' . $key . '/edit/' . ($data['uuid'] ?? '')) . '?search=' . urlencode($query);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($label === '') {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ['label' => $label, 'url' => $url];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function mapResultItem(string $key, string $label, array $data): ?array
|
|
|
|
|
{
|
|
|
|
|
$title = '';
|
|
|
|
|
$description = '';
|
|
|
|
|
$url = '';
|
|
|
|
|
$image = '';
|
|
|
|
|
|
|
|
|
|
if ($key === 'users') {
|
|
|
|
|
$title = trim(($data['first_name'] ?? '') . ' ' . ($data['last_name'] ?? ''));
|
|
|
|
|
$description = (string) ($data['email'] ?? '');
|
|
|
|
|
$url = lurl('admin/users/edit/' . ($data['uuid'] ?? ''));
|
|
|
|
|
} elseif ($key === 'address-book') {
|
|
|
|
|
$title = trim(($data['first_name'] ?? '') . ' ' . ($data['last_name'] ?? ''));
|
|
|
|
|
$description = (string) ($data['email'] ?? '');
|
|
|
|
|
$uuid = (string) ($data['uuid'] ?? '');
|
|
|
|
|
$url = lurl('address-book/view/' . $uuid);
|
2026-03-04 15:56:58 +01:00
|
|
|
$userAvatarService = self::userAvatarService();
|
|
|
|
|
if ($uuid !== '' && $userAvatarService->hasAvatar($uuid)) {
|
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
|
|
|
$image = lurl('admin/users/avatar-file') . '?uuid=' . urlencode($uuid) . '&size=64';
|
|
|
|
|
}
|
|
|
|
|
} elseif ($key === 'permissions') {
|
|
|
|
|
$title = (string) ($data['key'] ?? '');
|
|
|
|
|
$description = (string) ($data['description'] ?? '');
|
|
|
|
|
$url = lurl('admin/permissions/edit/' . ($data['id'] ?? ''));
|
|
|
|
|
} elseif ($key === 'scheduled-jobs') {
|
|
|
|
|
$jobLabel = trim((string) ($data['label'] ?? ''));
|
|
|
|
|
$jobKey = trim((string) ($data['job_key'] ?? ''));
|
|
|
|
|
$title = $jobLabel !== '' ? $jobLabel : $jobKey;
|
|
|
|
|
$status = trim((string) ($data['last_run_status'] ?? ''));
|
|
|
|
|
$description = $status !== '' ? strtoupper($status) : ($jobKey !== '' ? $jobKey : '');
|
|
|
|
|
$url = lurl('admin/scheduled-jobs/edit/' . ($data['id'] ?? ''));
|
|
|
|
|
} elseif ($key === 'pages') {
|
|
|
|
|
$title = (string) ($data['slug'] ?? '');
|
|
|
|
|
$description = t('Page');
|
|
|
|
|
$url = lurl('page/' . $title);
|
|
|
|
|
} elseif ($key === 'mail-log') {
|
|
|
|
|
$title = trim((string) ($data['subject'] ?? ''));
|
|
|
|
|
if ($title === '') {
|
|
|
|
|
$title = trim((string) ($data['to_email'] ?? ''));
|
|
|
|
|
}
|
|
|
|
|
$status = trim((string) ($data['status'] ?? ''));
|
|
|
|
|
$toEmail = trim((string) ($data['to_email'] ?? ''));
|
|
|
|
|
$description = trim(($status !== '' ? strtoupper($status) : '') . ($toEmail !== '' ? ' — ' . $toEmail : ''));
|
|
|
|
|
$url = lurl('admin/mail-log/view/' . ($data['id'] ?? ''));
|
|
|
|
|
} elseif ($key === 'api-audit') {
|
|
|
|
|
$method = strtoupper(trim((string) ($data['method'] ?? '')));
|
|
|
|
|
$path = trim((string) ($data['path'] ?? ''));
|
|
|
|
|
$statusCode = (int) ($data['status_code'] ?? 0);
|
|
|
|
|
$requestId = trim((string) ($data['request_id'] ?? ''));
|
|
|
|
|
$title = trim($method . ' ' . $path);
|
|
|
|
|
if ($title === '') {
|
|
|
|
|
$title = $requestId;
|
|
|
|
|
}
|
|
|
|
|
$description = trim(($statusCode > 0 ? (string) $statusCode : '') . ($requestId !== '' ? ' — ' . $requestId : ''));
|
|
|
|
|
$url = lurl('admin/api-audit/view/' . ($data['id'] ?? ''));
|
2026-03-04 15:56:58 +01:00
|
|
|
} elseif ($key === 'system-audit') {
|
|
|
|
|
$eventType = trim((string) ($data['event_type'] ?? ''));
|
|
|
|
|
$outcome = strtolower(trim((string) ($data['outcome'] ?? '')));
|
|
|
|
|
$requestId = trim((string) ($data['request_id'] ?? ''));
|
|
|
|
|
$title = $eventType !== '' ? $eventType : $requestId;
|
|
|
|
|
$description = trim(($outcome !== '' ? strtoupper($outcome) : '') . ($requestId !== '' ? ' — ' . $requestId : ''));
|
|
|
|
|
$url = lurl('admin/system-audit/view/' . ($data['id'] ?? ''));
|
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
|
|
|
} else {
|
|
|
|
|
$title = (string) ($data['description'] ?? '');
|
|
|
|
|
$description = $label;
|
|
|
|
|
$url = lurl('admin/' . $key . '/edit/' . ($data['uuid'] ?? ''));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($title === '' || $url === '') {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'type' => $label,
|
|
|
|
|
'title' => $title,
|
|
|
|
|
'description' => $description,
|
|
|
|
|
'url' => $url,
|
|
|
|
|
'image' => $image,
|
|
|
|
|
'icon' => SearchUiMetaProvider::iconForKey($key),
|
|
|
|
|
];
|
|
|
|
|
}
|
2026-02-23 12:58:19 +01:00
|
|
|
|
|
|
|
|
private static function userAvatarService(): UserAvatarService
|
|
|
|
|
{
|
2026-03-04 15:56:58 +01:00
|
|
|
if (!is_callable(self::$userAvatarServiceResolver)) {
|
|
|
|
|
throw new \RuntimeException('SearchItemMapperProvider is not configured for dependency: ' . UserAvatarService::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$service = (self::$userAvatarServiceResolver)();
|
|
|
|
|
if (!$service instanceof UserAvatarService) {
|
|
|
|
|
throw new \RuntimeException('SearchItemMapperProvider resolver returned invalid dependency: ' . UserAvatarService::class);
|
2026-02-23 12:58:19 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-04 15:56:58 +01:00
|
|
|
return $service;
|
2026-02-23 12:58:19 +01:00
|
|
|
}
|
2026-03-04 15:56:58 +01:00
|
|
|
|
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
|
|
|
}
|