Files
breadcrumb-the-shire/pages/address-book/saved-filter-save().php
fs 25370a1a55 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

114 lines
3.7 KiB
PHP

<?php
use MintyPHP\Router;
use MintyPHP\Session;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\User\UserSavedFilterService;
Guard::requireLogin();
Guard::requirePermissionOrForbidden(PermissionService::ADDRESS_BOOK_VIEW);
$buildAddressBookRedirect = static function (array $query): string {
$params = [];
$search = trim((string) ($query['search'] ?? ''));
$tenants = trim((string) ($query['tenants'] ?? ''));
$departments = trim((string) ($query['departments'] ?? ''));
$roles = trim((string) ($query['roles'] ?? ''));
$collectCustom = static function (array $source): array {
$custom = [];
foreach ($source as $rawKey => $rawValue) {
$key = strtolower(trim((string) $rawKey));
if ($key === '') {
continue;
}
if (preg_match('/^cf_[a-f0-9-]{36}$/', $key)) {
$value = trim((string) $rawValue);
if ($value !== '') {
$custom[$key] = $value;
}
continue;
}
if (preg_match('/^cfm_[a-f0-9-]{36}$/', $key)) {
$ids = array_values(array_filter(array_map(
'intval',
array_map('trim', explode(',', (string) $rawValue))
), static fn (int $id): bool => $id > 0));
$ids = array_values(array_unique($ids));
if ($ids) {
$custom[$key] = implode(',', $ids);
}
continue;
}
if (preg_match('/^cfd_[a-f0-9-]{36}_(from|to)$/', $key)) {
$value = trim((string) $rawValue);
if ($value !== '') {
$custom[$key] = $value;
}
}
}
ksort($custom, SORT_STRING);
return $custom;
};
if ($search !== '') {
$params['search'] = $search;
}
if ($tenants !== '') {
$params['tenants'] = $tenants;
}
if ($departments !== '') {
$params['departments'] = $departments;
}
if ($roles !== '') {
$params['roles'] = $roles;
}
foreach ($collectCustom($query) as $customKey => $customValue) {
$params[$customKey] = $customValue;
}
if (!$params) {
return 'address-book';
}
return 'address-book?' . http_build_query($params);
};
$redirect = $buildAddressBookRedirect($_POST);
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect($redirect);
return;
}
if (!Session::checkCsrfToken()) {
Flash::error(t('Form expired, please try again'), 'address-book', 'address_book_saved_filters_csrf');
Router::redirect($redirect);
return;
}
$userId = (int) ($_SESSION['user']['id'] ?? 0);
if ($userId <= 0) {
Router::redirect('login');
return;
}
$name = trim((string) ($_POST['name'] ?? ''));
$result = UserSavedFilterService::saveAddressBookFilter($userId, $name, $_POST);
if (!($result['ok'] ?? false)) {
$error = (string) ($result['error'] ?? '');
if ($error === 'name_required') {
Flash::error(t('Filter name is required'), 'address-book', 'address_book_saved_filter_name_required');
} elseif ($error === 'max_reached') {
Flash::error(t('Maximum number of saved filters reached'), 'address-book', 'address_book_saved_filter_max_reached');
} else {
Flash::error(t('Filter save failed'), 'address-book', 'address_book_saved_filter_save_failed');
}
Router::redirect($redirect);
return;
}
$_SESSION['address_book_saved_filters'] = UserSavedFilterService::listForAddressBook($userId);
Flash::success(t('Filter saved'), 'address-book', 'address_book_saved_filter_saved');
Router::redirect($redirect);