Heray-Was-Here
Server : LiteSpeed
System : Linux uk-fast-web1372.main-hosting.eu 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User : u390967363 ( 390967363)
PHP Version : 8.2.30
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
Directory :  /home/u390967363/domains/aibenproperties.com/public_html/app/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/u390967363/domains/aibenproperties.com/public_html/app/allocation-letter-pdf.php
<?php
session_start();
@set_time_limit(300);
require_once __DIR__ . '/includes/db.php';
require_once __DIR__ . '/includes/functions.php';
require_once __DIR__ . '/includes/doc_generator.php';
require_once __DIR__ . '/includes/mailer.php';

$apAutoload = __DIR__ . '/vendor/autoload.php';
if (is_file($apAutoload)) {
    require_once $apAutoload;
}
$uid = (int)($_SESSION['user_id'] ?? 0);
$role = strtolower(str_replace([' ', '-'], '_', (string)($_SESSION['user_role'] ?? '')));
if ($uid <= 0) {
    http_response_code(403);
    exit('Forbidden');
}

$allocId = isset($_REQUEST['allocation_id']) ? (int)$_REQUEST['allocation_id'] : 0;
if ($allocId <= 0) {
    http_response_code(400);
    exit('Invalid allocation id');
}

$action = strtolower((string)($_REQUEST['action'] ?? 'preview'));
if (!in_array($action, ['preview', 'download', 'send', 'save_to_portal'], true)) {
    $action = 'preview';
}

$isClient = ($role === 'client');
$canStaff = in_array($role, ['super_admin', 'admin', 'head_admin', 'admin_head', 'estate_manager', 'executive', 'executive_admin'], true);
$forceRegen = (!$isClient && $canStaff && isset($_REQUEST['regen']) && (string)$_REQUEST['regen'] === '1');
if (!$isClient && !$canStaff) {
    http_response_code(403);
    exit('Forbidden');
}

$allocRow = [];
try {
    $st = $pdo->prepare("SELECT id, user_id, status FROM allocations WHERE id = ? LIMIT 1");
    $st->execute([$allocId]);
    $allocRow = $st->fetch(PDO::FETCH_ASSOC) ?: [];
} catch (Throwable $e) {
    $allocRow = [];
}

if (!$allocRow) {
    http_response_code(404);
    exit('Allocation not found');
}

$clientId = (int)($allocRow['user_id'] ?? 0);
$hasDocuments = false;
try { $hasDocuments = $pdo->query("SHOW TABLES LIKE 'documents'")->rowCount() > 0; } catch (Throwable $e) { $hasDocuments = false; }

$resolveAbs = static function (string $path): string {
    $p = trim($path);
    if ($p === '') return '';
    if (preg_match('/^(?:[a-z]+:)?\\/\\//i', $p)) return $p;
    if (preg_match('/^[A-Za-z]:[\\\\\\/]/', $p)) return $p;
    $p = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, ltrim($p, "/\\"));
    return __DIR__ . DIRECTORY_SEPARATOR . $p;
};

$countPdfPagesFast = static function (string $absPath): int {
    if ($absPath === '' || !is_file($absPath)) return 0;
    $size = (int)@filesize($absPath);
    if ($size <= 0) return 0;
    $tailSize = 256 * 1024;
    if ($tailSize > $size) { $tailSize = $size; }
    $fp = @fopen($absPath, 'rb');
    if (!$fp) return 0;
    try {
        if ($size > $tailSize) { @fseek($fp, -$tailSize, SEEK_END); }
        $chunk = (string)@fread($fp, $tailSize);
    } finally {
        @fclose($fp);
    }
    if ($chunk === '') return 0;
    if (preg_match('/\\/Type\\s*\\/Pages\\b[\\s\\S]{0,1200}?\\/Count\\s+(\\d+)/', $chunk, $m)) {
        return (int)$m[1];
    }
    return 0;
};

$findLatestPdf = static function (int $allocationId) use ($resolveAbs): array {
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'documents' . DIRECTORY_SEPARATOR . 'generated' . DIRECTORY_SEPARATOR;
    $pattern = $dir . 'Allocation_Letter_' . $allocationId . '_*.pdf';
    $matches = glob($pattern) ?: [];
    if (!$matches) return ['', ''];
    usort($matches, static function ($a, $b) {
        return (int)@filemtime($b) <=> (int)@filemtime($a);
    });
    $abs = (string)($matches[0] ?? '');
    if ($abs === '') return ['', ''];
    $rel = str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', $abs);
    $rel = str_replace(DIRECTORY_SEPARATOR, '/', $rel);
    return [$abs, $rel];
};

$loadDocumentPdf = function () use ($pdo, $allocId, $clientId, $hasDocuments, $resolveAbs): array {
    if (!$hasDocuments) return ['', '', ''];
    try {
        $sql = "SELECT id, file_path, status FROM documents WHERE 1=1";
        $params = [];
        if (function_exists('tableHasColumn') && tableHasColumn('documents', 'allocation_id')) { $sql .= " AND allocation_id = ?"; $params[] = $allocId; }
        else { $sql .= " AND file_path LIKE ?"; $params[] = '%Allocation_Letter_' . $allocId . '_%'; }
        if ($clientId > 0 && function_exists('tableHasColumn') && tableHasColumn('documents', 'user_id')) { $sql .= " AND user_id = ?"; $params[] = $clientId; }
        $sql .= " ORDER BY id DESC LIMIT 1";
        $st = $pdo->prepare($sql);
        $st->execute($params);
        $row = $st->fetch(PDO::FETCH_ASSOC) ?: [];
        $rel = (string)($row['file_path'] ?? '');
        $status = strtolower((string)($row['status'] ?? ''));
        $abs = $resolveAbs($rel);
        if ($rel !== '' && is_file($abs) && filesize($abs) > 10 && preg_match('/\\.pdf$/i', $abs)) {
            return [$abs, $rel, $status];
        }
    } catch (Throwable $e) {}
    return ['', '', ''];
};

if ($action === 'send' || $action === 'save_to_portal') {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        http_response_code(405);
        exit('Method not allowed');
    }
    if (!ap_csrf_verify(ap_csrf_from_request())) {
        http_response_code(403);
        exit('Invalid CSRF token');
    }
    if (!$canStaff) {
        http_response_code(403);
        exit('Forbidden');
    }
}

if ($isClient) {
    if ($clientId <= 0 || $clientId !== $uid) {
        http_response_code(403);
        exit('Forbidden');
    }
    [$absDoc, $relDoc, $docStatus] = $loadDocumentPdf();
    $allowed = ['approved', 'issued', 'signed', 'released'];
    if ($absDoc === '' || !in_array($docStatus, $allowed, true)) {
        http_response_code(403);
        exit('Not available');
    }
    $pdfAbs = $absDoc;
    $pdfRel = $relDoc;
} else {
    [$absDoc, $relDoc, $docStatus] = $loadDocumentPdf();
    if ($absDoc === '') {
        [$absDoc, $relDoc] = $findLatestPdf($allocId);
    }
    if (!$forceRegen && $absDoc !== '' && is_file($absDoc)) {
        $docTime = (int)@filemtime($absDoc);
        $latestTplTime = 0;
        try {
            $tplFiles = [
                __DIR__ . '/includes/doc_templates.php',
                __DIR__ . '/includes/doc_generator.php',
            ];
            foreach ($tplFiles as $tf) {
                $t = is_file($tf) ? (int)@filemtime($tf) : 0;
                if ($t > $latestTplTime) { $latestTplTime = $t; }
            }
        } catch (Throwable $e) { $latestTplTime = 0; }
        if ($latestTplTime > 0 && $docTime > 0 && $latestTplTime > $docTime) {
            $forceRegen = true;
        }
        if (!$forceRegen && $docTime > 0) {
            try {
                $billingUpdatedAt = '';
                try {
                    if (function_exists('tableHasColumn') && tableHasColumn('allocation_billing', 'updated_at')) {
                        $stBu = $pdo->prepare("SELECT updated_at FROM allocation_billing WHERE allocation_id = ? LIMIT 1");
                        $stBu->execute([(int)$allocId]);
                        $billingUpdatedAt = (string)($stBu->fetchColumn() ?: '');
                    }
                } catch (Throwable $e) { $billingUpdatedAt = ''; }
                if ($billingUpdatedAt !== '') {
                    $billTime = strtotime($billingUpdatedAt);
                    if ($billTime && $billTime > $docTime) {
                        $forceRegen = true;
                    }
                }
            } catch (Throwable $e) {}
        }
        if (!$forceRegen && $docTime > 0) {
            try {
                $allocUpdatedAt = '';
                try {
                    $stAu = $pdo->prepare("SELECT updated_at FROM allocations WHERE id = ? LIMIT 1");
                    $stAu->execute([(int)$allocId]);
                    $allocUpdatedAt = (string)($stAu->fetchColumn() ?: '');
                } catch (Throwable $e) { $allocUpdatedAt = ''; }
                if ($allocUpdatedAt !== '') {
                    $allocTime = strtotime($allocUpdatedAt);
                    if ($allocTime && $allocTime > $docTime) {
                        $forceRegen = true;
                    }
                }
            } catch (Throwable $e) {}
        }
    }
    if (!$forceRegen && $absDoc !== '' && is_file($absDoc)) {
        $pages = $countPdfPagesFast($absDoc);
        if ($pages > 80) { $forceRegen = true; }
    }
    if ($forceRegen) {
        try {
            $gen = new DocGenerator($pdo);
            $gen->generateAllocationLetter($allocId, $uid);
        } catch (Throwable $e) {
            error_log('PDF Regeneration Error: ' . $e->getMessage());
        }
        [$absDoc, $relDoc, $docStatus] = $loadDocumentPdf();
        if ($absDoc === '') {
            [$absDoc, $relDoc] = $findLatestPdf($allocId);
        }
    }
    if ($absDoc === '' || !is_file($absDoc)) {
        try {
            $gen = new DocGenerator($pdo);
            $genResult = $gen->generateAllocationLetter($allocId, $uid);
            if (is_string($genResult) && $genResult !== '') {
                $maybeAbs = $resolveAbs($genResult);
                if (is_file($maybeAbs)) {
                    $absDoc = $maybeAbs;
                    $relDoc = $genResult;
                }
            }
            if ($absDoc === '' || !is_file($absDoc)) {
                [$absDoc, $relDoc, $docStatus] = $loadDocumentPdf();
            }
            if ($absDoc === '' || !is_file($absDoc)) {
                [$absDoc, $relDoc] = $findLatestPdf($allocId);
            }
        } catch (Throwable $e) {
            error_log('PDF Generation Error: ' . $e->getMessage());
        }
    }
    if (empty($absDoc) || !is_file($absDoc)) {
        http_response_code(500);
        $err = 'PDF generation failed. Please ensure mPDF is installed and working.';
        if (class_exists('\\Dompdf\\Dompdf')) {
            $err .= ' Dompdf is available.';
        }
        if (class_exists('\\Mpdf\\Mpdf')) {
            $err .= ' mPDF is available.';
        }
        exit($err);
    }
    $pdfAbs = $absDoc;
    $pdfRel = $relDoc;
}

if ($action === 'save_to_portal' || $action === 'send') {
    $updated = false;
    try {
        if ($hasDocuments && function_exists('tableHasColumn') && tableHasColumn('documents', 'status')) {
            $releasedToken = function_exists('pickColumnToken') ? pickColumnToken($pdo, 'documents', 'status', ['released', 'issued', 'signed', 'approved']) : 'released';
            $sql = "UPDATE documents SET status = ?" . ((function_exists('tableHasColumn') && tableHasColumn('documents', 'updated_at')) ? ", updated_at = ?" : "") . " WHERE 1=1";
            $params = [$releasedToken];
            if (function_exists('tableHasColumn') && tableHasColumn('documents', 'updated_at')) { $params[] = date('Y-m-d H:i:s'); }
            if (function_exists('tableHasColumn') && tableHasColumn('documents', 'type')) { $sql .= " AND type = ?"; $params[] = 'allocation_letter'; }
            if (function_exists('tableHasColumn') && tableHasColumn('documents', 'allocation_id')) { $sql .= " AND allocation_id = ?"; $params[] = $allocId; }
            else { $sql .= " AND file_path LIKE ?"; $params[] = '%Allocation_Letter_' . $allocId . '_%'; }
            if ($clientId > 0 && function_exists('tableHasColumn') && tableHasColumn('documents', 'user_id')) { $sql .= " AND user_id = ?"; $params[] = $clientId; }
            $st = $pdo->prepare($sql);
            $st->execute($params);
            $updated = true;
        }
    } catch (Throwable $e) { $updated = false; }

    if ($action === 'send' && $clientId > 0) {
        $base = function_exists('buildAbsBaseUrl') ? rtrim((string)buildAbsBaseUrl(), '/') : '';
        if ($base === '') {
            $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
            $host = (string)($_SERVER['HTTP_HOST'] ?? '');
            $base = $host !== '' ? ($scheme . '://' . $host) : '';
        }
        $fileUrl = $pdfRel !== '' && $base !== '' ? ($base . '/' . ltrim($pdfRel, '/')) : '';
        $msg = $fileUrl !== ''
            ? ("Your allocation letter is available. Download: " . $fileUrl)
            : "Your allocation letter is available in your client portal.";
        if (function_exists('sendNotification')) {
            try { sendNotification($clientId, 'allocation_letter_released', $msg, $pdo); } catch (Throwable $e) {}
        } elseif (function_exists('ap_create_notification')) {
            try {
                ap_create_notification($pdo, [
                    'user_id' => $clientId,
                    'department' => 'Client',
                    'title' => 'Allocation letter available',
                    'message' => $msg,
                    'type' => 'info',
                    'priority' => 'info',
                    'related_id' => $allocId,
                    'related_module' => 'client-documents.php',
                ]);
            } catch (Throwable $e) {}
        }
    }

    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['success' => true, 'saved' => $updated, 'path' => $pdfRel]);
    exit;
}

$filename = 'Allocation_Letter_' . str_pad((string)$allocId, 6, '0', STR_PAD_LEFT) . '.pdf';
header('Content-Type: application/pdf');
header('X-Content-Type-Options: nosniff');
header('Content-Disposition: ' . ($action === 'download' ? 'attachment' : 'inline') . '; filename="' . $filename . '"');
header('Content-Length: ' . filesize($pdfAbs));
readfile($pdfAbs);
exit;

Hry