PHP Classes

File: database/migrations/v1.11.0.38_advertising_library.php

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   database/migrations/v1.11.0.38_advertising_library.php   Download  
File: database/migrations/v1.11.0.38_advertising_library.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: 1 month ago
Size: 7,831 bytes
 

Contents

Class file image Download
<?php
/**
 * Migration: 1.11.0.38 - Add advertising library tables and import legacy ANSI ads
 */

function advertisingMigrationSlugify(string $text): string
{
   
$slug = strtolower(trim($text));
   
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
   
$slug = trim((string)$slug, '-');
    if (
$slug === '') {
        return
'ad';
    }

    return
substr($slug, 0, 120);
}

function
advertisingMigrationEnsureUtf8(string $text): string
{
    if (
$text === '') {
        return
'';
    }

    if (
mb_check_encoding($text, 'UTF-8')) {
        return
$text;
    }

   
$converted = @iconv('CP437', 'UTF-8//IGNORE', $text);
    if (
$converted !== false && $converted !== '') {
        return
$converted;
    }

   
$detected = mb_detect_encoding($text, ['UTF-8', 'Windows-1252', 'ISO-8859-1', 'ASCII'], true);
    if (
$detected !== false) {
        return
mb_convert_encoding($text, 'UTF-8', $detected);
    }

    return
mb_convert_encoding($text, 'UTF-8', 'CP437');
}

return function (
$db) {
   
$db->exec("
        CREATE TABLE IF NOT EXISTS advertisements (
            id SERIAL PRIMARY KEY,
            slug VARCHAR(120) NOT NULL UNIQUE,
            title VARCHAR(255) NOT NULL,
            description TEXT DEFAULT '',
            content TEXT NOT NULL,
            content_hash VARCHAR(64) NOT NULL,
            source_type VARCHAR(32) NOT NULL DEFAULT 'upload',
            legacy_filename VARCHAR(255) DEFAULT NULL,
            created_by_user_id INTEGER DEFAULT NULL REFERENCES users(id) ON DELETE SET NULL,
            updated_by_user_id INTEGER DEFAULT NULL REFERENCES users(id) ON DELETE SET NULL,
            is_active BOOLEAN NOT NULL DEFAULT TRUE,
            show_on_dashboard BOOLEAN NOT NULL DEFAULT TRUE,
            allow_auto_post BOOLEAN NOT NULL DEFAULT FALSE,
            dashboard_weight INTEGER NOT NULL DEFAULT 1,
            dashboard_priority INTEGER NOT NULL DEFAULT 0,
            start_at TIMESTAMPTZ DEFAULT NULL,
            end_at TIMESTAMPTZ DEFAULT NULL,
            created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
            updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
        )
    "
);

   
$db->exec("
        CREATE INDEX IF NOT EXISTS idx_advertisements_dashboard
            ON advertisements (is_active, show_on_dashboard, dashboard_priority, updated_at)
    "
);

   
$db->exec("
        CREATE INDEX IF NOT EXISTS idx_advertisements_content_hash
            ON advertisements (content_hash)
    "
);

   
$db->exec("
        CREATE TABLE IF NOT EXISTS advertisement_tags (
            id SERIAL PRIMARY KEY,
            name VARCHAR(80) NOT NULL UNIQUE,
            slug VARCHAR(80) NOT NULL UNIQUE
        )
    "
);

   
$db->exec("
        CREATE TABLE IF NOT EXISTS advertisement_tag_map (
            advertisement_id INTEGER NOT NULL REFERENCES advertisements(id) ON DELETE CASCADE,
            tag_id INTEGER NOT NULL REFERENCES advertisement_tags(id) ON DELETE CASCADE,
            PRIMARY KEY (advertisement_id, tag_id)
        )
    "
);

   
$db->exec("
        CREATE TABLE IF NOT EXISTS advertisement_campaigns (
            id SERIAL PRIMARY KEY,
            name VARCHAR(255) NOT NULL,
            description TEXT DEFAULT '',
            is_active BOOLEAN NOT NULL DEFAULT TRUE,
            from_user_id INTEGER DEFAULT NULL REFERENCES users(id) ON DELETE SET NULL,
            to_name VARCHAR(255) NOT NULL DEFAULT 'All',
            selection_mode VARCHAR(32) NOT NULL DEFAULT 'weighted_random',
            post_interval_minutes INTEGER NOT NULL DEFAULT 10080,
            min_repeat_gap_minutes INTEGER NOT NULL DEFAULT 10080,
            last_posted_at TIMESTAMPTZ DEFAULT NULL,
            last_posted_ad_id INTEGER DEFAULT NULL REFERENCES advertisements(id) ON DELETE SET NULL,
            created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
            updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
        )
    "
);

   
$db->exec("
        CREATE TABLE IF NOT EXISTS advertisement_campaign_targets (
            id SERIAL PRIMARY KEY,
            campaign_id INTEGER NOT NULL REFERENCES advertisement_campaigns(id) ON DELETE CASCADE,
            echoarea_tag VARCHAR(255) NOT NULL,
            domain VARCHAR(100) NOT NULL,
            subject_template VARCHAR(255) NOT NULL DEFAULT 'BBS Advertisement',
            is_active BOOLEAN NOT NULL DEFAULT TRUE
        )
    "
);

   
$db->exec("
        CREATE INDEX IF NOT EXISTS idx_ad_campaign_targets_campaign
            ON advertisement_campaign_targets (campaign_id, is_active)
    "
);

   
$db->exec("
        CREATE TABLE IF NOT EXISTS advertisement_campaign_ads (
            campaign_id INTEGER NOT NULL REFERENCES advertisement_campaigns(id) ON DELETE CASCADE,
            advertisement_id INTEGER NOT NULL REFERENCES advertisements(id) ON DELETE CASCADE,
            weight INTEGER NOT NULL DEFAULT 1,
            PRIMARY KEY (campaign_id, advertisement_id)
        )
    "
);

   
$db->exec("
        CREATE TABLE IF NOT EXISTS advertisement_post_log (
            id SERIAL PRIMARY KEY,
            advertisement_id INTEGER DEFAULT NULL REFERENCES advertisements(id) ON DELETE SET NULL,
            campaign_id INTEGER DEFAULT NULL REFERENCES advertisement_campaigns(id) ON DELETE SET NULL,
            message_id INTEGER DEFAULT NULL,
            echoarea_tag VARCHAR(255) NOT NULL,
            domain VARCHAR(100) NOT NULL,
            subject VARCHAR(255) NOT NULL,
            posted_by_user_id INTEGER DEFAULT NULL REFERENCES users(id) ON DELETE SET NULL,
            post_mode VARCHAR(32) NOT NULL DEFAULT 'manual',
            posted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
            status VARCHAR(32) NOT NULL DEFAULT 'success',
            error_text TEXT DEFAULT NULL
        )
    "
);

   
$db->exec("
        CREATE INDEX IF NOT EXISTS idx_ad_post_log_advertisement
            ON advertisement_post_log (advertisement_id, posted_at DESC)
    "
);

   
$adsDir = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'bbs_ads';
    if (!
is_dir($adsDir)) {
        return
true;
    }

   
$selectByLegacy = $db->prepare("SELECT id FROM advertisements WHERE legacy_filename = ?");
   
$selectBySlug = $db->prepare("SELECT id FROM advertisements WHERE slug = ?");
   
$insertAd = $db->prepare("
        INSERT INTO advertisements (
            slug,
            title,
            description,
            content,
            content_hash,
            source_type,
            legacy_filename,
            is_active,
            show_on_dashboard,
            allow_auto_post,
            dashboard_weight,
            dashboard_priority
        ) VALUES (?, ?, '', ?, ?, 'legacy_import', ?, TRUE, TRUE, TRUE, 1, 0)
    "
);

    foreach (
glob($adsDir . DIRECTORY_SEPARATOR . '*.ans') ?: [] as $path) {
       
$legacyFilename = basename($path);

       
$selectByLegacy->execute([$legacyFilename]);
        if (
$selectByLegacy->fetch(\PDO::FETCH_ASSOC)) {
            continue;
        }

       
$rawContent = @file_get_contents($path);
        if (
$rawContent === false) {
            continue;
        }

       
$content = advertisingMigrationEnsureUtf8($rawContent);
       
$contentHash = hash('sha256', $content);
       
$title = pathinfo($legacyFilename, PATHINFO_FILENAME);
       
$baseSlug = advertisingMigrationSlugify($title !== '' ? $title : $legacyFilename);
       
$slug = $baseSlug;
       
$suffix = 2;

        while (
true) {
           
$selectBySlug->execute([$slug]);
            if (!
$selectBySlug->fetch(\PDO::FETCH_ASSOC)) {
                break;
            }
           
$slug = substr($baseSlug, 0, 110) . '-' . $suffix;
           
$suffix++;
        }

       
$insertAd->execute([
           
$slug,
           
$title !== '' ? $title : $legacyFilename,
           
$content,
           
$contentHash,
           
$legacyFilename
       
]);
    }

    return
true;
};