Sindbad~EG File Manager

Current Path : /home/copmadinaarea/.trash/
Upload File :
Current File : /home/copmadinaarea/.trash/migrate_proofreading.php

<?php
require_once 'config/config.php';

// Check if user is superuser
session_start();
if (!isset($_SESSION['user_id']) || $_SESSION['account_type'] !== 'superuser') {
    die('Access denied. Superuser privileges required.');
}

$database = new Database();
$conn = $database->getConnection();

$migration_log = [];
$errors = [];

function log_migration($message, $success = true) {
    global $migration_log;
    $migration_log[] = [
        'message' => $message,
        'success' => $success,
        'timestamp' => date('Y-m-d H:i:s')
    ];
    echo ($success ? '[SUCCESS] ' : '[ERROR] ') . $message . "\n";
}

function execute_query($conn, $query, $description) {
    global $errors;
    try {
        $result = $conn->exec($query);
        log_migration($description);
        return true;
    } catch (PDOException $e) {
        $error_msg = "$description - Error: " . $e->getMessage();
        log_migration($error_msg, false);
        $errors[] = $error_msg;
        return false;
    }
}

echo "Starting Proofreading System Migration...\n";
echo "==========================================\n\n";

// 1. Add 'editor' to users account_type enum
$query1 = "ALTER TABLE users MODIFY COLUMN account_type ENUM('user', 'admin', 'superuser', 'editor') NOT NULL DEFAULT 'user'";
execute_query($conn, $query1, "Added 'editor' to users account_type enum");

// 2. Add editorial permission fields to users table
$query2 = "ALTER TABLE users 
           ADD COLUMN can_edit_others BOOLEAN DEFAULT FALSE AFTER account_type,
           ADD COLUMN editorial_scope ENUM('assembly', 'district', 'area') NULL AFTER can_edit_others";
execute_query($conn, $query2, "Added editorial permission fields to users table");

// 3. Extend news status enum
$query3 = "ALTER TABLE news MODIFY COLUMN status ENUM('draft', 'published', 'archived', 'pending_review', 'approved', 'rejected') NOT NULL DEFAULT 'draft'";
execute_query($conn, $query3, "Extended news status enum with proofreading statuses");

// 4. Add editorial fields to news table
$query4 = "ALTER TABLE news 
           ADD COLUMN assigned_editor_id INT NULL AFTER user_id,
           ADD COLUMN submitted_for_review_at TIMESTAMP NULL AFTER created_at,
           ADD COLUMN reviewed_at TIMESTAMP NULL AFTER submitted_for_review_at,
           ADD COLUMN approved_at TIMESTAMP NULL AFTER reviewed_at,
           ADD COLUMN published_at TIMESTAMP NULL AFTER approved_at,
           ADD COLUMN review_comments TEXT NULL AFTER published_at,
           ADD COLUMN internal_notes TEXT NULL AFTER review_comments,
           ADD INDEX idx_assigned_editor (assigned_editor_id),
           ADD INDEX idx_status_location (status, location_id),
           ADD INDEX idx_submitted_review (submitted_for_review_at),
           ADD FOREIGN KEY (assigned_editor_id) REFERENCES users(id) ON DELETE SET NULL";
execute_query($conn, $query4, "Added editorial fields and indexes to news table");

// 5. Create news_reviews table
$query5 = "CREATE TABLE news_reviews (
    id INT AUTO_INCREMENT PRIMARY KEY,
    news_id INT NOT NULL,
    reviewer_id INT NOT NULL,
    action ENUM('approve', 'reject', 'request_changes') NOT NULL,
    comments TEXT NULL,
    internal_notes TEXT NULL,
    reviewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_news_id (news_id),
    INDEX idx_reviewer_id (reviewer_id),
    INDEX idx_reviewed_at (reviewed_at),
    FOREIGN KEY (news_id) REFERENCES news(id) ON DELETE CASCADE,
    FOREIGN KEY (reviewer_id) REFERENCES users(id) ON DELETE CASCADE
)";
execute_query($conn, $query5, "Created news_reviews table");

// 6. Create editor_assignments table
$query6 = "CREATE TABLE editor_assignments (
    id INT AUTO_INCREMENT PRIMARY KEY,
    editor_id INT NOT NULL,
    location_id INT NOT NULL,
    assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_active BOOLEAN DEFAULT TRUE,
    created_by INT NOT NULL,
    UNIQUE KEY unique_editor_location (editor_id, location_id),
    INDEX idx_editor_id (editor_id),
    INDEX idx_location_id (location_id),
    INDEX idx_active (is_active),
    FOREIGN KEY (editor_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (location_id) REFERENCES locations(id) ON DELETE CASCADE,
    FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE CASCADE
)";
execute_query($conn, $query6, "Created editor_assignments table");

// 7. Create review_notifications table
$query7 = "CREATE TABLE review_notifications (
    id INT AUTO_INCREMENT PRIMARY KEY,
    news_id INT NOT NULL,
    recipient_id INT NOT NULL,
    notification_type ENUM('submitted', 'approved', 'rejected', 'published') NOT NULL,
    message TEXT NOT NULL,
    is_read BOOLEAN DEFAULT FALSE,
    sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    read_at TIMESTAMP NULL,
    INDEX idx_recipient_id (recipient_id),
    INDEX idx_news_id (news_id),
    INDEX idx_type (notification_type),
    INDEX idx_unread (is_read, recipient_id),
    FOREIGN KEY (news_id) REFERENCES news(id) ON DELETE CASCADE,
    FOREIGN KEY (recipient_id) REFERENCES users(id) ON DELETE CASCADE
)";
execute_query($conn, $query7, "Created review_notifications table");

// 8. Insert sample editor users
$sample_editors = [
    [
        'username' => 'editor_accra',
        'email' => 'editor.accra@copnews.org',
        'password' => password_hash('editor123', PASSWORD_DEFAULT),
        'user_name' => 'Accra District Editor',
        'location_id' => 5, // Accra Central District
        'account_type' => 'editor',
        'can_edit_others' => 1,
        'editorial_scope' => 'district'
    ],
    [
        'username' => 'editor_tema',
        'email' => 'editor.tema@copnews.org',
        'password' => password_hash('editor123', PASSWORD_DEFAULT),
        'user_name' => 'Tema District Editor',
        'location_id' => 4, // Tema District
        'account_type' => 'editor',
        'can_edit_others' => 1,
        'editorial_scope' => 'district'
    ],
    [
        'username' => 'editor_area_accra',
        'email' => 'area.editor.accra@copnews.org',
        'password' => password_hash('editor123', PASSWORD_DEFAULT),
        'user_name' => 'Greater Accra Area Editor',
        'location_id' => 1, // Greater Accra Area
        'account_type' => 'editor',
        'can_edit_others' => 1,
        'editorial_scope' => 'area'
    ]
];

foreach ($sample_editors as $editor) {
    $query = "INSERT INTO users (username, email, password, user_name, location_id, account_type, can_edit_others, editorial_scope, created_at) 
              VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())";
    
    try {
        $stmt = $conn->prepare($query);
        $stmt->execute([
            $editor['username'],
            $editor['email'],
            $editor['password'],
            $editor['user_name'],
            $editor['location_id'],
            $editor['account_type'],
            $editor['can_edit_others'],
            $editor['editorial_scope']
        ]);
        log_migration("Created sample editor: " . $editor['user_name']);
    } catch (PDOException $e) {
        if ($e->getCode() == 23000) { // Duplicate entry
            log_migration("Sample editor already exists: " . $editor['user_name']);
        } else {
            log_migration("Failed to create sample editor " . $editor['user_name'] . ": " . $e->getMessage(), false);
        }
    }
}

// 9. Create editor assignments for sample editors
$assignments = [
    ['editor_username' => 'editor_accra', 'location_id' => 5], // Accra Central District
    ['editor_username' => 'editor_accra', 'location_id' => 8], // Osu Assembly
    ['editor_username' => 'editor_tema', 'location_id' => 4], // Tema District
    ['editor_username' => 'editor_tema', 'location_id' => 7], // Community 1/9 Assembly
    ['editor_username' => 'editor_area_accra', 'location_id' => 1], // Greater Accra Area
];

foreach ($assignments as $assignment) {
    $query = "INSERT INTO editor_assignments (editor_id, location_id, created_by) 
              SELECT u.id, ?, 1 FROM users u WHERE u.username = ? AND NOT EXISTS (
                  SELECT 1 FROM editor_assignments ea WHERE ea.editor_id = u.id AND ea.location_id = ?
              )";
    
    try {
        $stmt = $conn->prepare($query);
        $stmt->execute([
            $assignment['location_id'],
            $assignment['editor_username'],
            $assignment['location_id']
        ]);
        
        if ($stmt->rowCount() > 0) {
            log_migration("Created editor assignment: " . $assignment['editor_username'] . " -> Location ID " . $assignment['location_id']);
        } else {
            log_migration("Editor assignment already exists: " . $assignment['editor_username'] . " -> Location ID " . $assignment['location_id']);
        }
    } catch (PDOException $e) {
        log_migration("Failed to create editor assignment: " . $e->getMessage(), false);
    }
}

// 10. Add system settings for editorial workflow
$settings = [
    ['setting_key' => 'editorial_auto_assign', 'setting_value' => '1', 'description' => 'Automatically assign editors based on location hierarchy'],
    ['setting_key' => 'editorial_email_notifications', 'setting_value' => '1', 'description' => 'Send email notifications for editorial actions'],
    ['setting_key' => 'editorial_review_timeout_days', 'setting_value' => '7', 'description' => 'Days before review timeout notification'],
    ['setting_key' => 'editorial_require_comments_on_reject', 'setting_value' => '1', 'description' => 'Require comments when rejecting articles']
];

foreach ($settings as $setting) {
    $query = "INSERT INTO settings (setting_key, setting_value, description, created_at) 
              VALUES (?, ?, ?, NOW()) 
              ON DUPLICATE KEY UPDATE 
              setting_value = VALUES(setting_value), 
              description = VALUES(description)";
    
    try {
        $stmt = $conn->prepare($query);
        $stmt->execute([$setting['setting_key'], $setting['setting_value'], $setting['description']]);
        log_migration("Added/updated setting: " . $setting['setting_key']);
    } catch (PDOException $e) {
        log_migration("Failed to add setting " . $setting['setting_key'] . ": " . $e->getMessage(), false);
    }
}

// 11. Create audit log entries for migration
$audit_query = "INSERT INTO audit_logs (user_id, action, table_name, record_id, details, ip_address, created_at) 
                VALUES (?, 'MIGRATION', 'SYSTEM', 0, ?, ?, NOW())";

try {
    $stmt = $conn->prepare($audit_query);
    $stmt->execute([
        $_SESSION['user_id'],
        'Proofreading system migration completed with ' . count($migration_log) . ' operations',
        $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'
    ]);
    log_migration("Created audit log entry for migration");
} catch (PDOException $e) {
    log_migration("Failed to create audit log entry: " . $e->getMessage(), false);
}

echo "\n==========================================\n";
echo "Migration Summary:\n";
echo "==========================================\n";

$success_count = 0;
$error_count = 0;

foreach ($migration_log as $entry) {
    if ($entry['success']) {
        $success_count++;
    } else {
        $error_count++;
    }
}

echo "Total operations: " . count($migration_log) . "\n";
echo "Successful: $success_count\n";
echo "Errors: $error_count\n\n";

if ($error_count > 0) {
    echo "ERRORS ENCOUNTERED:\n";
    echo "===================\n";
    foreach ($errors as $error) {
        echo "- $error\n";
    }
    echo "\nPlease review and fix errors before proceeding.\n";
} else {
    echo "✅ Migration completed successfully!\n\n";
    echo "Next steps:\n";
    echo "1. Test the editorial dashboard at: editorial/dashboard.php\n";
    echo "2. Login with sample editor accounts:\n";
    echo "   - Username: editor_accra, Password: editor123\n";
    echo "   - Username: editor_tema, Password: editor123\n";
    echo "   - Username: editor_area_accra, Password: editor123\n";
    echo "3. Create a test article and submit it for review\n";
    echo "4. Test the complete proofreading workflow\n\n";
}

echo "Migration log saved. You can now use the proofreading system.\n";
?>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists