Files

122 lines
3.3 KiB
PHP
Raw Permalink Normal View History

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class ScheduleBootstrapCommand extends Command
{
protected $signature = 'schedule:bootstrap
{--install-only : فقط خط cron همین ماژول را نصب کن}
{--run-only : فقط یک‌بار schedule:run بزن، cron را دست نزن}
{--dry-run : خط cron را نشان بده بدون نصب}
{--php= : مسیر php (پیش‌فرض PHP_BINARY)}';
protected $description = 'نصب cron این ماژول (schedule:run) و/یا اجرای یک‌بار زمان‌بند';
public function handle(): int
{
$runOnly = (bool) $this->option('run-only');
$installOnly = (bool) $this->option('install-only');
if ($runOnly && $installOnly) {
$this->error('فقط یکی از --run-only یا --install-only را بزنید.');
return self::FAILURE;
}
if (! $runOnly && ! $this->installCronLine()) {
return self::FAILURE;
}
if ($installOnly) {
return self::SUCCESS;
}
$this->info('==> php artisan schedule:run');
return $this->call('schedule:run');
}
private function installCronLine(): bool
{
$php = trim((string) ($this->option('php') ?: PHP_BINARY));
$artisan = base_path('artisan');
$marker = $artisan.' schedule:run';
$line = "* * * * * {$php} {$artisan} schedule:run >> /dev/null 2>&1";
$existing = $this->currentCrontab();
if ($this->crontabHasLine($existing, $marker)) {
$this->info("cron از قبل نصب است: {$artisan}");
return true;
}
if ($this->option('dry-run')) {
$this->line($line);
return true;
}
$payload = trim($existing);
if ($payload !== '') {
$payload .= "\n";
}
$payload .= $line."\n";
$tmp = tempnam(sys_get_temp_dir(), 'khaneghi-crontab-');
if ($tmp === false) {
$this->error('ساخت فایل موقت crontab ناموفق بود.');
return false;
}
file_put_contents($tmp, $payload);
exec('crontab '.escapeshellarg($tmp).' 2>&1', $output, $code);
@unlink($tmp);
if ($code !== 0) {
$this->error('نصب crontab ناموفق بود.');
foreach ($output as $row) {
$this->line($row);
}
return false;
}
$this->info("cron نصب شد:\n{$line}");
return true;
}
private function currentCrontab(): string
{
exec('crontab -l 2>/dev/null', $lines, $code);
if ($code !== 0) {
return '';
}
return implode("\n", $lines);
}
private function crontabHasLine(string $crontab, string $marker): bool
{
if ($crontab === '') {
return false;
}
foreach (preg_split('/\R/u', $crontab) ?: [] as $row) {
$row = trim((string) $row);
if ($row === '' || str_starts_with($row, '#')) {
continue;
}
if (str_contains($row, $marker)) {
return true;
}
}
return false;
}
}