IdentifierAppService
File: app/Services/Common/IdentifierAppService.php
Centralized service that answers "what state is the application in?". Every middleware check, wizard step, and redirect decision uses this service.
Why It Exists
Without this service, every controller and middleware would need to repeat the same database queries to determine if setup is complete, if the database is seeded, or if content exists. This service centralizes those checks so there's a single source of truth.
Methods
setup(): array
Returns whether a super user (admin) exists.
public static function setup(): array
{
return ['superUser' => User::query()->exists()];
}Used by: SetupMiddleware, SetupController::checks()
Why check this? Without an admin, nobody can log into the system. The application is unusable.
seeder(): array
Returns individual booleans for each seeded dataset.
public static function seeder(): array
{
return [
'geographic' => Setting::query()->where('module', 'core')->where('group', 'location')->exists(),
'gender' => Gender::query()->exists(),
'ethnicity' => Ethnicity::query()->exists(),
'localization' => Localization::query()->exists(),
'religion' => Religion::query()->exists(),
];
}Used by: MaintenanceMiddleware, SetupController::checks()
Why check this? Forms throughout the application reference seeded data (cities, genders, religions). Without it, dropdowns would be empty.
initial(): array
Returns content readiness for each public feature.
public static function initial(): array
{
return [
'school' => School::query()->exists() && SchoolEducationLevel::query()->exists(),
'news' => Article::query()->exists(),
'ratings' => Rating::query()->exists(),
'banner' => Banner::query()->exists(),
'announcement' => Announcement::query()->exists(),
'faq' => Faq::query()->exists(),
];
}Used by: MaintenanceMiddleware, SetupController::checks()
Why check this? The public landing page needs content to display. Without schools and articles, there's nothing to show.
isSetup(): bool
Master check — all conditions must pass before the app leaves setup mode. Uses all of the above methods internally.
Used by: SetupMiddleware
Full algorithm documented in the Setup Module.
isSeeder(): bool
Convenience method that checks if ALL seeder data is present. Intentionally less strict than isSetup().
public static function isSeeder(): bool
{
$s = self::seeder();
return $s['geographic'] && $s['gender'] && $s['ethnicity']
&& $s['localization'] && $s['religion'];
}Used by: MaintenanceMiddleware
Why less strict? Once the database has its fundamental data, users can be redirected to the admin portal. Branding and contact configuration can happen through the panel.
isMaintenance(): bool
Checks if maintenance mode is enabled via the core.maintenance_mode setting.
public static function isMaintenance(): bool
{
return Setting::query()
->where('module', 'core')->where('group', 'general')
->where('key', 'core.maintenance_mode')
->value('value') === 'true';
}Used by: MaintenanceMiddleware
How to Use
use App\Services\Common\IdentifierAppService;
// Quick checks
if (! IdentifierAppService::isSetup()) {
return redirect('/setup');
}
// Check specific state
$status = IdentifierAppService::status(); // all checks in one array
if ($status['maintenance']) {
// show maintenance page
}How to Extend
- Add a new key to the appropriate method (
setup(),seeder(), orinitial()) - If it should block setup completion, add it to
isSetup() - If it affects the maintenance redirect, add it to
MaintenanceMiddleware