reconstruction of the project
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
<?php namespace App\Models;
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Models\BaseModel;
|
||||
|
||||
class WhatsappGroupLink extends BaseModel
|
||||
{
|
||||
protected $table = 'whatsapp_group_links';
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'class_section_id',
|
||||
'class_section_name',
|
||||
@@ -16,7 +19,69 @@ class WhatsappGroupLink extends BaseModel
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
public $timestamps = true; // requires created_at / updated_at columns
|
||||
|
||||
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 (CI-compatible behavior)
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the link for a specific section in a specific term.
|
||||
@@ -27,113 +92,105 @@ class WhatsappGroupLink extends BaseModel
|
||||
* @param bool $onlyActive If true, require active=1.
|
||||
* @param bool $allowNullSemester If true, accept rows with semester IS NULL as well.
|
||||
*/
|
||||
public function getLinkForSection(
|
||||
public static function getLinkForSection(
|
||||
int $sectionId,
|
||||
string $year,
|
||||
string $sem,
|
||||
bool $onlyActive = true,
|
||||
bool $allowNullSemester = false
|
||||
): ?array {
|
||||
$year = trim($year);
|
||||
$sem = trim($sem);
|
||||
|
||||
$b = $this->asArray()
|
||||
->where('class_section_id', $sectionId)
|
||||
->where('school_year', $year);
|
||||
|
||||
if ($allowNullSemester) {
|
||||
$b = $b->groupStart()
|
||||
->where('semester', $sem)
|
||||
->orWhere('semester IS NULL', null, false)
|
||||
->groupEnd();
|
||||
} else {
|
||||
$b = $b->where('semester', $sem);
|
||||
}
|
||||
): ?self {
|
||||
$q = static::query()
|
||||
->forSection($sectionId)
|
||||
->forYear($year)
|
||||
->forSemester($sem, $allowNullSemester)
|
||||
->hasInviteLink();
|
||||
|
||||
if ($onlyActive) {
|
||||
$b = $b->where('active', 1);
|
||||
$q->active();
|
||||
}
|
||||
|
||||
// If you also want to ignore blank links:
|
||||
$b = $b->where('invite_link IS NOT NULL', null, false)
|
||||
->where('invite_link !=', '');
|
||||
|
||||
return $b->first() ?: null;
|
||||
return $q->orderByDesc('updated_at')
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all links for a term.
|
||||
*
|
||||
* @param string $year
|
||||
* @param string $sem
|
||||
* @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.
|
||||
* @param bool $allowNullSemester If true, include rows with semester IS NULL.
|
||||
*
|
||||
* @return array<WhatsappGroupLink>
|
||||
*/
|
||||
public function getAllForTerm(
|
||||
public static function getAllForTerm(
|
||||
string $year,
|
||||
string $sem,
|
||||
?bool $onlyActive = null,
|
||||
bool $allowNullSemester = false
|
||||
): array {
|
||||
$year = trim($year);
|
||||
$sem = trim($sem);
|
||||
|
||||
$b = $this->asArray()
|
||||
->where('school_year', $year);
|
||||
|
||||
if ($allowNullSemester) {
|
||||
$b = $b->groupStart()
|
||||
->where('semester', $sem)
|
||||
->orWhere('semester IS NULL', null, false)
|
||||
->groupEnd();
|
||||
} else {
|
||||
$b = $b->where('semester', $sem);
|
||||
}
|
||||
$q = static::query()
|
||||
->forYear($year)
|
||||
->forSemester($sem, $allowNullSemester);
|
||||
|
||||
if ($onlyActive === true) {
|
||||
$b = $b->where('active', 1);
|
||||
$q->active();
|
||||
} elseif ($onlyActive === false) {
|
||||
$b = $b->where('active', 0);
|
||||
$q->inactive();
|
||||
}
|
||||
|
||||
return $b->orderBy('class_section_name', 'ASC')->findAll();
|
||||
return $q->orderByDesc('updated_at')
|
||||
->orderByDesc('id')
|
||||
->get()
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: upsert a link row for a section/term.
|
||||
* Returns the row (array) after save.
|
||||
* Returns the model after save.
|
||||
*/
|
||||
public function upsertLinkForSection(
|
||||
public static function upsertLinkForSection(
|
||||
int $sectionId,
|
||||
string $sectionName,
|
||||
string $year,
|
||||
string $sem,
|
||||
string $inviteLink,
|
||||
bool $active = true
|
||||
): array {
|
||||
): self {
|
||||
$payload = [
|
||||
'class_section_id' => $sectionId,
|
||||
'class_section_name' => $sectionName,
|
||||
'school_year' => trim($year),
|
||||
'semester' => trim($sem),
|
||||
'invite_link' => trim($inviteLink),
|
||||
'active' => $active ? 1 : 0,
|
||||
];
|
||||
|
||||
// Try to find existing row (exact term)
|
||||
$existing = $this->asArray()
|
||||
->where('class_section_id', $sectionId)
|
||||
->where('school_year', $payload['school_year'])
|
||||
->where('semester', $payload['semester'])
|
||||
->first();
|
||||
|
||||
if ($existing) {
|
||||
$this->update((int)$existing['id'], $payload);
|
||||
$id = (int) $existing['id'];
|
||||
} else {
|
||||
$id = $this->insert($payload, true);
|
||||
}
|
||||
|
||||
return $this->find($id) ?? $payload;
|
||||
// NOTE: semester is part of the uniqueness key like your CI 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'],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user