Files
alrahma_sunday_school_api/app/Models/WhatsappGroupLink.php
T
2026-06-04 02:41:08 -04:00

193 lines
5.5 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;
class WhatsappGroupLink extends BaseModel
{
protected $table = 'whatsapp_group_links';
protected $fillable = [
'class_section_id',
'class_section_name',
'school_year',
'semester',
'invite_link',
'active',
];
public $timestamps = true; // requires created_at/updated_at
protected $casts = [
'class_section_id' => 'integer',
'active' => 'boolean',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/* ============================================================
* Scopes
* ============================================================
*/
public function scopeForSection(Builder $q, int $sectionId): Builder
{
return $q->where('class_section_id', $sectionId);
}
public function scopeForYear(Builder $q, string $year): Builder
{
return $q->where('school_year', trim($year));
}
public function scopeForSemester(Builder $q, string $semester, bool $allowNullSemester = false): Builder
{
$sem = trim($semester);
if ($sem === '') {
return $q;
}
if ($allowNullSemester) {
return $q->where(function (Builder $w) use ($sem) {
$w->where('semester', $sem)
->orWhereNull('semester');
});
}
return $q->where('semester', $sem);
}
public function scopeActive(Builder $q): Builder
{
return $q->where('active', 1);
}
public function scopeInactive(Builder $q): Builder
{
return $q->where('active', 0);
}
public function scopeHasInviteLink(Builder $q): Builder
{
return $q->whereNotNull('invite_link')
->where('invite_link', '!=', '');
}
/* ============================================================
* Methods (legacy-compatible behavior)
* ============================================================
*/
/**
* Get the link for a specific section in a specific term.
*
* @param int $sectionId Class/section code (not PK).
* @param string $year School year, e.g. "2025-2026".
* @param string $sem Semester, e.g. "Fall".
* @param bool $onlyActive If true, require active=1.
* @param bool $allowNullSemester If true, accept rows with semester IS NULL as well.
*/
public static function getLinkForSection(
int $sectionId,
string $year,
string $sem,
bool $onlyActive = true,
bool $allowNullSemester = false
): ?self {
$q = static::query()
->forSection($sectionId)
->forYear($year)
->forSemester($sem, $allowNullSemester)
->hasInviteLink();
if ($onlyActive) {
$q->active();
}
return $q->orderByDesc('updated_at')
->orderByDesc('id')
->first();
}
/**
* Get all links for a term.
*
* @param string $year
* @param string $sem
* @param bool|null $onlyActive true: active only, false: inactive only, null: both
* @param bool $allowNullSemester If true, include rows with semester IS NULL.
*
* @return array<WhatsappGroupLink>
*/
public static function getAllForTerm(
string $year,
string $sem,
?bool $onlyActive = null,
bool $allowNullSemester = false
): array {
$q = static::query()
->forYear($year)
->forSemester($sem, $allowNullSemester);
if ($onlyActive === true) {
$q->active();
} elseif ($onlyActive === false) {
$q->inactive();
}
return $q->orderByDesc('updated_at')
->orderByDesc('id')
->get()
->all();
}
/**
* Convenience: upsert a link row for a section/term.
* Returns the model after save.
*/
public static function upsertLinkForSection(
int $sectionId,
string $sectionName,
string $year,
string $sem,
string $inviteLink,
bool $active = true
): self {
$payload = [
'class_section_name' => $sectionName,
'invite_link' => trim($inviteLink),
'active' => $active ? 1 : 0,
];
// NOTE: semester is part of the uniqueness key like your legacy version.
return static::query()->updateOrCreate(
[
'class_section_id' => $sectionId,
'school_year' => trim($year),
'semester' => trim($sem),
],
$payload
);
}
/* ============================================================
* Optional validation helper
* ============================================================
*/
public static function rules(bool $updating = false): array
{
$req = $updating ? 'sometimes' : 'required';
return [
'class_section_id' => [$req, 'integer', 'min:1'],
'class_section_name' => [$req, 'string', 'max:255'],
'school_year' => [$req, 'string', 'max:20'],
'semester' => ['nullable', 'string', 'max:20'],
'invite_link' => [$req, 'string', 'max:2000'],
'active' => ['nullable', 'boolean'],
];
}
}