瀏覽代碼

combined pages

Benjamin Harris 2 月之前
父節點
當前提交
5ece4da2c8

+ 29 - 16
dashboard/crop-analysis/soil-test-data/soil-analysis.php

@@ -7,6 +7,7 @@
 
 require_once __DIR__.'/../../../config/database.php';
 require_once __DIR__.'/../../../lib/auth.php';
+require_once __DIR__.'/../../../lib/print_auth.php';
 require_once __DIR__.'/../../../lib/validation.php';
 require_once __DIR__.'/../../../lib/soil_calculations.php';
 
@@ -14,13 +15,18 @@ if (session_status() === PHP_SESSION_NONE) {
     session_start();
 }
 
-requireLogin();
+$record_id  = (int)  ($_GET['rid']   ?? 0);
+$rand_id    = trim(  $_GET['rand']   ?? '');
+$client_id  = (int)  ($_GET['cid']   ?? 0);
+$print_mode = isset($_GET['print']);
 
-$record_id = (float)($_GET['rid']  ?? 0);
-$rand_id   = (float)($_GET['rand'] ?? 0);
-$client_id = (int)  ($_GET['cid']  ?? 0);
+if ($print_mode) {
+    authenticatePrintPage($record_id, $rand_id);
+} else {
+    requireLogin();
+}
 
-if (!$record_id || !$rand_id) {
+if (!$record_id || $rand_id === '') {
     die('Invalid request parameters');
 }
 
@@ -120,18 +126,29 @@ include __DIR__.'/../../../layouts/header.php';
         </tbody>
     </table>
 
+    <?php if (!$print_mode): ?>
     <div class="d-print-none">
-        <div class="row p-2">
-            <div class="col">
-                <button type="button" class="btn btn-primary" onclick="generateGraph()">
-                    <i class="fas fa-chart-bar"></i> Generate Graph
-                </button>
+        <div class="row p-2 align-items-center">
+            <div class="col d-flex gap-2 flex-wrap">
+                <a href="/dashboard/crop-analysis/soil-test-data/soil-report.php?rid=<?= (int)$record_id ?>&rand=<?= urlencode((string)$rand_id) ?>&cid=<?= (int)$client_id ?>"
+                   class="btn btn-outline-primary btn-sm">
+                    <i class="fas fa-file-alt me-1"></i>View Report
+                </a>
+                <a href="/pdf-files/headlessChrome_pdf.php?type=soil-analysis&rid=<?= (int)$record_id ?>&rand=<?= urlencode((string)$rand_id) ?>&cid=<?= (int)$client_id ?>"
+                   class="btn btn-outline-secondary btn-sm">
+                    <i class="fas fa-file-pdf me-1"></i>PDF — Analysis
+                </a>
+                <a href="/pdf-files/headlessChrome_pdf.php?type=soil&rid=<?= (int)$record_id ?>&rand=<?= urlencode((string)$rand_id) ?>&cid=<?= (int)$client_id ?>"
+                   class="btn btn-success btn-sm">
+                    <i class="fas fa-file-pdf me-1"></i>PDF — Analysis &amp; Report
+                </a>
             </div>
-            <div class="col">
-                <div class="form-status-holder"></div>
+            <div class="col-auto">
+                <div class="form-status-holder small text-muted"></div>
             </div>
         </div>
     </div>
+    <?php endif; ?>
 
     <div class="row">
         <div class="col-md-12 text-center fw-bold h4">Soil Analysis Summary</div>
@@ -307,10 +324,6 @@ include __DIR__.'/../../../layouts/header.php';
 </div><!-- /.container -->
 
 <script>
-function generateGraph() {
-    alert('Graph generation functionality will be implemented here.');
-}
-
 $(document).ready(function () {
     var timeoutId;
     $('form textarea, form input').on('input propertychange change', function () {

+ 111 - 0
dashboard/crop-analysis/soil-test-data/soil-print-combined.php

@@ -0,0 +1,111 @@
+<?php
+/**
+ * soil-print-combined.php
+ *
+ * Combined print/PDF page: Soil Analysis + Soil Report in one document.
+ * Uses two iframes pointing at the existing individual pages to avoid
+ * duplicating any rendering logic.
+ *
+ * Accessed by headlessChrome_pdf.php (type=soil) — never directly by users.
+ * Auth is via the shared ptoken written by the generator.
+ *
+ * Both child iframes receive the same ptoken. authenticatePrintPage() does
+ * not delete the token file, so multiple requests with the same token work.
+ */
+
+require_once __DIR__ . '/../../../config/database.php';
+require_once __DIR__ . '/../../../lib/auth.php';
+require_once __DIR__ . '/../../../lib/print_auth.php';
+
+if (session_status() === PHP_SESSION_NONE) {
+    session_start();
+}
+
+$recordId = (int)  ($_GET['rid']   ?? 0);
+$randId   = trim(  $_GET['rand']   ?? '');
+$clientId = (int)  ($_GET['cid']   ?? 0);
+$stid     = trim(  $_GET['stid']   ?? '');
+$ptoken   = trim(  $_GET['ptoken'] ?? '');
+
+authenticatePrintPage($recordId, $randId);
+
+// Build child page URLs — pass the same ptoken so each iframe can auth
+$analysisUrl = '/dashboard/crop-analysis/soil-test-data/soil-analysis.php?'
+    . http_build_query([
+        'rid'    => $recordId,
+        'rand'   => $randId,
+        'cid'    => $clientId,
+        'stid'   => $stid,
+        'ptoken' => $ptoken,
+        'print'  => '1',
+    ]);
+
+$reportUrl = '/dashboard/crop-analysis/soil-test-data/soil-report-pdf.php?'
+    . http_build_query([
+        'rid'    => $recordId,
+        'rand'   => $randId,
+        'ptoken' => $ptoken,
+    ]);
+
+function h(string $v): string {
+    return htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
+}
+?>
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Soil Analysis &amp; Report</title>
+    <style>
+        * { margin: 0; padding: 0; box-sizing: border-box; }
+        body { background: #fff; }
+
+        iframe {
+            width: 100%;
+            border: none;
+            display: block;
+            min-height: 200px;
+        }
+
+        .page-section {
+            page-break-after: always;
+        }
+        .page-section:last-child {
+            page-break-after: avoid;
+        }
+
+        @media print {
+            @page { size: A4 portrait; margin: 0; }
+        }
+    </style>
+</head>
+<body>
+
+<div class="page-section">
+    <iframe id="frame-analysis" src="<?= h($analysisUrl) ?>" scrolling="no"></iframe>
+</div>
+
+<div class="page-section">
+    <iframe id="frame-report" src="<?= h($reportUrl) ?>" scrolling="no"></iframe>
+</div>
+
+<script>
+(function () {
+    function resizeFrame(iframe) {
+        try {
+            var h = iframe.contentDocument.documentElement.scrollHeight;
+            if (h > 0) iframe.style.height = h + 'px';
+        } catch (e) {
+            iframe.style.height = '2970px'; // A4 height fallback (~297mm at 96dpi)
+        }
+    }
+
+    ['frame-analysis', 'frame-report'].forEach(function (id) {
+        var el = document.getElementById(id);
+        el.addEventListener('load', function () { resizeFrame(el); });
+    });
+})();
+</script>
+
+</body>
+</html>

+ 7 - 0
dashboard/crop-analysis/soil-test-data/soil-report-pdf.php

@@ -138,6 +138,13 @@ function formatReportText(string $text): string
                 @page :bottom {
                     margin-bottom: 0cm;
                 }
+
+                body {
+                    min-width: 992px !important;
+                }
+                .container {
+                    min-width: 992px !important;
+                }
             .d-print-none  { display: none !important; }
             .page-break    { page-break-before: always; }
             body           { font-size: 11px; }

+ 6 - 2
dashboard/crop-analysis/soil-test-data/soil-report.php

@@ -133,8 +133,12 @@ include __DIR__ . '/../../../layouts/header.php';
                 &larr; Analysis
             </a>
             <a href="/dashboard/crop-analysis/soil-test-data/soil-report-pdf.php?rid=<?= $record_id ?>&rand=<?= urlencode($rand_id) ?>"
-               class="btn btn-success btn-sm" target="_blank">
-                <i class="fas fa-file-pdf me-1"></i>PDF Report
+               class="btn btn-outline-success btn-sm" target="_blank">
+                <i class="fas fa-file-pdf me-1"></i>PDF — Report
+            </a>
+            <a href="/pdf-files/headlessChrome_pdf.php?type=soil&rid=<?= $record_id ?>&rand=<?= urlencode($rand_id) ?>&cid=<?= $client_id ?>"
+               class="btn btn-success btn-sm">
+                <i class="fas fa-file-pdf me-1"></i>PDF — Analysis &amp; Report
             </a>
             <button type="button" class="btn btn-primary btn-sm" id="btn-generate-all">
                 <i class="fas fa-robot me-1"></i>Interpret All with AI