From 208cb93c9577d3eadd8a346ced70df8498ca2faa Mon Sep 17 00:00:00 2001 From: Snider Date: Tue, 17 Mar 2026 09:03:50 +0000 Subject: [PATCH] fix(dx): code style fixes, strict_types, and test repair - Remove non-existent src/Core/Service/ from CLAUDE.md L1 packages list - Fix LifecycleEventsTest: remove dependency on McpToolHandler interface (lives in core-mcp, not needed since McpToolsRegistering stores class name strings) - Run Laravel Pint to fix PSR-12 violations across all source and test files - Add missing declare(strict_types=1) to 18 PHP files (tests, seeders, Layout.php, GenerateServiceOgImages.php) Co-Authored-By: Virgil --- CLAUDE.md | 1 - config/core.php | 4 +- src/Core/Actions/ScheduleServiceProvider.php | 2 +- src/Core/Actions/ScheduledAction.php | 9 +- src/Core/Actions/ScheduledActionScanner.php | 5 +- src/Core/Activity/Concerns/LogsActivity.php | 3 +- .../Activity/Console/ActivityPruneCommand.php | 3 +- src/Core/Activity/Models/Activity.php | 5 +- .../View/Modal/Admin/ActivityFeed.php | 3 +- src/Core/Boot.php | 11 +-- .../Bouncer/Gate/Models/ActionPermission.php | 16 ++-- .../Bouncer/Gate/Models/ActionRequest.php | 18 ++-- .../Gate/Tests/Feature/ActionGateTest.php | 3 +- src/Core/Cdn/Boot.php | 35 +++++--- src/Core/Cdn/Console/CdnPurge.php | 20 +++-- src/Core/Cdn/Console/PushAssetsToCdn.php | 5 +- src/Core/Cdn/Facades/Cdn.php | 2 +- src/Core/Cdn/Jobs/PushAssetToCdn.php | 5 +- src/Core/Cdn/Models/StorageOffload.php | 7 +- src/Core/Cdn/Services/AssetPipeline.php | 3 +- src/Core/Cdn/Services/FluxCdnService.php | 5 +- src/Core/Cdn/Services/StorageOffload.php | 3 +- src/Core/Cdn/Services/StorageUrlResolver.php | 10 ++- .../Config/Console/ConfigExportCommand.php | 15 ++-- .../Config/Console/ConfigImportCommand.php | 12 +-- src/Core/Config/Console/ConfigListCommand.php | 5 +- .../Config/Console/ConfigPrimeCommand.php | 9 +- .../Config/Console/ConfigVersionCommand.php | 15 ++-- src/Core/Config/Contracts/ConfigProvider.php | 3 +- src/Core/Config/Models/Channel.php | 10 ++- src/Core/Config/Models/ConfigKey.php | 10 ++- src/Core/Config/Models/ConfigProfile.php | 12 +-- src/Core/Config/Models/ConfigResolved.php | 13 +-- src/Core/Config/Models/ConfigValue.php | 13 +-- src/Core/Config/Models/ConfigVersion.php | 25 +++--- .../Tests/Feature/ConfigServiceTest.php | 3 +- .../Config/View/Modal/Admin/ConfigPanel.php | 21 +++-- .../View/Modal/Admin/WorkspaceConfig.php | 11 ++- src/Core/Console/Commands/InstallCommand.php | 6 +- src/Core/Console/Commands/MakeModCommand.php | 6 +- src/Core/Console/Commands/MakePlugCommand.php | 6 +- .../Console/Commands/MakeWebsiteCommand.php | 6 +- .../Console/Commands/NewProjectCommand.php | 6 +- .../Commands/PruneEmailShieldStatsCommand.php | 6 +- src/Core/Crypt/EncryptArrayObject.php | 8 +- src/Core/Front/Admin/AdminMenuRegistry.php | 5 +- src/Core/Front/Admin/Boot.php | 18 ++-- .../Admin/View/Components/ActivityFeed.php | 3 +- .../Admin/View/Components/ActivityLog.php | 3 +- .../Front/Admin/View/Components/Alert.php | 3 +- .../Front/Admin/View/Components/CardGrid.php | 3 +- .../Admin/View/Components/ClearFilters.php | 3 +- .../Front/Admin/View/Components/DataTable.php | 3 +- .../Admin/View/Components/EditableTable.php | 3 +- .../Front/Admin/View/Components/Filter.php | 3 +- .../Front/Admin/View/Components/FilterBar.php | 3 +- .../Front/Admin/View/Components/LinkGrid.php | 3 +- .../Admin/View/Components/ManagerTable.php | 3 +- .../Front/Admin/View/Components/Metrics.php | 3 +- .../Admin/View/Components/ProgressList.php | 3 +- .../Front/Admin/View/Components/Search.php | 3 +- .../Admin/View/Components/ServiceCard.php | 3 +- .../Front/Admin/View/Components/Sidemenu.php | 11 ++- .../Front/Admin/View/Components/Stats.php | 3 +- .../Admin/View/Components/StatusCards.php | 3 +- src/Core/Front/Boot.php | 10 ++- src/Core/Front/Cli/Boot.php | 6 +- src/Core/Front/Components/Layout.php | 2 + src/Core/Front/Web/Boot.php | 18 ++-- .../Front/Web/Middleware/FindDomainRecord.php | 7 +- .../Front/Web/Middleware/ResilientSession.php | 3 +- .../Livewire/HeaderConfigurationManager.php | 3 +- .../Commands/TranslationCoverageCommand.php | 13 +-- .../Commands/TranslationMemoryCommand.php | 9 +- src/Core/LifecycleEventProvider.php | 6 +- src/Core/Media/Abstracts/MediaConversion.php | 3 +- src/Core/Media/Image/ImageOptimization.php | 5 +- src/Core/Search/Analytics/SearchAnalytics.php | 13 +-- src/Core/Search/Boot.php | 5 +- .../Search/Suggestions/SearchSuggestions.php | 13 +-- src/Core/Search/Unified.php | 20 +++-- src/Core/Seo/Boot.php | 5 +- .../Commands/GenerateServiceOgImages.php | 2 + src/Core/Seo/Jobs/GenerateOgImageJob.php | 10 ++- src/Core/Seo/Models/SeoScoreHistory.php | 14 +-- src/Core/Seo/SeoMetadata.php | 20 +++-- src/Core/Storage/CacheResilienceProvider.php | 5 +- .../Storage/Commands/WarmCacheCommand.php | 6 +- .../Tests/Feature/AdminComponentsTest.php | 3 +- .../Tests/Feature/AdminRouteSmokeTest.php | 6 +- src/Core/Tests/Feature/CdnIntegrationTest.php | 10 ++- src/Core/Tests/Feature/Config/ChannelTest.php | 3 +- .../Tests/Feature/Config/ConfigValueTest.php | 3 +- src/Core/Tests/Feature/CoreComponentsTest.php | 65 +++++++------- .../Tests/Feature/DatabaseMigrationTest.php | 11 ++- src/Core/Tests/Feature/EmailShieldTest.php | 3 +- src/Core/Tests/Feature/ErrorPagesTest.php | 10 ++- src/Core/Tests/Feature/ImageOptimizerTest.php | 4 +- .../Tests/Feature/MailConfigurationTest.php | 6 +- .../Feature/ModuleScannerIntegrationTest.php | 5 +- .../Feature/OffloadMigrateCommandTest.php | 2 + .../Feature/RewriteOffloadedUrlsTest.php | 2 + src/Core/Tests/Feature/SecurityFixesTest.php | 63 ++++++++------ .../Tests/Feature/SecurityHeadersTest.php | 5 +- src/Core/Tests/Feature/StorageOffloadTest.php | 8 +- .../Tests/Feature/ValidationRulesTest.php | 3 +- src/Core/Tests/Unit/HadesEncryptTest.php | 2 + src/Core/Tests/Unit/LthnHashTest.php | 2 + .../Unit/Services/BunnyCdnServiceTest.php | 5 +- src/Core/Webhook/CronTrigger.php | 2 +- src/Mod/Trees/Database/Seeders/TreeSeeder.php | 2 + src/Mod/Trees/Routes/web.php | 3 +- .../Tests/Feature/DailyLimitAndBonusTest.php | 3 +- .../Tests/Feature/QueueProcessingTest.php | 3 +- .../Trees/Tests/Feature/ReferralRouteTest.php | 3 +- .../Tests/Feature/SignupReferralTest.php | 3 +- src/Mod/Trees/Tests/Feature/StatsApiTest.php | 3 +- .../Feature/SubscriberMonthlyCommandTest.php | 3 +- .../Trees/Tests/Feature/TreePlantingTest.php | 3 +- src/Mod/Trees/Tests/Feature/TreesPageTest.php | 3 +- src/Mod/Trees/View/Modal/Web/Index.php | 3 +- tests/Feature/ActivityLogServiceTest.php | 3 +- tests/Feature/LazyModuleListenerTest.php | 3 +- tests/Feature/LifecycleEventsTest.php | 43 ++-------- tests/Feature/LogsActivityTraitTest.php | 3 +- tests/Feature/ModuleScannerTest.php | 3 +- tests/Feature/ScheduleSyncCommandTest.php | 3 +- tests/Feature/ScheduledActionScannerTest.php | 2 +- tests/Feature/ScheduledAttributeTest.php | 4 +- tests/Feature/SeederDiscoveryTest.php | 86 ++++++++++--------- tests/Feature/WebhookControllerTest.php | 3 +- .../Alpha/Database/Seeders/AlphaSeeder.php | 2 + .../Mod/Beta/Database/Seeders/BetaSeeder.php | 2 + .../Database/Seeders/CircularASeeder.php | 2 + .../Database/Seeders/CircularBSeeder.php | 2 + .../Gamma/Database/Seeders/DeltaSeeder.php | 2 + .../Gamma/Database/Seeders/GammaSeeder.php | 2 + 137 files changed, 654 insertions(+), 448 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bbc86db..9d27836 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -71,7 +71,6 @@ src/Core/Lang/ # Translation system with ICU + locale fallback chains src/Core/Media/ # Media handling with thumbnail helpers src/Core/Search/ # Search functionality src/Core/Seo/ # SEO utilities -src/Core/Service/ # Service discovery and dependency resolution src/Core/Storage/ # Storage with Redis circuit breaker + fallback src/Core/Webhook/ # Webhook system + CronTrigger scheduled action ``` diff --git a/config/core.php b/config/core.php index bf5f195..aafe449 100644 --- a/config/core.php +++ b/config/core.php @@ -1,5 +1,7 @@ env('CORE_ACTIVITY_MODEL', \Core\Activity\Models\Activity::class), + 'activity_model' => env('CORE_ACTIVITY_MODEL', Activity::class), ], ]; diff --git a/src/Core/Actions/ScheduleServiceProvider.php b/src/Core/Actions/ScheduleServiceProvider.php index 2d525e2..847a8c1 100644 --- a/src/Core/Actions/ScheduleServiceProvider.php +++ b/src/Core/Actions/ScheduleServiceProvider.php @@ -99,7 +99,7 @@ class ScheduleServiceProvider extends ServiceProvider } // Verify the class uses the Action trait - if (! in_array(\Core\Actions\Action::class, class_uses_recursive($class), true)) { + if (! in_array(Action::class, class_uses_recursive($class), true)) { logger()->warning("Scheduled action {$class} does not use the Action trait — skipping"); continue; diff --git a/src/Core/Actions/ScheduledAction.php b/src/Core/Actions/ScheduledAction.php index 298832c..1d489bd 100644 --- a/src/Core/Actions/ScheduledAction.php +++ b/src/Core/Actions/ScheduledAction.php @@ -13,6 +13,7 @@ namespace Core\Actions; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Carbon; /** * Represents a scheduled action persisted in the database. @@ -24,10 +25,10 @@ use Illuminate\Database\Eloquent\Model; * @property bool $without_overlapping * @property bool $run_in_background * @property bool $is_enabled - * @property \Illuminate\Support\Carbon|null $last_run_at - * @property \Illuminate\Support\Carbon|null $next_run_at - * @property \Illuminate\Support\Carbon $created_at - * @property \Illuminate\Support\Carbon $updated_at + * @property Carbon|null $last_run_at + * @property Carbon|null $next_run_at + * @property Carbon $created_at + * @property Carbon $updated_at */ class ScheduledAction extends Model { diff --git a/src/Core/Actions/ScheduledActionScanner.php b/src/Core/Actions/ScheduledActionScanner.php index 710774c..4d4f501 100644 --- a/src/Core/Actions/ScheduledActionScanner.php +++ b/src/Core/Actions/ScheduledActionScanner.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Actions; +use Core\ModuleScanner; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use ReflectionClass; @@ -24,7 +25,7 @@ use ReflectionClass; * It uses PHP's native reflection to read attributes — no file parsing. * * @see Scheduled The attribute this scanner discovers - * @see \Core\ModuleScanner Similar pattern for Boot.php discovery + * @see ModuleScanner Similar pattern for Boot.php discovery */ class ScheduledActionScanner { @@ -32,7 +33,7 @@ class ScheduledActionScanner * Scan directories for classes with #[Scheduled] attribute. * * @param array $paths Directories to scan recursively - * @return array Map of class name to attribute instance + * @return array Map of class name to attribute instance */ public function scan(array $paths): array { diff --git a/src/Core/Activity/Concerns/LogsActivity.php b/src/Core/Activity/Concerns/LogsActivity.php index 18e9896..72f0e07 100644 --- a/src/Core/Activity/Concerns/LogsActivity.php +++ b/src/Core/Activity/Concerns/LogsActivity.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Activity\Concerns; +use Spatie\Activitylog\Contracts\Activity; use Spatie\Activitylog\LogOptions; use Spatie\Activitylog\Traits\LogsActivity as SpatieLogsActivity; @@ -77,7 +78,7 @@ trait LogsActivity /** * Tap into the activity before it's saved to add workspace_id. */ - public function tapActivity(\Spatie\Activitylog\Contracts\Activity $activity, string $eventName): void + public function tapActivity(Activity $activity, string $eventName): void { if ($this->shouldIncludeWorkspace()) { $workspaceId = $this->getActivityWorkspaceId(); diff --git a/src/Core/Activity/Console/ActivityPruneCommand.php b/src/Core/Activity/Console/ActivityPruneCommand.php index 4d7bd53..72971f9 100644 --- a/src/Core/Activity/Console/ActivityPruneCommand.php +++ b/src/Core/Activity/Console/ActivityPruneCommand.php @@ -13,6 +13,7 @@ namespace Core\Activity\Console; use Core\Activity\Services\ActivityLogService; use Illuminate\Console\Command; +use Spatie\Activitylog\Models\Activity; /** * Command to prune old activity logs. @@ -48,7 +49,7 @@ class ActivityPruneCommand extends Command if ($this->option('dry-run')) { // Count without deleting - $activityModel = config('core.activity.activity_model', \Spatie\Activitylog\Models\Activity::class); + $activityModel = config('core.activity.activity_model', Activity::class); $count = $activityModel::where('created_at', '<', $cutoffDate)->count(); $this->info("Would delete {$count} activity records."); diff --git a/src/Core/Activity/Models/Activity.php b/src/Core/Activity/Models/Activity.php index 52a127e..9f420d6 100644 --- a/src/Core/Activity/Models/Activity.php +++ b/src/Core/Activity/Models/Activity.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Core\Activity\Models; use Core\Activity\Scopes\ActivityScopes; +use Illuminate\Support\Collection; use Spatie\Activitylog\Models\Activity as SpatieActivity; /** @@ -81,9 +82,9 @@ class Activity extends SpatieActivity /** * Get the changed attributes. * - * @return \Illuminate\Support\Collection + * @return Collection */ - public function getChangesAttribute(): \Illuminate\Support\Collection + public function getChangesAttribute(): Collection { $old = $this->old_values; $new = $this->new_values; diff --git a/src/Core/Activity/View/Modal/Admin/ActivityFeed.php b/src/Core/Activity/View/Modal/Admin/ActivityFeed.php index b92f66c..2ee47ac 100644 --- a/src/Core/Activity/View/Modal/Admin/ActivityFeed.php +++ b/src/Core/Activity/View/Modal/Admin/ActivityFeed.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Core\Activity\View\Modal\Admin; use Core\Activity\Services\ActivityLogService; +use Illuminate\Contracts\View\View; use Illuminate\Pagination\LengthAwarePaginator; use Livewire\Attributes\Computed; use Livewire\Attributes\Url; @@ -362,7 +363,7 @@ class ActivityFeed extends Component }; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('core.activity::admin.activity-feed'); } diff --git a/src/Core/Boot.php b/src/Core/Boot.php index 532ac14..9fd6964 100644 --- a/src/Core/Boot.php +++ b/src/Core/Boot.php @@ -14,6 +14,7 @@ namespace Core; use Illuminate\Foundation\Application; use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Middleware; +use Illuminate\Session\Middleware\StartSession; /** * Application bootstrap - configures Laravel with Core framework patterns. @@ -36,16 +37,16 @@ class Boot */ public static array $providers = [ // Lifecycle events - must load first to wire lazy listeners - \Core\LifecycleEventProvider::class, + LifecycleEventProvider::class, // Websites - domain-scoped, must wire before frontages fire events - \Core\Website\Boot::class, + Website\Boot::class, // Core frontages - fire lifecycle events - \Core\Front\Boot::class, + Front\Boot::class, // Base modules (from core-php package) - \Core\Mod\Boot::class, + Mod\Boot::class, ]; /** @@ -58,7 +59,7 @@ class Boot ->withMiddleware(function (Middleware $middleware): void { // Session middleware priority $middleware->priority([ - \Illuminate\Session\Middleware\StartSession::class, + StartSession::class, ]); $middleware->redirectGuestsTo('/login'); diff --git a/src/Core/Bouncer/Gate/Models/ActionPermission.php b/src/Core/Bouncer/Gate/Models/ActionPermission.php index a727539..df34dbb 100644 --- a/src/Core/Bouncer/Gate/Models/ActionPermission.php +++ b/src/Core/Bouncer/Gate/Models/ActionPermission.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Core\Bouncer\Gate\Models; +use Carbon\Carbon; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -29,9 +31,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property string $source How this was created ('trained', 'seeded', 'manual') * @property string|null $trained_route The route used during training * @property int|null $trained_by User ID who trained this action - * @property \Carbon\Carbon|null $trained_at When training occurred - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at + * @property Carbon|null $trained_at When training occurred + * @property Carbon $created_at + * @property Carbon $updated_at */ class ActionPermission extends Model { @@ -174,9 +176,9 @@ class ActionPermission extends Model /** * Get all actions for a guard. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function forGuard(string $guard): \Illuminate\Database\Eloquent\Collection + public static function forGuard(string $guard): Collection { return static::where('guard', $guard)->get(); } @@ -184,9 +186,9 @@ class ActionPermission extends Model /** * Get all allowed actions for a guard/role combination. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function allowedFor(string $guard, ?string $role = null): \Illuminate\Database\Eloquent\Collection + public static function allowedFor(string $guard, ?string $role = null): Collection { $query = static::where('guard', $guard) ->where('allowed', true); diff --git a/src/Core/Bouncer/Gate/Models/ActionRequest.php b/src/Core/Bouncer/Gate/Models/ActionRequest.php index 393776a..8eb31b6 100644 --- a/src/Core/Bouncer/Gate/Models/ActionRequest.php +++ b/src/Core/Bouncer/Gate/Models/ActionRequest.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Core\Bouncer\Gate\Models; +use Carbon\Carbon; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -30,8 +32,8 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property string|null $ip_address Client IP * @property string $status Result: 'allowed', 'denied', 'pending' * @property bool $was_trained Whether this request triggered training - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at + * @property Carbon $created_at + * @property Carbon $updated_at */ class ActionRequest extends Model { @@ -103,9 +105,9 @@ class ActionRequest extends Model /** * Get pending requests (for training review). * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function pending(): \Illuminate\Database\Eloquent\Collection + public static function pending(): Collection { return static::where('status', self::STATUS_PENDING) ->orderBy('created_at', 'desc') @@ -115,9 +117,9 @@ class ActionRequest extends Model /** * Get denied requests for an action. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function deniedFor(string $action): \Illuminate\Database\Eloquent\Collection + public static function deniedFor(string $action): Collection { return static::where('action', $action) ->where('status', self::STATUS_DENIED) @@ -128,9 +130,9 @@ class ActionRequest extends Model /** * Get requests by user. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function forUser(int $userId): \Illuminate\Database\Eloquent\Collection + public static function forUser(int $userId): Collection { return static::where('user_id', $userId) ->orderBy('created_at', 'desc') diff --git a/src/Core/Bouncer/Gate/Tests/Feature/ActionGateTest.php b/src/Core/Bouncer/Gate/Tests/Feature/ActionGateTest.php index 555b3d9..e2d9dcc 100644 --- a/src/Core/Bouncer/Gate/Tests/Feature/ActionGateTest.php +++ b/src/Core/Bouncer/Gate/Tests/Feature/ActionGateTest.php @@ -13,6 +13,7 @@ namespace Core\Bouncer\Gate\Tests\Feature; use Core\Bouncer\Gate\ActionGateService; use Core\Bouncer\Gate\Attributes\Action; +use Core\Bouncer\Gate\Boot; use Core\Bouncer\Gate\Models\ActionPermission; use Core\Bouncer\Gate\Models\ActionRequest; use Core\Bouncer\Gate\RouteActionMacro; @@ -40,7 +41,7 @@ class ActionGateTest extends TestCase protected function getPackageProviders($app): array { return [ - \Core\Bouncer\Gate\Boot::class, + Boot::class, ]; } diff --git a/src/Core/Cdn/Boot.php b/src/Core/Cdn/Boot.php index f44fd14..b18ef3e 100644 --- a/src/Core/Cdn/Boot.php +++ b/src/Core/Cdn/Boot.php @@ -11,6 +11,10 @@ declare(strict_types=1); namespace Core\Cdn; +use App\Facades\Cdn; +use App\Http\Middleware\RewriteOffloadedUrls; +use App\Jobs\PushAssetToCdn; +use App\Traits\HasCdnUrls; use Core\Cdn\Console\CdnPurge; use Core\Cdn\Console\OffloadMigrateCommand; use Core\Cdn\Console\PushAssetsToCdn; @@ -21,6 +25,9 @@ use Core\Cdn\Services\BunnyStorageService; use Core\Cdn\Services\FluxCdnService; use Core\Cdn\Services\StorageOffload; use Core\Cdn\Services\StorageUrlResolver; +use Core\Crypt\LthnHash; +use Core\Plug\Cdn\CdnManager; +use Core\Plug\Storage\StorageManager; use Illuminate\Support\ServiceProvider; /** @@ -45,11 +52,11 @@ class Boot extends ServiceProvider $this->mergeConfigFrom(__DIR__.'/offload.php', 'offload'); // Register Plug managers as singletons (when available) - if (class_exists(\Core\Plug\Cdn\CdnManager::class)) { - $this->app->singleton(\Core\Plug\Cdn\CdnManager::class); + if (class_exists(CdnManager::class)) { + $this->app->singleton(CdnManager::class); } - if (class_exists(\Core\Plug\Storage\StorageManager::class)) { - $this->app->singleton(\Core\Plug\Storage\StorageManager::class); + if (class_exists(StorageManager::class)) { + $this->app->singleton(StorageManager::class); } // Register legacy services as singletons (for backward compatibility) @@ -115,32 +122,32 @@ class Boot extends ServiceProvider // Crypt if (! class_exists(\App\Services\Crypt\LthnHash::class)) { - class_alias(\Core\Crypt\LthnHash::class, \App\Services\Crypt\LthnHash::class); + class_alias(LthnHash::class, \App\Services\Crypt\LthnHash::class); } // Models if (! class_exists(\App\Models\StorageOffload::class)) { - class_alias(\Core\Cdn\Models\StorageOffload::class, \App\Models\StorageOffload::class); + class_alias(Models\StorageOffload::class, \App\Models\StorageOffload::class); } // Facades - if (! class_exists(\App\Facades\Cdn::class)) { - class_alias(\Core\Cdn\Facades\Cdn::class, \App\Facades\Cdn::class); + if (! class_exists(Cdn::class)) { + class_alias(Facades\Cdn::class, Cdn::class); } // Traits - if (! trait_exists(\App\Traits\HasCdnUrls::class)) { - class_alias(\Core\Cdn\Traits\HasCdnUrls::class, \App\Traits\HasCdnUrls::class); + if (! trait_exists(HasCdnUrls::class)) { + class_alias(Traits\HasCdnUrls::class, HasCdnUrls::class); } // Middleware - if (! class_exists(\App\Http\Middleware\RewriteOffloadedUrls::class)) { - class_alias(\Core\Cdn\Middleware\RewriteOffloadedUrls::class, \App\Http\Middleware\RewriteOffloadedUrls::class); + if (! class_exists(RewriteOffloadedUrls::class)) { + class_alias(Middleware\RewriteOffloadedUrls::class, RewriteOffloadedUrls::class); } // Jobs - if (! class_exists(\App\Jobs\PushAssetToCdn::class)) { - class_alias(\Core\Cdn\Jobs\PushAssetToCdn::class, \App\Jobs\PushAssetToCdn::class); + if (! class_exists(PushAssetToCdn::class)) { + class_alias(Jobs\PushAssetToCdn::class, PushAssetToCdn::class); } } } diff --git a/src/Core/Cdn/Console/CdnPurge.php b/src/Core/Cdn/Console/CdnPurge.php index b947999..b2232d0 100644 --- a/src/Core/Cdn/Console/CdnPurge.php +++ b/src/Core/Cdn/Console/CdnPurge.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Core\Cdn\Console; +use Core\Plug\Cdn\Bunny\Purge; +use Core\Tenant\Models\Workspace; use Illuminate\Console\Command; class CdnPurge extends Command @@ -43,8 +45,8 @@ class CdnPurge extends Command { parent::__construct(); - if (class_exists(\Core\Plug\Cdn\Bunny\Purge::class)) { - $this->purger = new \Core\Plug\Cdn\Bunny\Purge; + if (class_exists(Purge::class)) { + $this->purger = new Purge; } } @@ -96,8 +98,8 @@ class CdnPurge extends Command // Purge by workspace if (empty($workspaceArg)) { $workspaceOptions = ['all', 'Select specific URLs']; - if (class_exists(\Core\Tenant\Models\Workspace::class)) { - $workspaceOptions = array_merge($workspaceOptions, \Core\Tenant\Models\Workspace::pluck('slug')->toArray()); + if (class_exists(Workspace::class)) { + $workspaceOptions = array_merge($workspaceOptions, Workspace::pluck('slug')->toArray()); } $workspaceArg = $this->choice( 'What would you like to purge?', @@ -218,13 +220,13 @@ class CdnPurge extends Command protected function purgeAllWorkspaces(bool $dryRun): int { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->error('Workspace purge requires Tenant module to be installed.'); return self::FAILURE; } - $workspaces = \Core\Tenant\Models\Workspace::all(); + $workspaces = Workspace::all(); if ($workspaces->isEmpty()) { $this->error('No workspaces found'); @@ -276,19 +278,19 @@ class CdnPurge extends Command protected function purgeWorkspace(string $slug, bool $dryRun): int { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->error('Workspace purge requires Tenant module to be installed.'); return self::FAILURE; } - $workspace = \Core\Tenant\Models\Workspace::where('slug', $slug)->first(); + $workspace = Workspace::where('slug', $slug)->first(); if (! $workspace) { $this->error("Workspace not found: {$slug}"); $this->newLine(); $this->info('Available workspaces:'); - \Core\Tenant\Models\Workspace::pluck('slug')->each(fn ($s) => $this->line(" - {$s}")); + Workspace::pluck('slug')->each(fn ($s) => $this->line(" - {$s}")); return self::FAILURE; } diff --git a/src/Core/Cdn/Console/PushAssetsToCdn.php b/src/Core/Cdn/Console/PushAssetsToCdn.php index 3e2e931..c4d2d4c 100644 --- a/src/Core/Cdn/Console/PushAssetsToCdn.php +++ b/src/Core/Cdn/Console/PushAssetsToCdn.php @@ -13,6 +13,7 @@ namespace Core\Cdn\Console; use Core\Cdn\Services\FluxCdnService; use Core\Cdn\Services\StorageUrlResolver; +use Core\Plug\Storage\Bunny\VBucket; use Illuminate\Console\Command; use Illuminate\Support\Facades\File; @@ -43,7 +44,7 @@ class PushAssetsToCdn extends Command public function handle(FluxCdnService $flux, StorageUrlResolver $cdn): int { - if (! class_exists(\Core\Plug\Storage\Bunny\VBucket::class)) { + if (! class_exists(VBucket::class)) { $this->error('Push assets to CDN requires Core\Plug\Storage\Bunny\VBucket class. Plug module not installed.'); return self::FAILURE; @@ -54,7 +55,7 @@ class PushAssetsToCdn extends Command // Create vBucket for workspace isolation $domain = $this->option('domain'); - $this->vbucket = \Core\Plug\Storage\Bunny\VBucket::public($domain); + $this->vbucket = VBucket::public($domain); $pushFlux = $this->option('flux'); $pushFontawesome = $this->option('fontawesome'); diff --git a/src/Core/Cdn/Facades/Cdn.php b/src/Core/Cdn/Facades/Cdn.php index 88672ef..d4f3156 100644 --- a/src/Core/Cdn/Facades/Cdn.php +++ b/src/Core/Cdn/Facades/Cdn.php @@ -42,7 +42,7 @@ use Illuminate\Support\Facades\Facade; * @method static string vBucketPath(string $domain, string $path) * @method static array vBucketUrls(string $domain, string $path) * - * @see \Core\Cdn\Services\StorageUrlResolver + * @see StorageUrlResolver */ class Cdn extends Facade { diff --git a/src/Core/Cdn/Jobs/PushAssetToCdn.php b/src/Core/Cdn/Jobs/PushAssetToCdn.php index fea657b..70c1736 100644 --- a/src/Core/Cdn/Jobs/PushAssetToCdn.php +++ b/src/Core/Cdn/Jobs/PushAssetToCdn.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Cdn\Jobs; +use Core\Plug\Storage\StorageManager; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -60,7 +61,7 @@ class PushAssetToCdn implements ShouldQueue */ public function handle(?object $storage = null): void { - if (! class_exists(\Core\Plug\Storage\StorageManager::class)) { + if (! class_exists(StorageManager::class)) { Log::warning('PushAssetToCdn: StorageManager not available, Plug module not installed'); return; @@ -68,7 +69,7 @@ class PushAssetToCdn implements ShouldQueue // Resolve from container if not injected if ($storage === null) { - $storage = app(\Core\Plug\Storage\StorageManager::class); + $storage = app(StorageManager::class); } if (! config('cdn.bunny.push_enabled', false)) { diff --git a/src/Core/Cdn/Models/StorageOffload.php b/src/Core/Cdn/Models/StorageOffload.php index 3de7912..a0b39f3 100644 --- a/src/Core/Cdn/Models/StorageOffload.php +++ b/src/Core/Cdn/Models/StorageOffload.php @@ -13,6 +13,7 @@ namespace Core\Cdn\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Carbon; /** * Tracks files that have been offloaded to remote storage. @@ -26,9 +27,9 @@ use Illuminate\Database\Eloquent\Model; * @property string|null $mime_type MIME type * @property string|null $category Category for path prefixing * @property array|null $metadata Additional metadata - * @property \Illuminate\Support\Carbon|null $offloaded_at When file was offloaded - * @property \Illuminate\Support\Carbon|null $created_at - * @property \Illuminate\Support\Carbon|null $updated_at + * @property Carbon|null $offloaded_at When file was offloaded + * @property Carbon|null $created_at + * @property Carbon|null $updated_at */ class StorageOffload extends Model { diff --git a/src/Core/Cdn/Services/AssetPipeline.php b/src/Core/Cdn/Services/AssetPipeline.php index dd3944a..323d536 100644 --- a/src/Core/Cdn/Services/AssetPipeline.php +++ b/src/Core/Cdn/Services/AssetPipeline.php @@ -13,6 +13,7 @@ namespace Core\Cdn\Services; use Core\Cdn\Jobs\PushAssetToCdn; use Illuminate\Http\UploadedFile; +use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; /** @@ -339,7 +340,7 @@ class AssetPipeline PushAssetToCdn::dispatch($disk, $path, $zone); } elseif ($this->storage !== null) { // Synchronous push if no queue configured (requires StorageManager from Plug module) - $diskInstance = \Illuminate\Support\Facades\Storage::disk($disk); + $diskInstance = Storage::disk($disk); if ($diskInstance->exists($path)) { $contents = $diskInstance->get($path); $this->storage->zone($zone)->upload()->contents($path, $contents); diff --git a/src/Core/Cdn/Services/FluxCdnService.php b/src/Core/Cdn/Services/FluxCdnService.php index 7f80550..2fd0ef5 100644 --- a/src/Core/Cdn/Services/FluxCdnService.php +++ b/src/Core/Cdn/Services/FluxCdnService.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Core\Cdn\Services; use Core\Helpers\Cdn; +use Flux\AssetManager; use Flux\Flux; /** @@ -83,7 +84,7 @@ class FluxCdnService // Use CDN when enabled (respects CDN_FORCE_LOCAL for testing) if (! $this->shouldUseCdn()) { - return \Flux\AssetManager::editorScripts(); + return AssetManager::editorScripts(); } // In production, use CDN URL (no vBucket - shared platform asset) @@ -109,7 +110,7 @@ class FluxCdnService // Use CDN when enabled (respects CDN_FORCE_LOCAL for testing) if (! $this->shouldUseCdn()) { - return \Flux\AssetManager::editorStyles(); + return AssetManager::editorStyles(); } // In production, use CDN URL (no vBucket - shared platform asset) diff --git a/src/Core/Cdn/Services/StorageOffload.php b/src/Core/Cdn/Services/StorageOffload.php index 5914fbe..fa4ed06 100644 --- a/src/Core/Cdn/Services/StorageOffload.php +++ b/src/Core/Cdn/Services/StorageOffload.php @@ -13,6 +13,7 @@ namespace Core\Cdn\Services; use Core\Cdn\Models\StorageOffload as OffloadModel; use Illuminate\Contracts\Filesystem\Filesystem; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Log; @@ -305,7 +306,7 @@ class StorageOffload /** * Get all offloaded files for a category. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ public function getByCategory(string $category) { diff --git a/src/Core/Cdn/Services/StorageUrlResolver.php b/src/Core/Cdn/Services/StorageUrlResolver.php index 0c5aff4..3ec6a84 100644 --- a/src/Core/Cdn/Services/StorageUrlResolver.php +++ b/src/Core/Cdn/Services/StorageUrlResolver.php @@ -12,6 +12,8 @@ declare(strict_types=1); namespace Core\Cdn\Services; use Carbon\Carbon; +use Core\Cdn\Jobs\PushAssetToCdn; +use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Storage; @@ -372,7 +374,7 @@ class StorageUrlResolver /** * Get the public storage disk. * - * @return \Illuminate\Contracts\Filesystem\Filesystem + * @return Filesystem */ public function publicDisk() { @@ -382,7 +384,7 @@ class StorageUrlResolver /** * Get the private storage disk. * - * @return \Illuminate\Contracts\Filesystem\Filesystem + * @return Filesystem */ public function privateDisk() { @@ -403,7 +405,7 @@ class StorageUrlResolver if ($stored && $pushToCdn && config('cdn.pipeline.auto_push', true)) { // Queue the push if configured, otherwise push synchronously if ($queue = config('cdn.pipeline.queue')) { - dispatch(new \Core\Cdn\Jobs\PushAssetToCdn('hetzner-public', $path, 'public'))->onQueue($queue); + dispatch(new PushAssetToCdn('hetzner-public', $path, 'public'))->onQueue($queue); } else { $this->pushToCdn('hetzner-public', $path, 'public'); } @@ -425,7 +427,7 @@ class StorageUrlResolver if ($stored && $pushToCdn && config('cdn.pipeline.auto_push', true)) { if ($queue = config('cdn.pipeline.queue')) { - dispatch(new \Core\Cdn\Jobs\PushAssetToCdn('hetzner-private', $path, 'private'))->onQueue($queue); + dispatch(new PushAssetToCdn('hetzner-private', $path, 'private'))->onQueue($queue); } else { $this->pushToCdn('hetzner-private', $path, 'private'); } diff --git a/src/Core/Config/Console/ConfigExportCommand.php b/src/Core/Config/Console/ConfigExportCommand.php index 8264886..2eb83b8 100644 --- a/src/Core/Config/Console/ConfigExportCommand.php +++ b/src/Core/Config/Console/ConfigExportCommand.php @@ -12,8 +12,11 @@ declare(strict_types=1); namespace Core\Config\Console; use Core\Config\ConfigExporter; +use Core\Config\Models\ConfigKey; +use Core\Tenant\Models\Workspace; use Illuminate\Console\Command; use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Export config to JSON or YAML file. @@ -45,13 +48,13 @@ class ConfigExportCommand extends Command // Resolve workspace $workspace = null; if ($workspaceSlug) { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->components->error('Tenant module not installed. Cannot export workspace config.'); return self::FAILURE; } - $workspace = \Core\Tenant\Models\Workspace::where('slug', $workspaceSlug)->first(); + $workspace = Workspace::where('slug', $workspaceSlug)->first(); if (! $workspace) { $this->components->error("Workspace not found: {$workspaceSlug}"); @@ -96,16 +99,16 @@ class ConfigExportCommand extends Command /** * Get autocompletion suggestions. */ - public function complete(CompletionInput $input, \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions): void + public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { if ($input->mustSuggestOptionValuesFor('workspace')) { - if (class_exists(\Core\Tenant\Models\Workspace::class)) { - $suggestions->suggestValues(\Core\Tenant\Models\Workspace::pluck('slug')->toArray()); + if (class_exists(Workspace::class)) { + $suggestions->suggestValues(Workspace::pluck('slug')->toArray()); } } if ($input->mustSuggestOptionValuesFor('category')) { - $suggestions->suggestValues(\Core\Config\Models\ConfigKey::distinct()->pluck('category')->toArray()); + $suggestions->suggestValues(ConfigKey::distinct()->pluck('category')->toArray()); } } } diff --git a/src/Core/Config/Console/ConfigImportCommand.php b/src/Core/Config/Console/ConfigImportCommand.php index 0788948..dc0ed83 100644 --- a/src/Core/Config/Console/ConfigImportCommand.php +++ b/src/Core/Config/Console/ConfigImportCommand.php @@ -13,8 +13,10 @@ namespace Core\Config\Console; use Core\Config\ConfigExporter; use Core\Config\ConfigVersioning; +use Core\Tenant\Models\Workspace; use Illuminate\Console\Command; use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Import config from JSON or YAML file. @@ -53,13 +55,13 @@ class ConfigImportCommand extends Command // Resolve workspace $workspace = null; if ($workspaceSlug) { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->components->error('Tenant module not installed. Cannot import workspace config.'); return self::FAILURE; } - $workspace = \Core\Tenant\Models\Workspace::where('slug', $workspaceSlug)->first(); + $workspace = Workspace::where('slug', $workspaceSlug)->first(); if (! $workspace) { $this->components->error("Workspace not found: {$workspaceSlug}"); @@ -174,11 +176,11 @@ class ConfigImportCommand extends Command /** * Get autocompletion suggestions. */ - public function complete(CompletionInput $input, \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions): void + public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { if ($input->mustSuggestOptionValuesFor('workspace')) { - if (class_exists(\Core\Tenant\Models\Workspace::class)) { - $suggestions->suggestValues(\Core\Tenant\Models\Workspace::pluck('slug')->toArray()); + if (class_exists(Workspace::class)) { + $suggestions->suggestValues(Workspace::pluck('slug')->toArray()); } } } diff --git a/src/Core/Config/Console/ConfigListCommand.php b/src/Core/Config/Console/ConfigListCommand.php index 97e3e9a..28f4398 100644 --- a/src/Core/Config/Console/ConfigListCommand.php +++ b/src/Core/Config/Console/ConfigListCommand.php @@ -13,6 +13,7 @@ namespace Core\Config\Console; use Core\Config\ConfigService; use Core\Config\Models\ConfigKey; +use Core\Tenant\Models\Workspace; use Illuminate\Console\Command; class ConfigListCommand extends Command @@ -33,13 +34,13 @@ class ConfigListCommand extends Command $workspace = null; if ($workspaceSlug) { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->error('Tenant module not installed. Cannot filter by workspace.'); return self::FAILURE; } - $workspace = \Core\Tenant\Models\Workspace::where('slug', $workspaceSlug)->first(); + $workspace = Workspace::where('slug', $workspaceSlug)->first(); if (! $workspace) { $this->error("Workspace not found: {$workspaceSlug}"); diff --git a/src/Core/Config/Console/ConfigPrimeCommand.php b/src/Core/Config/Console/ConfigPrimeCommand.php index c121eca..91bcc0c 100644 --- a/src/Core/Config/Console/ConfigPrimeCommand.php +++ b/src/Core/Config/Console/ConfigPrimeCommand.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Core\Config\Console; use Core\Config\ConfigService; +use Core\Tenant\Models\Workspace; use Illuminate\Console\Command; class ConfigPrimeCommand extends Command @@ -36,13 +37,13 @@ class ConfigPrimeCommand extends Command } if ($workspaceSlug) { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->error('Tenant module not installed. Cannot prime workspace config.'); return self::FAILURE; } - $workspace = \Core\Tenant\Models\Workspace::where('slug', $workspaceSlug)->first(); + $workspace = Workspace::where('slug', $workspaceSlug)->first(); if (! $workspace) { $this->error("Workspace not found: {$workspaceSlug}"); @@ -59,7 +60,7 @@ class ConfigPrimeCommand extends Command $this->info('Priming config cache for all workspaces...'); - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->warn('Tenant module not installed. Only priming system config.'); $config->prime(null); $this->info('System config cached.'); @@ -67,7 +68,7 @@ class ConfigPrimeCommand extends Command return self::SUCCESS; } - $this->withProgressBar(\Core\Tenant\Models\Workspace::all(), function ($workspace) use ($config) { + $this->withProgressBar(Workspace::all(), function ($workspace) use ($config) { $config->prime($workspace); }); diff --git a/src/Core/Config/Console/ConfigVersionCommand.php b/src/Core/Config/Console/ConfigVersionCommand.php index fa4140a..027f6c2 100644 --- a/src/Core/Config/Console/ConfigVersionCommand.php +++ b/src/Core/Config/Console/ConfigVersionCommand.php @@ -13,8 +13,11 @@ namespace Core\Config\Console; use Core\Config\ConfigVersioning; use Core\Config\Models\ConfigVersion; +use Core\Config\VersionDiff; +use Core\Tenant\Models\Workspace; use Illuminate\Console\Command; use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Manage config versions. @@ -50,13 +53,13 @@ class ConfigVersionCommand extends Command // Resolve workspace $workspace = null; if ($workspaceSlug) { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { $this->components->error('Tenant module not installed. Cannot manage workspace versions.'); return self::FAILURE; } - $workspace = \Core\Tenant\Models\Workspace::where('slug', $workspaceSlug)->first(); + $workspace = Workspace::where('slug', $workspaceSlug)->first(); if (! $workspace) { $this->components->error("Workspace not found: {$workspaceSlug}"); @@ -282,7 +285,7 @@ class ConfigVersionCommand extends Command /** * Display a diff. */ - protected function displayDiff(\Core\Config\VersionDiff $diff): void + protected function displayDiff(VersionDiff $diff): void { $this->components->info("Summary: {$diff->getSummary()}"); $this->newLine(); @@ -402,15 +405,15 @@ class ConfigVersionCommand extends Command /** * Get autocompletion suggestions. */ - public function complete(CompletionInput $input, \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions): void + public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { if ($input->mustSuggestArgumentValuesFor('action')) { $suggestions->suggestValues(['list', 'create', 'show', 'rollback', 'compare', 'diff', 'delete']); } if ($input->mustSuggestOptionValuesFor('workspace')) { - if (class_exists(\Core\Tenant\Models\Workspace::class)) { - $suggestions->suggestValues(\Core\Tenant\Models\Workspace::pluck('slug')->toArray()); + if (class_exists(Workspace::class)) { + $suggestions->suggestValues(Workspace::pluck('slug')->toArray()); } } } diff --git a/src/Core/Config/Contracts/ConfigProvider.php b/src/Core/Config/Contracts/ConfigProvider.php index 3cdd1a5..26b7783 100644 --- a/src/Core/Config/Contracts/ConfigProvider.php +++ b/src/Core/Config/Contracts/ConfigProvider.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Config\Contracts; +use Core\Config\ConfigResolver; use Core\Config\Models\Channel; /** @@ -72,7 +73,7 @@ use Core\Config\Models\Channel; * ``` * * - * @see \Core\Config\ConfigResolver::registerProvider() + * @see ConfigResolver::registerProvider() */ interface ConfigProvider { diff --git a/src/Core/Config/Models/Channel.php b/src/Core/Config/Models/Channel.php index 4ac8996..bd3dbc4 100644 --- a/src/Core/Config/Models/Channel.php +++ b/src/Core/Config/Models/Channel.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Core\Config\Models; +use Carbon\Carbon; +use Core\Tenant\Models\Workspace; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -35,8 +37,8 @@ use Illuminate\Support\Facades\Log; * @property int|null $parent_id * @property int|null $workspace_id * @property array|null $metadata - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at + * @property Carbon $created_at + * @property Carbon $updated_at */ class Channel extends Model { @@ -77,8 +79,8 @@ class Channel extends Model */ public function workspace(): BelongsTo { - if (class_exists(\Core\Tenant\Models\Workspace::class)) { - return $this->belongsTo(\Core\Tenant\Models\Workspace::class); + if (class_exists(Workspace::class)) { + return $this->belongsTo(Workspace::class); } // Return a null relationship when Tenant module is not installed diff --git a/src/Core/Config/Models/ConfigKey.php b/src/Core/Config/Models/ConfigKey.php index 798c012..ce8f403 100644 --- a/src/Core/Config/Models/ConfigKey.php +++ b/src/Core/Config/Models/ConfigKey.php @@ -11,7 +11,9 @@ declare(strict_types=1); namespace Core\Config\Models; +use Carbon\Carbon; use Core\Config\Enums\ConfigType; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -30,8 +32,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany; * @property string|null $description * @property mixed $default_value * @property bool $is_sensitive - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at + * @property Carbon $created_at + * @property Carbon $updated_at */ class ConfigKey extends Model { @@ -108,9 +110,9 @@ class ConfigKey extends Model /** * Get all keys for a category. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function forCategory(string $category): \Illuminate\Database\Eloquent\Collection + public static function forCategory(string $category): Collection { return static::where('category', $category)->get(); } diff --git a/src/Core/Config/Models/ConfigProfile.php b/src/Core/Config/Models/ConfigProfile.php index c54a101..57c65c1 100644 --- a/src/Core/Config/Models/ConfigProfile.php +++ b/src/Core/Config/Models/ConfigProfile.php @@ -11,7 +11,9 @@ declare(strict_types=1); namespace Core\Config\Models; +use Carbon\Carbon; use Core\Config\Enums\ScopeType; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -29,9 +31,9 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property int|null $scope_id * @property int|null $parent_profile_id * @property int $priority - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property \Carbon\Carbon|null $deleted_at + * @property Carbon $created_at + * @property Carbon $updated_at + * @property Carbon|null $deleted_at */ class ConfigProfile extends Model { @@ -90,9 +92,9 @@ class ConfigProfile extends Model /** * Get profiles for a scope. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function forScope(ScopeType $type, ?int $scopeId = null): \Illuminate\Database\Eloquent\Collection + public static function forScope(ScopeType $type, ?int $scopeId = null): Collection { return static::where('scope_type', $type) ->where('scope_id', $scopeId) diff --git a/src/Core/Config/Models/ConfigResolved.php b/src/Core/Config/Models/ConfigResolved.php index 0248281..dab2804 100644 --- a/src/Core/Config/Models/ConfigResolved.php +++ b/src/Core/Config/Models/ConfigResolved.php @@ -11,8 +11,11 @@ declare(strict_types=1); namespace Core\Config\Models; +use Carbon\Carbon; use Core\Config\ConfigResult; use Core\Config\Enums\ConfigType; +use Core\Tenant\Models\Workspace; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -36,7 +39,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property int|null $source_profile_id * @property int|null $source_channel_id * @property bool $virtual - * @property \Carbon\Carbon $computed_at + * @property Carbon $computed_at */ class ConfigResolved extends Model { @@ -71,8 +74,8 @@ class ConfigResolved extends Model */ public function workspace(): BelongsTo { - if (class_exists(\Core\Tenant\Models\Workspace::class)) { - return $this->belongsTo(\Core\Tenant\Models\Workspace::class); + if (class_exists(Workspace::class)) { + return $this->belongsTo(Workspace::class); } // Return a null relationship when Tenant module is not installed @@ -155,9 +158,9 @@ class ConfigResolved extends Model /** * Get all resolved config for a scope. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function forScope(?int $workspaceId = null, ?int $channelId = null): \Illuminate\Database\Eloquent\Collection + public static function forScope(?int $workspaceId = null, ?int $channelId = null): Collection { return static::where('workspace_id', $workspaceId) ->where('channel_id', $channelId) diff --git a/src/Core/Config/Models/ConfigValue.php b/src/Core/Config/Models/ConfigValue.php index 7ab2e55..0f783be 100644 --- a/src/Core/Config/Models/ConfigValue.php +++ b/src/Core/Config/Models/ConfigValue.php @@ -11,8 +11,11 @@ declare(strict_types=1); namespace Core\Config\Models; +use Carbon\Carbon; use Core\Config\ConfigResolver; use Core\Config\Enums\ScopeType; +use Illuminate\Contracts\Encryption\DecryptException; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Facades\Crypt; @@ -31,8 +34,8 @@ use Illuminate\Support\Facades\Crypt; * @property mixed $value * @property bool $locked * @property int|null $inherited_from - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at + * @property Carbon $created_at + * @property Carbon $updated_at */ class ConfigValue extends Model { @@ -76,7 +79,7 @@ class ConfigValue extends Model $encrypted = substr($decoded, strlen(self::ENCRYPTED_PREFIX)); return json_decode(Crypt::decryptString($encrypted), true); - } catch (\Illuminate\Contracts\Encryption\DecryptException) { + } catch (DecryptException) { // Return null if decryption fails (key rotation, corruption, etc.) return null; } @@ -255,9 +258,9 @@ class ConfigValue extends Model * * @param array $profileIds * @param array|null $channelIds Include null for "all channels" values - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function forKeyInProfiles(int $keyId, array $profileIds, ?array $channelIds = null): \Illuminate\Database\Eloquent\Collection + public static function forKeyInProfiles(int $keyId, array $profileIds, ?array $channelIds = null): Collection { return static::where('key_id', $keyId) ->whereIn('profile_id', $profileIds) diff --git a/src/Core/Config/Models/ConfigVersion.php b/src/Core/Config/Models/ConfigVersion.php index 190a65f..eb86863 100644 --- a/src/Core/Config/Models/ConfigVersion.php +++ b/src/Core/Config/Models/ConfigVersion.php @@ -11,6 +11,9 @@ declare(strict_types=1); namespace Core\Config\Models; +use Carbon\Carbon; +use Core\Tenant\Models\Workspace; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -26,7 +29,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property string $label * @property string $snapshot * @property string|null $author - * @property \Carbon\Carbon $created_at + * @property Carbon $created_at */ class ConfigVersion extends Model { @@ -65,8 +68,8 @@ class ConfigVersion extends Model */ public function workspace(): BelongsTo { - if (class_exists(\Core\Tenant\Models\Workspace::class)) { - return $this->belongsTo(\Core\Tenant\Models\Workspace::class); + if (class_exists(Workspace::class)) { + return $this->belongsTo(Workspace::class); } // Return a null relationship when Tenant module is not installed @@ -136,9 +139,9 @@ class ConfigVersion extends Model * Get versions for a scope. * * @param int|null $workspaceId Workspace ID or null for system - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function forScope(?int $workspaceId = null): \Illuminate\Database\Eloquent\Collection + public static function forScope(?int $workspaceId = null): Collection { return static::where('workspace_id', $workspaceId) ->orderByDesc('created_at') @@ -160,9 +163,9 @@ class ConfigVersion extends Model /** * Get versions created by a specific author. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ - public static function byAuthor(string $author): \Illuminate\Database\Eloquent\Collection + public static function byAuthor(string $author): Collection { return static::where('author', $author) ->orderByDesc('created_at') @@ -172,11 +175,11 @@ class ConfigVersion extends Model /** * Get versions created within a date range. * - * @param \Carbon\Carbon $from Start date - * @param \Carbon\Carbon $to End date - * @return \Illuminate\Database\Eloquent\Collection + * @param Carbon $from Start date + * @param Carbon $to End date + * @return Collection */ - public static function inDateRange(\Carbon\Carbon $from, \Carbon\Carbon $to): \Illuminate\Database\Eloquent\Collection + public static function inDateRange(Carbon $from, Carbon $to): Collection { return static::whereBetween('created_at', [$from, $to]) ->orderByDesc('created_at') diff --git a/src/Core/Config/Tests/Feature/ConfigServiceTest.php b/src/Core/Config/Tests/Feature/ConfigServiceTest.php index d9e3bf7..46d9ed9 100644 --- a/src/Core/Config/Tests/Feature/ConfigServiceTest.php +++ b/src/Core/Config/Tests/Feature/ConfigServiceTest.php @@ -19,8 +19,9 @@ use Core\Config\Models\ConfigProfile; use Core\Config\Models\ConfigResolved; use Core\Config\Models\ConfigValue; use Core\Tenant\Models\Workspace; +use Illuminate\Foundation\Testing\RefreshDatabase; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); beforeEach(function () { // Clear hash for clean test state diff --git a/src/Core/Config/View/Modal/Admin/ConfigPanel.php b/src/Core/Config/View/Modal/Admin/ConfigPanel.php index 579914b..01ddb92 100644 --- a/src/Core/Config/View/Modal/Admin/ConfigPanel.php +++ b/src/Core/Config/View/Modal/Admin/ConfigPanel.php @@ -15,6 +15,9 @@ use Core\Config\ConfigService; use Core\Config\Models\ConfigKey; use Core\Config\Models\ConfigProfile; use Core\Config\Models\ConfigValue; +use Core\Tenant\Models\Workspace; +use Illuminate\Contracts\View\View; +use Illuminate\Database\Eloquent\Collection; use Livewire\Attributes\Computed; use Livewire\Attributes\Url; use Livewire\Component; @@ -24,7 +27,7 @@ use Livewire\Component; * * @property-read ConfigProfile $activeProfile * @property-read array $categories - * @property-read \Illuminate\Database\Eloquent\Collection $workspaces + * @property-read Collection $workspaces */ class ConfigPanel extends Component { @@ -79,17 +82,17 @@ class ConfigPanel extends Component * Get all workspaces (requires Tenant module). */ #[Computed] - public function workspaces(): \Illuminate\Database\Eloquent\Collection + public function workspaces(): Collection { - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { - return new \Illuminate\Database\Eloquent\Collection; + if (! class_exists(Workspace::class)) { + return new Collection; } - return \Core\Tenant\Models\Workspace::orderBy('name')->get(); + return Workspace::orderBy('name')->get(); } #[Computed] - public function keys(): \Illuminate\Database\Eloquent\Collection + public function keys(): Collection { return ConfigKey::query() ->when($this->category, fn ($q) => $q->where('category', $this->category)) @@ -119,8 +122,8 @@ class ConfigPanel extends Component #[Computed] public function selectedWorkspace(): ?object { - if ($this->workspaceId && class_exists(\Core\Tenant\Models\Workspace::class)) { - return \Core\Tenant\Models\Workspace::find($this->workspaceId); + if ($this->workspaceId && class_exists(Workspace::class)) { + return Workspace::find($this->workspaceId); } return null; @@ -271,7 +274,7 @@ class ConfigPanel extends Component $this->dispatch('config-cleared'); } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('core.config::admin.config-panel') ->layout('hub::admin.layouts.app', ['title' => 'Configuration']); diff --git a/src/Core/Config/View/Modal/Admin/WorkspaceConfig.php b/src/Core/Config/View/Modal/Admin/WorkspaceConfig.php index 04a569c..1a3cdda 100644 --- a/src/Core/Config/View/Modal/Admin/WorkspaceConfig.php +++ b/src/Core/Config/View/Modal/Admin/WorkspaceConfig.php @@ -15,6 +15,9 @@ use Core\Config\ConfigService; use Core\Config\Models\ConfigKey; use Core\Config\Models\ConfigProfile; use Core\Config\Models\ConfigValue; +use Core\Tenant\Services\WorkspaceService; +use Illuminate\Contracts\View\View; +use Illuminate\Support\Collection; use Livewire\Attributes\Computed; use Livewire\Attributes\On; use Livewire\Component; @@ -28,7 +31,7 @@ use Livewire\Component; * @property-read ConfigProfile $systemProfile * @property-read object|null $workspace * @property-read string $prefix - * @property-read array $tabs + * @property-read array $tabs */ class WorkspaceConfig extends Component { @@ -46,8 +49,8 @@ class WorkspaceConfig extends Component $this->config = $config; // Try to resolve WorkspaceService if Tenant module is installed - if (class_exists(\Core\Tenant\Services\WorkspaceService::class)) { - $this->workspaceService = app(\Core\Tenant\Services\WorkspaceService::class); + if (class_exists(WorkspaceService::class)) { + $this->workspaceService = app(WorkspaceService::class); } } @@ -277,7 +280,7 @@ class WorkspaceConfig extends Component $this->dispatch('config-cleared'); } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('core.config::admin.workspace-config') ->layout('hub::admin.layouts.app', ['title' => 'Settings']); diff --git a/src/Core/Console/Commands/InstallCommand.php b/src/Core/Console/Commands/InstallCommand.php index 3fd375d..09aafba 100644 --- a/src/Core/Console/Commands/InstallCommand.php +++ b/src/Core/Console/Commands/InstallCommand.php @@ -13,6 +13,8 @@ namespace Core\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\File; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Core PHP Framework Installation Command. @@ -484,8 +486,8 @@ class InstallCommand extends Command * but implements the method for consistency with other commands. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { // No argument/option values need completion for this command // All options are flags (--force, --no-interaction, --dry-run) diff --git a/src/Core/Console/Commands/MakeModCommand.php b/src/Core/Console/Commands/MakeModCommand.php index a069743..d6ad61b 100644 --- a/src/Core/Console/Commands/MakeModCommand.php +++ b/src/Core/Console/Commands/MakeModCommand.php @@ -14,6 +14,8 @@ namespace Core\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\File; use Illuminate\Support\Str; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Generate a new module scaffold. @@ -508,8 +510,8 @@ BLADE; * Get shell completion suggestions for arguments. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestArgumentValuesFor('name')) { // Suggest common module naming patterns diff --git a/src/Core/Console/Commands/MakePlugCommand.php b/src/Core/Console/Commands/MakePlugCommand.php index 0d187f5..872c6b2 100644 --- a/src/Core/Console/Commands/MakePlugCommand.php +++ b/src/Core/Console/Commands/MakePlugCommand.php @@ -14,6 +14,8 @@ namespace Core\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\File; use Illuminate\Support\Str; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Generate a new Plug provider scaffold. @@ -604,8 +606,8 @@ PHP; * Get shell completion suggestions for arguments and options. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestArgumentValuesFor('name')) { // Suggest common social platform names diff --git a/src/Core/Console/Commands/MakeWebsiteCommand.php b/src/Core/Console/Commands/MakeWebsiteCommand.php index ef852c3..2b34e3f 100644 --- a/src/Core/Console/Commands/MakeWebsiteCommand.php +++ b/src/Core/Console/Commands/MakeWebsiteCommand.php @@ -14,6 +14,8 @@ namespace Core\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\File; use Illuminate\Support\Str; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Generate a new Website scaffold. @@ -574,8 +576,8 @@ BLADE; * Get shell completion suggestions for arguments and options. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestArgumentValuesFor('name')) { // Suggest common website naming patterns diff --git a/src/Core/Console/Commands/NewProjectCommand.php b/src/Core/Console/Commands/NewProjectCommand.php index 2005d2c..8e75d34 100644 --- a/src/Core/Console/Commands/NewProjectCommand.php +++ b/src/Core/Console/Commands/NewProjectCommand.php @@ -15,6 +15,8 @@ use Illuminate\Console\Command; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Process; use Illuminate\Support\Str; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Create a new Core PHP Framework project. @@ -343,8 +345,8 @@ class NewProjectCommand extends Command * Get shell completion suggestions. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestArgumentValuesFor('name')) { // Suggest common project naming patterns diff --git a/src/Core/Console/Commands/PruneEmailShieldStatsCommand.php b/src/Core/Console/Commands/PruneEmailShieldStatsCommand.php index fa231e3..1ab5dac 100644 --- a/src/Core/Console/Commands/PruneEmailShieldStatsCommand.php +++ b/src/Core/Console/Commands/PruneEmailShieldStatsCommand.php @@ -13,6 +13,8 @@ namespace Core\Console\Commands; use Core\Mail\EmailShieldStat; use Illuminate\Console\Command; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Prune old Email Shield statistics records. @@ -135,8 +137,8 @@ class PruneEmailShieldStatsCommand extends Command * Get shell completion suggestions for options. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestOptionValuesFor('days')) { // Suggest common retention periods diff --git a/src/Core/Crypt/EncryptArrayObject.php b/src/Core/Crypt/EncryptArrayObject.php index 3533124..ee96379 100644 --- a/src/Core/Crypt/EncryptArrayObject.php +++ b/src/Core/Crypt/EncryptArrayObject.php @@ -12,7 +12,9 @@ declare(strict_types=1); namespace Core\Crypt; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; +use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Database\Eloquent\Casts\ArrayObject; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Log; @@ -27,7 +29,7 @@ class EncryptArrayObject implements CastsAttributes /** * Cast the given value to an ArrayObject. * - * @param \Illuminate\Database\Eloquent\Model $model + * @param Model $model * @param mixed $value * @param array $attributes */ @@ -36,7 +38,7 @@ class EncryptArrayObject implements CastsAttributes if (isset($attributes[$key])) { try { $decrypted = Crypt::decryptString($attributes[$key]); - } catch (\Illuminate\Contracts\Encryption\DecryptException $e) { + } catch (DecryptException $e) { Log::warning('Failed to decrypt array object', ['key' => $key, 'error' => $e->getMessage()]); return null; @@ -59,7 +61,7 @@ class EncryptArrayObject implements CastsAttributes /** * Prepare the given value for storage. * - * @param \Illuminate\Database\Eloquent\Model $model + * @param Model $model * @param mixed $value * @param array $attributes * @return array|null diff --git a/src/Core/Front/Admin/AdminMenuRegistry.php b/src/Core/Front/Admin/AdminMenuRegistry.php index 5b3d6e7..da3423b 100644 --- a/src/Core/Front/Admin/AdminMenuRegistry.php +++ b/src/Core/Front/Admin/AdminMenuRegistry.php @@ -14,6 +14,7 @@ namespace Core\Front\Admin; use Core\Front\Admin\Contracts\AdminMenuProvider; use Core\Front\Admin\Contracts\DynamicMenuProvider; use Core\Front\Admin\Validation\IconValidator; +use Core\Tenant\Services\EntitlementService; use Illuminate\Support\Facades\Cache; /** @@ -111,8 +112,8 @@ class AdminMenuRegistry public function __construct(?object $entitlements = null, ?IconValidator $iconValidator = null) { - if ($entitlements === null && class_exists(\Core\Tenant\Services\EntitlementService::class)) { - $this->entitlements = app(\Core\Tenant\Services\EntitlementService::class); + if ($entitlements === null && class_exists(EntitlementService::class)) { + $this->entitlements = app(EntitlementService::class); } else { $this->entitlements = $entitlements; } diff --git a/src/Core/Front/Admin/Boot.php b/src/Core/Front/Admin/Boot.php index 8b939a2..2dc22f9 100644 --- a/src/Core/Front/Admin/Boot.php +++ b/src/Core/Front/Admin/Boot.php @@ -31,9 +31,15 @@ use Core\Front\Admin\View\Components\Stats; use Core\Front\Admin\View\Components\StatusCards; use Core\Headers\SecurityHeaders; use Core\LifecycleEventProvider; +use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; +use Illuminate\Cookie\Middleware\EncryptCookies; use Illuminate\Foundation\Configuration\Middleware; +use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken; +use Illuminate\Routing\Middleware\SubstituteBindings; +use Illuminate\Session\Middleware\StartSession; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; +use Illuminate\View\Middleware\ShareErrorsFromSession; /** * Admin frontage - admin dashboard stage. @@ -49,12 +55,12 @@ class Boot extends ServiceProvider public static function middleware(Middleware $middleware): void { $middleware->group('admin', [ - \Illuminate\Cookie\Middleware\EncryptCookies::class, - \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, - \Illuminate\Session\Middleware\StartSession::class, - \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, - \Illuminate\Routing\Middleware\SubstituteBindings::class, + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + ShareErrorsFromSession::class, + ValidateCsrfToken::class, + SubstituteBindings::class, SecurityHeaders::class, 'auth', ]); diff --git a/src/Core/Front/Admin/View/Components/ActivityFeed.php b/src/Core/Front/Admin/View/Components/ActivityFeed.php index 0ac08f8..fee0977 100644 --- a/src/Core/Front/Admin/View/Components/ActivityFeed.php +++ b/src/Core/Front/Admin/View/Components/ActivityFeed.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class ActivityFeed extends Component @@ -34,7 +35,7 @@ class ActivityFeed extends Component return $item['color'] ?? 'gray'; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.activity-feed'); } diff --git a/src/Core/Front/Admin/View/Components/ActivityLog.php b/src/Core/Front/Admin/View/Components/ActivityLog.php index 2fd38b9..ddb8ec3 100644 --- a/src/Core/Front/Admin/View/Components/ActivityLog.php +++ b/src/Core/Front/Admin/View/Components/ActivityLog.php @@ -13,6 +13,7 @@ namespace Core\Front\Admin\View\Components; use Carbon\Carbon; use Illuminate\Contracts\Pagination\Paginator; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class ActivityLog extends Component @@ -57,7 +58,7 @@ class ActivityLog extends Component return is_array($value) ? json_encode($value) : (string) $value; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.activity-log'); } diff --git a/src/Core/Front/Admin/View/Components/Alert.php b/src/Core/Front/Admin/View/Components/Alert.php index 8735340..6f44693 100644 --- a/src/Core/Front/Admin/View/Components/Alert.php +++ b/src/Core/Front/Admin/View/Components/Alert.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class Alert extends Component @@ -42,7 +43,7 @@ class Alert extends Component }; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.alert'); } diff --git a/src/Core/Front/Admin/View/Components/CardGrid.php b/src/Core/Front/Admin/View/Components/CardGrid.php index fc9c1b4..936511b 100644 --- a/src/Core/Front/Admin/View/Components/CardGrid.php +++ b/src/Core/Front/Admin/View/Components/CardGrid.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class CardGrid extends Component @@ -52,7 +53,7 @@ class CardGrid extends Component }; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.card-grid'); } diff --git a/src/Core/Front/Admin/View/Components/ClearFilters.php b/src/Core/Front/Admin/View/Components/ClearFilters.php index 0a9252b..2e26e7a 100644 --- a/src/Core/Front/Admin/View/Components/ClearFilters.php +++ b/src/Core/Front/Admin/View/Components/ClearFilters.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class ClearFilters extends Component @@ -26,7 +27,7 @@ class ClearFilters extends Component ->implode('; '); } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.clear-filters'); } diff --git a/src/Core/Front/Admin/View/Components/DataTable.php b/src/Core/Front/Admin/View/Components/DataTable.php index a10368f..8f17c93 100644 --- a/src/Core/Front/Admin/View/Components/DataTable.php +++ b/src/Core/Front/Admin/View/Components/DataTable.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class DataTable extends Component @@ -45,7 +46,7 @@ class DataTable extends Component return $align === 'right' ? 'text-right' : ''; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.data-table'); } diff --git a/src/Core/Front/Admin/View/Components/EditableTable.php b/src/Core/Front/Admin/View/Components/EditableTable.php index 3b27ad8..69c9362 100644 --- a/src/Core/Front/Admin/View/Components/EditableTable.php +++ b/src/Core/Front/Admin/View/Components/EditableTable.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; use Illuminate\Contracts\Pagination\Paginator; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class EditableTable extends Component @@ -74,7 +75,7 @@ class EditableTable extends Component return count($this->columns) + ($this->selectable ? 1 : 0); } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.editable-table'); } diff --git a/src/Core/Front/Admin/View/Components/Filter.php b/src/Core/Front/Admin/View/Components/Filter.php index 0308776..fcb3470 100644 --- a/src/Core/Front/Admin/View/Components/Filter.php +++ b/src/Core/Front/Admin/View/Components/Filter.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\Support\Collection; use Illuminate\View\Component; @@ -49,7 +50,7 @@ class Filter extends Component })->values()->all(); } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.filter'); } diff --git a/src/Core/Front/Admin/View/Components/FilterBar.php b/src/Core/Front/Admin/View/Components/FilterBar.php index bb627e8..7279631 100644 --- a/src/Core/Front/Admin/View/Components/FilterBar.php +++ b/src/Core/Front/Admin/View/Components/FilterBar.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class FilterBar extends Component @@ -34,7 +35,7 @@ class FilterBar extends Component }; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.filter-bar'); } diff --git a/src/Core/Front/Admin/View/Components/LinkGrid.php b/src/Core/Front/Admin/View/Components/LinkGrid.php index cccaa8b..63cd926 100644 --- a/src/Core/Front/Admin/View/Components/LinkGrid.php +++ b/src/Core/Front/Admin/View/Components/LinkGrid.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class LinkGrid extends Component @@ -44,7 +45,7 @@ class LinkGrid extends Component return $item['icon'] ?? 'arrow-right'; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.link-grid'); } diff --git a/src/Core/Front/Admin/View/Components/ManagerTable.php b/src/Core/Front/Admin/View/Components/ManagerTable.php index e3a8b93..e111418 100644 --- a/src/Core/Front/Admin/View/Components/ManagerTable.php +++ b/src/Core/Front/Admin/View/Components/ManagerTable.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; use Illuminate\Contracts\Pagination\Paginator; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class ManagerTable extends Component @@ -56,7 +57,7 @@ class ManagerTable extends Component }; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.manager-table'); } diff --git a/src/Core/Front/Admin/View/Components/Metrics.php b/src/Core/Front/Admin/View/Components/Metrics.php index a27bcd2..49e7c88 100644 --- a/src/Core/Front/Admin/View/Components/Metrics.php +++ b/src/Core/Front/Admin/View/Components/Metrics.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class Metrics extends Component @@ -34,7 +35,7 @@ class Metrics extends Component }; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.metrics'); } diff --git a/src/Core/Front/Admin/View/Components/ProgressList.php b/src/Core/Front/Admin/View/Components/ProgressList.php index 884a6e1..08152af 100644 --- a/src/Core/Front/Admin/View/Components/ProgressList.php +++ b/src/Core/Front/Admin/View/Components/ProgressList.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class ProgressList extends Component @@ -52,7 +53,7 @@ class ProgressList extends Component return is_numeric($value) ? number_format($value) : (string) $value; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.progress-list'); } diff --git a/src/Core/Front/Admin/View/Components/Search.php b/src/Core/Front/Admin/View/Components/Search.php index dcee006..b641e33 100644 --- a/src/Core/Front/Admin/View/Components/Search.php +++ b/src/Core/Front/Admin/View/Components/Search.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class Search extends Component @@ -24,7 +25,7 @@ class Search extends Component $this->wireModel = $this->model ? "wire:model.live.debounce.300ms=\"{$this->model}\"" : ''; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.search'); } diff --git a/src/Core/Front/Admin/View/Components/ServiceCard.php b/src/Core/Front/Admin/View/Components/ServiceCard.php index 8bfec29..7f1bd4b 100644 --- a/src/Core/Front/Admin/View/Components/ServiceCard.php +++ b/src/Core/Front/Admin/View/Components/ServiceCard.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class ServiceCard extends Component @@ -52,7 +53,7 @@ class ServiceCard extends Component $this->statusColor = $this->status === 'online' ? 'green' : 'red'; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.service-card'); } diff --git a/src/Core/Front/Admin/View/Components/Sidemenu.php b/src/Core/Front/Admin/View/Components/Sidemenu.php index 88f6bbf..37d3d27 100644 --- a/src/Core/Front/Admin/View/Components/Sidemenu.php +++ b/src/Core/Front/Admin/View/Components/Sidemenu.php @@ -12,6 +12,9 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; use Core\Front\Admin\AdminMenuRegistry; +use Core\Tenant\Models\User; +use Core\Tenant\Services\WorkspaceService; +use Illuminate\Contracts\View\View; use Illuminate\Support\Facades\Auth; use Illuminate\View\Component; @@ -39,19 +42,19 @@ class Sidemenu extends Component // Use current workspace from session, not default $workspace = null; - if (class_exists(\Core\Tenant\Services\WorkspaceService::class)) { - $workspace = app(\Core\Tenant\Services\WorkspaceService::class)->currentModel(); + if (class_exists(WorkspaceService::class)) { + $workspace = app(WorkspaceService::class)->currentModel(); } $isAdmin = false; - if (class_exists(\Core\Tenant\Models\User::class) && $user instanceof \Core\Tenant\Models\User) { + if (class_exists(User::class) && $user instanceof User) { $isAdmin = $user->isHades(); } return app(AdminMenuRegistry::class)->build($workspace, $isAdmin); } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.sidemenu'); } diff --git a/src/Core/Front/Admin/View/Components/Stats.php b/src/Core/Front/Admin/View/Components/Stats.php index 04c3efc..e76c83b 100644 --- a/src/Core/Front/Admin/View/Components/Stats.php +++ b/src/Core/Front/Admin/View/Components/Stats.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class Stats extends Component @@ -36,7 +37,7 @@ class Stats extends Component }; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.stats'); } diff --git a/src/Core/Front/Admin/View/Components/StatusCards.php b/src/Core/Front/Admin/View/Components/StatusCards.php index 909a77c..9ba0b19 100644 --- a/src/Core/Front/Admin/View/Components/StatusCards.php +++ b/src/Core/Front/Admin/View/Components/StatusCards.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Front\Admin\View\Components; +use Illuminate\Contracts\View\View; use Illuminate\View\Component; class StatusCards extends Component @@ -39,7 +40,7 @@ class StatusCards extends Component return $item['color'] ?? 'gray'; } - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('admin::components.status-cards'); } diff --git a/src/Core/Front/Boot.php b/src/Core/Front/Boot.php index e230dd4..d2409b1 100644 --- a/src/Core/Front/Boot.php +++ b/src/Core/Front/Boot.php @@ -12,6 +12,8 @@ declare(strict_types=1); namespace Core\Front; use Illuminate\Foundation\Configuration\Middleware; +use Illuminate\Routing\Middleware\SubstituteBindings; +use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\AggregateServiceProvider; /** @@ -54,12 +56,12 @@ class Boot extends AggregateServiceProvider // Application::configure(), before package providers load. // Packages add their own aliases during boot via lifecycle events. $middleware->group('api', [ - \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', - \Illuminate\Routing\Middleware\SubstituteBindings::class, + ThrottleRequests::class.':api', + SubstituteBindings::class, ]); $middleware->group('mcp', [ - \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', - \Illuminate\Routing\Middleware\SubstituteBindings::class, + ThrottleRequests::class.':api', + SubstituteBindings::class, ]); } } diff --git a/src/Core/Front/Cli/Boot.php b/src/Core/Front/Cli/Boot.php index 5e76367..0a1ca2f 100644 --- a/src/Core/Front/Cli/Boot.php +++ b/src/Core/Front/Cli/Boot.php @@ -11,7 +11,9 @@ declare(strict_types=1); namespace Core\Front\Cli; +use Core\Actions\ScheduleServiceProvider; use Core\Events\ConsoleBooting; +use Illuminate\Routing\Router; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Gate; use Illuminate\Support\ServiceProvider; @@ -35,7 +37,7 @@ class Boot extends ServiceProvider return; } - $this->app->register(\Core\Actions\ScheduleServiceProvider::class); + $this->app->register(ScheduleServiceProvider::class); $this->fireConsoleBooting(); } @@ -58,7 +60,7 @@ class Boot extends ServiceProvider } // Process middleware aliases - $router = $this->app->make(\Illuminate\Routing\Router::class); + $router = $this->app->make(Router::class); foreach ($event->middlewareRequests() as [$alias, $class]) { $router->aliasMiddleware($alias, $class); } diff --git a/src/Core/Front/Components/Layout.php b/src/Core/Front/Components/Layout.php index b3d90c9..bbc4a2a 100644 --- a/src/Core/Front/Components/Layout.php +++ b/src/Core/Front/Components/Layout.php @@ -1,5 +1,7 @@ group('web', [ - \Illuminate\Cookie\Middleware\EncryptCookies::class, - \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, - \Illuminate\Session\Middleware\StartSession::class, + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, ResilientSession::class, - \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, - \Illuminate\Routing\Middleware\SubstituteBindings::class, + ShareErrorsFromSession::class, + ValidateCsrfToken::class, + SubstituteBindings::class, SecurityHeaders::class, FindDomainRecord::class, ]); diff --git a/src/Core/Front/Web/Middleware/FindDomainRecord.php b/src/Core/Front/Web/Middleware/FindDomainRecord.php index b634723..6dfae3f 100644 --- a/src/Core/Front/Web/Middleware/FindDomainRecord.php +++ b/src/Core/Front/Web/Middleware/FindDomainRecord.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Core\Front\Web\Middleware; use Closure; +use Core\Tenant\Models\Workspace; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; @@ -84,12 +85,12 @@ class FindDomainRecord protected function resolveWorkspaceFromDomain(string $host): ?object { // Check if Tenant module is installed - if (! class_exists(\Core\Tenant\Models\Workspace::class)) { + if (! class_exists(Workspace::class)) { return null; } // Check for custom domain first - $workspace = \Core\Tenant\Models\Workspace::where('domain', $host)->first(); + $workspace = Workspace::where('domain', $host)->first(); if ($workspace) { return $workspace; } @@ -104,7 +105,7 @@ class FindDomainRecord if (count($parts) >= 1) { $workspaceSlug = $parts[0]; - return \Core\Tenant\Models\Workspace::where('slug', $workspaceSlug) + return Workspace::where('slug', $workspaceSlug) ->where('is_active', true) ->first(); } diff --git a/src/Core/Front/Web/Middleware/ResilientSession.php b/src/Core/Front/Web/Middleware/ResilientSession.php index 04c562a..6493bab 100644 --- a/src/Core/Front/Web/Middleware/ResilientSession.php +++ b/src/Core/Front/Web/Middleware/ResilientSession.php @@ -13,6 +13,7 @@ namespace Core\Front\Web\Middleware; use Closure; use Illuminate\Contracts\Encryption\DecryptException; +use Illuminate\Database\QueryException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use Symfony\Component\HttpFoundation\Response; @@ -43,7 +44,7 @@ class ResilientSession return $next($request); } catch (DecryptException $e) { return $this->handleSessionError($request, $e, 'decrypt'); - } catch (\Illuminate\Database\QueryException $e) { + } catch (QueryException $e) { // Only catch session-related query exceptions if ($this->isSessionError($e)) { return $this->handleSessionError($request, $e, 'database'); diff --git a/src/Core/Headers/Livewire/HeaderConfigurationManager.php b/src/Core/Headers/Livewire/HeaderConfigurationManager.php index 9af1c9b..5f493f7 100644 --- a/src/Core/Headers/Livewire/HeaderConfigurationManager.php +++ b/src/Core/Headers/Livewire/HeaderConfigurationManager.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Headers\Livewire; +use Illuminate\Contracts\View\View; use Illuminate\Support\Facades\Config; use Livewire\Component; @@ -451,7 +452,7 @@ class HeaderConfigurationManager extends Component /** * Render the component. */ - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('core::headers.livewire.header-configuration-manager'); } diff --git a/src/Core/Lang/Console/Commands/TranslationCoverageCommand.php b/src/Core/Lang/Console/Commands/TranslationCoverageCommand.php index 1cc95ed..ce20d14 100644 --- a/src/Core/Lang/Console/Commands/TranslationCoverageCommand.php +++ b/src/Core/Lang/Console/Commands/TranslationCoverageCommand.php @@ -12,7 +12,10 @@ declare(strict_types=1); namespace Core\Lang\Console\Commands; use Core\Lang\Coverage\TranslationCoverage; +use Core\Lang\Coverage\TranslationCoverageReport; use Illuminate\Console\Command; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Report translation coverage across the codebase. @@ -164,7 +167,7 @@ class TranslationCoverageCommand extends Command /** * Display per-locale statistics. * - * @param \Core\Lang\Coverage\TranslationCoverageReport $report + * @param TranslationCoverageReport $report */ protected function displayLocaleStats($report): void { @@ -201,7 +204,7 @@ class TranslationCoverageCommand extends Command /** * Display missing keys. * - * @param \Core\Lang\Coverage\TranslationCoverageReport $report + * @param TranslationCoverageReport $report */ protected function displayMissingKeys($report, bool $verbose): void { @@ -241,7 +244,7 @@ class TranslationCoverageCommand extends Command /** * Display unused keys. * - * @param \Core\Lang\Coverage\TranslationCoverageReport $report + * @param TranslationCoverageReport $report */ protected function displayUnusedKeys($report, bool $verbose): void { @@ -291,8 +294,8 @@ class TranslationCoverageCommand extends Command * Get shell completion suggestions. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestOptionValuesFor('locale')) { // Suggest available locales diff --git a/src/Core/Lang/Console/Commands/TranslationMemoryCommand.php b/src/Core/Lang/Console/Commands/TranslationMemoryCommand.php index 9958769..5eeadac 100644 --- a/src/Core/Lang/Console/Commands/TranslationMemoryCommand.php +++ b/src/Core/Lang/Console/Commands/TranslationMemoryCommand.php @@ -11,8 +11,11 @@ declare(strict_types=1); namespace Core\Lang\Console\Commands; +use Core\Lang\TranslationMemory\FuzzyMatcher; use Core\Lang\TranslationMemory\TranslationMemory; use Illuminate\Console\Command; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Translation Memory management command. @@ -388,7 +391,7 @@ class TranslationMemoryCommand extends Command $confidence = $suggestion['confidence']; $similarityColor = $similarity >= 0.9 ? 'green' : ($similarity >= 0.75 ? 'yellow' : 'red'); - $category = \Core\Lang\TranslationMemory\FuzzyMatcher::categorizeSimilarity($similarity); + $category = FuzzyMatcher::categorizeSimilarity($similarity); $this->line(" ".sprintf('%.0f%%', $similarity * 100).' match ('.$category.')'); $this->line(" Source: {$entry->getSource()}"); @@ -566,8 +569,8 @@ class TranslationMemoryCommand extends Command * Get shell completion suggestions. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestArgumentValuesFor('action')) { $suggestions->suggestValues([ diff --git a/src/Core/LifecycleEventProvider.php b/src/Core/LifecycleEventProvider.php index b514e08..1acb1d3 100644 --- a/src/Core/LifecycleEventProvider.php +++ b/src/Core/LifecycleEventProvider.php @@ -20,6 +20,8 @@ use Core\Events\McpRoutesRegistering; use Core\Events\McpToolsRegistering; use Core\Events\QueueWorkerBooting; use Core\Events\WebRoutesRegistering; +use Core\Front\Mcp\Contracts\McpToolHandler; +use Illuminate\Routing\Router; use Illuminate\Support\Facades\Route; use Illuminate\Support\ServiceProvider; use Livewire\Livewire; @@ -252,7 +254,7 @@ class LifecycleEventProvider extends ServiceProvider */ protected static function processMiddleware(Events\LifecycleEvent $event): void { - /** @var \Illuminate\Routing\Router $router */ + /** @var Router $router */ $router = app('router'); foreach ($event->middlewareRequests() as [$alias, $class]) { @@ -456,7 +458,7 @@ class LifecycleEventProvider extends ServiceProvider * * @return array Fully qualified class names of McpToolHandler implementations * - * @see \Core\Front\Mcp\Contracts\McpToolHandler (in php-mcp package) + * @see McpToolHandler (in php-mcp package) */ public static function fireMcpTools(): array { diff --git a/src/Core/Media/Abstracts/MediaConversion.php b/src/Core/Media/Abstracts/MediaConversion.php index 9e4fe2e..f0a779a 100644 --- a/src/Core/Media/Abstracts/MediaConversion.php +++ b/src/Core/Media/Abstracts/MediaConversion.php @@ -15,6 +15,7 @@ use Core\Media\Events\ConversionProgress; use Core\Media\Jobs\ProcessMediaConversion; use Core\Media\Support\ConversionProgressReporter; use Core\Media\Support\MediaConversionData; +use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; @@ -463,7 +464,7 @@ abstract class MediaConversion /** * Get a filesystem instance for the given disk. */ - protected function filesystem(string $disk): \Illuminate\Contracts\Filesystem\Filesystem + protected function filesystem(string $disk): Filesystem { return Storage::disk($disk); } diff --git a/src/Core/Media/Image/ImageOptimization.php b/src/Core/Media/Image/ImageOptimization.php index e30c242..831941f 100644 --- a/src/Core/Media/Image/ImageOptimization.php +++ b/src/Core/Media/Image/ImageOptimization.php @@ -15,6 +15,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; +use Illuminate\Support\Carbon; /** * Image optimisation record. @@ -30,8 +31,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; * @property int|null $workspace_id * @property string|null $optimizable_type * @property int|null $optimizable_id - * @property \Illuminate\Support\Carbon|null $created_at - * @property \Illuminate\Support\Carbon|null $updated_at + * @property Carbon|null $created_at + * @property Carbon|null $updated_at */ class ImageOptimization extends Model { diff --git a/src/Core/Search/Analytics/SearchAnalytics.php b/src/Core/Search/Analytics/SearchAnalytics.php index 03a248c..3582211 100644 --- a/src/Core/Search/Analytics/SearchAnalytics.php +++ b/src/Core/Search/Analytics/SearchAnalytics.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Search\Analytics; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; @@ -210,9 +211,9 @@ class SearchAnalytics * * @param int $limit Maximum number of queries to return * @param int $days Number of days to look back - * @return \Illuminate\Support\Collection + * @return Collection */ - public function getPopularQueries(int $limit = 10, int $days = 7): \Illuminate\Support\Collection + public function getPopularQueries(int $limit = 10, int $days = 7): Collection { if (! $this->isEnabled()) { return collect(); @@ -232,9 +233,9 @@ class SearchAnalytics * * @param int $limit Maximum number of queries to return * @param int $days Number of days to look back - * @return \Illuminate\Support\Collection + * @return Collection */ - public function getZeroResultQueries(int $limit = 20, int $days = 30): \Illuminate\Support\Collection + public function getZeroResultQueries(int $limit = 20, int $days = 30): Collection { if (! $this->isEnabled()) { return collect(); @@ -254,9 +255,9 @@ class SearchAnalytics * Get search trend over time. * * @param int $days Number of days to look back - * @return \Illuminate\Support\Collection + * @return Collection */ - public function getTrend(int $days = 30): \Illuminate\Support\Collection + public function getTrend(int $days = 30): Collection { if (! $this->isEnabled()) { return collect(); diff --git a/src/Core/Search/Boot.php b/src/Core/Search/Boot.php index f67ade4..be8042e 100644 --- a/src/Core/Search/Boot.php +++ b/src/Core/Search/Boot.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Search; +use App\Services\Search\UnifiedSearchService; use Core\Search\Analytics\SearchAnalytics; use Core\Search\Suggestions\SearchSuggestions; use Illuminate\Support\ServiceProvider; @@ -72,8 +73,8 @@ class Boot extends ServiceProvider */ protected function registerBackwardCompatAliases(): void { - if (! class_exists(\App\Services\Search\UnifiedSearchService::class)) { - class_alias(Unified::class, \App\Services\Search\UnifiedSearchService::class); + if (! class_exists(UnifiedSearchService::class)) { + class_alias(Unified::class, UnifiedSearchService::class); } } } diff --git a/src/Core/Search/Suggestions/SearchSuggestions.php b/src/Core/Search/Suggestions/SearchSuggestions.php index 7a2aacd..4c33d4d 100644 --- a/src/Core/Search/Suggestions/SearchSuggestions.php +++ b/src/Core/Search/Suggestions/SearchSuggestions.php @@ -11,6 +11,9 @@ declare(strict_types=1); namespace Core\Search\Suggestions; +use Core\Mod\Uptelligence\Models\Asset; +use Core\Mod\Uptelligence\Models\Pattern; +use Core\Search\Analytics\SearchAnalytics; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; @@ -43,7 +46,7 @@ use Illuminate\Support\Facades\Schema; * 'sources' => ['popular', 'recent', 'content'], * ] * - * @see \Core\Search\Analytics\SearchAnalytics For search tracking integration + * @see SearchAnalytics For search tracking integration */ class SearchSuggestions { @@ -259,9 +262,9 @@ class SearchSuggestions $escaped = $this->escapeLikeQuery($prefix); // Search patterns if available - if (class_exists(\Core\Mod\Uptelligence\Models\Pattern::class)) { + if (class_exists(Pattern::class)) { try { - $patterns = \Core\Mod\Uptelligence\Models\Pattern::where('name', 'like', "{$escaped}%") + $patterns = Pattern::where('name', 'like', "{$escaped}%") ->limit($limit) ->pluck('name') ->map(fn ($name) => [ @@ -278,9 +281,9 @@ class SearchSuggestions } // Search assets if available - if (class_exists(\Core\Mod\Uptelligence\Models\Asset::class)) { + if (class_exists(Asset::class)) { try { - $assets = \Core\Mod\Uptelligence\Models\Asset::where('name', 'like', "{$escaped}%") + $assets = Asset::where('name', 'like', "{$escaped}%") ->limit($limit) ->pluck('name') ->map(fn ($name) => [ diff --git a/src/Core/Search/Unified.php b/src/Core/Search/Unified.php index c76550b..671908e 100644 --- a/src/Core/Search/Unified.php +++ b/src/Core/Search/Unified.php @@ -11,6 +11,10 @@ declare(strict_types=1); namespace Core\Search; +use Core\Mod\Agentic\Models\AgentPlan; +use Core\Mod\Uptelligence\Models\Asset; +use Core\Mod\Uptelligence\Models\Pattern; +use Core\Mod\Uptelligence\Models\UpstreamTodo; use Core\Search\Analytics\SearchAnalytics; use Core\Search\Suggestions\SearchSuggestions; use Illuminate\Support\Collection; @@ -410,14 +414,14 @@ class Unified */ protected function searchPatterns(string $query): Collection { - if (! class_exists(\Core\Mod\Uptelligence\Models\Pattern::class)) { + if (! class_exists(Pattern::class)) { return collect(); } $escaped = $this->escapeLikeQuery($query); try { - return \Core\Mod\Uptelligence\Models\Pattern::where('name', 'like', "%{$escaped}%") + return Pattern::where('name', 'like', "%{$escaped}%") ->orWhere('description', 'like', "%{$escaped}%") ->orWhere('category', 'like', "%{$escaped}%") ->limit(20) @@ -448,14 +452,14 @@ class Unified */ protected function searchAssets(string $query): Collection { - if (! class_exists(\Core\Mod\Uptelligence\Models\Asset::class)) { + if (! class_exists(Asset::class)) { return collect(); } $escaped = $this->escapeLikeQuery($query); try { - return \Core\Mod\Uptelligence\Models\Asset::where('name', 'like', "%{$escaped}%") + return Asset::where('name', 'like', "%{$escaped}%") ->orWhere('slug', 'like', "%{$escaped}%") ->orWhere('description', 'like', "%{$escaped}%") ->limit(20) @@ -487,14 +491,14 @@ class Unified */ protected function searchTodos(string $query): Collection { - if (! class_exists(\Core\Mod\Uptelligence\Models\UpstreamTodo::class)) { + if (! class_exists(UpstreamTodo::class)) { return collect(); } $escaped = $this->escapeLikeQuery($query); try { - return \Core\Mod\Uptelligence\Models\UpstreamTodo::where('title', 'like', "%{$escaped}%") + return UpstreamTodo::where('title', 'like', "%{$escaped}%") ->orWhere('description', 'like', "%{$escaped}%") ->limit(20) ->get() @@ -525,14 +529,14 @@ class Unified */ protected function searchPlans(string $query): Collection { - if (! class_exists(\Core\Mod\Agentic\Models\AgentPlan::class)) { + if (! class_exists(AgentPlan::class)) { return collect(); } $escaped = $this->escapeLikeQuery($query); try { - return \Core\Mod\Agentic\Models\AgentPlan::where('title', 'like', "%{$escaped}%") + return AgentPlan::where('title', 'like', "%{$escaped}%") ->orWhere('slug', 'like', "%{$escaped}%") ->orWhere('description', 'like', "%{$escaped}%") ->limit(20) diff --git a/src/Core/Seo/Boot.php b/src/Core/Seo/Boot.php index 875b930..321f590 100644 --- a/src/Core/Seo/Boot.php +++ b/src/Core/Seo/Boot.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Core\Seo; +use App\Services\Content\SchemaService; use Core\Seo\Analytics\SeoScoreTrend; use Core\Seo\Console\Commands\AuditCanonicalUrls; use Core\Seo\Console\Commands\RecordSeoScores; @@ -105,8 +106,8 @@ class Boot extends ServiceProvider protected function registerBackwardCompatAliases(): void { // Schema (high-level JSON-LD generator) - if (! class_exists(\App\Services\Content\SchemaService::class)) { - class_alias(Schema::class, \App\Services\Content\SchemaService::class); + if (! class_exists(SchemaService::class)) { + class_alias(Schema::class, SchemaService::class); } // Services diff --git a/src/Core/Seo/Console/Commands/GenerateServiceOgImages.php b/src/Core/Seo/Console/Commands/GenerateServiceOgImages.php index 10231a2..f51fbbb 100644 --- a/src/Core/Seo/Console/Commands/GenerateServiceOgImages.php +++ b/src/Core/Seo/Console/Commands/GenerateServiceOgImages.php @@ -1,5 +1,7 @@ pageId); + $ogService = app(DynamicOgImageService::class); + $page = Page::find($this->pageId); if (! $page) { Log::warning("OG image generation skipped: page {$this->pageId} not found"); diff --git a/src/Core/Seo/Models/SeoScoreHistory.php b/src/Core/Seo/Models/SeoScoreHistory.php index 10fc96c..76d4f1f 100644 --- a/src/Core/Seo/Models/SeoScoreHistory.php +++ b/src/Core/Seo/Models/SeoScoreHistory.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Core\Seo\Models; +use Carbon\Carbon; +use Core\Seo\SeoMetadata; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; @@ -42,8 +44,8 @@ use Illuminate\Support\Collection; * @property array|null $issues * @property array|null $suggestions * @property array|null $snapshot - * @property \Carbon\Carbon $recorded_at - * @property \Carbon\Carbon $created_at + * @property Carbon $recorded_at + * @property Carbon $created_at */ class SeoScoreHistory extends Model { @@ -100,7 +102,7 @@ class SeoScoreHistory extends Model */ public function seoMetadata(): BelongsTo { - return $this->belongsTo(\Core\Seo\SeoMetadata::class, 'seo_metadata_id'); + return $this->belongsTo(SeoMetadata::class, 'seo_metadata_id'); } /** @@ -224,11 +226,11 @@ class SeoScoreHistory extends Model /** * Get scores recorded within a date range. * - * @param \Carbon\Carbon $from Start date - * @param \Carbon\Carbon $to End date + * @param Carbon $from Start date + * @param Carbon $to End date * @return Collection */ - public static function inDateRange(\Carbon\Carbon $from, \Carbon\Carbon $to): Collection + public static function inDateRange(Carbon $from, Carbon $to): Collection { return static::whereBetween('recorded_at', [$from, $to]) ->orderByDesc('recorded_at') diff --git a/src/Core/Seo/SeoMetadata.php b/src/Core/Seo/SeoMetadata.php index 471653f..3cb6485 100644 --- a/src/Core/Seo/SeoMetadata.php +++ b/src/Core/Seo/SeoMetadata.php @@ -13,6 +13,8 @@ namespace Core\Seo; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphTo; +use Illuminate\Support\Carbon; +use Illuminate\Support\Collection; /** * SEO metadata for any model. @@ -31,8 +33,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; * @property int|null $seo_score * @property array|null $seo_issues * @property array|null $seo_suggestions - * @property \Illuminate\Support\Carbon|null $created_at - * @property \Illuminate\Support\Carbon|null $updated_at + * @property Carbon|null $created_at + * @property Carbon|null $updated_at */ class SeoMetadata extends Model { @@ -317,7 +319,7 @@ class SeoMetadata extends Model /** * Check if this canonical URL conflicts with other records. * - * @return array{has_conflict: bool, count: int, records: \Illuminate\Support\Collection} + * @return array{has_conflict: bool, count: int, records: Collection} */ public function checkCanonicalConflict(): array { @@ -370,9 +372,9 @@ class SeoMetadata extends Model * Get score history for this metadata. * * @param int $limit Maximum records to return - * @return \Illuminate\Support\Collection + * @return Collection */ - public function getScoreHistory(int $limit = 100): \Illuminate\Support\Collection + public function getScoreHistory(int $limit = 100): Collection { $trend = app(Analytics\SeoScoreTrend::class); @@ -383,9 +385,9 @@ class SeoMetadata extends Model * Get daily score trend for this metadata. * * @param int $days Days to look back - * @return \Illuminate\Support\Collection + * @return Collection */ - public function getDailyScoreTrend(int $days = 30): \Illuminate\Support\Collection + public function getDailyScoreTrend(int $days = 30): Collection { $trend = app(Analytics\SeoScoreTrend::class); @@ -396,9 +398,9 @@ class SeoMetadata extends Model * Get weekly score trend for this metadata. * * @param int $weeks Weeks to look back - * @return \Illuminate\Support\Collection + * @return Collection */ - public function getWeeklyScoreTrend(int $weeks = 12): \Illuminate\Support\Collection + public function getWeeklyScoreTrend(int $weeks = 12): Collection { $trend = app(Analytics\SeoScoreTrend::class); diff --git a/src/Core/Storage/CacheResilienceProvider.php b/src/Core/Storage/CacheResilienceProvider.php index e79be1d..905a156 100644 --- a/src/Core/Storage/CacheResilienceProvider.php +++ b/src/Core/Storage/CacheResilienceProvider.php @@ -17,6 +17,7 @@ use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; use Illuminate\Support\ServiceProvider; +use Predis\Client; /** * Provides resilient cache/session configuration. @@ -178,7 +179,7 @@ class CacheResilienceProvider extends ServiceProvider } // Fall back to Predis library - if (class_exists(\Predis\Client::class)) { + if (class_exists(Client::class)) { return $this->checkPredis($host, $port, $password, $timeout); } @@ -233,7 +234,7 @@ class CacheResilienceProvider extends ServiceProvider $options['password'] = $password; } - $client = new \Predis\Client($options, [ + $client = new Client($options, [ 'exceptions' => true, ]); diff --git a/src/Core/Storage/Commands/WarmCacheCommand.php b/src/Core/Storage/Commands/WarmCacheCommand.php index 45338b7..5d5e17b 100644 --- a/src/Core/Storage/Commands/WarmCacheCommand.php +++ b/src/Core/Storage/Commands/WarmCacheCommand.php @@ -13,6 +13,8 @@ namespace Core\Storage\Commands; use Core\Storage\CacheWarmer; use Illuminate\Console\Command; +use Symfony\Component\Console\Completion\CompletionInput; +use Symfony\Component\Console\Completion\CompletionSuggestions; /** * Warm registered cache items. @@ -271,8 +273,8 @@ class WarmCacheCommand extends Command * Get shell completion suggestions for options. */ public function complete( - \Symfony\Component\Console\Completion\CompletionInput $input, - \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions + CompletionInput $input, + CompletionSuggestions $suggestions ): void { if ($input->mustSuggestOptionValuesFor('store')) { // Suggest common cache stores diff --git a/src/Core/Tests/Feature/AdminComponentsTest.php b/src/Core/Tests/Feature/AdminComponentsTest.php index c5346b6..715196f 100644 --- a/src/Core/Tests/Feature/AdminComponentsTest.php +++ b/src/Core/Tests/Feature/AdminComponentsTest.php @@ -17,6 +17,7 @@ declare(strict_types=1); */ use Illuminate\Support\Facades\Blade; +use Illuminate\View\Compilers\BladeCompiler; use Illuminate\View\Component; uses()->group('admin-components'); @@ -307,7 +308,7 @@ describe('Admin Component Integration', function () { $errors = []; foreach ($files as $file) { try { - $compiler = app(\Illuminate\View\Compilers\BladeCompiler::class); + $compiler = app(BladeCompiler::class); $compiler->compile($file); } catch (Throwable $e) { $errors[] = [ diff --git a/src/Core/Tests/Feature/AdminRouteSmokeTest.php b/src/Core/Tests/Feature/AdminRouteSmokeTest.php index b84b20a..7fb8aae 100644 --- a/src/Core/Tests/Feature/AdminRouteSmokeTest.php +++ b/src/Core/Tests/Feature/AdminRouteSmokeTest.php @@ -53,7 +53,7 @@ describe('Admin Route Discovery', function () { try { $response = $this->actingAs($this->hadesUser)->get('/'.$uri); - } catch (\Throwable $e) { + } catch (Throwable $e) { $failures[] = [ 'uri' => $uri, 'status' => 500, @@ -338,7 +338,7 @@ describe('Hub Route Architecture', function () { * Uses middleware detection to find admin routes, not URL patterns. * This catches all routes with 'admin' middleware regardless of URL structure. * - * @return array<\Illuminate\Routing\Route> + * @return array */ function discoverAdminRoutes(): array { @@ -383,7 +383,7 @@ function discoverAdminRoutes(): array /** * Discover all hub GET routes (hub/*) from Laravel's route registrar. * - * @return array<\Illuminate\Routing\Route> + * @return array */ function discoverHubRoutes(): array { diff --git a/src/Core/Tests/Feature/CdnIntegrationTest.php b/src/Core/Tests/Feature/CdnIntegrationTest.php index 477d045..df53cf8 100644 --- a/src/Core/Tests/Feature/CdnIntegrationTest.php +++ b/src/Core/Tests/Feature/CdnIntegrationTest.php @@ -1,5 +1,7 @@ urlResolver->publicDisk(); - $this->assertInstanceOf(\Illuminate\Contracts\Filesystem\Filesystem::class, $disk); + $this->assertInstanceOf(Filesystem::class, $disk); } public function test_url_resolver_returns_private_disk_instance(): void { $disk = $this->urlResolver->privateDisk(); - $this->assertInstanceOf(\Illuminate\Contracts\Filesystem\Filesystem::class, $disk); + $this->assertInstanceOf(Filesystem::class, $disk); } public function test_asset_pipeline_handles_large_files(): void diff --git a/src/Core/Tests/Feature/Config/ChannelTest.php b/src/Core/Tests/Feature/Config/ChannelTest.php index 3f076dc..5c1caba 100644 --- a/src/Core/Tests/Feature/Config/ChannelTest.php +++ b/src/Core/Tests/Feature/Config/ChannelTest.php @@ -10,9 +10,10 @@ declare(strict_types=1); use Core\Config\Models\Channel; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Log; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); describe('Channel', function () { describe('inheritanceChain', function () { diff --git a/src/Core/Tests/Feature/Config/ConfigValueTest.php b/src/Core/Tests/Feature/Config/ConfigValueTest.php index 4451872..38fc061 100644 --- a/src/Core/Tests/Feature/Config/ConfigValueTest.php +++ b/src/Core/Tests/Feature/Config/ConfigValueTest.php @@ -16,8 +16,9 @@ use Core\Config\Models\ConfigKey; use Core\Config\Models\ConfigProfile; use Core\Config\Models\ConfigResolved; use Core\Config\Models\ConfigValue; +use Illuminate\Foundation\Testing\RefreshDatabase; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); beforeEach(function () { // Create essential test fixtures diff --git a/src/Core/Tests/Feature/CoreComponentsTest.php b/src/Core/Tests/Feature/CoreComponentsTest.php index 48c86c9..99d2d6f 100644 --- a/src/Core/Tests/Feature/CoreComponentsTest.php +++ b/src/Core/Tests/Feature/CoreComponentsTest.php @@ -18,6 +18,13 @@ declare(strict_types=1); * Run with: php artisan test app/Core/Tests/Feature/CoreComponentsTest.php */ +use Core\Front\Components\Button; +use Core\Front\Components\Card; +use Core\Front\Components\Heading; +use Core\Front\Components\Layout; +use Core\Front\Components\NavList; +use Core\Front\Components\Text; +use Core\Pro; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\File; use Illuminate\View\Compilers\BladeCompiler; @@ -28,56 +35,56 @@ describe('Core Detection Helpers', function () { it('detects Flux Pro installation', function () { // Flux Pro is installed in this project - expect(\Core\Pro::hasFluxPro())->toBeTrue(); + expect(Pro::hasFluxPro())->toBeTrue(); }); it('identifies Flux Pro components', function () { - expect(\Core\Pro::requiresFluxPro('calendar'))->toBeTrue(); - expect(\Core\Pro::requiresFluxPro('editor'))->toBeTrue(); - expect(\Core\Pro::requiresFluxPro('chart'))->toBeTrue(); - expect(\Core\Pro::requiresFluxPro('chart.line'))->toBeTrue(); // Nested component - expect(\Core\Pro::requiresFluxPro('core:kanban'))->toBeTrue(); // With prefix + expect(Pro::requiresFluxPro('calendar'))->toBeTrue(); + expect(Pro::requiresFluxPro('editor'))->toBeTrue(); + expect(Pro::requiresFluxPro('chart'))->toBeTrue(); + expect(Pro::requiresFluxPro('chart.line'))->toBeTrue(); // Nested component + expect(Pro::requiresFluxPro('core:kanban'))->toBeTrue(); // With prefix // Free components - expect(\Core\Pro::requiresFluxPro('button'))->toBeFalse(); - expect(\Core\Pro::requiresFluxPro('input'))->toBeFalse(); - expect(\Core\Pro::requiresFluxPro('modal'))->toBeFalse(); + expect(Pro::requiresFluxPro('button'))->toBeFalse(); + expect(Pro::requiresFluxPro('input'))->toBeFalse(); + expect(Pro::requiresFluxPro('modal'))->toBeFalse(); }); it('respects FontAwesome Pro config', function () { - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => false]); - expect(\Core\Pro::hasFontAwesomePro())->toBeFalse(); + expect(Pro::hasFontAwesomePro())->toBeFalse(); - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => true]); - expect(\Core\Pro::hasFontAwesomePro())->toBeTrue(); + expect(Pro::hasFontAwesomePro())->toBeTrue(); // Clean up - \Core\Pro::clearCache(); + Pro::clearCache(); }); it('provides correct FA styles based on Pro/Free', function () { - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => false]); - $freeStyles = \Core\Pro::fontAwesomeStyles(); + $freeStyles = Pro::fontAwesomeStyles(); expect($freeStyles)->toContain('solid'); expect($freeStyles)->toContain('regular'); expect($freeStyles)->toContain('brands'); expect($freeStyles)->not->toContain('jelly'); expect($freeStyles)->not->toContain('light'); - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => true]); - $proStyles = \Core\Pro::fontAwesomeStyles(); + $proStyles = Pro::fontAwesomeStyles(); expect($proStyles)->toContain('jelly'); expect($proStyles)->toContain('light'); expect($proStyles)->toContain('thin'); // Clean up - \Core\Pro::clearCache(); + Pro::clearCache(); }); }); @@ -670,7 +677,7 @@ describe('Core Pro Component Rendering', function () { describe('Core PHP Builders', function () { it('Button builder renders HTML', function () { - $button = \Core\Front\Components\Button::make() + $button = Button::make() ->label('Save') ->primary(); // Use the actual API method @@ -682,7 +689,7 @@ describe('Core PHP Builders', function () { }); it('Card builder renders with title and body', function () { - $card = \Core\Front\Components\Card::make() + $card = Card::make() ->title('Card Title') ->body('Card content goes here'); @@ -694,7 +701,7 @@ describe('Core PHP Builders', function () { }); it('Heading builder renders with level', function () { - $heading = \Core\Front\Components\Heading::make() + $heading = Heading::make() ->text('Page Title') ->level(1); @@ -706,7 +713,7 @@ describe('Core PHP Builders', function () { }); it('Text builder renders with variant', function () { - $text = \Core\Front\Components\Text::make() + $text = Text::make() ->content('Some text') ->muted(); @@ -717,7 +724,7 @@ describe('Core PHP Builders', function () { it('NavList builder renders items', function () { // NavList::item() signature is: label, href, active, icon - $navlist = \Core\Front\Components\NavList::make() + $navlist = NavList::make() ->item('Dashboard', '/dashboard', false, 'home') ->item('Settings', '/settings', false, 'cog'); @@ -732,7 +739,7 @@ describe('Core PHP Builders', function () { it('Layout builder renders HLCRF structure', function () { // Layout uses short method names: h(), c(), f() - $layout = \Core\Front\Components\Layout::make('HCF') + $layout = Layout::make('HCF') ->h('Header Content') ->c('Main Content') ->f('Footer Content'); @@ -810,7 +817,7 @@ describe('Custom Components (Non-Flux)', function () { it('core:icon falls back to solid for jelly when FA Free', function () { // Without FA Pro config, jelly icons should fall back to solid - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => false]); $html = Blade::render(''); @@ -820,7 +827,7 @@ describe('Custom Components (Non-Flux)', function () { it('core:icon uses jelly style when FA Pro enabled', function () { // With FA Pro config, jelly icons should use fa-jelly - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => true]); $html = Blade::render(''); @@ -828,7 +835,7 @@ describe('Custom Components (Non-Flux)', function () { expect($html)->toContain('fa-jelly'); // Clean up - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => false]); }); @@ -841,7 +848,7 @@ describe('Custom Components (Non-Flux)', function () { }); it('core:icon falls back pro-only styles to free equivalents', function () { - \Core\Pro::clearCache(); + Pro::clearCache(); config(['core.fontawesome.pro' => false]); // Light → Regular diff --git a/src/Core/Tests/Feature/DatabaseMigrationTest.php b/src/Core/Tests/Feature/DatabaseMigrationTest.php index 79e40da..07f15bc 100644 --- a/src/Core/Tests/Feature/DatabaseMigrationTest.php +++ b/src/Core/Tests/Feature/DatabaseMigrationTest.php @@ -8,6 +8,9 @@ */ declare(strict_types=1); +use Core\Mod\Commerce\Database\Seeders\TaxRateSeeder; +use Core\Tenant\Database\Seeders\PackageSeeder; +use Database\Seeders\DatabaseSeeder; /** * Database Migration Tests @@ -84,15 +87,15 @@ describe('Database Migrations', function () { }); it('DatabaseSeeder class exists and has run method', function () { - expect(class_exists(\Database\Seeders\DatabaseSeeder::class))->toBeTrue(); - expect(method_exists(\Database\Seeders\DatabaseSeeder::class, 'run'))->toBeTrue(); + expect(class_exists(DatabaseSeeder::class))->toBeTrue(); + expect(method_exists(DatabaseSeeder::class, 'run'))->toBeTrue(); }); it('critical seeder classes exist in modules', function () { // Check for module seeders - these live in Mod namespaces $moduleSeederClasses = [ - \Core\Tenant\Database\Seeders\PackageSeeder::class, - \Core\Mod\Commerce\Database\Seeders\TaxRateSeeder::class, + PackageSeeder::class, + TaxRateSeeder::class, ]; $found = 0; diff --git a/src/Core/Tests/Feature/EmailShieldTest.php b/src/Core/Tests/Feature/EmailShieldTest.php index 5f88af5..64462b9 100644 --- a/src/Core/Tests/Feature/EmailShieldTest.php +++ b/src/Core/Tests/Feature/EmailShieldTest.php @@ -14,10 +14,11 @@ use Core\Mail\EmailShield; use Core\Mail\EmailShieldStat; use Core\Mail\EmailValidationResult; use Core\Mail\Rules\ValidatedEmail; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Validator; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); beforeEach(function () { // Clear the cache before each test to ensure clean state diff --git a/src/Core/Tests/Feature/ErrorPagesTest.php b/src/Core/Tests/Feature/ErrorPagesTest.php index f18291e..4412c0a 100644 --- a/src/Core/Tests/Feature/ErrorPagesTest.php +++ b/src/Core/Tests/Feature/ErrorPagesTest.php @@ -16,6 +16,8 @@ declare(strict_types=1); * Error handling is configured in bootstrap/app.php. */ +use App\Support\HadesEncrypt; +use Core\Tenant\Models\User; use Illuminate\Support\Facades\Config; describe('Static Error Files', function () { @@ -87,7 +89,7 @@ describe('404 Error Page', function () { describe('403 Error Page', function () { it('returns 403 for forbidden access', function () { // Create a regular user (not hades) - $user = \Core\Tenant\Models\User::factory()->create([ + $user = User::factory()->create([ 'account_type' => 'apollo', ]); @@ -152,11 +154,11 @@ describe('Error Page Brand Consistency', function () { describe('HADES Encryption', function () { it('HadesEncrypt class exists and is functional', function () { - expect(class_exists(\App\Support\HadesEncrypt::class))->toBeTrue(); + expect(class_exists(HadesEncrypt::class))->toBeTrue(); // Test encryption with a sample exception - $exception = new \Exception('Test error message'); - $encrypted = \App\Support\HadesEncrypt::encrypt($exception); + $exception = new Exception('Test error message'); + $encrypted = HadesEncrypt::encrypt($exception); // Should return encrypted string or null if no public key expect($encrypted === null || is_string($encrypted))->toBeTrue(); diff --git a/src/Core/Tests/Feature/ImageOptimizerTest.php b/src/Core/Tests/Feature/ImageOptimizerTest.php index 48dc07c..c856759 100644 --- a/src/Core/Tests/Feature/ImageOptimizerTest.php +++ b/src/Core/Tests/Feature/ImageOptimizerTest.php @@ -1,5 +1,7 @@ optimize('/path/to/nonexistent/file.jpg'); - })->throws(\InvalidArgumentException::class, 'File not found'); + })->throws(InvalidArgumentException::class, 'File not found'); it('handles invalid image files gracefully', function () { // Create a text file pretending to be an image diff --git a/src/Core/Tests/Feature/MailConfigurationTest.php b/src/Core/Tests/Feature/MailConfigurationTest.php index b57e0fa..363c3d1 100644 --- a/src/Core/Tests/Feature/MailConfigurationTest.php +++ b/src/Core/Tests/Feature/MailConfigurationTest.php @@ -9,6 +9,8 @@ declare(strict_types=1); +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Mail\SendQueuedMailable; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Queue; @@ -68,12 +70,12 @@ describe('Mail Sending', function () { Mail::to('recipient@example.com')->queue($mailable); - Queue::assertPushed(\Illuminate\Mail\SendQueuedMailable::class); + Queue::assertPushed(SendQueuedMailable::class); }); it('ContactFormSubmission implements ShouldQueue', function () { expect(ContactFormSubmission::class) - ->toImplement(\Illuminate\Contracts\Queue\ShouldQueue::class); + ->toImplement(ShouldQueue::class); }); }); diff --git a/src/Core/Tests/Feature/ModuleScannerIntegrationTest.php b/src/Core/Tests/Feature/ModuleScannerIntegrationTest.php index 7f0384d..383f182 100644 --- a/src/Core/Tests/Feature/ModuleScannerIntegrationTest.php +++ b/src/Core/Tests/Feature/ModuleScannerIntegrationTest.php @@ -10,6 +10,7 @@ declare(strict_types=1); use Core\Events\AdminPanelBooting; +use Core\Events\WebRoutesRegistering; use Core\LazyModuleListener; use Core\ModuleScanner; use Illuminate\Support\ServiceProvider; @@ -27,8 +28,8 @@ describe('ModuleScanner integration', function () { // Common events should have listeners $commonEvents = [ - \Core\Events\AdminPanelBooting::class, - \Core\Events\WebRoutesRegistering::class, + AdminPanelBooting::class, + WebRoutesRegistering::class, ]; foreach ($commonEvents as $event) { diff --git a/src/Core/Tests/Feature/OffloadMigrateCommandTest.php b/src/Core/Tests/Feature/OffloadMigrateCommandTest.php index ade68cc..9728958 100644 --- a/src/Core/Tests/Feature/OffloadMigrateCommandTest.php +++ b/src/Core/Tests/Feature/OffloadMigrateCommandTest.php @@ -1,5 +1,7 @@ user = User::factory()->create(); @@ -51,10 +64,10 @@ describe('Checkout Authorization Fixes', function () { ]); // Test authorization via component mount logic - $component = new \Core\Mod\Commerce\View\Modal\Web\CheckoutSuccess; + $component = new CheckoutSuccess; // Use reflection to call protected authorizeOrder - \Illuminate\Support\Facades\Auth::login($this->user); + Auth::login($this->user); $reflection = new ReflectionClass($component); $method = $reflection->getMethod('authorizeOrder'); $method->setAccessible(true); @@ -77,9 +90,9 @@ describe('Checkout Authorization Fixes', function () { ]); // Test authorization via component logic - $component = new \Core\Mod\Commerce\View\Modal\Web\CheckoutSuccess; + $component = new CheckoutSuccess; - \Illuminate\Support\Facades\Auth::login($this->user); + Auth::login($this->user); $reflection = new ReflectionClass($component); $method = $reflection->getMethod('authorizeOrder'); $method->setAccessible(true); @@ -106,9 +119,9 @@ describe('Checkout Authorization Fixes', function () { ]); // Test authorization via component logic - $component = new \Core\Mod\Commerce\View\Modal\Web\CheckoutCancel; + $component = new CheckoutCancel; - \Illuminate\Support\Facades\Auth::login($this->user); + Auth::login($this->user); $reflection = new ReflectionClass($component); $method = $reflection->getMethod('authorizeOrder'); $method->setAccessible(true); @@ -233,7 +246,7 @@ describe('Analytics Goal Controller N+1 Fix', function () { it('eager loads website relationship on show', function () { // Skip if route not registered (Analytics API routes not wired up in Boot.php) - if (! \Illuminate\Support\Facades\Route::has('api.analytics.goals.show')) { + if (! Route::has('api.analytics.goals.show')) { $this->markTestSkipped('Analytics goals API route not registered'); } @@ -248,13 +261,13 @@ describe('Analytics Goal Controller N+1 Fix', function () { ]); // Count queries - \Illuminate\Support\Facades\DB::enableQueryLog(); + DB::enableQueryLog(); $response = $this->actingAs($this->user) ->getJson("/api/v1/analytics/goals/{$goal->id}"); - $queries = \Illuminate\Support\Facades\DB::getQueryLog(); - \Illuminate\Support\Facades\DB::disableQueryLog(); + $queries = DB::getQueryLog(); + DB::disableQueryLog(); // Should be 200 OK expect($response->status())->toBe(200); @@ -321,11 +334,11 @@ describe('BTCPay Gateway Return Type', function () { 'commerce.gateways.btcpay.webhook_secret' => 'test_webhook_secret', ]); - $gateway = new \Core\Mod\Commerce\Services\PaymentGateway\BTCPayGateway; + $gateway = new BTCPayGateway; // Mock HTTP to fail so we test the error path - \Illuminate\Support\Facades\Http::fake([ - '*' => \Illuminate\Support\Facades\Http::response(['error' => 'Test error'], 400), + Http::fake([ + '*' => Http::response(['error' => 'Test error'], 400), ]); $result = $gateway->refund($payment, 50.00, 'Test refund'); @@ -356,11 +369,11 @@ describe('BTCPay Gateway Return Type', function () { 'commerce.gateways.btcpay.webhook_secret' => 'test_webhook_secret', ]); - $gateway = new \Core\Mod\Commerce\Services\PaymentGateway\BTCPayGateway; + $gateway = new BTCPayGateway; // Mock HTTP to succeed - \Illuminate\Support\Facades\Http::fake([ - '*' => \Illuminate\Support\Facades\Http::response([ + Http::fake([ + '*' => Http::response([ 'id' => 'refund_123', 'status' => 'processed', ], 200), @@ -394,7 +407,7 @@ describe('SocialPost Controller User Type Check', function () { describe('LIKE Wildcard Injection Fix', function () { it('escapes LIKE wildcards in MediaPicker search', function () { // Test the escapeLikeWildcards helper directly - $component = new \Core\Mod\Social\View\Modal\Admin\MediaPicker; + $component = new MediaPicker; $reflection = new ReflectionClass($component); $method = $reflection->getMethod('escapeLikeWildcards'); @@ -410,7 +423,7 @@ describe('LIKE Wildcard Injection Fix', function () { }); it('does not affect normal search terms', function () { - $component = new \Core\Mod\Social\View\Modal\Admin\MediaPicker; + $component = new MediaPicker; $reflection = new ReflectionClass($component); $method = $reflection->getMethod('escapeLikeWildcards'); @@ -429,8 +442,8 @@ describe('Null Workspace Checks', function () { $freshUser = User::factory()->create(); // Test without a default workspace - should not crash - \Livewire\Livewire::actingAs($freshUser) - ->test(\Core\Mod\Social\View\Modal\Admin\TemplateIndex::class) + Livewire::actingAs($freshUser) + ->test(TemplateIndex::class) ->assertStatus(200); }); @@ -502,8 +515,8 @@ describe('Checkout Edge Cases', function () { 'currency' => 'GBP', ]); - $component = new \Core\Mod\Commerce\View\Modal\Web\CheckoutSuccess; - \Illuminate\Support\Facades\Auth::login($freshUser); + $component = new CheckoutSuccess; + Auth::login($freshUser); $reflection = new ReflectionClass($component); $method = $reflection->getMethod('authorizeOrder'); @@ -528,8 +541,8 @@ describe('Checkout Edge Cases', function () { 'currency' => 'GBP', ]); - $component = new \Core\Mod\Commerce\View\Modal\Web\CheckoutCancel; - \Illuminate\Support\Facades\Auth::login($freshUser); + $component = new CheckoutCancel; + Auth::login($freshUser); $reflection = new ReflectionClass($component); $method = $reflection->getMethod('authorizeOrder'); diff --git a/src/Core/Tests/Feature/SecurityHeadersTest.php b/src/Core/Tests/Feature/SecurityHeadersTest.php index 5ff7989..aa38e98 100644 --- a/src/Core/Tests/Feature/SecurityHeadersTest.php +++ b/src/Core/Tests/Feature/SecurityHeadersTest.php @@ -8,6 +8,7 @@ */ declare(strict_types=1); +use Core\Tenant\Models\User; /** * Security Headers Tests (TASK-010 Phase 4) @@ -74,7 +75,7 @@ describe('Security Headers on Public Routes', function () { describe('Security Headers on Authenticated Routes', function () { beforeEach(function () { - $this->user = \Core\Tenant\Models\User::factory()->create(); + $this->user = User::factory()->create(); }); it('has security headers on hub routes', function () { @@ -98,7 +99,7 @@ describe('Security Headers on Authenticated Routes', function () { describe('Security Headers on API Routes', function () { beforeEach(function () { - $this->user = \Core\Tenant\Models\User::factory()->create([ + $this->user = User::factory()->create([ 'account_type' => 'hades', ]); }); diff --git a/src/Core/Tests/Feature/StorageOffloadTest.php b/src/Core/Tests/Feature/StorageOffloadTest.php index e6bc7da..776cc29 100644 --- a/src/Core/Tests/Feature/StorageOffloadTest.php +++ b/src/Core/Tests/Feature/StorageOffloadTest.php @@ -1,5 +1,7 @@ offloadService->getDisk(); - $this->assertInstanceOf(\Illuminate\Contracts\Filesystem\Filesystem::class, $disk); + $this->assertInstanceOf(Filesystem::class, $disk); } public function test_can_get_disk_name(): void diff --git a/src/Core/Tests/Feature/ValidationRulesTest.php b/src/Core/Tests/Feature/ValidationRulesTest.php index 86a264f..e97a17f 100644 --- a/src/Core/Tests/Feature/ValidationRulesTest.php +++ b/src/Core/Tests/Feature/ValidationRulesTest.php @@ -14,10 +14,11 @@ use Core\Mod\Social\Enums\ResourceStatus; use Core\Tenant\Models\User; use Core\Tenant\Rules\CheckUserPasswordRule; use Core\Tenant\Rules\ResourceStatusRule; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); describe('CheckUserPasswordRule', function () { it('passes validation when password matches', function () { diff --git a/src/Core/Tests/Unit/HadesEncryptTest.php b/src/Core/Tests/Unit/HadesEncryptTest.php index 2b92b57..73d1040 100644 --- a/src/Core/Tests/Unit/HadesEncryptTest.php +++ b/src/Core/Tests/Unit/HadesEncryptTest.php @@ -1,5 +1,7 @@ get($url); diff --git a/src/Mod/Trees/Database/Seeders/TreeSeeder.php b/src/Mod/Trees/Database/Seeders/TreeSeeder.php index 8f538e0..5de8846 100644 --- a/src/Mod/Trees/Database/Seeders/TreeSeeder.php +++ b/src/Mod/Trees/Database/Seeders/TreeSeeder.php @@ -1,5 +1,7 @@ group(function () { Route::get('/trees', TreesIndex::class)->name('trees'); // Agent referral tracking (Trees for Agents) - Route::get('/ref/{provider}/{model?}', [\Core\Tenant\Controllers\ReferralController::class, 'track']) + Route::get('/ref/{provider}/{model?}', [ReferralController::class, 'track']) ->name('referral.agent'); }); diff --git a/src/Mod/Trees/Tests/Feature/DailyLimitAndBonusTest.php b/src/Mod/Trees/Tests/Feature/DailyLimitAndBonusTest.php index 7f58c1c..4975fdd 100644 --- a/src/Mod/Trees/Tests/Feature/DailyLimitAndBonusTest.php +++ b/src/Mod/Trees/Tests/Feature/DailyLimitAndBonusTest.php @@ -5,8 +5,9 @@ declare(strict_types=1); use Core\Mod\Trees\Models\TreePlanting; use Core\Mod\Trees\Models\TreeReserve; use Core\Tenant\Models\AgentReferralBonus; +use Illuminate\Foundation\Testing\RefreshDatabase; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); beforeEach(function () { // Ensure tree reserve has trees available diff --git a/src/Mod/Trees/Tests/Feature/QueueProcessingTest.php b/src/Mod/Trees/Tests/Feature/QueueProcessingTest.php index e0a5194..f8a6623 100644 --- a/src/Mod/Trees/Tests/Feature/QueueProcessingTest.php +++ b/src/Mod/Trees/Tests/Feature/QueueProcessingTest.php @@ -4,8 +4,9 @@ declare(strict_types=1); use Core\Mod\Trees\Models\TreePlanting; use Core\Mod\Trees\Models\TreeReserve; +use Illuminate\Foundation\Testing\RefreshDatabase; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); beforeEach(function () { TreeReserve::replenish(100); diff --git a/src/Mod/Trees/Tests/Feature/ReferralRouteTest.php b/src/Mod/Trees/Tests/Feature/ReferralRouteTest.php index a495ab9..878b2c0 100644 --- a/src/Mod/Trees/Tests/Feature/ReferralRouteTest.php +++ b/src/Mod/Trees/Tests/Feature/ReferralRouteTest.php @@ -1,8 +1,9 @@ user = User::factory()->create(); diff --git a/src/Mod/Trees/Tests/Feature/TreesPageTest.php b/src/Mod/Trees/Tests/Feature/TreesPageTest.php index 1ee7bb2..4435888 100644 --- a/src/Mod/Trees/Tests/Feature/TreesPageTest.php +++ b/src/Mod/Trees/Tests/Feature/TreesPageTest.php @@ -4,8 +4,9 @@ declare(strict_types=1); use Core\Mod\Trees\Models\TreePlanting; use Core\Mod\Trees\Models\TreeReserve; +use Illuminate\Foundation\Testing\RefreshDatabase; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); beforeEach(function () { TreeReserve::replenish(100); diff --git a/src/Mod/Trees/View/Modal/Web/Index.php b/src/Mod/Trees/View/Modal/Web/Index.php index a1a2e92..b7c7ea3 100644 --- a/src/Mod/Trees/View/Modal/Web/Index.php +++ b/src/Mod/Trees/View/Modal/Web/Index.php @@ -6,6 +6,7 @@ namespace Core\Mod\Trees\View\Modal\Web; use Core\Mod\Trees\Models\TreePlanting; use Core\Mod\Trees\Models\TreePlantingStats; +use Illuminate\Contracts\View\View; use Illuminate\Support\Collection; use Livewire\Component; @@ -17,7 +18,7 @@ use Livewire\Component; */ class Index extends Component { - public function render(): \Illuminate\Contracts\View\View + public function render(): View { return view('trees::web.index', [ 'stats' => $this->getGlobalStats(), diff --git a/tests/Feature/ActivityLogServiceTest.php b/tests/Feature/ActivityLogServiceTest.php index bb89134..868e8b3 100644 --- a/tests/Feature/ActivityLogServiceTest.php +++ b/tests/Feature/ActivityLogServiceTest.php @@ -7,6 +7,7 @@ namespace Core\Tests\Feature; use Core\Activity\Services\ActivityLogService; use Core\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use Spatie\Activitylog\ActivitylogServiceProvider; use Spatie\Activitylog\Models\Activity; class ActivityLogServiceTest extends TestCase @@ -18,7 +19,7 @@ class ActivityLogServiceTest extends TestCase protected function getPackageProviders($app): array { return array_merge(parent::getPackageProviders($app), [ - \Spatie\Activitylog\ActivitylogServiceProvider::class, + ActivitylogServiceProvider::class, ]); } diff --git a/tests/Feature/LazyModuleListenerTest.php b/tests/Feature/LazyModuleListenerTest.php index f85abdb..b9787a4 100644 --- a/tests/Feature/LazyModuleListenerTest.php +++ b/tests/Feature/LazyModuleListenerTest.php @@ -9,6 +9,7 @@ use Core\Events\WebRoutesRegistering; use Core\LazyModuleListener; use Core\Tests\TestCase; use Illuminate\Support\ServiceProvider; +use Mod\ServiceProviderModule\Boot; class LazyModuleListenerTest extends TestCase { @@ -129,7 +130,7 @@ class LazyModuleListenerTest extends TestCase require_once $this->getFixturePath('Mod/ServiceProviderModule/Boot.php'); $listener = new LazyModuleListener( - \Mod\ServiceProviderModule\Boot::class, + Boot::class, 'onWebRoutes' ); diff --git a/tests/Feature/LifecycleEventsTest.php b/tests/Feature/LifecycleEventsTest.php index 7fbf14b..552ec93 100644 --- a/tests/Feature/LifecycleEventsTest.php +++ b/tests/Feature/LifecycleEventsTest.php @@ -15,48 +15,15 @@ use Core\Events\MediaRequested; use Core\Events\QueueWorkerBooting; use Core\Events\SearchRequested; use Core\Events\WebRoutesRegistering; -use Core\Front\Mcp\Contracts\McpToolHandler; use Core\Tests\TestCase; -// Test fixture implementing McpToolHandler -class TestMcpHandler implements McpToolHandler -{ - public static function schema(): array - { - return ['name' => 'test', 'description' => 'Test', 'inputSchema' => []]; - } +// Test fixtures — McpToolsRegistering stores class names as strings, +// so these don't need to implement the McpToolHandler interface (lives in core-mcp). +class TestMcpHandler {} - public function handle(array $args, \Core\Front\Mcp\McpContext $context): array - { - return []; - } -} +class TestMcpHandler2 {} -class TestMcpHandler2 implements McpToolHandler -{ - public static function schema(): array - { - return ['name' => 'test2', 'description' => 'Test 2', 'inputSchema' => []]; - } - - public function handle(array $args, \Core\Front\Mcp\McpContext $context): array - { - return []; - } -} - -class TestMcpHandler3 implements McpToolHandler -{ - public static function schema(): array - { - return ['name' => 'test3', 'description' => 'Test 3', 'inputSchema' => []]; - } - - public function handle(array $args, \Core\Front\Mcp\McpContext $context): array - { - return []; - } -} +class TestMcpHandler3 {} class LifecycleEventsTest extends TestCase { diff --git a/tests/Feature/LogsActivityTraitTest.php b/tests/Feature/LogsActivityTraitTest.php index 1ad8e75..78c9951 100644 --- a/tests/Feature/LogsActivityTraitTest.php +++ b/tests/Feature/LogsActivityTraitTest.php @@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Schema\Blueprint; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Schema; +use Spatie\Activitylog\ActivitylogServiceProvider; use Spatie\Activitylog\LogOptions; use Spatie\Activitylog\Models\Activity; @@ -56,7 +57,7 @@ class LogsActivityTraitTest extends TestCase protected function getPackageProviders($app): array { return array_merge(parent::getPackageProviders($app), [ - \Spatie\Activitylog\ActivitylogServiceProvider::class, + ActivitylogServiceProvider::class, ]); } diff --git a/tests/Feature/ModuleScannerTest.php b/tests/Feature/ModuleScannerTest.php index 992b3dc..df446a6 100644 --- a/tests/Feature/ModuleScannerTest.php +++ b/tests/Feature/ModuleScannerTest.php @@ -9,6 +9,7 @@ use Core\Events\FrameworkBooted; use Core\Events\WebRoutesRegistering; use Core\ModuleScanner; use Core\Tests\TestCase; +use Mod\PrivateListens\Boot; class ModuleScannerTest extends TestCase { @@ -145,7 +146,7 @@ PHP); { require_once $this->getFixturePath('Mod/PrivateListens/Boot.php'); - $result = $this->scanner->extractListens(\Mod\PrivateListens\Boot::class); + $result = $this->scanner->extractListens(Boot::class); $this->assertIsArray($result); $this->assertEmpty($result); diff --git a/tests/Feature/ScheduleSyncCommandTest.php b/tests/Feature/ScheduleSyncCommandTest.php index 8200310..66c2d07 100644 --- a/tests/Feature/ScheduleSyncCommandTest.php +++ b/tests/Feature/ScheduleSyncCommandTest.php @@ -6,6 +6,7 @@ namespace Core\Tests\Feature; use Core\Actions\ScheduledAction; use Core\Console\Commands\ScheduleSyncCommand; +use Illuminate\Contracts\Console\Kernel; use Illuminate\Foundation\Testing\RefreshDatabase; use Orchestra\Testbench\TestCase; @@ -36,7 +37,7 @@ class ScheduleSyncCommandTest extends TestCase { parent::setUp(); - $this->app->make(\Illuminate\Contracts\Console\Kernel::class)->registerCommand( + $this->app->make(Kernel::class)->registerCommand( $this->app->make(ScheduleSyncCommand::class) ); } diff --git a/tests/Feature/ScheduledActionScannerTest.php b/tests/Feature/ScheduledActionScannerTest.php index b228689..68ae539 100644 --- a/tests/Feature/ScheduledActionScannerTest.php +++ b/tests/Feature/ScheduledActionScannerTest.php @@ -17,7 +17,7 @@ class ScheduledActionScannerTest extends TestCase protected function setUp(): void { parent::setUp(); - $this->scanner = new ScheduledActionScanner(); + $this->scanner = new ScheduledActionScanner; } public function test_scan_discovers_scheduled_actions(): void diff --git a/tests/Feature/ScheduledAttributeTest.php b/tests/Feature/ScheduledAttributeTest.php index 048512b..d769b0a 100644 --- a/tests/Feature/ScheduledAttributeTest.php +++ b/tests/Feature/ScheduledAttributeTest.php @@ -57,6 +57,4 @@ class ScheduledAttributeTest extends TestCase } #[Scheduled(frequency: 'everyMinute')] -class ScheduledAttributeTest_Stub -{ -} +class ScheduledAttributeTest_Stub {} diff --git a/tests/Feature/SeederDiscoveryTest.php b/tests/Feature/SeederDiscoveryTest.php index 2b92c58..5a7663a 100644 --- a/tests/Feature/SeederDiscoveryTest.php +++ b/tests/Feature/SeederDiscoveryTest.php @@ -9,6 +9,12 @@ use Core\Database\Seeders\Attributes\SeederBefore; use Core\Database\Seeders\Exceptions\CircularDependencyException; use Core\Database\Seeders\SeederDiscovery; use Core\Tests\TestCase; +use Mod\Alpha\Database\Seeders\AlphaSeeder; +use Mod\Beta\Database\Seeders\BetaSeeder; +use Mod\Circular\Database\Seeders\CircularASeeder; +use Mod\Circular\Database\Seeders\CircularBSeeder; +use Mod\Gamma\Database\Seeders\DeltaSeeder; +use Mod\Gamma\Database\Seeders\GammaSeeder; class SeederDiscoveryTest extends TestCase { @@ -50,30 +56,30 @@ class SeederDiscoveryTest extends TestCase { // Exclude circular dependency seeders for this test $this->discovery->exclude([ - \Mod\Circular\Database\Seeders\CircularASeeder::class, - \Mod\Circular\Database\Seeders\CircularBSeeder::class, + CircularASeeder::class, + CircularBSeeder::class, ]); $seeders = $this->discovery->getSeeders(); - $this->assertArrayHasKey(\Mod\Alpha\Database\Seeders\AlphaSeeder::class, $seeders); - $this->assertArrayHasKey(\Mod\Beta\Database\Seeders\BetaSeeder::class, $seeders); - $this->assertArrayHasKey(\Mod\Gamma\Database\Seeders\GammaSeeder::class, $seeders); - $this->assertArrayHasKey(\Mod\Gamma\Database\Seeders\DeltaSeeder::class, $seeders); + $this->assertArrayHasKey(AlphaSeeder::class, $seeders); + $this->assertArrayHasKey(BetaSeeder::class, $seeders); + $this->assertArrayHasKey(GammaSeeder::class, $seeders); + $this->assertArrayHasKey(DeltaSeeder::class, $seeders); } public function test_extracts_priority_from_property(): void { $seeders = $this->discovery->getSeeders(); - $this->assertEquals(10, $seeders[\Mod\Alpha\Database\Seeders\AlphaSeeder::class]['priority']); + $this->assertEquals(10, $seeders[AlphaSeeder::class]['priority']); } public function test_extracts_priority_from_attribute(): void { $seeders = $this->discovery->getSeeders(); - $this->assertEquals(50, $seeders[\Mod\Beta\Database\Seeders\BetaSeeder::class]['priority']); + $this->assertEquals(50, $seeders[BetaSeeder::class]['priority']); } public function test_uses_default_priority_when_not_specified(): void @@ -83,7 +89,7 @@ class SeederDiscoveryTest extends TestCase // CircularASeeder has no priority declaration $this->assertEquals( SeederDiscovery::DEFAULT_PRIORITY, - $seeders[\Mod\Circular\Database\Seeders\CircularASeeder::class]['priority'] + $seeders[CircularASeeder::class]['priority'] ); } @@ -92,8 +98,8 @@ class SeederDiscoveryTest extends TestCase $seeders = $this->discovery->getSeeders(); $this->assertContains( - \Mod\Beta\Database\Seeders\BetaSeeder::class, - $seeders[\Mod\Gamma\Database\Seeders\GammaSeeder::class]['after'] + BetaSeeder::class, + $seeders[GammaSeeder::class]['after'] ); } @@ -102,8 +108,8 @@ class SeederDiscoveryTest extends TestCase $seeders = $this->discovery->getSeeders(); $this->assertContains( - \Mod\Alpha\Database\Seeders\AlphaSeeder::class, - $seeders[\Mod\Beta\Database\Seeders\BetaSeeder::class]['after'] + AlphaSeeder::class, + $seeders[BetaSeeder::class]['after'] ); } @@ -112,8 +118,8 @@ class SeederDiscoveryTest extends TestCase $seeders = $this->discovery->getSeeders(); $this->assertContains( - \Mod\Beta\Database\Seeders\BetaSeeder::class, - $seeders[\Mod\Gamma\Database\Seeders\DeltaSeeder::class]['before'] + BetaSeeder::class, + $seeders[DeltaSeeder::class]['before'] ); } @@ -123,11 +129,11 @@ class SeederDiscoveryTest extends TestCase $discovery = new SeederDiscovery( [$this->getFixturePath('Mod')], [ - \Mod\Beta\Database\Seeders\BetaSeeder::class, - \Mod\Gamma\Database\Seeders\GammaSeeder::class, - \Mod\Gamma\Database\Seeders\DeltaSeeder::class, - \Mod\Circular\Database\Seeders\CircularASeeder::class, - \Mod\Circular\Database\Seeders\CircularBSeeder::class, + BetaSeeder::class, + GammaSeeder::class, + DeltaSeeder::class, + CircularASeeder::class, + CircularBSeeder::class, ] ); @@ -135,21 +141,21 @@ class SeederDiscoveryTest extends TestCase // Only AlphaSeeder should remain $this->assertCount(1, $ordered); - $this->assertEquals(\Mod\Alpha\Database\Seeders\AlphaSeeder::class, $ordered[0]); + $this->assertEquals(AlphaSeeder::class, $ordered[0]); } public function test_respects_dependency_ordering(): void { $this->discovery->exclude([ - \Mod\Circular\Database\Seeders\CircularASeeder::class, - \Mod\Circular\Database\Seeders\CircularBSeeder::class, + CircularASeeder::class, + CircularBSeeder::class, ]); $ordered = $this->discovery->discover(); - $alphaIndex = array_search(\Mod\Alpha\Database\Seeders\AlphaSeeder::class, $ordered); - $betaIndex = array_search(\Mod\Beta\Database\Seeders\BetaSeeder::class, $ordered); - $gammaIndex = array_search(\Mod\Gamma\Database\Seeders\GammaSeeder::class, $ordered); + $alphaIndex = array_search(AlphaSeeder::class, $ordered); + $betaIndex = array_search(BetaSeeder::class, $ordered); + $gammaIndex = array_search(GammaSeeder::class, $ordered); // Alpha must come before Beta (Beta has SeederAfter(Alpha)) $this->assertLessThan($betaIndex, $alphaIndex, 'Alpha should run before Beta'); @@ -161,14 +167,14 @@ class SeederDiscoveryTest extends TestCase public function test_respects_before_dependency(): void { $this->discovery->exclude([ - \Mod\Circular\Database\Seeders\CircularASeeder::class, - \Mod\Circular\Database\Seeders\CircularBSeeder::class, + CircularASeeder::class, + CircularBSeeder::class, ]); $ordered = $this->discovery->discover(); - $deltaIndex = array_search(\Mod\Gamma\Database\Seeders\DeltaSeeder::class, $ordered); - $betaIndex = array_search(\Mod\Beta\Database\Seeders\BetaSeeder::class, $ordered); + $deltaIndex = array_search(DeltaSeeder::class, $ordered); + $betaIndex = array_search(BetaSeeder::class, $ordered); // Delta must come before Beta (Delta has SeederBefore(Beta)) $this->assertLessThan($betaIndex, $deltaIndex, 'Delta should run before Beta'); @@ -203,14 +209,14 @@ class SeederDiscoveryTest extends TestCase public function test_exclusion_filter_works(): void { $this->discovery->exclude([ - \Mod\Alpha\Database\Seeders\AlphaSeeder::class, - \Mod\Circular\Database\Seeders\CircularASeeder::class, - \Mod\Circular\Database\Seeders\CircularBSeeder::class, + AlphaSeeder::class, + CircularASeeder::class, + CircularBSeeder::class, ]); $seeders = $this->discovery->getSeeders(); - $this->assertArrayNotHasKey(\Mod\Alpha\Database\Seeders\AlphaSeeder::class, $seeders); + $this->assertArrayNotHasKey(AlphaSeeder::class, $seeders); } public function test_add_paths_appends_to_existing(): void @@ -222,8 +228,8 @@ class SeederDiscoveryTest extends TestCase $seeders = $discovery->getSeeders(); - $this->assertArrayHasKey(\Mod\Alpha\Database\Seeders\AlphaSeeder::class, $seeders); - $this->assertArrayHasKey(\Mod\Beta\Database\Seeders\BetaSeeder::class, $seeders); + $this->assertArrayHasKey(AlphaSeeder::class, $seeders); + $this->assertArrayHasKey(BetaSeeder::class, $seeders); } public function test_set_paths_replaces_existing(): void @@ -234,15 +240,15 @@ class SeederDiscoveryTest extends TestCase $discovery->setPaths([$this->getFixturePath('Mod/Beta')]); $seeders = $discovery->getSeeders(); - $this->assertArrayNotHasKey(\Mod\Alpha\Database\Seeders\AlphaSeeder::class, $seeders); - $this->assertArrayHasKey(\Mod\Beta\Database\Seeders\BetaSeeder::class, $seeders); + $this->assertArrayNotHasKey(AlphaSeeder::class, $seeders); + $this->assertArrayHasKey(BetaSeeder::class, $seeders); } public function test_reset_clears_cache(): void { $this->discovery->exclude([ - \Mod\Circular\Database\Seeders\CircularASeeder::class, - \Mod\Circular\Database\Seeders\CircularBSeeder::class, + CircularASeeder::class, + CircularBSeeder::class, ]); $seeders1 = $this->discovery->getSeeders(); diff --git a/tests/Feature/WebhookControllerTest.php b/tests/Feature/WebhookControllerTest.php index 3f68725..125e0c5 100644 --- a/tests/Feature/WebhookControllerTest.php +++ b/tests/Feature/WebhookControllerTest.php @@ -6,6 +6,7 @@ namespace Core\Tests\Feature; use Core\Tests\TestCase; use Core\Webhook\WebhookCall; +use Core\Webhook\WebhookController; use Core\Webhook\WebhookReceived; use Core\Webhook\WebhookVerifier; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -23,7 +24,7 @@ class WebhookControllerTest extends TestCase protected function defineRoutes($router): void { - $router->post('/webhooks/{source}', [\Core\Webhook\WebhookController::class, 'handle']) + $router->post('/webhooks/{source}', [WebhookController::class, 'handle']) ->where('source', '[a-z0-9\-]+'); } diff --git a/tests/Fixtures/Mod/Alpha/Database/Seeders/AlphaSeeder.php b/tests/Fixtures/Mod/Alpha/Database/Seeders/AlphaSeeder.php index 2ae8ef7..4d59e4c 100644 --- a/tests/Fixtures/Mod/Alpha/Database/Seeders/AlphaSeeder.php +++ b/tests/Fixtures/Mod/Alpha/Database/Seeders/AlphaSeeder.php @@ -1,5 +1,7 @@