116 lines
3.5 KiB
PHP
116 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\System;
|
|
|
|
use App\Models\Configuration;
|
|
use DateTimeImmutable;
|
|
use DateTimeZone;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class ConfigUpdateService
|
|
{
|
|
private array $tasks = [
|
|
'update_date_age_reference' => 'taskUpdateDateAgeReference',
|
|
'enable_attendance_on' => 'taskEnableAttendanceOn',
|
|
'enable_attendance_off' => 'taskEnableAttendanceOff',
|
|
'set_semester_spring' => 'taskSetSemesterSpring',
|
|
'set_semester_fall' => 'taskSetSemesterFall',
|
|
];
|
|
|
|
public function availableTasks(): array
|
|
{
|
|
return array_keys($this->tasks);
|
|
}
|
|
|
|
public function runTask(string $task, bool $dry, bool $force, DateTimeZone $tz): array
|
|
{
|
|
if (!isset($this->tasks[$task])) {
|
|
return ['ok' => false, 'message' => 'Unknown task.'];
|
|
}
|
|
|
|
$lockFile = storage_path('app/locks/config_update_' . $task . '.lock');
|
|
if (!is_dir(dirname($lockFile))) {
|
|
@mkdir(dirname($lockFile), 0775, true);
|
|
}
|
|
|
|
$fp = @fopen($lockFile, 'c+');
|
|
if (!$fp) {
|
|
return ['ok' => false, 'message' => 'Unable to open lock file.'];
|
|
}
|
|
|
|
if (!$force && !flock($fp, LOCK_EX | LOCK_NB)) {
|
|
fclose($fp);
|
|
return ['ok' => false, 'message' => 'Task is already running.'];
|
|
}
|
|
|
|
try {
|
|
$method = $this->tasks[$task];
|
|
$ok = (bool) $this->{$method}($dry, $force, $tz);
|
|
return ['ok' => $ok, 'task' => $task];
|
|
} catch (\Throwable $e) {
|
|
Log::error('ConfigUpdate task failed: ' . $e->getMessage());
|
|
return ['ok' => false, 'message' => $e->getMessage()];
|
|
} finally {
|
|
try {
|
|
flock($fp, LOCK_UN);
|
|
fclose($fp);
|
|
@unlink($lockFile);
|
|
} catch (\Throwable $e) {
|
|
}
|
|
}
|
|
}
|
|
|
|
private function taskEnableAttendanceOn(bool $dry, bool $force, DateTimeZone $tz): bool
|
|
{
|
|
return $this->setConfig('enable_attendance', '1', $dry);
|
|
}
|
|
|
|
private function taskEnableAttendanceOff(bool $dry, bool $force, DateTimeZone $tz): bool
|
|
{
|
|
return $this->setConfig('enable_attendance', '0', $dry);
|
|
}
|
|
|
|
private function taskUpdateDateAgeReference(bool $dry, bool $force, DateTimeZone $tz): bool
|
|
{
|
|
$now = new DateTimeImmutable('now', $tz);
|
|
$isJune1 = $now->format('n-j') === '6-1';
|
|
if (!$isJune1 && !$force) {
|
|
return true;
|
|
}
|
|
|
|
$value = $now->format('Y') . '-12-31';
|
|
return $dry ? true : Configuration::setConfigValueByKey('date_age_reference', $value);
|
|
}
|
|
|
|
private function taskSetSemesterSpring(bool $dry, bool $force, DateTimeZone $tz): bool
|
|
{
|
|
$now = new DateTimeImmutable('now', $tz);
|
|
$isFeb1 = $now->format('n-j') === '2-1';
|
|
if (!$isFeb1 && !$force) {
|
|
return true;
|
|
}
|
|
|
|
return $dry ? true : Configuration::setConfigValueByKey('semester', 'Spring');
|
|
}
|
|
|
|
private function taskSetSemesterFall(bool $dry, bool $force, DateTimeZone $tz): bool
|
|
{
|
|
$now = new DateTimeImmutable('now', $tz);
|
|
$isJun1 = $now->format('n-j') === '6-1';
|
|
if (!$isJun1 && !$force) {
|
|
return true;
|
|
}
|
|
|
|
return $dry ? true : Configuration::setConfigValueByKey('semester', 'Fall');
|
|
}
|
|
|
|
private function setConfig(string $key, string $value, bool $dry): bool
|
|
{
|
|
if ($dry) {
|
|
return true;
|
|
}
|
|
|
|
return Configuration::setConfigValueByKey($key, $value);
|
|
}
|
|
}
|