Files
nexusphp/app/Models/Exam.php

298 lines
9.8 KiB
PHP
Raw Normal View History

2021-04-19 20:13:21 +08:00
<?php
namespace App\Models;
2022-06-27 01:39:01 +08:00
use Carbon\Carbon;
use Google\Service\Dataproc\RegexValidation;
use Illuminate\Database\Eloquent\Casts\Attribute;
2021-05-08 16:25:55 +08:00
use Illuminate\Database\Eloquent\Model;
2021-04-19 20:13:21 +08:00
class Exam extends NexusModel
{
2024-04-13 13:55:32 +08:00
protected $fillable = [
'name', 'description', 'begin', 'end', 'duration', 'status', 'is_discovered', 'filters', 'indexes', 'priority',
2024-05-18 14:53:30 +08:00
'recurring', 'type', 'success_reward_bonus', 'fail_deduct_bonus'
2024-04-13 13:55:32 +08:00
];
2021-04-23 20:05:39 +08:00
2021-04-25 02:12:14 +08:00
public $timestamps = true;
2021-04-23 20:05:39 +08:00
protected $casts = [
2023-04-29 03:46:14 +08:00
'filters' => 'array',
2021-04-23 20:05:39 +08:00
'indexes' => 'array',
];
2021-04-20 20:18:02 +08:00
const STATUS_ENABLED = 0;
const STATUS_DISABLED = 1;
public static $status = [
2021-04-23 20:05:39 +08:00
self::STATUS_ENABLED => ['text' => 'Enabled'],
self::STATUS_DISABLED => ['text' => 'Disabled'],
2021-04-20 20:18:02 +08:00
];
2021-05-02 17:24:05 +08:00
const DISCOVERED_YES = 1;
const DISCOVERED_NO = 0;
public static $discovers = [
self::DISCOVERED_NO => ['text' => 'No'],
self::DISCOVERED_YES => ['text' => 'Yes'],
];
2021-04-20 20:18:02 +08:00
const INDEX_UPLOADED = 1;
const INDEX_SEED_TIME_AVERAGE = 2;
2021-04-20 20:18:02 +08:00
const INDEX_DOWNLOADED = 3;
2021-05-05 22:28:19 +08:00
const INDEX_SEED_BONUS = 4;
const INDEX_SEED_POINTS = 5;
const INDEX_UPLOAD_TORRENT_COUNT = 6;
2021-04-20 20:18:02 +08:00
public static array $indexes = [
2021-06-12 23:21:40 +08:00
self::INDEX_UPLOADED => ['name' => 'Uploaded', 'unit' => 'GB', 'source_user_field' => 'uploaded'],
self::INDEX_DOWNLOADED => ['name' => 'Downloaded', 'unit' => 'GB', 'source_user_field' => 'downloaded'],
2022-07-02 15:08:23 +08:00
self::INDEX_SEED_TIME_AVERAGE => ['name' => 'Seed time average', 'unit' => 'Hour', 'source_user_field' => 'seedtime'],
2022-02-22 13:34:50 +08:00
self::INDEX_SEED_BONUS => ['name' => 'Bonus', 'unit' => '', 'source_user_field' => 'seedbonus'],
self::INDEX_SEED_POINTS => ['name' => 'Seed points', 'unit' => '', 'source_user_field' => ''],
self::INDEX_UPLOAD_TORRENT_COUNT => ['name' => 'Upload torrent', 'unit' => '', 'source_user_field' => ''],
2021-04-23 20:05:39 +08:00
];
const FILTER_USER_CLASS = 'classes';
const FILTER_USER_REGISTER_TIME_RANGE = 'register_time_range';
const FILTER_USER_DONATE = 'donate_status';
const FILTER_USER_REGISTER_DAYS_RANGE = 'register_days_range';
2021-04-23 20:05:39 +08:00
public static $filters = [
2021-05-02 17:24:05 +08:00
self::FILTER_USER_CLASS => ['name' => 'User class'],
self::FILTER_USER_REGISTER_TIME_RANGE => ['name' => 'User register time range'],
2021-06-12 23:21:40 +08:00
self::FILTER_USER_DONATE => ['name' => 'User donated'],
self::FILTER_USER_REGISTER_DAYS_RANGE => ['name' => 'User register days range'],
2021-04-20 20:18:02 +08:00
];
const RECURRING_DAILY = "Daily";
2024-04-13 13:55:32 +08:00
const RECURRING_WEEKLY = "Weekly";
const RECURRING_MONTHLY = "Monthly";
2024-05-18 14:53:30 +08:00
const TYPE_EXAM = 1;
const TYPE_TASK = 2;
2021-05-08 16:25:55 +08:00
protected static function booted()
{
static::saving(function (Model $model) {
$model->duration = (int)$model->duration;
});
}
2022-07-02 15:08:23 +08:00
public static function listIndex($onlyKeyValue = false): array
{
$result = self::$indexes;
$keyValues = [];
foreach ($result as $key => &$value) {
$text = nexus_trans("exam.index_text_$key");
$value['text'] = $text;
$keyValues[$key] = $text;
}
if ($onlyKeyValue) {
return $keyValues;
}
return $result;
}
2024-04-13 13:55:32 +08:00
public static function listRecurringOptions(): array
{
return [
self::RECURRING_DAILY => nexus_trans("exam.recurring_daily"),
2024-04-13 13:55:32 +08:00
self::RECURRING_WEEKLY => nexus_trans("exam.recurring_weekly"),
self::RECURRING_MONTHLY => nexus_trans("exam.recurring_monthly"),
];
}
2024-05-18 14:53:30 +08:00
public static function listTypeOptions(): array
{
return [
self::TYPE_EXAM => nexus_trans("exam.type_exam"),
self::TYPE_TASK => nexus_trans("exam.type_task"),
];
}
public function getTypeTextAttribute()
{
return self::listTypeOptions()[$this->type] ?? "";
}
2024-04-13 13:55:32 +08:00
protected function getRecurringTextAttribute(): string
{
$options = self::listRecurringOptions();
return $options[$this->recurring] ?? '';
}
public function getStatusTextAttribute(): string
2021-04-20 20:18:02 +08:00
{
2022-07-02 15:08:23 +08:00
return $this->status == self::STATUS_ENABLED ? nexus_trans('label.enabled') : nexus_trans('label.disabled');
2021-04-20 20:18:02 +08:00
}
2021-05-02 17:24:05 +08:00
public function getIsDiscoveredTextAttribute(): string
{
return self::$discovers[$this->is_discovered]['text'] ?? '';
}
2021-05-08 16:31:19 +08:00
public function getDurationTextAttribute(): string
2021-05-06 01:49:05 +08:00
{
2021-05-08 16:31:19 +08:00
if ($this->duration > 0) {
return $this->duration . ' Days';
2021-05-08 16:25:55 +08:00
}
return '';
2021-05-06 01:49:05 +08:00
}
2022-06-27 01:39:01 +08:00
public function getIndexFormattedAttribute(): string
{
$indexes = $this->indexes;
$arr = [];
foreach ($indexes as $index) {
if (isset($index['checked']) && $index['checked']) {
$arr[] = sprintf(
'%s: %s %s',
2022-07-02 15:08:23 +08:00
nexus_trans("exam.index_text_{$index['index']}"),
2022-06-27 01:39:01 +08:00
$index['require_value'],
self::$indexes[$index['index']]['unit'] ?? ''
);
}
}
return implode("<br/>", $arr);
}
public function getFilterFormattedAttribute(): string
{
$currentFilters = $this->filters;
$arr = [];
$filter = self::FILTER_USER_CLASS;
2023-04-29 03:46:14 +08:00
if (!empty($currentFilters[$filter])) {
$classes = collect(User::$classes)->only($currentFilters[$filter]);
2024-06-07 02:51:05 +08:00
$arr[] = sprintf(
'%s: %s',
nexus_trans("exam.filters.$filter"), $classes->map(fn ($value, $key) => User::getClassText($key))->implode(', ')
);
2022-06-27 01:39:01 +08:00
}
$filter = self::FILTER_USER_REGISTER_TIME_RANGE;
2023-04-29 03:46:14 +08:00
if (!empty($currentFilters[$filter])) {
$range = $currentFilters[$filter];
if (!empty($range[0]) || !empty($range[1])) {
$arr[] = sprintf(
"%s: <br/>%s ~ %s",
nexus_trans("exam.filters.$filter"),
$range[0] ? Carbon::parse($range[0])->toDateTimeString() : '--',
$range[1] ? Carbon::parse($range[1])->toDateTimeString() : '--'
);
}
2022-06-27 01:39:01 +08:00
}
$filter = self::FILTER_USER_REGISTER_DAYS_RANGE;
if (!empty($currentFilters[$filter])) {
$range = $currentFilters[$filter];
if (!empty($range[0]) || !empty($range[1])) {
$arr[] = sprintf(
"%s: %s ~ %s",
nexus_trans("exam.filters.$filter"),
$range[0] ?? "--",
$range[1] ?? '--'
);
}
}
2022-06-27 01:39:01 +08:00
$filter = self::FILTER_USER_DONATE;
2023-04-29 03:46:14 +08:00
if (!empty($currentFilters[$filter])) {
$donateStatus = collect(User::$donateStatus)->only($currentFilters[$filter]);
2022-07-02 15:08:23 +08:00
$arr[] = sprintf('%s: %s', nexus_trans("exam.filters.$filter"), $donateStatus->pluck('text')->implode(', '));
2022-06-27 01:39:01 +08:00
}
return implode("<br/>", $arr);
}
2024-04-13 13:55:32 +08:00
public function getBeginForUser(): Carbon
{
2024-04-13 13:55:32 +08:00
if (!empty($this->begin)) {
return Carbon::parse($this->begin);
}
if (!empty($this->recurring)) {
return $this->getRecurringBegin(Carbon::now());
}
return Carbon::now();
}
2024-04-13 13:55:32 +08:00
public function getEndForUser(): Carbon
{
2024-04-13 13:55:32 +08:00
if (!empty($this->end)) {
return Carbon::parse($this->end);
}
if (!empty($this->duration)) {
return $this->getBeginForUser()->clone()->addDays($this->duration);
}
if (!empty($this->recurring)) {
return $this->getRecurringEnd(Carbon::now());
}
throw new \RuntimeException(nexus_trans("exam.time_condition_invalid"));
}
public function getRecurringBegin(Carbon $time): Carbon
{
$recurring = $this->recurring;
if ($recurring == self::RECURRING_WEEKLY) {
return $time->startOfWeek();
} elseif ($recurring == self::RECURRING_MONTHLY) {
return $time->startOfMonth();
} elseif ($recurring == self::RECURRING_DAILY) {
return $time->startOfDay();
2024-04-13 13:55:32 +08:00
}
throw new \RuntimeException("Invalid recurring: $recurring");
}
public function getRecurringEnd(Carbon $time): Carbon
{
$recurring = $this->recurring;
if ($recurring == self::RECURRING_WEEKLY) {
return $time->endOfWeek();
} elseif ($recurring == self::RECURRING_MONTHLY) {
return $time->endOfMonth();
} elseif ($recurring == self::RECURRING_DAILY) {
return $time->endOfDay();
2024-04-13 13:55:32 +08:00
}
throw new \RuntimeException("Invalid recurring: $recurring");
}
2024-05-24 02:27:44 +08:00
public function getMessageSubjectTransKey(string $result): string
{
return match ($this->type) {
self::TYPE_EXAM => "exam.checkout_{$result}_message_subject_for_exam",
self::TYPE_TASK => "exam.checkout_{$result}_message_subject_for_task",
default => throw new \RuntimeException("Invalid type: " . $this->type)
};
}
public function getMessageContentTransKey(string $result): string
{
return match ($this->type) {
self::TYPE_EXAM => "exam.checkout_{$result}_message_content_for_exam",
self::TYPE_TASK => "exam.checkout_{$result}_message_content_for_task",
default => throw new \RuntimeException("Invalid type: " . $this->type)
};
}
2024-06-27 03:29:03 +08:00
public function getPassResultTransKey(string $result): string
{
return match ($this->type) {
self::TYPE_EXAM => "exam.result_{$result}_for_exam",
self::TYPE_TASK => "exam.result_{$result}_for_task",
default => throw new \RuntimeException("Invalid type: " . $this->type)
};
}
2024-05-24 02:27:44 +08:00
public function isTypeExam(): bool
{
return $this->type == self::TYPE_EXAM;
}
public function isTypeTask(): bool
{
return $this->type == self::TYPE_TASK;
}
2021-04-19 20:13:21 +08:00
}