Files
alrahma_sunday_school/app/Database/Migrations/2026-07-30-000200_CreateParentPolicyAcceptances.php
2026-08-15 15:07:16 -04:00

177 lines
5.3 KiB
PHP

<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateParentPolicyAcceptances extends Migration
{
public function up(): void
{
if ($this->db->tableExists('parent_policy_acceptances')) {
return;
}
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
'auto_increment' => true,
],
'parent_id' => [
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
'null' => false,
],
'school_year' => [
'type' => 'VARCHAR',
'constraint' => 9,
'null' => false,
],
'accepted_at' => [
'type' => 'DATETIME',
'null' => false,
],
'source' => [
'type' => 'VARCHAR',
'constraint' => 40,
'null' => false,
'default' => 'registration',
],
'ip_address' => [
'type' => 'VARCHAR',
'constraint' => 45,
'null' => true,
],
'user_agent' => [
'type' => 'VARCHAR',
'constraint' => 255,
'null' => true,
],
'created_at' => [
'type' => 'DATETIME',
'null' => true,
],
'updated_at' => [
'type' => 'DATETIME',
'null' => true,
],
]);
$this->forge->addKey('id', true);
$this->forge->addUniqueKey(['parent_id', 'school_year'], 'uq_parent_policy_year');
$this->forge->addKey('school_year');
$this->forge->createTable('parent_policy_acceptances', true);
$this->backfillExistingAcceptances();
}
public function down(): void
{
$this->forge->dropTable('parent_policy_acceptances', true);
}
private function backfillExistingAcceptances(): void
{
if (! $this->db->tableExists('users')) {
return;
}
$schoolYear = $this->configuredSchoolYear();
if ($schoolYear === null) {
return;
}
$builder = $this->db->table('users u')
->select('u.id')
->where('u.accept_school_policy', 1);
$hasUserType = $this->db->fieldExists('user_type', 'users');
$hasRoleTables = $this->db->tableExists('user_roles') && $this->db->tableExists('roles');
if ($hasUserType && $hasRoleTables) {
$builder->groupStart()
->where('u.user_type', 'primary')
->orWhere(
'EXISTS (SELECT 1 FROM user_roles ur INNER JOIN roles r ON r.id = ur.role_id WHERE ur.user_id = u.id AND LOWER(r.name) = ' . $this->db->escape('parent') . ')',
null,
false
)
->groupEnd();
} elseif ($hasUserType) {
$builder->where('u.user_type', 'primary');
} elseif ($hasRoleTables) {
$builder->where(
'EXISTS (SELECT 1 FROM user_roles ur INNER JOIN roles r ON r.id = ur.role_id WHERE ur.user_id = u.id AND LOWER(r.name) = ' . $this->db->escape('parent') . ')',
null,
false
);
} else {
return;
}
$rows = $builder->get()
->getResultArray();
foreach ($rows as $row) {
$parentId = (int) ($row['id'] ?? 0);
if ($parentId <= 0) {
continue;
}
$existing = $this->db->table('parent_policy_acceptances')
->where('parent_id', $parentId)
->where('school_year', $schoolYear)
->get(1)
->getRowArray();
if ($existing !== null) {
continue;
}
$this->db->table('parent_policy_acceptances')->insert([
'parent_id' => $parentId,
'school_year' => $schoolYear,
'accepted_at' => date('Y-m-d H:i:s'),
'source' => 'legacy_backfill',
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
]);
}
}
private function configuredSchoolYear(): ?string
{
if ($this->db->tableExists('school_years')) {
$row = $this->db->table('school_years')
->select('name')
->where('status', 'active')
->orderBy('id', 'DESC')
->get(1)
->getRowArray();
$name = trim((string) ($row['name'] ?? ''));
if (preg_match('/^\d{4}-\d{4}$/', $name)) {
return $name;
}
}
if (! $this->db->tableExists('configuration')) {
return null;
}
$row = $this->db->table('configuration')
->select('config_value')
->where('config_key', 'school_year')
->orderBy('id', 'DESC')
->get(1)
->getRowArray();
$name = trim((string) ($row['config_value'] ?? ''));
return preg_match('/^\d{4}-\d{4}$/', $name) ? $name : null;
}
}