PHP Classes

File: database/migrations/v1.11.0.44_qwk_user_conference_map.php

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   database/migrations/v1.11.0.44_qwk_user_conference_map.php   Download  
File: database/migrations/v1.11.0.44_qwk_user_conference_map.php
Role: Example script
Content type: text/plain
Description: Example script
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 5,114 bytes
 

Contents

Class file image Download
<?php
/**
 * Migration: v1.11.0.44_qwk_user_conference_map
 *
 * Adds a persistent per-user QWK conference number map so conference
 * numbering remains stable across downloads. Existing users are backfilled
 * from their latest saved QWK download map where possible, then any remaining
 * active subscriptions are assigned the next available number in the current
 * subscription order.
 */

return function($db) {
   
$db->exec("
        CREATE TABLE IF NOT EXISTS qwk_user_conference_map (
            user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
            echoarea_id INTEGER NOT NULL REFERENCES echoareas(id) ON DELETE CASCADE,
            conference_number INTEGER NOT NULL CHECK (conference_number > 0),
            created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
            updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
            PRIMARY KEY (user_id, echoarea_id),
            UNIQUE (user_id, conference_number)
        )
    "
);

   
$db->exec("
        CREATE INDEX IF NOT EXISTS idx_qwk_user_conference_map_user
            ON qwk_user_conference_map (user_id, conference_number)
    "
);

   
$users = $db->query("SELECT id FROM users ORDER BY id")->fetchAll(PDO::FETCH_COLUMN);

   
$latestLogStmt = $db->prepare("
        SELECT conference_map
        FROM qwk_download_log
        WHERE user_id = ?
        ORDER BY downloaded_at DESC
        LIMIT 1
    "
);

   
$areaLookupStmt = $db->prepare("
        SELECT id
        FROM echoareas
        WHERE LOWER(tag) = LOWER(?) AND LOWER(COALESCE(domain, '')) = LOWER(COALESCE(?, ''))
        LIMIT 1
    "
);

   
$activeSubsStmt = $db->prepare("
        SELECT e.id
        FROM echoareas e
        JOIN user_echoarea_subscriptions s ON e.id = s.echoarea_id
        WHERE s.user_id = ? AND s.is_active = TRUE AND e.is_active = TRUE
          AND (COALESCE(e.is_sysop_only, FALSE) = FALSE OR EXISTS (
                SELECT 1 FROM users u WHERE u.id = ? AND u.is_admin = TRUE
              ))
        ORDER BY
            CASE
                WHEN COALESCE(e.is_local, FALSE) = TRUE THEN 0
                WHEN LOWER(e.domain) = 'lovlynet' THEN 1
                ELSE 2
            END,
            e.tag
    "
);

   
$existingStmt = $db->prepare("
        SELECT echoarea_id, conference_number
        FROM qwk_user_conference_map
        WHERE user_id = ?
    "
);

   
$insertStmt = $db->prepare("
        INSERT INTO qwk_user_conference_map (user_id, echoarea_id, conference_number, created_at, updated_at)
        VALUES (?, ?, ?, NOW(), NOW())
        ON CONFLICT (user_id, echoarea_id)
        DO UPDATE SET updated_at = NOW()
    "
);

    foreach (
$users as $userId) {
       
$usedNumbers = [];
       
$seenAreas = [];

       
$latestLogStmt->execute([$userId]);
       
$conferenceMapJson = $latestLogStmt->fetchColumn();
        if (
$conferenceMapJson) {
           
$conferenceMap = json_decode($conferenceMapJson, true);
            if (
is_array($conferenceMap)) {
               
ksort($conferenceMap, SORT_NUMERIC);
                foreach (
$conferenceMap as $number => $conf) {
                   
$conferenceNumber = (int)$number;
                    if (
$conferenceNumber <= 0 || !empty($conf['is_netmail'])) {
                        continue;
                    }

                   
$tag = trim((string)($conf['tag'] ?? ''));
                    if (
$tag === '') {
                        continue;
                    }

                   
$domain = (string)($conf['domain'] ?? '');
                   
$areaLookupStmt->execute([$tag, $domain]);
                   
$echoareaId = $areaLookupStmt->fetchColumn();
                    if (!
$echoareaId) {
                        continue;
                    }

                   
$echoareaId = (int)$echoareaId;
                    if (isset(
$usedNumbers[$conferenceNumber]) || isset($seenAreas[$echoareaId])) {
                        continue;
                    }

                   
$insertStmt->execute([$userId, $echoareaId, $conferenceNumber]);
                   
$usedNumbers[$conferenceNumber] = true;
                   
$seenAreas[$echoareaId] = true;
                }
            }
        }

       
$existingStmt->execute([$userId]);
        foreach (
$existingStmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
           
$usedNumbers[(int)$row['conference_number']] = true;
           
$seenAreas[(int)$row['echoarea_id']] = true;
        }

       
$activeSubsStmt->execute([$userId, $userId]);
       
$activeEchoareaIds = array_map('intval', $activeSubsStmt->fetchAll(PDO::FETCH_COLUMN));
        foreach (
$activeEchoareaIds as $echoareaId) {
            if (isset(
$seenAreas[$echoareaId])) {
                continue;
            }

           
$conferenceNumber = 1;
            while (isset(
$usedNumbers[$conferenceNumber])) {
               
$conferenceNumber++;
            }

           
$insertStmt->execute([$userId, $echoareaId, $conferenceNumber]);
           
$usedNumbers[$conferenceNumber] = true;
           
$seenAreas[$echoareaId] = true;
        }
    }

    return
true;
};