|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace App; |
| 4 | + |
| 5 | +use App\Http\Controllers\SecretariatController; |
| 6 | +use Carbon\Carbon; |
| 7 | +use Illuminate\Database\Eloquent\Model; |
| 8 | +use Illuminate\Support\Facades\Log; |
| 9 | + |
| 10 | +/** |
| 11 | + * This class implements the logic of triggering certain (recurring) events (eg. automatic status changes) |
| 12 | + * when we reach a given datetime. The triggers will fire a signal that we handle accordingly. |
| 13 | + * Members of this models should not get created through the site. It is stored in the database |
| 14 | + * so the dates can be changed on the run, everything else should be static. |
| 15 | + * The handlers of each signal will do one or two things: |
| 16 | + * - Runs the function/does the changes relvant to the event. |
| 17 | + * - (only recurring events) Updates the trigger date. |
| 18 | + */ |
| 19 | +class EventTrigger extends Model |
| 20 | +{ |
| 21 | + public $timestamps = false; |
| 22 | + public $incrementing = false; |
| 23 | + protected $primaryKey = 'signal'; |
| 24 | + protected $fillable = [ |
| 25 | + 'name', 'data', 'date', 'signal', 'comment', |
| 26 | + ]; |
| 27 | + |
| 28 | + protected $casts = [ |
| 29 | + 'date' => 'datetime', |
| 30 | + ]; |
| 31 | + |
| 32 | + // Signal for setting the default activation date to the next semester. |
| 33 | + const INTERNET_ACTIVATION_SIGNAL = 0; |
| 34 | + // Signal for notifying the students to make a statement regarding their status |
| 35 | + // in the next semester. |
| 36 | + const SEND_STATUS_STATEMENT_REQUEST = 1; |
| 37 | + // Deadline for the above signal; when triggered, everyone who did not make a |
| 38 | + // statement will be set to inactive. |
| 39 | + const DEACTIVATE_STATUS_SIGNAL = 2; |
| 40 | + const SIGNALS = [ |
| 41 | + self::INTERNET_ACTIVATION_SIGNAL, |
| 42 | + self::SEND_STATUS_STATEMENT_REQUEST, |
| 43 | + self::DEACTIVATE_STATUS_SIGNAL, |
| 44 | + ]; |
| 45 | + |
| 46 | + public static function listen() |
| 47 | + { |
| 48 | + $now = Carbon::now(); |
| 49 | + $events = EventTrigger::where('date', '<=', $now) |
| 50 | + ->where('date', '>', $now->subHours(1)); |
| 51 | + foreach ($events as $event) { |
| 52 | + $event->handleSignal(); |
| 53 | + } |
| 54 | + |
| 55 | + return $events; |
| 56 | + } |
| 57 | + |
| 58 | + /* Getters */ |
| 59 | + |
| 60 | + public static function internetActivationDeadline() |
| 61 | + { |
| 62 | + return self::find(self::INTERNET_ACTIVATION_SIGNAL)->data; |
| 63 | + } |
| 64 | + |
| 65 | + public static function statementRequestDate() |
| 66 | + { |
| 67 | + return self::find(self::SEND_STATUS_STATEMENT_REQUEST)->date; |
| 68 | + } |
| 69 | + |
| 70 | + public static function statementDeadline() |
| 71 | + { |
| 72 | + return self::find(self::DEACTIVATE_STATUS_SIGNAL)->date; |
| 73 | + } |
| 74 | + |
| 75 | + /* Handlers which are fired when the set date is reached. */ |
| 76 | + |
| 77 | + public function handleSignal() |
| 78 | + { |
| 79 | + switch ($this->signal) { |
| 80 | + case self::INTERNET_ACTIVATION_SIGNAL: |
| 81 | + $this->handleInternetActivationSignal(); |
| 82 | + break; |
| 83 | + case self::SEND_STATUS_STATEMENT_REQUEST: |
| 84 | + $this->handleSendStatusStatementRequest(); |
| 85 | + break; |
| 86 | + case self::DEACTIVATE_STATUS_SIGNAL: |
| 87 | + $this->deactivateStatus(); |
| 88 | + break; |
| 89 | + default: |
| 90 | + Log::warning('Event Trigger got undefined signal: '.$this->signal); |
| 91 | + break; |
| 92 | + } |
| 93 | + |
| 94 | + return $this; |
| 95 | + } |
| 96 | + |
| 97 | + private function handleInternetActivationSignal() |
| 98 | + { |
| 99 | + $months_to_add = Semester::current()->isSpring() ? 7 : 5; |
| 100 | + $current_date = Carbon::instance($this->date); |
| 101 | + $current_data = Carbon::parse($this->data); |
| 102 | + $this->update([ |
| 103 | + // Update the new trigger date |
| 104 | + 'date' => $current_date->addMonth($months_to_add), |
| 105 | + // Update the new activation deadline |
| 106 | + 'data' => $current_data->addMonth($months_to_add), |
| 107 | + ]); |
| 108 | + } |
| 109 | + |
| 110 | + private function handleSendStatusStatementRequest() |
| 111 | + { |
| 112 | + $months_to_add = Semester::current()->isSpring() ? 7 : 5; |
| 113 | + $current_date = Carbon::instance($this->date); |
| 114 | + |
| 115 | + // Triggering the event |
| 116 | + SecretariatController::sendStatementMail(); |
| 117 | + |
| 118 | + $this->update([ |
| 119 | + // Update the new trigger date |
| 120 | + 'date' => $current_date->addMonth($months_to_add), |
| 121 | + ]); |
| 122 | + } |
| 123 | + |
| 124 | + private function deactivateStatus() |
| 125 | + { |
| 126 | + $months_to_add = Semester::current()->isSpring() ? 7 : 5; |
| 127 | + $current_date = Carbon::instance($this->date); |
| 128 | + |
| 129 | + // Triggering the event |
| 130 | + SecretariatController::finalizeStatements(); |
| 131 | + |
| 132 | + $this->update([ |
| 133 | + // Update the new trigger date |
| 134 | + 'date' => $current_date->addMonth($months_to_add), |
| 135 | + ]); |
| 136 | + } |
| 137 | +} |
0 commit comments