Initial commit: Pireon Admin — headless admin panel and public API
Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
82
app/Console/Commands/ScheduleContentCommand.php
Normal file
82
app/Console/Commands/ScheduleContentCommand.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\CallStatus;
|
||||
use App\Models\Call;
|
||||
use App\Models\Page;
|
||||
use App\Models\Project;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Keeps the stored state honest about what the site is actually showing.
|
||||
*
|
||||
* Most of scheduling needs no command at all: the `published` scopes read the
|
||||
* dates, so content appears and disappears on time whether or not anything is
|
||||
* running. What a scope cannot do is change what the panel *says*, and a panel
|
||||
* that reports "Open" for a call the site stopped offering weeks ago is how a
|
||||
* counter stops being read.
|
||||
*
|
||||
* So this closes what has expired and leaves everything else alone. In
|
||||
* particular it does not touch the status of pages or projects: their window
|
||||
* already hides them, and rewriting a status would throw away the one somebody
|
||||
* chose in order to record something the dates already say.
|
||||
*/
|
||||
class ScheduleContentCommand extends Command
|
||||
{
|
||||
protected $signature = 'content:schedule
|
||||
{--dry-run : Report what would change without changing it}';
|
||||
|
||||
protected $description = 'Close calls past their date and report content entering or leaving the site';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$expired = Call::query()
|
||||
->where('status', CallStatus::Open)
|
||||
->whereNotNull('closes_at')
|
||||
->where('closes_at', '<', now())
|
||||
->get();
|
||||
|
||||
foreach ($expired as $call) {
|
||||
$title = $call->getTranslation('title', (string) config('locales.default'), false);
|
||||
|
||||
$this->components->twoColumnDetail(
|
||||
$title ?: "#{$call->id}",
|
||||
'<fg=gray>'.__('console.schedule.closed').'</>',
|
||||
);
|
||||
|
||||
if (! $this->option('dry-run')) {
|
||||
$call->update(['status' => CallStatus::Closed]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->report();
|
||||
|
||||
$this->components->info(
|
||||
trans_choice('console.schedule.summary', $expired->count(), ['count' => $expired->count()])
|
||||
);
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* What the dates are about to do on their own. Nothing here needs acting
|
||||
* on; it is here so that a scheduled release is visible in the logs before
|
||||
* it happens rather than only afterwards.
|
||||
*/
|
||||
protected function report(): void
|
||||
{
|
||||
$pending = Page::query()->scheduled()->count() + Project::query()->scheduled()->count();
|
||||
$expiring = Page::query()->expired()->count() + Project::query()->expired()->count();
|
||||
|
||||
if ($pending > 0) {
|
||||
$this->components->twoColumnDetail(__('console.schedule.pending'), (string) $pending);
|
||||
}
|
||||
|
||||
if ($expiring > 0) {
|
||||
$this->components->twoColumnDetail(__('console.schedule.off_site'), (string) $expiring);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user