| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- <?php
- // generate_docx.php
- declare(strict_types=1);
- ini_set('display_errors','0'); error_reporting(E_ALL);
- use PhpOffice\PhpWord\PhpWord;
- use PhpOffice\PhpWord\IOFactory;
- use PhpOffice\PhpWord\Shared\Html;
- use PhpOffice\PhpWord\ComplexType\TblWidth;
- use PhpOffice\PhpWord\Style\TOC as TOCStyle;
- header('Content-Type: application/json; charset=utf-8');
- header('Access-Control-Allow-Methods: POST, OPTIONS');
- header('Access-Control-Allow-Headers: Content-Type');
- if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') { http_response_code(204); exit; }
- require __DIR__ . '/vendor/autoload.php';
- try {
- $raw = file_get_contents('php://input') ?: '{}';
- $in = json_decode($raw, true) ?: [];
- $md = (string)($in['markdown'] ?? '');
- $ctx = (array)($in['context'] ?? []);
- if ($md === '') throw new RuntimeException('Missing markdown');
- // Simple Markdown → HTML
- $parsedown = new Parsedown();
- $parsedown->setBreaksEnabled(true);
- $htmlBody = $parsedown->text($md);
- $address = $ctx['address'] ?? '';
- $preparedFor = $ctx['prepared_for'] ?? '—';
- $preparedBy = $ctx['prepared_by'] ?? 'Modulos Design';
- $when = date('j F Y');
- $intent = trim((string)($ctx['project_intent'] ?? ''));
- $pw = new PhpWord();
- // Base styles
- $pw->addTitleStyle(1, ['size'=>20,'bold'=>true,'color'=>'1f2937']);
- $pw->addTitleStyle(2, ['size'=>16,'bold'=>true,'color'=>'334155']);
- $pw->addTitleStyle(3, ['size'=>13,'bold'=>true,'color'=>'475569']);
- $pw->setDefaultFontName('Calibri');
- $pw->setDefaultFontSize(11);
- // COVER SECTION
- $cover = $pw->addSection();
- $cover->addText('Supporting Planning Report', ['bold'=>true,'size'=>28,'color'=>'0f172a'], ['spaceAfter'=>240]);
- if ($address) $cover->addText('Address: '.$address, [], ['spaceAfter'=>120]);
- $cover->addText('Prepared for: '.$preparedFor);
- $cover->addText('Prepared by: '.$preparedBy);
- $cover->addText('Date: '.$when);
- if ($intent) { $cover->addTextBreak(1); $cover->addText('Project intent: '.$intent, ['italic'=>true]); }
- $cover->addPageBreak();
- // TOC SECTION
- $toc = $pw->addSection();
- $toc->addText('Contents', ['bold'=>true,'size'=>18], ['spaceAfter'=>200]);
- $pw->addTableStyle('TOCStyle', [], ['indent'=>0, 'tabLeader'=>TOCStyle::TABLEADER_DOT]);
- $toc->addTOC(['size'=>11], ['tabLeader'=>TOCStyle::TABLEADER_DOT, 'indent'=>0, 'name'=>'TOCStyle']);
- $toc->addPageBreak();
- // BODY SECTION (inject HTML; Parsedown produced h1/h2/h3 → Word titles)
- $body = $pw->addSection();
- Html::addHtml($body, $htmlBody, false, false);
- // Save to tmp and stream URL back (or data URI)
- $tmpDir = sys_get_temp_dir();
- $file = $tmpDir . '/PlanningReport-' . preg_replace('~[^\w\-]+~','_', $address ?: 'Site') . '.docx';
- IOFactory::createWriter($pw, 'Word2007')->save($file);
- echo json_encode(['ok'=>true, 'url'=>"download.php?file=".basename($file)]);
- } catch (Throwable $e) {
- http_response_code(500);
- echo json_encode(['ok'=>false,'error'=>$e->getMessage()]);
- }
|