refactor: remove 13 dead code artifacts across core/

Dead methods (9):
- Command::bootstrapModuleApp() — unused by all subclasses
- SearchConfig::providerCoverageGaps() — diagnostic method, never called
- RequestInput::queryArray() — no callers
- LocaleResolver::getAvailableLocales() / getDefaultLocale() — unused getters
- EmailVerificationService::getExpiryMinutes() — constant wrapper, never called
- AuthService::loginAndRedirect() — convenience wrapper, never called
- DepartmentService::listForUserAssignments() — no callers
- UserTenantContextService::getAvailableDepartmentsByTenant() — no callers

Dead functions (3):
- navActivePublicPages(), appNormalizeStringList(), appNormalizePositiveIntList()

Dead constant (1):
- PermissionService::API_DOCS_VIEW — duplicated via other paths

Orphaned file (1):
- bin/cli-bootstrap.php — never included anywhere

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 08:48:29 +02:00
parent b1a907b79c
commit 94b746ddf8
13 changed files with 1 additions and 247 deletions

View File

@@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
use MintyPHP\App\AppContainer;
use MintyPHP\Http\RequestContext;
/**
* Shared app bootstrap for non-module CLI commands.
*/
function cliBootstrapApp(string $channel = 'cli', string $path = 'bin/cli'): AppContainer
{
static $booted = false;
/** @var AppContainer|null $container */
static $container = null;
if (!$booted) {
chdir(__DIR__ . '/..');
require_once 'vendor/autoload.php';
require_once 'config/config.php';
require_once 'core/Support/helpers.php';
/** @var AppContainer $resolved */
$resolved = require 'core/App/registerContainer.php';
setAppContainer($resolved);
$container = $resolved;
$booted = true;
}
RequestContext::start([
'channel' => $channel,
'method' => 'CLI',
'path' => $path,
]);
if (!$container instanceof AppContainer) {
throw new RuntimeException('CLI app container bootstrap failed.');
}
return $container;
}

View File

@@ -3,7 +3,6 @@
namespace MintyPHP\Console;
use MintyPHP\Console\Support\CliAppBootstrap;
use MintyPHP\Console\Support\ModuleCliRuntime;
/**
* Base class for CLI commands.
@@ -50,12 +49,4 @@ abstract class Command
CliAppBootstrap::bootstrap($channel, $path ?? 'bin/console ' . $this->name());
}
/**
* Bootstrap the app for module CLI commands.
* Loads the module CLI infrastructure (error policy, locking, app container).
*/
protected function bootstrapModuleApp(): void
{
ModuleCliRuntime::bootstrap();
}
}

View File

@@ -63,15 +63,6 @@ final class RequestInput
return (int) $this->query($key, $default);
}
/**
* @return array<int|string, mixed>
*/
public function queryArray(string $key): array
{
$value = $this->query($key, []);
return is_array($value) ? $value : [];
}
/**
* @return array<string, mixed>
*/

View File

@@ -109,16 +109,6 @@ class LocaleResolver
return in_array($locale, $this->availableLocales, true);
}
public function getAvailableLocales(): array
{
return $this->availableLocales;
}
public function getDefaultLocale(): string
{
return $this->defaultLocale;
}
private function looksLikeLocale(string $candidate): bool
{
return preg_match('/^[a-z]{2}(?:-[a-z]{2})?$/i', $candidate) === 1;

View File

@@ -72,7 +72,6 @@ class PermissionService
public const USERS_IMPORT_ASSIGNMENTS = 'users.import_assignments';
public const CUSTOM_FIELDS_MANAGE = 'custom_fields.manage';
public const CUSTOM_FIELDS_EDIT_VALUES = 'custom_fields.edit_values';
public const API_DOCS_VIEW = 'api_docs.view';
public const DOCS_VIEW = 'docs.view';
public const MAIL_LOG_VIEW = 'mail_log.view';
public const STATS_VIEW = 'stats.view';

View File

@@ -14,7 +14,6 @@ use MintyPHP\Service\Audit\AuditRecorderInterface;
use MintyPHP\Service\User\UserAccountService;
use MintyPHP\Service\User\UserTenantContextService;
use MintyPHP\Session;
use MintyPHP\Support\Flash;
/**
* Orchestrates authentication flows: login, registration, logout, and session refresh.
@@ -235,38 +234,6 @@ class AuthService
return ['ok' => true, 'user' => $user];
}
public function loginAndRedirect(
string $email,
string $password,
string $successTarget = 'admin',
string $failTarget = 'login',
bool $remember = false
): void {
$result = $this->login($email, $password);
if (!($result['ok'] ?? false)) {
// Check if user needs to verify email
if (!empty($result['needs_verification'])) {
$this->sessionStore->set('email_verification_email', $result['email'] ?? $email);
Flash::error(t('Please verify your email first'), 'verify-email', 'login_not_verified');
Router::redirect('verify-email');
}
$message = $result['message'] ?? 'Email/password not valid';
$key = $result['flash_key'] ?? 'login_invalid';
Flash::error($message, $failTarget, $key);
Router::redirect($failTarget);
}
if ($remember) {
$userId = (int) ($this->sessionUser()['id'] ?? 0);
if ($userId > 0) {
$this->rememberMeService->rememberUser($userId);
}
}
Router::redirect($successTarget);
}
public function register(array $data): array
{
$email = trim((string) ($data['email'] ?? ''));

View File

@@ -142,11 +142,6 @@ class EmailVerificationService
return $this->sendVerification((int) $user['id'], $locale);
}
public function getExpiryMinutes(): int
{
return self::EXPIRY_MINUTES;
}
private function generateCode(): string
{
$max = (10 ** self::CODE_LENGTH) - 1;

View File

@@ -79,28 +79,7 @@ class DepartmentService
return $this->departmentRepository->listByIds($departmentIds);
}
// Merges the tenant-scoped list with any already-selected departments outside the filter —
// ensures a user keeps visibility of departments they're already assigned to.
public function listForUserAssignments(array $tenantIds, array $selectedDepartmentIds): array
{
$departments = $tenantIds ? $this->listByTenantIds($tenantIds) : $this->list();
$extraDepartments = $selectedDepartmentIds ? $this->listByIds($selectedDepartmentIds) : [];
if (!$extraDepartments) {
return $departments;
}
$departmentMap = [];
foreach ($departments as $department) {
if (isset($department['id'])) {
$departmentMap[(int) $department['id']] = $department;
}
}
foreach ($extraDepartments as $department) {
if (isset($department['id'])) {
$departmentMap[(int) $department['id']] = $department;
}
}
return array_values($departmentMap);
}
public function findByUuid(string $uuid): ?array
{

View File

@@ -132,48 +132,6 @@ class UserTenantContextService
return $tenants;
}
/**
* Get available departments grouped by tenant for a user.
* Returns an array of groups: ['tenant' => [...], 'departments' => [...]]
*/
public function getAvailableDepartmentsByTenant(int $userId): array
{
$tenants = $this->getAvailableTenants($userId);
if (!$tenants) {
return [];
}
$groups = [];
foreach ($tenants as $tenant) {
$tenantId = (int) ($tenant['id'] ?? 0);
if ($tenantId <= 0) {
continue;
}
$departments = $this->directoryGateway->listDepartmentsByTenantIds([$tenantId]);
usort($departments, static function ($a, $b) {
return strcmp((string) ($a['description'] ?? ''), (string) ($b['description'] ?? ''));
});
$departments = array_map(static function (array $department): array {
return [
'id' => (int) ($department['id'] ?? 0),
'uuid' => $department['uuid'] ?? '',
'description' => $department['description'] ?? '',
];
}, $departments);
$groups[] = [
'tenant' => [
'id' => (int) ($tenant['id'] ?? 0),
'uuid' => $tenant['uuid'] ?? '',
'description' => $tenant['description'] ?? '',
],
'departments' => $departments,
];
}
return $groups;
}
/**
* Set the current tenant for a user (with validation)
*/

View File

@@ -241,25 +241,4 @@ class SearchConfig
return SearchQueryNormalizer::normalizeScoreQuery($query);
}
/**
* @return array{missingIcons: string[], missingListUrls: string[]}
*/
public static function providerCoverageGaps(): array
{
$missingIcons = [];
$missingListUrls = [];
foreach (SearchSqlResourceProvider::resourceKeys() as $key) {
if (!SearchUiMetaProvider::hasIconForKey($key)) {
$missingIcons[] = $key;
}
if (!SearchUiMetaProvider::hasListUrlForKey($key)) {
$missingListUrls[] = $key;
}
}
return [
'missingIcons' => $missingIcons,
'missingListUrls' => $missingListUrls,
];
}
}

View File

@@ -354,34 +354,6 @@ function layoutHasAdminPanel(array $layoutAuth): bool
return false;
}
/**
* Normalize list-like input to sorted unique non-empty strings.
*
* @return list<string>
*/
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<int>
*/
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;
}
/**
* Reserved top-level keys in layout navigation context that modules must not override.
*

View File

@@ -416,30 +416,6 @@ function navActive($path, bool $prefix = false): array
];
}
/**
* Resolve active state for public page links (static pages and page/* slugs).
*
* @param array $extraSlugs Additional public slugs that should be treated as active.
* @return array{class:string,aria:string,isActive:bool}
*/
function navActivePublicPages(array $extraSlugs = []): array
{
$current = \MintyPHP\Http\Request::path();
if ($current === '') {
return ['class' => '', 'aria' => '', 'isActive' => false];
}
// "page/<slug>" routes and known standalone slugs should highlight the same nav entry.
$publicSlugs = array_merge(['imprint', 'privacy', 'terms'], $extraSlugs);
$isActive = strpos($current, 'page/') === 0 || in_array($current, $publicSlugs, true);
return [
'class' => $isActive ? 'active' : '',
'aria' => $isActive ? 'aria-current="page"' : '',
'isActive' => $isActive,
];
}
/**
* Load and cache the asset registry config from config/assets.php.
*/

View File

@@ -187,5 +187,4 @@ Die `Command`-Basisklasse stellt Helfer bereit:
| Methode | Zweck |
|---|---|
| `$this->bootstrapApp($channel)` | App-Bootstrap fuer Nicht-Modul-Kommandos |
| `$this->bootstrapModuleApp()` | App-Bootstrap mit Modul-Error-Policy und Locking |
| `$this->projectRoot()` | Gibt den absoluten Projekt-Root-Pfad zurueck |