From 4b31fc7664aa7cdc02c24a027731b8110508a87b Mon Sep 17 00:00:00 2001 From: fs Date: Thu, 5 Mar 2026 08:26:51 +0100 Subject: [PATCH] =?UTF-8?q?Repo=20Interface=20f=C3=BCr=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/architektur.md | 12 +- docs/entwickler-checkliste.md | 4 + docs/frontend-javascript.md | 13 +- .../Access/PermissionRepository.php | 2 +- .../Access/PermissionRepositoryInterface.php | 22 ++ .../Access/RolePermissionRepository.php | 2 +- .../RolePermissionRepositoryInterface.php | 20 ++ lib/Repository/Access/RoleRepository.php | 4 +- .../Access/RoleRepositoryInterface.php | 30 ++ lib/Repository/Access/UserRoleRepository.php | 2 +- .../Access/UserRoleRepositoryInterface.php | 16 + .../Audit/ApiAuditLogRepository.php | 2 +- .../Audit/ApiAuditLogRepositoryInterface.php | 16 + .../Audit/ImportAuditRunRepository.php | 2 +- .../ImportAuditRunRepositoryInterface.php | 18 ++ .../Audit/SystemAuditLogRepository.php | 2 +- .../SystemAuditLogRepositoryInterface.php | 16 + .../Audit/UserLifecycleAuditRepository.php | 2 +- .../UserLifecycleAuditRepositoryInterface.php | 22 ++ lib/Repository/Auth/ApiTokenRepository.php | 2 +- .../Auth/ApiTokenRepositoryInterface.php | 44 +++ .../Auth/EmailVerificationRepository.php | 2 +- .../EmailVerificationRepositoryInterface.php | 18 ++ .../Auth/PasswordResetRepository.php | 2 +- .../Auth/PasswordResetRepositoryInterface.php | 20 ++ .../Auth/RememberTokenRepository.php | 2 +- .../Auth/RememberTokenRepositoryInterface.php | 22 ++ lib/Repository/Mail/MailLogRepository.php | 2 +- .../Mail/MailLogRepositoryInterface.php | 16 + lib/Repository/Org/DepartmentRepository.php | 4 +- .../Org/DepartmentRepositoryInterface.php | 36 +++ .../Org/UserDepartmentRepository.php | 2 +- .../Org/UserDepartmentRepositoryInterface.php | 16 + .../Scheduler/ScheduledJobRepository.php | 2 +- .../ScheduledJobRepositoryInterface.php | 30 ++ .../Scheduler/ScheduledJobRunRepository.php | 2 +- .../ScheduledJobRunRepositoryInterface.php | 12 + .../Scheduler/SchedulerRuntimeRepository.php | 2 +- .../SchedulerRuntimeRepositoryInterface.php | 10 + .../Search/SearchQueryRepository.php | 2 +- .../Search/SearchQueryRepositoryInterface.php | 17 + .../Security/RateLimitRepository.php | 2 +- .../Security/RateLimitRepositoryInterface.php | 25 ++ lib/Repository/Settings/SettingRepository.php | 2 +- .../Settings/SettingRepositoryInterface.php | 12 + lib/Repository/Stats/AdminStatsRepository.php | 2 +- .../Stats/AdminStatsRepositoryInterface.php | 11 + .../Support/DatabaseSessionRepository.php | 2 +- .../DatabaseSessionRepositoryInterface.php | 16 + .../Tenant/TenantMicrosoftAuthRepository.php | 2 +- ...TenantMicrosoftAuthRepositoryInterface.php | 12 + lib/Repository/Tenant/TenantRepository.php | 4 +- .../Tenant/TenantRepositoryInterface.php | 26 ++ .../Tenant/UserTenantRepository.php | 2 +- .../Tenant/UserTenantRepositoryInterface.php | 14 + .../User/UserExternalIdentityRepository.php | 4 +- ...serExternalIdentityRepositoryInterface.php | 12 + .../User/UserListQueryRepository.php | 2 +- .../User/UserListQueryRepositoryInterface.php | 8 + lib/Repository/User/UserReadRepository.php | 2 +- .../User/UserReadRepositoryInterface.php | 20 ++ .../User/UserSavedFilterRepository.php | 2 +- .../UserSavedFilterRepositoryInterface.php | 14 + lib/Repository/User/UserWriteRepository.php | 2 +- .../User/UserWriteRepositoryInterface.php | 40 +++ .../Access/AccessRepositoryFactory.php | 9 +- lib/Service/Access/AccessServicesFactory.php | 12 +- lib/Service/Access/PermissionService.php | 12 +- lib/Service/Access/RoleService.php | 4 +- lib/Service/Audit/ApiAuditService.php | 4 +- lib/Service/Audit/AuditRepositoryFactory.php | 9 +- lib/Service/Audit/AuditServicesFactory.php | 12 +- lib/Service/Audit/ImportAuditService.php | 4 +- lib/Service/Audit/SystemAuditService.php | 4 +- .../Audit/UserLifecycleAuditService.php | 4 +- lib/Service/Auth/ApiTokenService.php | 8 +- .../Auth/AuthExternalIdentityGateway.php | 4 +- lib/Service/Auth/AuthRepositoryFactory.php | 21 +- lib/Service/Auth/AuthService.php | 8 +- lib/Service/Auth/AuthTenantGateway.php | 4 +- lib/Service/Auth/EmailVerificationService.php | 12 +- lib/Service/Auth/PasswordResetService.php | 8 +- lib/Service/Auth/RememberMeService.php | 12 +- lib/Service/Auth/SsoUserLinkService.php | 12 +- lib/Service/Auth/TenantSsoService.php | 4 +- .../Directory/DirectoryRepositoryFactory.php | 9 +- .../Directory/DirectoryServicesFactory.php | 12 +- .../Import/ImportRepositoryFactory.php | 3 +- lib/Service/Import/ImportServicesFactory.php | 4 +- .../Profile/DepartmentImportGateway.php | 12 +- .../Import/Profile/UserImportGateway.php | 16 +- lib/Service/Mail/MailLogService.php | 4 +- lib/Service/Mail/MailRepositoryFactory.php | 3 +- lib/Service/Mail/MailService.php | 4 +- lib/Service/Mail/MailServicesFactory.php | 4 +- lib/Service/Org/DepartmentService.php | 4 +- lib/Service/Scheduler/ScheduledJobService.php | 8 +- .../Scheduler/SchedulerRepositoryFactory.php | 9 +- lib/Service/Scheduler/SchedulerRunService.php | 12 +- .../Scheduler/SchedulerServicesFactory.php | 12 +- lib/Service/Security/RateLimiterService.php | 4 +- .../Security/SecurityRepositoryFactory.php | 3 +- .../Security/SecurityServicesFactory.php | 4 +- .../Settings/SettingRepositoryFactory.php | 12 +- lib/Service/Settings/SettingService.php | 16 +- .../Settings/SettingServicesFactory.php | 16 +- .../Tenant/TenantRepositoryFactory.php | 9 +- lib/Service/Tenant/TenantScopeService.php | 12 +- lib/Service/Tenant/TenantService.php | 8 +- lib/Service/Tenant/TenantServicesFactory.php | 12 +- lib/Service/User/UserAccountService.php | 12 +- lib/Service/User/UserAssignmentService.php | 16 +- lib/Service/User/UserDirectoryGateway.php | 12 +- .../User/UserLifecycleRestoreService.php | 8 +- lib/Service/User/UserLifecycleService.php | 8 +- lib/Service/User/UserPasswordService.php | 4 +- lib/Service/User/UserRepositoryFactory.php | 30 +- lib/Service/User/UserSavedFilterService.php | 4 +- lib/Service/User/UserServicesFactory.php | 28 +- lib/Service/User/UserTenantContextService.php | 12 +- lib/Support/helpers/app.php | 141 +++++++++ pages/address-book/index(default).phtml | 231 ++------------ pages/admin/api-audit/index(default).phtml | 172 ++-------- pages/admin/api-docs/index(default).phtml | 2 +- pages/admin/departments/index(default).phtml | 146 ++------- pages/admin/import-audit/index(default).phtml | 128 ++------ pages/admin/mail-log/index(default).phtml | 122 ++------ pages/admin/permissions/index(default).phtml | 104 ++---- pages/admin/roles/index(default).phtml | 155 ++------- .../admin/scheduled-jobs/edit(default).phtml | 143 ++------- .../admin/scheduled-jobs/index(default).phtml | 119 ++----- pages/admin/system-audit/index(default).phtml | 131 ++------ pages/admin/tenants/index(default).phtml | 174 ++--------- .../user-lifecycle-audit/index(default).phtml | 99 ++---- pages/admin/users/index(default).phtml | 295 ++++-------------- pages/page/index(page).phtml | 14 +- pages/search/index(default).phtml | 83 ++--- templates/default.phtml | 4 +- .../partials/app-main-aside-icon-bar.phtml | 15 +- templates/partials/app-main-aside.phtml | 105 ++----- tests/Architecture/AuthzUiContractTest.php | 13 + .../CoreStarterkitContractTest.php | 64 +++- .../Architecture/FilterDrawerContractTest.php | 26 +- tests/Architecture/ListFilterContractTest.php | 18 +- .../RepositoryInterfaceContractTest.php | 132 ++++++++ .../StatusTaxonomyContractTest.php | 8 +- tests/Service/Audit/ApiAuditServiceTest.php | 8 +- .../Scheduler/SchedulerRunServiceTest.php | 8 +- tools/codex-skills/core-guardrails/SKILL.md | 2 +- .../references/boundaries-core.md | 7 + .../references/quality-gates.md | 1 + web/index.php | 6 + web/js/app-init.js | 2 +- web/js/components/_template.js | 28 -- web/js/components/app-filter-overflow.js | 73 ----- web/js/components/app-toggle-toolbar.js | 92 ------ web/js/core/app-page-config.js | 37 +++ web/js/pages/address-book-index.js | 208 ++++++++++++ web/js/pages/admin-api-audit-index.js | 148 +++++++++ web/js/pages/admin-departments-index.js | 121 +++++++ web/js/pages/admin-import-audit-index.js | 103 ++++++ web/js/pages/admin-mail-log-index.js | 102 ++++++ web/js/pages/admin-permissions-index.js | 77 +++++ web/js/pages/admin-roles-index.js | 126 ++++++++ web/js/pages/admin-scheduled-jobs-edit.js | 106 +++++++ web/js/pages/admin-scheduled-jobs-index.js | 96 ++++++ web/js/pages/admin-system-audit-index.js | 108 +++++++ web/js/pages/admin-tenants-index.js | 145 +++++++++ .../pages/admin-user-lifecycle-audit-index.js | 76 +++++ web/js/pages/admin-users-index.js | 199 ++++++++++++ web/js/pages/search-index.js | 69 ++++ 171 files changed, 3518 insertions(+), 2297 deletions(-) create mode 100644 lib/Repository/Access/PermissionRepositoryInterface.php create mode 100644 lib/Repository/Access/RolePermissionRepositoryInterface.php create mode 100644 lib/Repository/Access/RoleRepositoryInterface.php create mode 100644 lib/Repository/Access/UserRoleRepositoryInterface.php create mode 100644 lib/Repository/Audit/ApiAuditLogRepositoryInterface.php create mode 100644 lib/Repository/Audit/ImportAuditRunRepositoryInterface.php create mode 100644 lib/Repository/Audit/SystemAuditLogRepositoryInterface.php create mode 100644 lib/Repository/Audit/UserLifecycleAuditRepositoryInterface.php create mode 100644 lib/Repository/Auth/ApiTokenRepositoryInterface.php create mode 100644 lib/Repository/Auth/EmailVerificationRepositoryInterface.php create mode 100644 lib/Repository/Auth/PasswordResetRepositoryInterface.php create mode 100644 lib/Repository/Auth/RememberTokenRepositoryInterface.php create mode 100644 lib/Repository/Mail/MailLogRepositoryInterface.php create mode 100644 lib/Repository/Org/DepartmentRepositoryInterface.php create mode 100644 lib/Repository/Org/UserDepartmentRepositoryInterface.php create mode 100644 lib/Repository/Scheduler/ScheduledJobRepositoryInterface.php create mode 100644 lib/Repository/Scheduler/ScheduledJobRunRepositoryInterface.php create mode 100644 lib/Repository/Scheduler/SchedulerRuntimeRepositoryInterface.php create mode 100644 lib/Repository/Search/SearchQueryRepositoryInterface.php create mode 100644 lib/Repository/Security/RateLimitRepositoryInterface.php create mode 100644 lib/Repository/Settings/SettingRepositoryInterface.php create mode 100644 lib/Repository/Stats/AdminStatsRepositoryInterface.php create mode 100644 lib/Repository/Support/DatabaseSessionRepositoryInterface.php create mode 100644 lib/Repository/Tenant/TenantMicrosoftAuthRepositoryInterface.php create mode 100644 lib/Repository/Tenant/TenantRepositoryInterface.php create mode 100644 lib/Repository/Tenant/UserTenantRepositoryInterface.php create mode 100644 lib/Repository/User/UserExternalIdentityRepositoryInterface.php create mode 100644 lib/Repository/User/UserListQueryRepositoryInterface.php create mode 100644 lib/Repository/User/UserReadRepositoryInterface.php create mode 100644 lib/Repository/User/UserSavedFilterRepositoryInterface.php create mode 100644 lib/Repository/User/UserWriteRepositoryInterface.php create mode 100644 tests/Architecture/RepositoryInterfaceContractTest.php delete mode 100644 web/js/components/_template.js delete mode 100644 web/js/components/app-filter-overflow.js delete mode 100644 web/js/components/app-toggle-toolbar.js create mode 100644 web/js/core/app-page-config.js create mode 100644 web/js/pages/address-book-index.js create mode 100644 web/js/pages/admin-api-audit-index.js create mode 100644 web/js/pages/admin-departments-index.js create mode 100644 web/js/pages/admin-import-audit-index.js create mode 100644 web/js/pages/admin-mail-log-index.js create mode 100644 web/js/pages/admin-permissions-index.js create mode 100644 web/js/pages/admin-roles-index.js create mode 100644 web/js/pages/admin-scheduled-jobs-edit.js create mode 100644 web/js/pages/admin-scheduled-jobs-index.js create mode 100644 web/js/pages/admin-system-audit-index.js create mode 100644 web/js/pages/admin-tenants-index.js create mode 100644 web/js/pages/admin-user-lifecycle-audit-index.js create mode 100644 web/js/pages/admin-users-index.js create mode 100644 web/js/pages/search-index.js diff --git a/docs/architektur.md b/docs/architektur.md index 0dbf218..6f87a0e 100644 --- a/docs/architektur.md +++ b/docs/architektur.md @@ -1,6 +1,6 @@ # Architektur-Kompass -Letzte Aktualisierung: 2026-02-25 +Letzte Aktualisierung: 2026-03-04 ## Ziel @@ -34,8 +34,10 @@ Verbindliche Kurzregeln für Architekturentscheidungen. - In `pages/admin/**` keine `Factory::class`-Referenzen. - Request-Input in Actions nur über `requestInput()` lesen. - Validierungsfehler über `FormErrors` führen und für APIs mit `ApiResponse::validationFromFormErrors(...)` ausgeben. +- In `pages/api/v1/**` kein direktes JSON-Body-Lesen über `ApiResponse::readJsonBody(...)`. - `Flash` nur für Redirect-/Outcome-Meldungen verwenden, nicht als primäre Validation-Struktur. - Listen-Endpoints in `pages/**/data().php` sind GET-only (`gridRequireGetRequest()`). +- Query-Filter in `data().php` über `gridParseFilters(...)` + `filter-schema.php` normalisieren. - Grid-Query-Parameter (`limit`, `offset`, `order`, `dir`) in `data().php` über `gridQueryLimitOffset()` und `gridQueryOrderDir()` normalisieren. ## Instanziierungsregeln (MUSS) @@ -61,6 +63,13 @@ Verbindliche Kurzregeln für Architekturentscheidungen. - Für einzelne Views setzen Actions explizit `$viewAuth['page']` (bevorzugt über `UiCapabilityMap` + `UiAccessService::pageCapabilities()`). - In `templates/**` keine direkten `can('...')`- oder Permission-Key-Checks. +## Frontend-Page-Module (MUSS) + +- In `pages/**` und `templates/**` sind inline `` ohne `src` verboten. +- Seiteninitialisierung liegt in dedizierten ESM-Page-Modulen unter `web/js/pages/*`. +- Pro Seite wird Konfiguration per `` bereitgestellt und im Modul über `readPageConfig(...)` gelesen. +- In `pages/**` und `templates/**` muessen alle JS-`src` (eigene und Vendor) ueber `assetVersion('...js...')` laufen. + ## Mindestchecks vor Merge ```bash @@ -80,6 +89,7 @@ Struktur-Gates zusätzlich: (rg -n '\bDB::' pages -g '*.php' || true) | wc -l (rg -n 'app\([^\n]*Factory::class\)->create' pages/admin -g '*.php' || true) | wc -l (rg -n 'Factory::class' pages/admin -g '*.php' || true) | wc -l +(rg -n 'ApiResponse::readJsonBody\(' pages/api/v1 -g '*.php' || true) | wc -l ``` Architektur-Contract: diff --git a/docs/entwickler-checkliste.md b/docs/entwickler-checkliste.md index bed1862..65f50ec 100644 --- a/docs/entwickler-checkliste.md +++ b/docs/entwickler-checkliste.md @@ -38,6 +38,9 @@ Kurze Definition of Done vor Merge. - [ ] Aktive Filter-Chips vorhanden (`data-active-filter-chips`) und Remove/Clear funktionieren - [ ] Kein Legacy-Toggle in Listen (`data-toolbar-toggle`, `data-filter-overflow`, `data-filter-toggle`) - [ ] Falls Save-Filter vorhanden: gespeicherter Zustand stammt aus Applied State (`gridConfig.baseUrl()`) +- [ ] Keine inline `` bereitstellen. +- Page-Module lesen Config zentral über `readPageConfig(...)` aus `web/js/core/app-page-config.js`. +- JS-`src` in `pages/**` und `templates/**` nur über `assetVersion('...js...')`. ## Defensive DOM-Nutzung diff --git a/lib/Repository/Access/PermissionRepository.php b/lib/Repository/Access/PermissionRepository.php index 95065d4..1bc8260 100644 --- a/lib/Repository/Access/PermissionRepository.php +++ b/lib/Repository/Access/PermissionRepository.php @@ -5,7 +5,7 @@ namespace MintyPHP\Repository\Access; use MintyPHP\DB; use MintyPHP\Repository\Support\RepoQuery; -class PermissionRepository +class PermissionRepository implements PermissionRepositoryInterface { public function list(): array { diff --git a/lib/Repository/Access/PermissionRepositoryInterface.php b/lib/Repository/Access/PermissionRepositoryInterface.php new file mode 100644 index 0000000..bea74a0 --- /dev/null +++ b/lib/Repository/Access/PermissionRepositoryInterface.php @@ -0,0 +1,22 @@ + 0) : false; } - public function create(array $data) + public function create(array $data): mixed { return DB::insert( 'insert into roles (uuid, description, code, active, created_by, created) values (?,?,?,?,?,NOW())', diff --git a/lib/Repository/Access/RoleRepositoryInterface.php b/lib/Repository/Access/RoleRepositoryInterface.php new file mode 100644 index 0000000..e3d3e38 --- /dev/null +++ b/lib/Repository/Access/RoleRepositoryInterface.php @@ -0,0 +1,30 @@ + $params diff --git a/lib/Repository/Search/SearchQueryRepositoryInterface.php b/lib/Repository/Search/SearchQueryRepositoryInterface.php new file mode 100644 index 0000000..69bf315 --- /dev/null +++ b/lib/Repository/Search/SearchQueryRepositoryInterface.php @@ -0,0 +1,17 @@ + $params + * @return array + */ + public function selectRows(string $sql, array $params = []): array; + + /** + * @param array $params + */ + public function selectCount(string $sql, array $params = []): int; +} diff --git a/lib/Repository/Security/RateLimitRepository.php b/lib/Repository/Security/RateLimitRepository.php index 4497011..f5cabf8 100644 --- a/lib/Repository/Security/RateLimitRepository.php +++ b/lib/Repository/Security/RateLimitRepository.php @@ -4,7 +4,7 @@ namespace MintyPHP\Repository\Security; use MintyPHP\DB; -class RateLimitRepository +class RateLimitRepository implements RateLimitRepositoryInterface { public function findByScopeAndHash(string $scope, string $subjectHash): ?array { diff --git a/lib/Repository/Security/RateLimitRepositoryInterface.php b/lib/Repository/Security/RateLimitRepositoryInterface.php new file mode 100644 index 0000000..2651857 --- /dev/null +++ b/lib/Repository/Security/RateLimitRepositoryInterface.php @@ -0,0 +1,25 @@ + diff --git a/lib/Repository/Stats/AdminStatsRepositoryInterface.php b/lib/Repository/Stats/AdminStatsRepositoryInterface.php new file mode 100644 index 0000000..be858ce --- /dev/null +++ b/lib/Repository/Stats/AdminStatsRepositoryInterface.php @@ -0,0 +1,11 @@ + + */ + public function buildViewData(): array; +} diff --git a/lib/Repository/Support/DatabaseSessionRepository.php b/lib/Repository/Support/DatabaseSessionRepository.php index 06672fb..f0a6b40 100644 --- a/lib/Repository/Support/DatabaseSessionRepository.php +++ b/lib/Repository/Support/DatabaseSessionRepository.php @@ -4,7 +4,7 @@ namespace MintyPHP\Repository\Support; use MintyPHP\DB; -class DatabaseSessionRepository +class DatabaseSessionRepository implements DatabaseSessionRepositoryInterface { public function acquireAdvisoryLock(string $lockName, int $timeoutSeconds = 0): bool { diff --git a/lib/Repository/Support/DatabaseSessionRepositoryInterface.php b/lib/Repository/Support/DatabaseSessionRepositoryInterface.php new file mode 100644 index 0000000..5bca570 --- /dev/null +++ b/lib/Repository/Support/DatabaseSessionRepositoryInterface.php @@ -0,0 +1,16 @@ +unwrap($row); } - public function create(array $data) + public function create(array $data): mixed { return DB::insert( 'insert into tenants (uuid, description, address, postal_code, city, country, region, vat_id, tax_number, phone, fax, email, support_email, support_phone, billing_email, website, privacy_url, imprint_url, primary_color, default_theme, allow_user_theme, status, status_changed_at, status_changed_by, created_by, created) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())', diff --git a/lib/Repository/Tenant/TenantRepositoryInterface.php b/lib/Repository/Tenant/TenantRepositoryInterface.php new file mode 100644 index 0000000..58aa81d --- /dev/null +++ b/lib/Repository/Tenant/TenantRepositoryInterface.php @@ -0,0 +1,26 @@ +unwrap($row); } - public function createLink(array $data) + public function createLink(array $data): mixed { return DB::insert( 'insert into user_external_identities (user_id, provider, oid, tid, issuer, subject, email_at_link_time, created) values (?,?,?,?,?,?,?,NOW())', diff --git a/lib/Repository/User/UserExternalIdentityRepositoryInterface.php b/lib/Repository/User/UserExternalIdentityRepositoryInterface.php new file mode 100644 index 0000000..6a44cbb --- /dev/null +++ b/lib/Repository/User/UserExternalIdentityRepositoryInterface.php @@ -0,0 +1,12 @@ +permissionRepository ??= new PermissionRepository(); } - public function createRolePermissionRepository(): RolePermissionRepository + public function createRolePermissionRepository(): RolePermissionRepositoryInterface { return $this->rolePermissionRepository ??= new RolePermissionRepository(); } - public function createUserRoleRepository(): UserRoleRepository + public function createUserRoleRepository(): UserRoleRepositoryInterface { return $this->userRoleRepository ??= new UserRoleRepository(); } diff --git a/lib/Service/Access/AccessServicesFactory.php b/lib/Service/Access/AccessServicesFactory.php index fe342c8..c1d47c5 100644 --- a/lib/Service/Access/AccessServicesFactory.php +++ b/lib/Service/Access/AccessServicesFactory.php @@ -2,9 +2,9 @@ namespace MintyPHP\Service\Access; -use MintyPHP\Repository\Access\PermissionRepository; -use MintyPHP\Repository\Access\RolePermissionRepository; -use MintyPHP\Repository\Access\UserRoleRepository; +use MintyPHP\Repository\Access\PermissionRepositoryInterface; +use MintyPHP\Repository\Access\RolePermissionRepositoryInterface; +use MintyPHP\Repository\Access\UserRoleRepositoryInterface; class AccessServicesFactory { @@ -19,17 +19,17 @@ class AccessServicesFactory $this->accessPolicyFactoryResolver = \Closure::fromCallable($accessPolicyFactoryResolver); } - public function createPermissionRepository(): PermissionRepository + public function createPermissionRepository(): PermissionRepositoryInterface { return $this->accessRepositoryFactory->createPermissionRepository(); } - public function createRolePermissionRepository(): RolePermissionRepository + public function createRolePermissionRepository(): RolePermissionRepositoryInterface { return $this->accessRepositoryFactory->createRolePermissionRepository(); } - public function createUserRoleRepository(): UserRoleRepository + public function createUserRoleRepository(): UserRoleRepositoryInterface { return $this->accessRepositoryFactory->createUserRoleRepository(); } diff --git a/lib/Service/Access/PermissionService.php b/lib/Service/Access/PermissionService.php index f225eae..a1cbc4b 100644 --- a/lib/Service/Access/PermissionService.php +++ b/lib/Service/Access/PermissionService.php @@ -2,9 +2,9 @@ namespace MintyPHP\Service\Access; -use MintyPHP\Repository\Access\PermissionRepository; -use MintyPHP\Repository\Access\RolePermissionRepository; -use MintyPHP\Repository\Access\UserRoleRepository; +use MintyPHP\Repository\Access\PermissionRepositoryInterface; +use MintyPHP\Repository\Access\RolePermissionRepositoryInterface; +use MintyPHP\Repository\Access\UserRoleRepositoryInterface; use MintyPHP\Service\Audit\SystemAuditService; class PermissionService @@ -12,9 +12,9 @@ class PermissionService private array $apiPermissionCache = []; public function __construct( - private readonly PermissionRepository $permissionRepository, - private readonly RolePermissionRepository $rolePermissionRepository, - private readonly UserRoleRepository $userRoleRepository, + private readonly PermissionRepositoryInterface $permissionRepository, + private readonly RolePermissionRepositoryInterface $rolePermissionRepository, + private readonly UserRoleRepositoryInterface $userRoleRepository, private readonly SystemAuditService $systemAuditService ) { } diff --git a/lib/Service/Access/RoleService.php b/lib/Service/Access/RoleService.php index 4d2ff83..f2a8eee 100644 --- a/lib/Service/Access/RoleService.php +++ b/lib/Service/Access/RoleService.php @@ -2,14 +2,14 @@ namespace MintyPHP\Service\Access; -use MintyPHP\Repository\Access\RoleRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; use MintyPHP\Service\Audit\SystemAuditService; use MintyPHP\Service\Directory\DirectorySettingsGateway; class RoleService { public function __construct( - private readonly RoleRepository $roleRepository, + private readonly RoleRepositoryInterface $roleRepository, private readonly DirectorySettingsGateway $settingsGateway, private readonly SystemAuditService $systemAuditService ) { diff --git a/lib/Service/Audit/ApiAuditService.php b/lib/Service/Audit/ApiAuditService.php index 4ce9835..dd679e4 100644 --- a/lib/Service/Audit/ApiAuditService.php +++ b/lib/Service/Audit/ApiAuditService.php @@ -4,7 +4,7 @@ namespace MintyPHP\Service\Audit; use MintyPHP\Http\ApiAuth; use MintyPHP\Http\RequestContext; -use MintyPHP\Repository\Audit\ApiAuditLogRepository; +use MintyPHP\Repository\Audit\ApiAuditLogRepositoryInterface; class ApiAuditService { @@ -15,7 +15,7 @@ class ApiAuditService private ?array $context = null; - public function __construct(private readonly ApiAuditLogRepository $apiAuditLogRepository) + public function __construct(private readonly ApiAuditLogRepositoryInterface $apiAuditLogRepository) { } diff --git a/lib/Service/Audit/AuditRepositoryFactory.php b/lib/Service/Audit/AuditRepositoryFactory.php index add3daa..d6a4729 100644 --- a/lib/Service/Audit/AuditRepositoryFactory.php +++ b/lib/Service/Audit/AuditRepositoryFactory.php @@ -3,8 +3,11 @@ namespace MintyPHP\Service\Audit; use MintyPHP\Repository\Audit\ApiAuditLogRepository; +use MintyPHP\Repository\Audit\ApiAuditLogRepositoryInterface; use MintyPHP\Repository\Audit\SystemAuditLogRepository; +use MintyPHP\Repository\Audit\SystemAuditLogRepositoryInterface; use MintyPHP\Repository\Audit\UserLifecycleAuditRepository; +use MintyPHP\Repository\Audit\UserLifecycleAuditRepositoryInterface; class AuditRepositoryFactory { @@ -12,17 +15,17 @@ class AuditRepositoryFactory private ?UserLifecycleAuditRepository $userLifecycleAuditRepository = null; private ?SystemAuditLogRepository $systemAuditLogRepository = null; - public function createApiAuditLogRepository(): ApiAuditLogRepository + public function createApiAuditLogRepository(): ApiAuditLogRepositoryInterface { return $this->apiAuditLogRepository ??= new ApiAuditLogRepository(); } - public function createUserLifecycleAuditRepository(): UserLifecycleAuditRepository + public function createUserLifecycleAuditRepository(): UserLifecycleAuditRepositoryInterface { return $this->userLifecycleAuditRepository ??= new UserLifecycleAuditRepository(); } - public function createSystemAuditLogRepository(): SystemAuditLogRepository + public function createSystemAuditLogRepository(): SystemAuditLogRepositoryInterface { return $this->systemAuditLogRepository ??= new SystemAuditLogRepository(); } diff --git a/lib/Service/Audit/AuditServicesFactory.php b/lib/Service/Audit/AuditServicesFactory.php index b06264d..8242257 100644 --- a/lib/Service/Audit/AuditServicesFactory.php +++ b/lib/Service/Audit/AuditServicesFactory.php @@ -2,9 +2,9 @@ namespace MintyPHP\Service\Audit; -use MintyPHP\Repository\Audit\ApiAuditLogRepository; -use MintyPHP\Repository\Audit\SystemAuditLogRepository; -use MintyPHP\Repository\Audit\UserLifecycleAuditRepository; +use MintyPHP\Repository\Audit\ApiAuditLogRepositoryInterface; +use MintyPHP\Repository\Audit\SystemAuditLogRepositoryInterface; +use MintyPHP\Repository\Audit\UserLifecycleAuditRepositoryInterface; use MintyPHP\Service\Settings\SettingGateway; class AuditServicesFactory @@ -19,17 +19,17 @@ class AuditServicesFactory private readonly SettingGateway $settingGateway ) {} - public function createApiAuditLogRepository(): ApiAuditLogRepository + public function createApiAuditLogRepository(): ApiAuditLogRepositoryInterface { return $this->auditRepositoryFactory->createApiAuditLogRepository(); } - public function createUserLifecycleAuditRepository(): UserLifecycleAuditRepository + public function createUserLifecycleAuditRepository(): UserLifecycleAuditRepositoryInterface { return $this->auditRepositoryFactory->createUserLifecycleAuditRepository(); } - public function createSystemAuditLogRepository(): SystemAuditLogRepository + public function createSystemAuditLogRepository(): SystemAuditLogRepositoryInterface { return $this->auditRepositoryFactory->createSystemAuditLogRepository(); } diff --git a/lib/Service/Audit/ImportAuditService.php b/lib/Service/Audit/ImportAuditService.php index 136972f..6c7abfa 100644 --- a/lib/Service/Audit/ImportAuditService.php +++ b/lib/Service/Audit/ImportAuditService.php @@ -3,7 +3,7 @@ namespace MintyPHP\Service\Audit; use MintyPHP\Domain\Taxonomy\ImportAuditStatus; -use MintyPHP\Repository\Audit\ImportAuditRunRepository; +use MintyPHP\Repository\Audit\ImportAuditRunRepositoryInterface; use MintyPHP\Repository\Support\RepoQuery; class ImportAuditService @@ -15,7 +15,7 @@ class ImportAuditService */ private array $startedAtByRunId = []; - public function __construct(private readonly ImportAuditRunRepository $importAuditRunRepository) + public function __construct(private readonly ImportAuditRunRepositoryInterface $importAuditRunRepository) { } diff --git a/lib/Service/Audit/SystemAuditService.php b/lib/Service/Audit/SystemAuditService.php index 0d3447f..0bbd7f6 100644 --- a/lib/Service/Audit/SystemAuditService.php +++ b/lib/Service/Audit/SystemAuditService.php @@ -6,7 +6,7 @@ use MintyPHP\Domain\Taxonomy\SystemAuditChannel; use MintyPHP\Domain\Taxonomy\SystemAuditOutcome; use MintyPHP\Http\RequestContext; use MintyPHP\Http\ApiAuth; -use MintyPHP\Repository\Audit\SystemAuditLogRepository; +use MintyPHP\Repository\Audit\SystemAuditLogRepositoryInterface; use MintyPHP\Repository\Support\RepoQuery; use MintyPHP\Service\Settings\SettingGateway; @@ -17,7 +17,7 @@ class SystemAuditService private const RETENTION_DAYS_FALLBACK = 365; public function __construct( - private readonly SystemAuditLogRepository $systemAuditLogRepository, + private readonly SystemAuditLogRepositoryInterface $systemAuditLogRepository, private readonly SystemAuditRedactionService $systemAuditRedactionService, private readonly SettingGateway $settingGateway ) { diff --git a/lib/Service/Audit/UserLifecycleAuditService.php b/lib/Service/Audit/UserLifecycleAuditService.php index a20fd80..9eac8fa 100644 --- a/lib/Service/Audit/UserLifecycleAuditService.php +++ b/lib/Service/Audit/UserLifecycleAuditService.php @@ -5,7 +5,7 @@ namespace MintyPHP\Service\Audit; use MintyPHP\Domain\Taxonomy\UserLifecycleAction; use MintyPHP\Domain\Taxonomy\UserLifecycleStatus; use MintyPHP\Domain\Taxonomy\UserLifecycleTriggerType; -use MintyPHP\Repository\Audit\UserLifecycleAuditRepository; +use MintyPHP\Repository\Audit\UserLifecycleAuditRepositoryInterface; use MintyPHP\Support\Crypto; class UserLifecycleAuditService @@ -42,7 +42,7 @@ class UserLifecycleAuditService 'active_changed_at', ]; - public function __construct(private readonly UserLifecycleAuditRepository $userLifecycleAuditRepository) + public function __construct(private readonly UserLifecycleAuditRepositoryInterface $userLifecycleAuditRepository) { } diff --git a/lib/Service/Auth/ApiTokenService.php b/lib/Service/Auth/ApiTokenService.php index 41b0665..0400650 100644 --- a/lib/Service/Auth/ApiTokenService.php +++ b/lib/Service/Auth/ApiTokenService.php @@ -2,17 +2,17 @@ namespace MintyPHP\Service\Auth; -use MintyPHP\Repository\Auth\ApiTokenRepository; +use MintyPHP\Repository\Auth\ApiTokenRepositoryInterface; use MintyPHP\Repository\Support\DatabaseSessionRepository; -use MintyPHP\Repository\User\UserReadRepository; +use MintyPHP\Repository\User\UserReadRepositoryInterface; class ApiTokenService { private const MAX_TOKENS_PER_USER = 10; public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly ApiTokenRepository $apiTokenRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly ApiTokenRepositoryInterface $apiTokenRepository, private readonly AuthSettingsGateway $settingsGateway, private readonly AuthScopeGateway $scopeGateway, private readonly DatabaseSessionRepository $databaseSessionRepository diff --git a/lib/Service/Auth/AuthExternalIdentityGateway.php b/lib/Service/Auth/AuthExternalIdentityGateway.php index c6e76f6..d1bec00 100644 --- a/lib/Service/Auth/AuthExternalIdentityGateway.php +++ b/lib/Service/Auth/AuthExternalIdentityGateway.php @@ -2,11 +2,11 @@ namespace MintyPHP\Service\Auth; -use MintyPHP\Repository\User\UserExternalIdentityRepository; +use MintyPHP\Repository\User\UserExternalIdentityRepositoryInterface; class AuthExternalIdentityGateway { - public function __construct(private readonly UserExternalIdentityRepository $userExternalIdentityRepository) + public function __construct(private readonly UserExternalIdentityRepositoryInterface $userExternalIdentityRepository) { } diff --git a/lib/Service/Auth/AuthRepositoryFactory.php b/lib/Service/Auth/AuthRepositoryFactory.php index d54d3fa..0a43a9e 100644 --- a/lib/Service/Auth/AuthRepositoryFactory.php +++ b/lib/Service/Auth/AuthRepositoryFactory.php @@ -3,12 +3,19 @@ namespace MintyPHP\Service\Auth; use MintyPHP\Repository\Auth\ApiTokenRepository; +use MintyPHP\Repository\Auth\ApiTokenRepositoryInterface; use MintyPHP\Repository\Auth\EmailVerificationRepository; +use MintyPHP\Repository\Auth\EmailVerificationRepositoryInterface; use MintyPHP\Repository\Auth\PasswordResetRepository; +use MintyPHP\Repository\Auth\PasswordResetRepositoryInterface; use MintyPHP\Repository\Auth\RememberTokenRepository; +use MintyPHP\Repository\Auth\RememberTokenRepositoryInterface; use MintyPHP\Repository\Tenant\TenantMicrosoftAuthRepository; +use MintyPHP\Repository\Tenant\TenantMicrosoftAuthRepositoryInterface; use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; use MintyPHP\Repository\User\UserExternalIdentityRepository; +use MintyPHP\Repository\User\UserExternalIdentityRepositoryInterface; class AuthRepositoryFactory { @@ -20,37 +27,37 @@ class AuthRepositoryFactory private ?TenantMicrosoftAuthRepository $tenantMicrosoftAuthRepository = null; private ?UserExternalIdentityRepository $userExternalIdentityRepository = null; - public function createApiTokenRepository(): ApiTokenRepository + public function createApiTokenRepository(): ApiTokenRepositoryInterface { return $this->apiTokenRepository ??= new ApiTokenRepository(); } - public function createRememberTokenRepository(): RememberTokenRepository + public function createRememberTokenRepository(): RememberTokenRepositoryInterface { return $this->rememberTokenRepository ??= new RememberTokenRepository(); } - public function createPasswordResetRepository(): PasswordResetRepository + public function createPasswordResetRepository(): PasswordResetRepositoryInterface { return $this->passwordResetRepository ??= new PasswordResetRepository(); } - public function createEmailVerificationRepository(): EmailVerificationRepository + public function createEmailVerificationRepository(): EmailVerificationRepositoryInterface { return $this->emailVerificationRepository ??= new EmailVerificationRepository(); } - public function createTenantRepository(): TenantRepository + public function createTenantRepository(): TenantRepositoryInterface { return $this->tenantRepository ??= new TenantRepository(); } - public function createTenantMicrosoftAuthRepository(): TenantMicrosoftAuthRepository + public function createTenantMicrosoftAuthRepository(): TenantMicrosoftAuthRepositoryInterface { return $this->tenantMicrosoftAuthRepository ??= new TenantMicrosoftAuthRepository(); } - public function createUserExternalIdentityRepository(): UserExternalIdentityRepository + public function createUserExternalIdentityRepository(): UserExternalIdentityRepositoryInterface { return $this->userExternalIdentityRepository ??= new UserExternalIdentityRepository(); } diff --git a/lib/Service/Auth/AuthService.php b/lib/Service/Auth/AuthService.php index 5a756fc..0495319 100644 --- a/lib/Service/Auth/AuthService.php +++ b/lib/Service/Auth/AuthService.php @@ -3,8 +3,8 @@ namespace MintyPHP\Service\Auth; use MintyPHP\Auth; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Router; use MintyPHP\Service\User\UserAccountService; use MintyPHP\Service\User\UserTenantContextService; @@ -15,8 +15,8 @@ use MintyPHP\Support\Flash; class AuthService { public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, private readonly UserAccountService $userAccountService, private readonly UserTenantContextService $userTenantContextService, private readonly RememberMeService $rememberMeService, diff --git a/lib/Service/Auth/AuthTenantGateway.php b/lib/Service/Auth/AuthTenantGateway.php index 15501f7..a047835 100644 --- a/lib/Service/Auth/AuthTenantGateway.php +++ b/lib/Service/Auth/AuthTenantGateway.php @@ -2,11 +2,11 @@ namespace MintyPHP\Service\Auth; -use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; class AuthTenantGateway { - public function __construct(private readonly TenantRepository $tenantRepository) + public function __construct(private readonly TenantRepositoryInterface $tenantRepository) { } diff --git a/lib/Service/Auth/EmailVerificationService.php b/lib/Service/Auth/EmailVerificationService.php index 447b9de..8fe319f 100644 --- a/lib/Service/Auth/EmailVerificationService.php +++ b/lib/Service/Auth/EmailVerificationService.php @@ -4,9 +4,9 @@ namespace MintyPHP\Service\Auth; use MintyPHP\Http\Request; use MintyPHP\I18n; -use MintyPHP\Repository\Auth\EmailVerificationRepository; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\Auth\EmailVerificationRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Service\Mail\MailService; class EmailVerificationService @@ -16,9 +16,9 @@ class EmailVerificationService private const MAX_ATTEMPTS = 5; public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, - private readonly EmailVerificationRepository $emailVerificationRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, + private readonly EmailVerificationRepositoryInterface $emailVerificationRepository, private readonly MailService $mailService ) { } diff --git a/lib/Service/Auth/PasswordResetService.php b/lib/Service/Auth/PasswordResetService.php index c115fa9..9210454 100644 --- a/lib/Service/Auth/PasswordResetService.php +++ b/lib/Service/Auth/PasswordResetService.php @@ -4,8 +4,8 @@ namespace MintyPHP\Service\Auth; use MintyPHP\Http\Request; use MintyPHP\I18n; -use MintyPHP\Repository\Auth\PasswordResetRepository; -use MintyPHP\Repository\User\UserReadRepository; +use MintyPHP\Repository\Auth\PasswordResetRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; use MintyPHP\Service\Mail\MailService; use MintyPHP\Service\User\UserPasswordService; @@ -16,8 +16,8 @@ class PasswordResetService private const MAX_ATTEMPTS = 5; public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly PasswordResetRepository $passwordResetRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly PasswordResetRepositoryInterface $passwordResetRepository, private readonly UserPasswordService $userPasswordService, private readonly RememberMeService $rememberMeService, private readonly MailService $mailService diff --git a/lib/Service/Auth/RememberMeService.php b/lib/Service/Auth/RememberMeService.php index 5bad78a..171e5ae 100644 --- a/lib/Service/Auth/RememberMeService.php +++ b/lib/Service/Auth/RememberMeService.php @@ -4,9 +4,9 @@ namespace MintyPHP\Service\Auth; use MintyPHP\Auth; use MintyPHP\I18n; -use MintyPHP\Repository\Auth\RememberTokenRepository; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\Auth\RememberTokenRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Service\User\UserTenantContextService; use MintyPHP\Session; @@ -16,9 +16,9 @@ class RememberMeService private const LIFETIME_DAYS = 30; public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, - private readonly RememberTokenRepository $rememberTokenRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, + private readonly RememberTokenRepositoryInterface $rememberTokenRepository, private readonly UserTenantContextService $userTenantContextService, private readonly AuthPermissionGateway $permissionGateway, private readonly AuthSavedFilterGateway $savedFilterGateway diff --git a/lib/Service/Auth/SsoUserLinkService.php b/lib/Service/Auth/SsoUserLinkService.php index 5407c62..81be22b 100644 --- a/lib/Service/Auth/SsoUserLinkService.php +++ b/lib/Service/Auth/SsoUserLinkService.php @@ -2,19 +2,19 @@ namespace MintyPHP\Service\Auth; -use MintyPHP\Repository\Tenant\UserTenantRepository; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Service\User\UserAssignmentService; use MintyPHP\Service\User\UserAvatarService; class SsoUserLinkService { public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, private readonly UserAssignmentService $userAssignmentService, - private readonly UserTenantRepository $userTenantRepository, + private readonly UserTenantRepositoryInterface $userTenantRepository, private readonly AuthSettingsGateway $settingsGateway, private readonly AuthTenantSsoGateway $tenantSsoGateway, private readonly AuthAvatarGateway $avatarGateway, diff --git a/lib/Service/Auth/TenantSsoService.php b/lib/Service/Auth/TenantSsoService.php index 0977037..8851841 100644 --- a/lib/Service/Auth/TenantSsoService.php +++ b/lib/Service/Auth/TenantSsoService.php @@ -2,7 +2,7 @@ namespace MintyPHP\Service\Auth; -use MintyPHP\Repository\Tenant\TenantMicrosoftAuthRepository; +use MintyPHP\Repository\Tenant\TenantMicrosoftAuthRepositoryInterface; class TenantSsoService { @@ -20,7 +20,7 @@ class TenantSsoService public function __construct( private readonly AuthTenantGateway $tenantGateway, - private readonly TenantMicrosoftAuthRepository $tenantMicrosoftAuthRepository, + private readonly TenantMicrosoftAuthRepositoryInterface $tenantMicrosoftAuthRepository, private readonly AuthSettingsGateway $settingsGateway, private readonly AuthCryptoGateway $cryptoGateway ) { diff --git a/lib/Service/Directory/DirectoryRepositoryFactory.php b/lib/Service/Directory/DirectoryRepositoryFactory.php index c6eeb21..74cfce2 100644 --- a/lib/Service/Directory/DirectoryRepositoryFactory.php +++ b/lib/Service/Directory/DirectoryRepositoryFactory.php @@ -3,8 +3,11 @@ namespace MintyPHP\Service\Directory; use MintyPHP\Repository\Access\RoleRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; use MintyPHP\Repository\Org\DepartmentRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; class DirectoryRepositoryFactory { @@ -12,17 +15,17 @@ class DirectoryRepositoryFactory private ?DepartmentRepository $departmentRepository = null; private ?RoleRepository $roleRepository = null; - public function createTenantRepository(): TenantRepository + public function createTenantRepository(): TenantRepositoryInterface { return $this->tenantRepository ??= new TenantRepository(); } - public function createDepartmentRepository(): DepartmentRepository + public function createDepartmentRepository(): DepartmentRepositoryInterface { return $this->departmentRepository ??= new DepartmentRepository(); } - public function createRoleRepository(): RoleRepository + public function createRoleRepository(): RoleRepositoryInterface { return $this->roleRepository ??= new RoleRepository(); } diff --git a/lib/Service/Directory/DirectoryServicesFactory.php b/lib/Service/Directory/DirectoryServicesFactory.php index 4a7f7f4..94b16d8 100644 --- a/lib/Service/Directory/DirectoryServicesFactory.php +++ b/lib/Service/Directory/DirectoryServicesFactory.php @@ -2,9 +2,9 @@ namespace MintyPHP\Service\Directory; -use MintyPHP\Repository\Access\RoleRepository; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; use MintyPHP\Service\Access\RoleService; use MintyPHP\Service\Audit\AuditServicesFactory; use MintyPHP\Service\Org\DepartmentService; @@ -54,17 +54,17 @@ class DirectoryServicesFactory ); } - public function createTenantRepository(): TenantRepository + public function createTenantRepository(): TenantRepositoryInterface { return $this->directoryRepositoryFactory->createTenantRepository(); } - public function createDepartmentRepository(): DepartmentRepository + public function createDepartmentRepository(): DepartmentRepositoryInterface { return $this->directoryRepositoryFactory->createDepartmentRepository(); } - public function createRoleRepository(): RoleRepository + public function createRoleRepository(): RoleRepositoryInterface { return $this->directoryRepositoryFactory->createRoleRepository(); } diff --git a/lib/Service/Import/ImportRepositoryFactory.php b/lib/Service/Import/ImportRepositoryFactory.php index 239a5cb..985edae 100644 --- a/lib/Service/Import/ImportRepositoryFactory.php +++ b/lib/Service/Import/ImportRepositoryFactory.php @@ -3,12 +3,13 @@ namespace MintyPHP\Service\Import; use MintyPHP\Repository\Audit\ImportAuditRunRepository; +use MintyPHP\Repository\Audit\ImportAuditRunRepositoryInterface; class ImportRepositoryFactory { private ?ImportAuditRunRepository $importAuditRunRepository = null; - public function createImportAuditRunRepository(): ImportAuditRunRepository + public function createImportAuditRunRepository(): ImportAuditRunRepositoryInterface { return $this->importAuditRunRepository ??= new ImportAuditRunRepository(); } diff --git a/lib/Service/Import/ImportServicesFactory.php b/lib/Service/Import/ImportServicesFactory.php index a25b395..190fe40 100644 --- a/lib/Service/Import/ImportServicesFactory.php +++ b/lib/Service/Import/ImportServicesFactory.php @@ -2,7 +2,7 @@ namespace MintyPHP\Service\Import; -use MintyPHP\Repository\Audit\ImportAuditRunRepository; +use MintyPHP\Repository\Audit\ImportAuditRunRepositoryInterface; use MintyPHP\Service\Access\AccessServicesFactory; use MintyPHP\Service\Access\PermissionGateway; use MintyPHP\Service\Audit\ImportAuditService; @@ -86,7 +86,7 @@ class ImportServicesFactory return $this->importTempFileService ??= new ImportTempFileService(); } - private function getImportAuditRunRepository(): ImportAuditRunRepository + private function getImportAuditRunRepository(): ImportAuditRunRepositoryInterface { return $this->importRepositoryFactory->createImportAuditRunRepository(); } diff --git a/lib/Service/Import/Profile/DepartmentImportGateway.php b/lib/Service/Import/Profile/DepartmentImportGateway.php index 2a0daa7..5433259 100644 --- a/lib/Service/Import/Profile/DepartmentImportGateway.php +++ b/lib/Service/Import/Profile/DepartmentImportGateway.php @@ -2,15 +2,15 @@ namespace MintyPHP\Service\Import\Profile; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; use MintyPHP\Service\Org\DepartmentService; class DepartmentImportGateway { public function __construct( - private readonly DepartmentRepository $departmentRepository, - private readonly TenantRepository $tenantRepository, + private readonly DepartmentRepositoryInterface $departmentRepository, + private readonly TenantRepositoryInterface $tenantRepository, private readonly DepartmentService $departmentService ) { } @@ -44,12 +44,12 @@ class DepartmentImportGateway return $this->departmentService()->createFromAdmin($input, $currentUserId); } - private function departmentRepository(): DepartmentRepository + private function departmentRepository(): DepartmentRepositoryInterface { return $this->departmentRepository; } - private function tenantRepository(): TenantRepository + private function tenantRepository(): TenantRepositoryInterface { return $this->tenantRepository; } diff --git a/lib/Service/Import/Profile/UserImportGateway.php b/lib/Service/Import/Profile/UserImportGateway.php index d82ec44..422f843 100644 --- a/lib/Service/Import/Profile/UserImportGateway.php +++ b/lib/Service/Import/Profile/UserImportGateway.php @@ -2,17 +2,17 @@ namespace MintyPHP\Service\Import\Profile; -use MintyPHP\Repository\Access\RoleRepository; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Tenant\TenantRepository; -use MintyPHP\Repository\User\UserReadRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; use MintyPHP\Service\User\UserAccountService; use MintyPHP\Service\User\UserRepositoryFactory; class UserImportGateway { public function __construct( - private readonly UserReadRepository $userReadRepository, + private readonly UserReadRepositoryInterface $userReadRepository, private readonly UserAccountService $userAccountService, private readonly UserRepositoryFactory $userRepositoryFactory ) { @@ -62,17 +62,17 @@ class UserImportGateway return $this->userAccountService->createFromAdmin($input, $currentUserId); } - private function tenantRepository(): TenantRepository + private function tenantRepository(): TenantRepositoryInterface { return $this->userRepositoryFactory->createTenantRepository(); } - private function roleRepository(): RoleRepository + private function roleRepository(): RoleRepositoryInterface { return $this->userRepositoryFactory->createRoleRepository(); } - private function departmentRepository(): DepartmentRepository + private function departmentRepository(): DepartmentRepositoryInterface { return $this->userRepositoryFactory->createDepartmentRepository(); } diff --git a/lib/Service/Mail/MailLogService.php b/lib/Service/Mail/MailLogService.php index 29b487c..a09121d 100644 --- a/lib/Service/Mail/MailLogService.php +++ b/lib/Service/Mail/MailLogService.php @@ -2,11 +2,11 @@ namespace MintyPHP\Service\Mail; -use MintyPHP\Repository\Mail\MailLogRepository; +use MintyPHP\Repository\Mail\MailLogRepositoryInterface; class MailLogService { - public function __construct(private readonly MailLogRepository $mailLogRepository) + public function __construct(private readonly MailLogRepositoryInterface $mailLogRepository) { } diff --git a/lib/Service/Mail/MailRepositoryFactory.php b/lib/Service/Mail/MailRepositoryFactory.php index 0b012ee..5340687 100644 --- a/lib/Service/Mail/MailRepositoryFactory.php +++ b/lib/Service/Mail/MailRepositoryFactory.php @@ -3,12 +3,13 @@ namespace MintyPHP\Service\Mail; use MintyPHP\Repository\Mail\MailLogRepository; +use MintyPHP\Repository\Mail\MailLogRepositoryInterface; class MailRepositoryFactory { private ?MailLogRepository $mailLogRepository = null; - public function createMailLogRepository(): MailLogRepository + public function createMailLogRepository(): MailLogRepositoryInterface { return $this->mailLogRepository ??= new MailLogRepository(); } diff --git a/lib/Service/Mail/MailService.php b/lib/Service/Mail/MailService.php index 61e05bb..9434068 100644 --- a/lib/Service/Mail/MailService.php +++ b/lib/Service/Mail/MailService.php @@ -4,7 +4,7 @@ namespace MintyPHP\Service\Mail; use MintyPHP\Domain\Taxonomy\MailLogStatus; use MintyPHP\I18n; -use MintyPHP\Repository\Mail\MailLogRepository; +use MintyPHP\Repository\Mail\MailLogRepositoryInterface; use MintyPHP\Service\Settings\SettingGateway; use PHPMailer\PHPMailer\Exception as MailerException; use PHPMailer\PHPMailer\PHPMailer; @@ -12,7 +12,7 @@ use PHPMailer\PHPMailer\PHPMailer; class MailService { public function __construct( - private readonly MailLogRepository $mailLogRepository, + private readonly MailLogRepositoryInterface $mailLogRepository, private readonly SettingGateway $settingGateway ) { } diff --git a/lib/Service/Mail/MailServicesFactory.php b/lib/Service/Mail/MailServicesFactory.php index eef0a4b..6f96b70 100644 --- a/lib/Service/Mail/MailServicesFactory.php +++ b/lib/Service/Mail/MailServicesFactory.php @@ -2,7 +2,7 @@ namespace MintyPHP\Service\Mail; -use MintyPHP\Repository\Mail\MailLogRepository; +use MintyPHP\Repository\Mail\MailLogRepositoryInterface; use MintyPHP\Service\Settings\SettingGateway; class MailServicesFactory @@ -15,7 +15,7 @@ class MailServicesFactory private readonly SettingGateway $settingGateway ) {} - public function createMailLogRepository(): MailLogRepository + public function createMailLogRepository(): MailLogRepositoryInterface { return $this->mailRepositoryFactory->createMailLogRepository(); } diff --git a/lib/Service/Org/DepartmentService.php b/lib/Service/Org/DepartmentService.php index fbb897f..3202a27 100644 --- a/lib/Service/Org/DepartmentService.php +++ b/lib/Service/Org/DepartmentService.php @@ -2,7 +2,7 @@ namespace MintyPHP\Service\Org; -use MintyPHP\Repository\Org\DepartmentRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; use MintyPHP\Service\Audit\SystemAuditService; use MintyPHP\Service\Directory\DirectoryScopeGateway; use MintyPHP\Service\Directory\DirectorySettingsGateway; @@ -12,7 +12,7 @@ class DepartmentService { public function __construct( private readonly UserServicesFactory $userServicesFactory, - private readonly DepartmentRepository $departmentRepository, + private readonly DepartmentRepositoryInterface $departmentRepository, private readonly DirectorySettingsGateway $settingsGateway, private readonly DirectoryScopeGateway $scopeGateway, private readonly SystemAuditService $systemAuditService diff --git a/lib/Service/Scheduler/ScheduledJobService.php b/lib/Service/Scheduler/ScheduledJobService.php index 95a46d7..d0ac3bf 100644 --- a/lib/Service/Scheduler/ScheduledJobService.php +++ b/lib/Service/Scheduler/ScheduledJobService.php @@ -2,16 +2,16 @@ namespace MintyPHP\Service\Scheduler; -use MintyPHP\Repository\Scheduler\ScheduledJobRepository; -use MintyPHP\Repository\Scheduler\ScheduledJobRunRepository; +use MintyPHP\Repository\Scheduler\ScheduledJobRepositoryInterface; +use MintyPHP\Repository\Scheduler\ScheduledJobRunRepositoryInterface; class ScheduledJobService { private const RUN_RETENTION_DAYS = 90; public function __construct( - private readonly ScheduledJobRepository $scheduledJobRepository, - private readonly ScheduledJobRunRepository $scheduledJobRunRepository, + private readonly ScheduledJobRepositoryInterface $scheduledJobRepository, + private readonly ScheduledJobRunRepositoryInterface $scheduledJobRunRepository, private readonly ScheduledJobRegistry $scheduledJobRegistry, private readonly ScheduleCalculator $scheduleCalculator ) { diff --git a/lib/Service/Scheduler/SchedulerRepositoryFactory.php b/lib/Service/Scheduler/SchedulerRepositoryFactory.php index c09eb81..805fec6 100644 --- a/lib/Service/Scheduler/SchedulerRepositoryFactory.php +++ b/lib/Service/Scheduler/SchedulerRepositoryFactory.php @@ -3,8 +3,11 @@ namespace MintyPHP\Service\Scheduler; use MintyPHP\Repository\Scheduler\ScheduledJobRepository; +use MintyPHP\Repository\Scheduler\ScheduledJobRepositoryInterface; use MintyPHP\Repository\Scheduler\ScheduledJobRunRepository; +use MintyPHP\Repository\Scheduler\ScheduledJobRunRepositoryInterface; use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepository; +use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepositoryInterface; class SchedulerRepositoryFactory { @@ -12,17 +15,17 @@ class SchedulerRepositoryFactory private ?ScheduledJobRunRepository $scheduledJobRunRepository = null; private ?SchedulerRuntimeRepository $schedulerRuntimeRepository = null; - public function createScheduledJobRepository(): ScheduledJobRepository + public function createScheduledJobRepository(): ScheduledJobRepositoryInterface { return $this->scheduledJobRepository ??= new ScheduledJobRepository(); } - public function createScheduledJobRunRepository(): ScheduledJobRunRepository + public function createScheduledJobRunRepository(): ScheduledJobRunRepositoryInterface { return $this->scheduledJobRunRepository ??= new ScheduledJobRunRepository(); } - public function createSchedulerRuntimeRepository(): SchedulerRuntimeRepository + public function createSchedulerRuntimeRepository(): SchedulerRuntimeRepositoryInterface { return $this->schedulerRuntimeRepository ??= new SchedulerRuntimeRepository(); } diff --git a/lib/Service/Scheduler/SchedulerRunService.php b/lib/Service/Scheduler/SchedulerRunService.php index be5ad27..38d1202 100644 --- a/lib/Service/Scheduler/SchedulerRunService.php +++ b/lib/Service/Scheduler/SchedulerRunService.php @@ -6,9 +6,9 @@ use MintyPHP\Domain\Taxonomy\ScheduledJobRunStatus; use MintyPHP\Domain\Taxonomy\ScheduledJobTriggerType; use MintyPHP\Domain\Taxonomy\SchedulerRuntimeResult; use MintyPHP\Domain\Taxonomy\SystemAuditOutcome; -use MintyPHP\Repository\Scheduler\ScheduledJobRepository; -use MintyPHP\Repository\Scheduler\ScheduledJobRunRepository; -use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepository; +use MintyPHP\Repository\Scheduler\ScheduledJobRepositoryInterface; +use MintyPHP\Repository\Scheduler\ScheduledJobRunRepositoryInterface; +use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepositoryInterface; use MintyPHP\Repository\Support\DatabaseSessionRepository; use MintyPHP\Repository\Support\RepoQuery; use MintyPHP\Service\Audit\SystemAuditService; @@ -27,9 +27,9 @@ class SchedulerRunService public function __construct( private readonly ScheduledJobService $scheduledJobService, - private readonly ScheduledJobRepository $scheduledJobRepository, - private readonly ScheduledJobRunRepository $scheduledJobRunRepository, - private readonly SchedulerRuntimeRepository $schedulerRuntimeRepository, + private readonly ScheduledJobRepositoryInterface $scheduledJobRepository, + private readonly ScheduledJobRunRepositoryInterface $scheduledJobRunRepository, + private readonly SchedulerRuntimeRepositoryInterface $schedulerRuntimeRepository, private readonly ScheduledJobRegistry $scheduledJobRegistry, private readonly ScheduleCalculator $scheduleCalculator, private readonly DatabaseSessionRepository $databaseSessionRepository, diff --git a/lib/Service/Scheduler/SchedulerServicesFactory.php b/lib/Service/Scheduler/SchedulerServicesFactory.php index 288272b..93ddca2 100644 --- a/lib/Service/Scheduler/SchedulerServicesFactory.php +++ b/lib/Service/Scheduler/SchedulerServicesFactory.php @@ -2,9 +2,9 @@ namespace MintyPHP\Service\Scheduler; -use MintyPHP\Repository\Scheduler\ScheduledJobRepository; -use MintyPHP\Repository\Scheduler\ScheduledJobRunRepository; -use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepository; +use MintyPHP\Repository\Scheduler\ScheduledJobRepositoryInterface; +use MintyPHP\Repository\Scheduler\ScheduledJobRunRepositoryInterface; +use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepositoryInterface; use MintyPHP\Repository\Support\DatabaseSessionRepository; use MintyPHP\Service\Audit\AuditServicesFactory; use MintyPHP\Service\Audit\SystemAuditService; @@ -54,17 +54,17 @@ class SchedulerServicesFactory return $this->getUserLifecycleService(); } - private function getScheduledJobRepository(): ScheduledJobRepository + private function getScheduledJobRepository(): ScheduledJobRepositoryInterface { return $this->schedulerRepositoryFactory->createScheduledJobRepository(); } - private function getScheduledJobRunRepository(): ScheduledJobRunRepository + private function getScheduledJobRunRepository(): ScheduledJobRunRepositoryInterface { return $this->schedulerRepositoryFactory->createScheduledJobRunRepository(); } - private function getSchedulerRuntimeRepository(): SchedulerRuntimeRepository + private function getSchedulerRuntimeRepository(): SchedulerRuntimeRepositoryInterface { return $this->schedulerRepositoryFactory->createSchedulerRuntimeRepository(); } diff --git a/lib/Service/Security/RateLimiterService.php b/lib/Service/Security/RateLimiterService.php index 0622092..d7e4e62 100644 --- a/lib/Service/Security/RateLimiterService.php +++ b/lib/Service/Security/RateLimiterService.php @@ -4,13 +4,13 @@ namespace MintyPHP\Service\Security; use DateTimeImmutable; use DateTimeZone; -use MintyPHP\Repository\Security\RateLimitRepository; +use MintyPHP\Repository\Security\RateLimitRepositoryInterface; class RateLimiterService { private const HASH_ALGO = 'sha256'; - public function __construct(private readonly RateLimitRepository $rateLimitRepository) + public function __construct(private readonly RateLimitRepositoryInterface $rateLimitRepository) { } diff --git a/lib/Service/Security/SecurityRepositoryFactory.php b/lib/Service/Security/SecurityRepositoryFactory.php index d1cd8d0..8c6bd72 100644 --- a/lib/Service/Security/SecurityRepositoryFactory.php +++ b/lib/Service/Security/SecurityRepositoryFactory.php @@ -3,12 +3,13 @@ namespace MintyPHP\Service\Security; use MintyPHP\Repository\Security\RateLimitRepository; +use MintyPHP\Repository\Security\RateLimitRepositoryInterface; class SecurityRepositoryFactory { private ?RateLimitRepository $rateLimitRepository = null; - public function createRateLimitRepository(): RateLimitRepository + public function createRateLimitRepository(): RateLimitRepositoryInterface { return $this->rateLimitRepository ??= new RateLimitRepository(); } diff --git a/lib/Service/Security/SecurityServicesFactory.php b/lib/Service/Security/SecurityServicesFactory.php index 3b8985d..91383b8 100644 --- a/lib/Service/Security/SecurityServicesFactory.php +++ b/lib/Service/Security/SecurityServicesFactory.php @@ -2,7 +2,7 @@ namespace MintyPHP\Service\Security; -use MintyPHP\Repository\Security\RateLimitRepository; +use MintyPHP\Repository\Security\RateLimitRepositoryInterface; class SecurityServicesFactory { @@ -12,7 +12,7 @@ class SecurityServicesFactory private readonly SecurityRepositoryFactory $securityRepositoryFactory ) {} - public function createRateLimitRepository(): RateLimitRepository + public function createRateLimitRepository(): RateLimitRepositoryInterface { return $this->securityRepositoryFactory->createRateLimitRepository(); } diff --git a/lib/Service/Settings/SettingRepositoryFactory.php b/lib/Service/Settings/SettingRepositoryFactory.php index f4803e4..6263840 100644 --- a/lib/Service/Settings/SettingRepositoryFactory.php +++ b/lib/Service/Settings/SettingRepositoryFactory.php @@ -3,9 +3,13 @@ namespace MintyPHP\Service\Settings; use MintyPHP\Repository\Access\RoleRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; use MintyPHP\Repository\Org\DepartmentRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; use MintyPHP\Repository\Settings\SettingRepository; +use MintyPHP\Repository\Settings\SettingRepositoryInterface; use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; class SettingRepositoryFactory { @@ -14,22 +18,22 @@ class SettingRepositoryFactory private ?RoleRepository $roleRepository = null; private ?DepartmentRepository $departmentRepository = null; - public function createSettingRepository(): SettingRepository + public function createSettingRepository(): SettingRepositoryInterface { return $this->settingRepository ??= new SettingRepository(); } - public function createTenantRepository(): TenantRepository + public function createTenantRepository(): TenantRepositoryInterface { return $this->tenantRepository ??= new TenantRepository(); } - public function createRoleRepository(): RoleRepository + public function createRoleRepository(): RoleRepositoryInterface { return $this->roleRepository ??= new RoleRepository(); } - public function createDepartmentRepository(): DepartmentRepository + public function createDepartmentRepository(): DepartmentRepositoryInterface { return $this->departmentRepository ??= new DepartmentRepository(); } diff --git a/lib/Service/Settings/SettingService.php b/lib/Service/Settings/SettingService.php index 9e60515..f20124c 100644 --- a/lib/Service/Settings/SettingService.php +++ b/lib/Service/Settings/SettingService.php @@ -2,19 +2,19 @@ namespace MintyPHP\Service\Settings; -use MintyPHP\Repository\Access\RoleRepository; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Settings\SettingRepository; -use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Settings\SettingRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; use MintyPHP\Support\Crypto; class SettingService { public function __construct( - private readonly SettingRepository $settingRepository, - private readonly TenantRepository $tenantRepository, - private readonly RoleRepository $roleRepository, - private readonly DepartmentRepository $departmentRepository, + private readonly SettingRepositoryInterface $settingRepository, + private readonly TenantRepositoryInterface $tenantRepository, + private readonly RoleRepositoryInterface $roleRepository, + private readonly DepartmentRepositoryInterface $departmentRepository, private readonly ThemeConfigService $themeConfigService ) { } diff --git a/lib/Service/Settings/SettingServicesFactory.php b/lib/Service/Settings/SettingServicesFactory.php index df5dfe1..c9c6de7 100644 --- a/lib/Service/Settings/SettingServicesFactory.php +++ b/lib/Service/Settings/SettingServicesFactory.php @@ -2,10 +2,10 @@ namespace MintyPHP\Service\Settings; -use MintyPHP\Repository\Access\RoleRepository; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Settings\SettingRepository; -use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Settings\SettingRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; class SettingServicesFactory { @@ -18,7 +18,7 @@ class SettingServicesFactory private readonly SettingRepositoryFactory $settingRepositoryFactory ) {} - public function createSettingRepository(): SettingRepository + public function createSettingRepository(): SettingRepositoryInterface { return $this->settingRepositoryFactory->createSettingRepository(); } @@ -49,17 +49,17 @@ class SettingServicesFactory return $this->themeConfigService ??= new ThemeConfigService(); } - private function createTenantRepository(): TenantRepository + private function createTenantRepository(): TenantRepositoryInterface { return $this->settingRepositoryFactory->createTenantRepository(); } - private function createRoleRepository(): RoleRepository + private function createRoleRepository(): RoleRepositoryInterface { return $this->settingRepositoryFactory->createRoleRepository(); } - private function createDepartmentRepository(): DepartmentRepository + private function createDepartmentRepository(): DepartmentRepositoryInterface { return $this->settingRepositoryFactory->createDepartmentRepository(); } diff --git a/lib/Service/Tenant/TenantRepositoryFactory.php b/lib/Service/Tenant/TenantRepositoryFactory.php index bce8042..c96ea97 100644 --- a/lib/Service/Tenant/TenantRepositoryFactory.php +++ b/lib/Service/Tenant/TenantRepositoryFactory.php @@ -3,8 +3,11 @@ namespace MintyPHP\Service\Tenant; use MintyPHP\Repository\Org\DepartmentRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; use MintyPHP\Repository\Tenant\UserTenantRepository; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; class TenantRepositoryFactory { @@ -12,17 +15,17 @@ class TenantRepositoryFactory private ?DepartmentRepository $departmentRepository = null; private ?UserTenantRepository $userTenantRepository = null; - public function createTenantRepository(): TenantRepository + public function createTenantRepository(): TenantRepositoryInterface { return $this->tenantRepository ??= new TenantRepository(); } - public function createDepartmentRepository(): DepartmentRepository + public function createDepartmentRepository(): DepartmentRepositoryInterface { return $this->departmentRepository ??= new DepartmentRepository(); } - public function createUserTenantRepository(): UserTenantRepository + public function createUserTenantRepository(): UserTenantRepositoryInterface { return $this->userTenantRepository ??= new UserTenantRepository(); } diff --git a/lib/Service/Tenant/TenantScopeService.php b/lib/Service/Tenant/TenantScopeService.php index 4864b57..2af9688 100644 --- a/lib/Service/Tenant/TenantScopeService.php +++ b/lib/Service/Tenant/TenantScopeService.php @@ -2,18 +2,18 @@ namespace MintyPHP\Service\Tenant; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Tenant\TenantRepository; -use MintyPHP\Repository\Tenant\UserTenantRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; use MintyPHP\Service\Access\PermissionGateway; use MintyPHP\Service\Access\PermissionService; class TenantScopeService { public function __construct( - private readonly TenantRepository $tenantRepository, - private readonly DepartmentRepository $departmentRepository, - private readonly UserTenantRepository $userTenantRepository, + private readonly TenantRepositoryInterface $tenantRepository, + private readonly DepartmentRepositoryInterface $departmentRepository, + private readonly UserTenantRepositoryInterface $userTenantRepository, private readonly PermissionGateway $permissionGateway ) { } diff --git a/lib/Service/Tenant/TenantService.php b/lib/Service/Tenant/TenantService.php index caa8508..5757bb8 100644 --- a/lib/Service/Tenant/TenantService.php +++ b/lib/Service/Tenant/TenantService.php @@ -4,16 +4,16 @@ namespace MintyPHP\Service\Tenant; use MintyPHP\Domain\Taxonomy\SystemAuditOutcome; use MintyPHP\Domain\Taxonomy\TenantStatus; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; use MintyPHP\Service\Audit\SystemAuditService; use MintyPHP\Service\Directory\DirectorySettingsGateway; class TenantService { public function __construct( - private readonly TenantRepository $tenantRepository, - private readonly DepartmentRepository $departmentRepository, + private readonly TenantRepositoryInterface $tenantRepository, + private readonly DepartmentRepositoryInterface $departmentRepository, private readonly DirectorySettingsGateway $settingsGateway, private readonly SystemAuditService $systemAuditService ) { diff --git a/lib/Service/Tenant/TenantServicesFactory.php b/lib/Service/Tenant/TenantServicesFactory.php index c1548cf..2820223 100644 --- a/lib/Service/Tenant/TenantServicesFactory.php +++ b/lib/Service/Tenant/TenantServicesFactory.php @@ -2,9 +2,9 @@ namespace MintyPHP\Service\Tenant; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Tenant\TenantRepository; -use MintyPHP\Repository\Tenant\UserTenantRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; use MintyPHP\Service\Access\PermissionGateway; class TenantServicesFactory @@ -38,17 +38,17 @@ class TenantServicesFactory return $this->tenantFaviconService ??= new TenantFaviconService(); } - public function createTenantRepository(): TenantRepository + public function createTenantRepository(): TenantRepositoryInterface { return $this->tenantRepositoryFactory->createTenantRepository(); } - public function createDepartmentRepository(): DepartmentRepository + public function createDepartmentRepository(): DepartmentRepositoryInterface { return $this->tenantRepositoryFactory->createDepartmentRepository(); } - public function createUserTenantRepository(): UserTenantRepository + public function createUserTenantRepository(): UserTenantRepositoryInterface { return $this->tenantRepositoryFactory->createUserTenantRepository(); } diff --git a/lib/Service/User/UserAccountService.php b/lib/Service/User/UserAccountService.php index 72be408..908d0ce 100644 --- a/lib/Service/User/UserAccountService.php +++ b/lib/Service/User/UserAccountService.php @@ -3,17 +3,17 @@ namespace MintyPHP\Service\User; use MintyPHP\I18n; -use MintyPHP\Repository\User\UserListQueryRepository; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\User\UserListQueryRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Service\Audit\SystemAuditService; class UserAccountService { public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, - private readonly UserListQueryRepository $userListQueryRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, + private readonly UserListQueryRepositoryInterface $userListQueryRepository, private readonly UserAssignmentService $userAssignmentService, private readonly UserPasswordService $userPasswordService, private readonly UserSettingsGateway $settingsGateway, diff --git a/lib/Service/User/UserAssignmentService.php b/lib/Service/User/UserAssignmentService.php index 86160f7..eea112a 100644 --- a/lib/Service/User/UserAssignmentService.php +++ b/lib/Service/User/UserAssignmentService.php @@ -2,19 +2,19 @@ namespace MintyPHP\Service\User; -use MintyPHP\Repository\Access\UserRoleRepository; -use MintyPHP\Repository\Org\UserDepartmentRepository; +use MintyPHP\Repository\Access\UserRoleRepositoryInterface; +use MintyPHP\Repository\Org\UserDepartmentRepositoryInterface; use MintyPHP\Repository\Support\DatabaseSessionRepository; -use MintyPHP\Repository\Tenant\UserTenantRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; class UserAssignmentService { public function __construct( - private readonly UserWriteRepository $userWriteRepository, - private readonly UserTenantRepository $userTenantRepository, - private readonly UserRoleRepository $userRoleRepository, - private readonly UserDepartmentRepository $userDepartmentRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, + private readonly UserTenantRepositoryInterface $userTenantRepository, + private readonly UserRoleRepositoryInterface $userRoleRepository, + private readonly UserDepartmentRepositoryInterface $userDepartmentRepository, private readonly UserDirectoryGateway $directoryGateway, private readonly UserPermissionGateway $permissionGateway, private readonly DatabaseSessionRepository $databaseSessionRepository diff --git a/lib/Service/User/UserDirectoryGateway.php b/lib/Service/User/UserDirectoryGateway.php index 8ee95d3..b029380 100644 --- a/lib/Service/User/UserDirectoryGateway.php +++ b/lib/Service/User/UserDirectoryGateway.php @@ -2,9 +2,9 @@ namespace MintyPHP\Service\User; -use MintyPHP\Repository\Access\RoleRepository; -use MintyPHP\Repository\Org\DepartmentRepository; -use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; class UserDirectoryGateway { @@ -63,17 +63,17 @@ class UserDirectoryGateway return $this->departmentRepository()->listByTenantIds($tenantIds); } - private function tenantRepository(): TenantRepository + private function tenantRepository(): TenantRepositoryInterface { return $this->userRepositoryFactory->createTenantRepository(); } - private function roleRepository(): RoleRepository + private function roleRepository(): RoleRepositoryInterface { return $this->userRepositoryFactory->createRoleRepository(); } - private function departmentRepository(): DepartmentRepository + private function departmentRepository(): DepartmentRepositoryInterface { return $this->userRepositoryFactory->createDepartmentRepository(); } diff --git a/lib/Service/User/UserLifecycleRestoreService.php b/lib/Service/User/UserLifecycleRestoreService.php index 5a04c5d..5dac63d 100644 --- a/lib/Service/User/UserLifecycleRestoreService.php +++ b/lib/Service/User/UserLifecycleRestoreService.php @@ -4,15 +4,15 @@ namespace MintyPHP\Service\User; use MintyPHP\Repository\Support\DatabaseSessionRepository; use MintyPHP\Repository\Support\RepoQuery; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Service\Audit\UserLifecycleAuditService; class UserLifecycleRestoreService { public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, private readonly UserLifecycleAuditService $userLifecycleAuditService, private readonly DatabaseSessionRepository $databaseSessionRepository ) { diff --git a/lib/Service/User/UserLifecycleService.php b/lib/Service/User/UserLifecycleService.php index 930ede9..bac2795 100644 --- a/lib/Service/User/UserLifecycleService.php +++ b/lib/Service/User/UserLifecycleService.php @@ -4,8 +4,8 @@ namespace MintyPHP\Service\User; use MintyPHP\Repository\Support\DatabaseSessionRepository; use MintyPHP\Repository\Support\RepoQuery; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Service\Access\PermissionService; use MintyPHP\Service\Audit\UserLifecycleAuditService; @@ -15,8 +15,8 @@ class UserLifecycleService private const BATCH_SIZE = 500; public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, private readonly UserSettingsGateway $settingsGateway, private readonly UserLifecycleAuditService $userLifecycleAuditService, private readonly DatabaseSessionRepository $databaseSessionRepository diff --git a/lib/Service/User/UserPasswordService.php b/lib/Service/User/UserPasswordService.php index d1e969f..9cf752d 100644 --- a/lib/Service/User/UserPasswordService.php +++ b/lib/Service/User/UserPasswordService.php @@ -2,13 +2,13 @@ namespace MintyPHP\Service\User; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; class UserPasswordService { public function __construct( private readonly UserPasswordPolicyService $passwordPolicyService, - private readonly UserWriteRepository $userWriteRepository + private readonly UserWriteRepositoryInterface $userWriteRepository ) { } diff --git a/lib/Service/User/UserRepositoryFactory.php b/lib/Service/User/UserRepositoryFactory.php index cbb7257..94844bb 100644 --- a/lib/Service/User/UserRepositoryFactory.php +++ b/lib/Service/User/UserRepositoryFactory.php @@ -3,15 +3,25 @@ namespace MintyPHP\Service\User; use MintyPHP\Repository\Access\RoleRepository; +use MintyPHP\Repository\Access\RoleRepositoryInterface; use MintyPHP\Repository\Access\UserRoleRepository; +use MintyPHP\Repository\Access\UserRoleRepositoryInterface; use MintyPHP\Repository\Org\DepartmentRepository; +use MintyPHP\Repository\Org\DepartmentRepositoryInterface; use MintyPHP\Repository\Org\UserDepartmentRepository; +use MintyPHP\Repository\Org\UserDepartmentRepositoryInterface; use MintyPHP\Repository\Tenant\TenantRepository; +use MintyPHP\Repository\Tenant\TenantRepositoryInterface; use MintyPHP\Repository\Tenant\UserTenantRepository; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; use MintyPHP\Repository\User\UserListQueryRepository; +use MintyPHP\Repository\User\UserListQueryRepositoryInterface; use MintyPHP\Repository\User\UserReadRepository; +use MintyPHP\Repository\User\UserReadRepositoryInterface; use MintyPHP\Repository\User\UserSavedFilterRepository; +use MintyPHP\Repository\User\UserSavedFilterRepositoryInterface; use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; class UserRepositoryFactory { @@ -26,52 +36,52 @@ class UserRepositoryFactory private ?UserRoleRepository $userRoleRepository = null; private ?UserDepartmentRepository $userDepartmentRepository = null; - public function createUserReadRepository(): UserReadRepository + public function createUserReadRepository(): UserReadRepositoryInterface { return $this->userReadRepository ??= new UserReadRepository(); } - public function createUserWriteRepository(): UserWriteRepository + public function createUserWriteRepository(): UserWriteRepositoryInterface { return $this->userWriteRepository ??= new UserWriteRepository(); } - public function createUserListQueryRepository(): UserListQueryRepository + public function createUserListQueryRepository(): UserListQueryRepositoryInterface { return $this->userListQueryRepository ??= new UserListQueryRepository(); } - public function createUserSavedFilterRepository(): UserSavedFilterRepository + public function createUserSavedFilterRepository(): UserSavedFilterRepositoryInterface { return $this->userSavedFilterRepository ??= new UserSavedFilterRepository(); } - public function createTenantRepository(): TenantRepository + public function createTenantRepository(): TenantRepositoryInterface { return $this->tenantRepository ??= new TenantRepository(); } - public function createRoleRepository(): RoleRepository + public function createRoleRepository(): RoleRepositoryInterface { return $this->roleRepository ??= new RoleRepository(); } - public function createDepartmentRepository(): DepartmentRepository + public function createDepartmentRepository(): DepartmentRepositoryInterface { return $this->departmentRepository ??= new DepartmentRepository(); } - public function createUserTenantRepository(): UserTenantRepository + public function createUserTenantRepository(): UserTenantRepositoryInterface { return $this->userTenantRepository ??= new UserTenantRepository(); } - public function createUserRoleRepository(): UserRoleRepository + public function createUserRoleRepository(): UserRoleRepositoryInterface { return $this->userRoleRepository ??= new UserRoleRepository(); } - public function createUserDepartmentRepository(): UserDepartmentRepository + public function createUserDepartmentRepository(): UserDepartmentRepositoryInterface { return $this->userDepartmentRepository ??= new UserDepartmentRepository(); } diff --git a/lib/Service/User/UserSavedFilterService.php b/lib/Service/User/UserSavedFilterService.php index 2c210fa..fd42891 100644 --- a/lib/Service/User/UserSavedFilterService.php +++ b/lib/Service/User/UserSavedFilterService.php @@ -3,7 +3,7 @@ namespace MintyPHP\Service\User; use MintyPHP\Repository\Support\RepoQuery; -use MintyPHP\Repository\User\UserSavedFilterRepository; +use MintyPHP\Repository\User\UserSavedFilterRepositoryInterface; class UserSavedFilterService { @@ -12,7 +12,7 @@ class UserSavedFilterService private const SEARCH_MAX_LENGTH = 200; private const MAX_PER_USER_CONTEXT = 20; - public function __construct(private readonly UserSavedFilterRepository $userSavedFilterRepository) + public function __construct(private readonly UserSavedFilterRepositoryInterface $userSavedFilterRepository) { } diff --git a/lib/Service/User/UserServicesFactory.php b/lib/Service/User/UserServicesFactory.php index b252306..5f5f6da 100644 --- a/lib/Service/User/UserServicesFactory.php +++ b/lib/Service/User/UserServicesFactory.php @@ -2,14 +2,14 @@ namespace MintyPHP\Service\User; -use MintyPHP\Repository\Access\UserRoleRepository; -use MintyPHP\Repository\Org\UserDepartmentRepository; +use MintyPHP\Repository\Access\UserRoleRepositoryInterface; +use MintyPHP\Repository\Org\UserDepartmentRepositoryInterface; use MintyPHP\Repository\Support\DatabaseSessionRepository; -use MintyPHP\Repository\Tenant\UserTenantRepository; -use MintyPHP\Repository\User\UserListQueryRepository; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserSavedFilterRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; +use MintyPHP\Repository\User\UserListQueryRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserSavedFilterRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; use MintyPHP\Service\Audit\AuditServicesFactory; use MintyPHP\Service\Audit\UserLifecycleAuditService; @@ -92,37 +92,37 @@ class UserServicesFactory ); } - public function createUserReadRepository(): UserReadRepository + public function createUserReadRepository(): UserReadRepositoryInterface { return $this->userRepositoryFactory->createUserReadRepository(); } - public function createUserWriteRepository(): UserWriteRepository + public function createUserWriteRepository(): UserWriteRepositoryInterface { return $this->userRepositoryFactory->createUserWriteRepository(); } - public function createUserListQueryRepository(): UserListQueryRepository + public function createUserListQueryRepository(): UserListQueryRepositoryInterface { return $this->userRepositoryFactory->createUserListQueryRepository(); } - public function createUserSavedFilterRepository(): UserSavedFilterRepository + public function createUserSavedFilterRepository(): UserSavedFilterRepositoryInterface { return $this->userRepositoryFactory->createUserSavedFilterRepository(); } - public function createUserTenantRepository(): UserTenantRepository + public function createUserTenantRepository(): UserTenantRepositoryInterface { return $this->userRepositoryFactory->createUserTenantRepository(); } - public function createUserRoleRepository(): UserRoleRepository + public function createUserRoleRepository(): UserRoleRepositoryInterface { return $this->userRepositoryFactory->createUserRoleRepository(); } - public function createUserDepartmentRepository(): UserDepartmentRepository + public function createUserDepartmentRepository(): UserDepartmentRepositoryInterface { return $this->userRepositoryFactory->createUserDepartmentRepository(); } diff --git a/lib/Service/User/UserTenantContextService.php b/lib/Service/User/UserTenantContextService.php index 65415fc..6ae2767 100644 --- a/lib/Service/User/UserTenantContextService.php +++ b/lib/Service/User/UserTenantContextService.php @@ -2,16 +2,16 @@ namespace MintyPHP\Service\User; -use MintyPHP\Repository\Tenant\UserTenantRepository; -use MintyPHP\Repository\User\UserReadRepository; -use MintyPHP\Repository\User\UserWriteRepository; +use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface; +use MintyPHP\Repository\User\UserReadRepositoryInterface; +use MintyPHP\Repository\User\UserWriteRepositoryInterface; class UserTenantContextService { public function __construct( - private readonly UserReadRepository $userReadRepository, - private readonly UserWriteRepository $userWriteRepository, - private readonly UserTenantRepository $userTenantRepository, + private readonly UserReadRepositoryInterface $userReadRepository, + private readonly UserWriteRepositoryInterface $userWriteRepository, + private readonly UserTenantRepositoryInterface $userTenantRepository, private readonly UserScopeGateway $scopeGateway, private readonly UserDirectoryGateway $directoryGateway ) { diff --git a/lib/Support/helpers/app.php b/lib/Support/helpers/app.php index bc1699e..62d7dc6 100644 --- a/lib/Support/helpers/app.php +++ b/lib/Support/helpers/app.php @@ -413,3 +413,144 @@ function sortByDescription(array &$items): void strcasecmp((string) ($a['description'] ?? ''), (string) ($b['description'] ?? '')) ); } + +/** + * Decide whether any admin panel capability is available in layout auth. + * + * @param array $layoutAuth + */ +function layoutHasAdminPanel(array $layoutAuth): bool +{ + $capabilityKeys = array_keys(\MintyPHP\Service\Access\UiCapabilityMap::LAYOUT); + foreach ($capabilityKeys as $key) { + if ($key === 'can_view_address_book') { + continue; + } + if (!empty($layoutAuth[$key])) { + return true; + } + } + + return false; +} + +/** + * Normalize list-like input to sorted unique non-empty strings. + * + * @return list + */ +function appNormalizeStringList(mixed $value): array +{ + $raw = is_array($value) ? $value : explode(',', (string) $value); + $list = array_filter(array_map('trim', $raw), static fn ($item) => $item !== ''); + $list = array_values(array_unique($list)); + sort($list, SORT_STRING); + return $list; +} + +/** + * Normalize list-like input to sorted unique positive integers. + * + * @return list + */ +function appNormalizePositiveIntList(mixed $value): array +{ + $raw = is_array($value) ? $value : explode(',', (string) $value); + $list = array_values(array_unique(array_map('intval', $raw))); + $list = array_values(array_filter($list, static fn ($item) => $item > 0)); + sort($list, SORT_NUMERIC); + return $list; +} + +/** + * Normalize address-book custom field query keys/values. + * + * @param array $rawQuery + * @return array> + */ +function appNormalizeAddressBookCustomFilterQuery(array $rawQuery): array +{ + $normalized = []; + foreach ($rawQuery 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 !== '') { + $normalized[$key] = $value; + } + continue; + } + if (preg_match('/^cfm_[a-f0-9-]{36}$/', $key)) { + $ids = appNormalizePositiveIntList($rawValue); + if ($ids) { + $normalized[$key] = $ids; + } + continue; + } + if (preg_match('/^cfd_[a-f0-9-]{36}_(from|to)$/', $key)) { + $value = trim((string) $rawValue); + $dt = \DateTimeImmutable::createFromFormat('Y-m-d', $value); + if ($dt && $dt->format('Y-m-d') === $value) { + $normalized[$key] = $value; + } + } + } + ksort($normalized, SORT_STRING); + return $normalized; +} + +/** + * Build precomputed layout navigation context for templates. + * + * @param array $layoutAuth + * @param array $session + * @param array $query + * @return array + */ +function appBuildLayoutNavContext(array $layoutAuth, array $session, array $query): array +{ + $currentTenant = is_array($session['current_tenant'] ?? null) ? $session['current_tenant'] : null; + $availableTenants = is_array($session['available_tenants'] ?? null) ? $session['available_tenants'] : []; + $tenantUuid = trim((string) ($currentTenant['uuid'] ?? '')); + $tenantName = trim((string) ($currentTenant['description'] ?? '')); + + $tenantQueryParam = ''; + if (count($availableTenants) > 1 && $tenantUuid !== '') { + $tenantQueryParam = '?tenant=' . urlencode($tenantUuid); + } + + $tenantHasAvatar = false; + if ($tenantUuid !== '' && class_exists(\MintyPHP\Service\Tenant\TenantAvatarService::class)) { + $tenantHasAvatar = app(\MintyPHP\Service\Tenant\TenantAvatarService::class)->hasAvatar($tenantUuid); + } + + $csrfKey = \MintyPHP\Session::$csrfSessionKey; + $csrfToken = (string) ($session[$csrfKey] ?? ''); + + return [ + 'hasAdminPanel' => layoutHasAdminPanel($layoutAuth), + 'currentTenant' => $currentTenant, + 'availableTenants' => $availableTenants, + 'tenantQueryParam' => $tenantQueryParam, + 'tenantAvatar' => [ + 'uuid' => $tenantUuid, + 'name' => $tenantName, + 'hasAvatar' => $tenantHasAvatar, + ], + 'addressBook' => [ + 'url' => lurl('address-book'), + 'activeSearch' => trim((string) ($query['search'] ?? '')), + 'activeTenants' => appNormalizeStringList($query['tenants'] ?? ''), + 'activeDepartments' => appNormalizePositiveIntList($query['departments'] ?? ''), + 'activeRoles' => appNormalizePositiveIntList($query['roles'] ?? ''), + 'activeCustomFilters' => appNormalizeAddressBookCustomFilterQuery($query), + 'peopleGroups' => is_array($session['available_departments_by_tenant'] ?? null) ? $session['available_departments_by_tenant'] : [], + 'savedFilters' => is_array($session['address_book_saved_filters'] ?? null) ? $session['address_book_saved_filters'] : [], + ], + 'csrfKey' => $csrfKey, + 'csrfToken' => $csrfToken, + ]; +} diff --git a/pages/address-book/index(default).phtml b/pages/address-book/index(default).phtml index 93c7e99..e46f2cf 100644 --- a/pages/address-book/index(default).phtml +++ b/pages/address-book/index(default).phtml @@ -236,209 +236,28 @@ require templatePath('partials/app-list-titlebar.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'name' => t('Name'), + 'email' => t('Email'), + 'phone' => t('Phone'), + 'mobile' => t('Mobile'), + 'shortDial' => t('Short dial'), + 'tenants' => t('Tenants'), + 'departments' => t('Departments'), + 'roles' => t('Roles'), + ], +]; +?> + + + diff --git a/pages/admin/api-audit/index(default).phtml b/pages/admin/api-audit/index(default).phtml index e112686..2f7b3b7 100644 --- a/pages/admin/api-audit/index(default).phtml +++ b/pages/admin/api-audit/index(default).phtml @@ -41,149 +41,29 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'created' => t('Created'), + 'statusCode' => t('Status code'), + 'method' => t('Method'), + 'path' => t('Path'), + 'durationMs' => t('Duration (ms)'), + 'user' => t('User'), + 'tenant' => t('Tenant'), + 'errorCode' => t('Error code'), + 'ip' => t('IP'), + ], +]; +?> + + + diff --git a/pages/admin/api-docs/index(default).phtml b/pages/admin/api-docs/index(default).phtml index e7fcf5f..743a2e0 100644 --- a/pages/admin/api-docs/index(default).phtml +++ b/pages/admin/api-docs/index(default).phtml @@ -11,7 +11,7 @@ require templatePath('partials/app-breadcrumb.phtml');
- + - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'description' => t('Description'), + 'status' => t('Status'), + 'code' => t('Code'), + 'costCenter' => t('Cost center'), + 'activeUsers' => t('Active users'), + 'inactiveUsers' => t('Inactive users'), + 'created' => t('Created'), + 'modified' => t('Modified'), + 'active' => t('Active'), + 'inactive' => t('Inactive'), + ], +]; +?> + + + diff --git a/pages/admin/import-audit/index(default).phtml b/pages/admin/import-audit/index(default).phtml index f5437f9..4af116a 100644 --- a/pages/admin/import-audit/index(default).phtml +++ b/pages/admin/import-audit/index(default).phtml @@ -42,103 +42,31 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'created' => t('Created'), + 'status' => t('Status'), + 'profile' => t('Profile'), + 'durationMs' => t('Duration (ms)'), + 'rowsTotal' => t('Rows total'), + 'createdCount' => t('Created count'), + 'skippedCount' => t('Skipped count'), + 'failedCount' => t('Failed count'), + 'user' => t('User'), + 'users' => t('Users'), + 'departments' => t('Departments'), + ], +]; +?> + + + diff --git a/pages/admin/mail-log/index(default).phtml b/pages/admin/mail-log/index(default).phtml index d9b79a6..5f1c7fc 100644 --- a/pages/admin/mail-log/index(default).phtml +++ b/pages/admin/mail-log/index(default).phtml @@ -28,103 +28,25 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'created' => t('Created'), + 'status' => t('Status'), + 'recipient' => t('Recipient'), + 'subject' => t('Subject'), + 'template' => t('Template'), + ], +]; +?> + + + diff --git a/pages/admin/permissions/index(default).phtml b/pages/admin/permissions/index(default).phtml index baa1f4b..29e1c50 100644 --- a/pages/admin/permissions/index(default).phtml +++ b/pages/admin/permissions/index(default).phtml @@ -38,83 +38,27 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'description' => t('Description'), + 'permissionKey' => t('Permission key'), + 'status' => t('Status'), + 'system' => t('System'), + 'created' => t('Created'), + 'active' => t('Active'), + 'inactive' => t('Inactive'), + ], +]; +?> + + + diff --git a/pages/admin/roles/index(default).phtml b/pages/admin/roles/index(default).phtml index 96a2bc2..b546b28 100644 --- a/pages/admin/roles/index(default).phtml +++ b/pages/admin/roles/index(default).phtml @@ -38,131 +38,30 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'description' => t('Description'), + 'status' => t('Status'), + 'code' => t('Code'), + 'activeUsers' => t('Active users'), + 'inactiveUsers' => t('Inactive users'), + 'permissions' => t('Permissions'), + 'created' => t('Created'), + 'modified' => t('Modified'), + 'active' => t('Active'), + 'inactive' => t('Inactive'), + ], +]; +?> + + + diff --git a/pages/admin/scheduled-jobs/edit(default).phtml b/pages/admin/scheduled-jobs/edit(default).phtml index 714c099..a2d09c9 100644 --- a/pages/admin/scheduled-jobs/edit(default).phtml +++ b/pages/admin/scheduled-jobs/edit(default).phtml @@ -234,115 +234,34 @@ if ($canRunNow) { - - + (int) $jobId, + 'gridLang' => $gridLang, + 'search' => [ + 'input' => '#scheduled-job-runs-search', + 'param' => 'search', + 'debounce' => 250, + ], + 'filters' => [ + ['input' => '#scheduled-job-runs-status-filter', 'param' => 'status'], + ['input' => '#scheduled-job-runs-trigger-filter', 'param' => 'trigger_type'], + ], + 'labels' => [ + 'started' => t('Started'), + 'status' => t('Status'), + 'trigger' => t('Trigger'), + 'durationMs' => t('Duration (ms)'), + 'errorCode' => t('Error code'), + 'user' => t('User'), + 'runUuid' => t('Run UUID'), + ], +]; +?> + + + diff --git a/pages/admin/scheduled-jobs/index(default).phtml b/pages/admin/scheduled-jobs/index(default).phtml index 5c00672..115c873 100644 --- a/pages/admin/scheduled-jobs/index(default).phtml +++ b/pages/admin/scheduled-jobs/index(default).phtml @@ -42,97 +42,28 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'job' => t('Job'), + 'enabled' => t('Enabled'), + 'disabled' => t('Disabled'), + 'nextRun' => t('Next run'), + 'schedule' => t('Schedule'), + 'lastRun' => t('Last run'), + 'status' => t('Status'), + 'lastError' => t('Last error'), + ], +]; +?> + + + diff --git a/pages/admin/system-audit/index(default).phtml b/pages/admin/system-audit/index(default).phtml index 84b0f64..ce679aa 100644 --- a/pages/admin/system-audit/index(default).phtml +++ b/pages/admin/system-audit/index(default).phtml @@ -42,109 +42,28 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'created' => t('Created'), + 'status' => t('Status'), + 'event' => t('Event'), + 'channel' => t('Channel'), + 'actor' => t('Actor'), + 'targetType' => t('Target type'), + 'requestId' => t('Request ID'), + 'errorCode' => t('Error code'), + ], +]; +?> + + + diff --git a/pages/admin/tenants/index(default).phtml b/pages/admin/tenants/index(default).phtml index eddf026..817c0b8 100644 --- a/pages/admin/tenants/index(default).phtml +++ b/pages/admin/tenants/index(default).phtml @@ -38,149 +38,31 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'description' => t('Description'), + 'status' => t('Status'), + 'theme' => t('Theme'), + 'sso' => t('SSO'), + 'activeUsers' => t('Active users'), + 'inactiveUsers' => t('Inactive users'), + 'created' => t('Created'), + 'active' => t('Active'), + 'default' => t('Default'), + 'microsoftOnly' => t('Microsoft only'), + 'inactive' => t('Inactive'), + ], +]; +?> + + + diff --git a/pages/admin/user-lifecycle-audit/index(default).phtml b/pages/admin/user-lifecycle-audit/index(default).phtml index b8df520..4b22e58 100644 --- a/pages/admin/user-lifecycle-audit/index(default).phtml +++ b/pages/admin/user-lifecycle-audit/index(default).phtml @@ -46,77 +46,28 @@ require templatePath('partials/app-list-filters.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'gridLang' => $gridLang, + 'labels' => [ + 'created' => t('Created'), + 'status' => t('Status'), + 'action' => t('Action'), + 'trigger' => t('Trigger'), + 'targetEmail' => t('Target email'), + 'targetUuid' => t('Target UUID'), + 'reasonCode' => t('Reason code'), + 'restoredAt' => t('Restored at'), + ], +]; +?> + + + diff --git a/pages/admin/users/index(default).phtml b/pages/admin/users/index(default).phtml index d4418a8..7d75d8e 100644 --- a/pages/admin/users/index(default).phtml +++ b/pages/admin/users/index(default).phtml @@ -112,229 +112,72 @@ require templatePath('partials/app-list-filters.phtml'); - - - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'filterChipMeta' => $filterChipMeta, + 'currentUserUuid' => (string) $currentUserUuid, + 'canUpdateUsers' => (bool) $canUpdateUsers, + 'canUpdateSelf' => (bool) $canUpdateSelf, + 'csrf' => $gridCsrf, + 'gridLang' => $gridLang, + 'labels' => [ + 'avatar' => t('Avatar'), + 'firstName' => t('First name'), + 'lastName' => t('Last name'), + 'email' => t('Email'), + 'state' => t('State'), + 'tenants' => t('Tenants'), + 'departments' => t('Departments'), + 'roles' => t('Roles'), + 'phone' => t('Phone'), + 'mobile' => t('Mobile'), + 'shortDial' => t('Short dial'), + 'created' => t('Created'), + 'modified' => t('Modified'), + 'lastLogin' => t('Last login'), + 'selectAll' => t('Select all'), + 'active' => t('Active'), + 'inactive' => t('Inactive'), + 'never' => t('Never'), + 'bulkActivateConfirm' => t('Activate users?'), + 'bulkDeactivateConfirm' => t('Deactivate users?'), + 'bulkDeleteConfirm' => t('Delete users?'), + 'bulkSendAccessConfirm' => t('Send access emails to selected users?'), + 'bulkAccessPdfConfirm' => t('Generate access PDFs for selected users?'), + 'primaryTenant' => t('Primary tenant'), + 'bulkMessages' => [ + 'activate' => [ + 'success' => t('%d users activated'), + 'error' => t('Failed to activate users'), + ], + 'deactivate' => [ + 'success' => t('%d users deactivated'), + 'error' => t('Failed to deactivate users'), + ], + 'delete' => [ + 'success' => t('%d users deleted'), + 'error' => t('Failed to delete users'), + ], + 'send-access' => [ + 'success' => t('Access emails sent to %d users'), + 'partial' => t('Access emails sent to %d users, %f failed'), + 'error' => t('Failed to send access emails'), + ], + ], + ], +]; +?> + + + + diff --git a/pages/page/index(page).phtml b/pages/page/index(page).phtml index 365f240..d56f382 100644 --- a/pages/page/index(page).phtml +++ b/pages/page/index(page).phtml @@ -23,24 +23,24 @@
- + - + - + - + - + - + - + diff --git a/pages/search/index(default).phtml b/pages/search/index(default).phtml index 97ab3d2..56abd78 100644 --- a/pages/search/index(default).phtml +++ b/pages/search/index(default).phtml @@ -25,68 +25,21 @@ require templatePath('partials/app-list-titlebar.phtml');
- - + $searchConfig, + 'filterSchema' => $clientFilterSchema, + 'gridLang' => $gridLang, + 'labels' => [ + 'result' => t('Result'), + 'type' => t('Type'), + ], +]; +?> + + + diff --git a/templates/default.phtml b/templates/default.phtml index d92157e..af79450 100644 --- a/templates/default.phtml +++ b/templates/default.phtml @@ -21,7 +21,7 @@ if ($bufferTitle !== '') { style="" > - + <?php e($pageTitle); ?> @@ -51,7 +51,7 @@ if ($bufferTitle !== '') { - + diff --git a/templates/partials/app-main-aside-icon-bar.phtml b/templates/partials/app-main-aside-icon-bar.phtml index df00388..1f575ac 100644 --- a/templates/partials/app-main-aside-icon-bar.phtml +++ b/templates/partials/app-main-aside-icon-bar.phtml @@ -3,18 +3,7 @@ $accountUrl = accountUrl(); $accountName = currentUserDisplayName(); $accountTooltip = $accountName !== '' ? $accountName : t('Account'); $layoutAuth = is_array($viewAuth['layout'] ?? null) ? $viewAuth['layout'] : []; -$canViewTenants = (bool) ($layoutAuth['can_view_tenants'] ?? false); -$canViewDepartments = (bool) ($layoutAuth['can_view_departments'] ?? false); -$canViewUsers = (bool) ($layoutAuth['can_view_users'] ?? false); -$canViewRoles = (bool) ($layoutAuth['can_view_roles'] ?? false); -$canViewPermissions = (bool) ($layoutAuth['can_view_permissions'] ?? false); -$canViewSettings = (bool) ($layoutAuth['can_view_settings'] ?? false); -$canViewMailLog = (bool) ($layoutAuth['can_view_mail_log'] ?? false); -$canViewSystemAudit = (bool) ($layoutAuth['can_view_system_audit'] ?? false); -$canViewStats = (bool) ($layoutAuth['can_view_stats'] ?? false); -$hasAdminPanel = $canViewTenants || $canViewDepartments || $canViewUsers - || $canViewRoles || $canViewPermissions || $canViewSettings - || $canViewMailLog || $canViewSystemAudit || $canViewStats; +$hasAdminPanel = layoutHasAdminPanel($layoutAuth); $canViewAddressBook = (bool) ($layoutAuth['can_view_address_book'] ?? false); $addressBookUrl = lurl('address-book'); ?> @@ -54,7 +43,7 @@ $addressBookUrl = lurl('address-book');
    - +