1fc2e1131SJaap de Haan<?php 2fc2e1131SJaap de Haan 3a494ddccSgithub-actions[bot]use dokuwiki\Extension\SyntaxPlugin; 44c812427SJaap de Haanuse dokuwiki\File\MediaResolver; 5a494ddccSgithub-actions[bot] 6fc2e1131SJaap de Haan/** 7fc2e1131SJaap de Haan * @license See LICENSE file 8fc2e1131SJaap de Haan */ 9fc2e1131SJaap de Haan// See help: https://www.dokuwiki.org/devel:syntax_plugins 10242f4056SJaap de Haan// The HTML structure generated by this syntax plugin is: 11242f4056SJaap de Haan// 12242f4056SJaap de Haan// <div class="plugin-bpmnio" id="__(bpmn|dmn)_js_<hash>"> 13242f4056SJaap de Haan// <div class="bpmn_js_data"> 14242f4056SJaap de Haan// ... base64 encoded xml 15242f4056SJaap de Haan// </div> 16242f4056SJaap de Haan// <div class="bpmn_js_canvas {$class}"> 17242f4056SJaap de Haan// <div class="bpmn_js_container">... rendered herein</div> 18242f4056SJaap de Haan// </div> 19242f4056SJaap de Haan// </div> 20a494ddccSgithub-actions[bot]class syntax_plugin_bpmnio_bpmnio extends SyntaxPlugin 21fc2e1131SJaap de Haan{ 224c812427SJaap de Haan protected string $type = ''; // 'bpmn' or 'dmn' 234c812427SJaap de Haan protected string $src = ''; // media file 2494260a7fSJaap de Haan protected string $zoom = ''; // optional scaling factor 25f0ae282cSJaap de Haan 26*36b712d8SJaap de Haan private function loadLinkProcessor(): void 27*36b712d8SJaap de Haan { 28*36b712d8SJaap de Haan require_once __DIR__ . '/../inc/link_processor.php'; 29*36b712d8SJaap de Haan } 30*36b712d8SJaap de Haan 319ff8d41cSJaap de Haan public function getPType(): string 32fc2e1131SJaap de Haan { 33fc2e1131SJaap de Haan return 'block'; 34fc2e1131SJaap de Haan } 35fc2e1131SJaap de Haan 369ff8d41cSJaap de Haan public function getType(): string 37fc2e1131SJaap de Haan { 38fc2e1131SJaap de Haan return 'protected'; 39fc2e1131SJaap de Haan } 40fc2e1131SJaap de Haan 419ff8d41cSJaap de Haan public function getSort(): int 42fc2e1131SJaap de Haan { 43fc2e1131SJaap de Haan return 0; 44fc2e1131SJaap de Haan } 45fc2e1131SJaap de Haan 469ff8d41cSJaap de Haan public function connectTo($mode): void 47fc2e1131SJaap de Haan { 48fc2e1131SJaap de Haan $this->Lexer->addEntryPattern('<bpmnio.*?>(?=.*?</bpmnio>)', $mode, 'plugin_bpmnio_bpmnio'); 49fc2e1131SJaap de Haan } 50fc2e1131SJaap de Haan 519ff8d41cSJaap de Haan public function postConnect(): void 52fc2e1131SJaap de Haan { 53fc2e1131SJaap de Haan $this->Lexer->addExitPattern('</bpmnio>', 'plugin_bpmnio_bpmnio'); 54fc2e1131SJaap de Haan } 55fc2e1131SJaap de Haan 569ff8d41cSJaap de Haan public function handle($match, $state, $pos, Doku_Handler $handler): array 57fc2e1131SJaap de Haan { 58f0ae282cSJaap de Haan switch ($state) { 59f0ae282cSJaap de Haan case DOKU_LEXER_ENTER: 604c812427SJaap de Haan $matched = []; 614c812427SJaap de Haan preg_match('/<bpmnio\s+([^>]+)>/', $match, $matched); 624c812427SJaap de Haan 634c812427SJaap de Haan $attrs = []; 644c812427SJaap de Haan if (!empty($matched[1])) { 654c812427SJaap de Haan $attrs = $this->buildAttributes($matched[1]); 664c812427SJaap de Haan } 674c812427SJaap de Haan 684c812427SJaap de Haan $this->type = $attrs['type'] ?? 'bpmn'; 694c812427SJaap de Haan $this->src = $attrs['src'] ?? ''; 7094260a7fSJaap de Haan $this->zoom = $this->normalizeZoom($attrs['zoom'] ?? null) ?? ''; 714c812427SJaap de Haan 7294260a7fSJaap de Haan return [$state, $this->type, '', $pos, '', false, $this->zoom]; 73f0ae282cSJaap de Haan 74f0ae282cSJaap de Haan case DOKU_LEXER_UNMATCHED: 75c4f02a6eSJaap de Haan $posStart = $pos; 76c4f02a6eSJaap de Haan $posEnd = $pos + strlen($match); 774c812427SJaap de Haan 784c812427SJaap de Haan $inline = empty($this->src); 794c812427SJaap de Haan if (!$inline) { 804c812427SJaap de Haan $match = $this->getMedia($this->src); 814c812427SJaap de Haan } 8294260a7fSJaap de Haan return [$state, $this->type, base64_encode($match), $posStart, $posEnd, $inline, $this->zoom]; 83f0ae282cSJaap de Haan 84f0ae282cSJaap de Haan case DOKU_LEXER_EXIT: 85ae85f1faSJaap de Haan $this->type = ''; 864c812427SJaap de Haan $this->src = ''; 8794260a7fSJaap de Haan $this->zoom = ''; 8894260a7fSJaap de Haan return [$state, '', '', '', '', '', false, '']; 89fc2e1131SJaap de Haan } 90a494ddccSgithub-actions[bot] return []; 91fc2e1131SJaap de Haan } 92fc2e1131SJaap de Haan 934c812427SJaap de Haan private function buildAttributes($string) 944c812427SJaap de Haan { 954c812427SJaap de Haan $attrs = []; 964c812427SJaap de Haan preg_match_all('/(\w+)=["\'](.*?)["\']/', $string, $matches, PREG_SET_ORDER); 974c812427SJaap de Haan foreach ($matches as $match) { 984c812427SJaap de Haan $attrs[$match[1]] = $match[2]; 994c812427SJaap de Haan } 1004c812427SJaap de Haan return $attrs; 1014c812427SJaap de Haan } 1024c812427SJaap de Haan 10394260a7fSJaap de Haan private function normalizeZoom($zoom): ?string 10494260a7fSJaap de Haan { 10594260a7fSJaap de Haan if ($zoom === null || $zoom === '') { 10694260a7fSJaap de Haan return null; 10794260a7fSJaap de Haan } 10894260a7fSJaap de Haan 10994260a7fSJaap de Haan if (!is_numeric($zoom)) { 11094260a7fSJaap de Haan return null; 11194260a7fSJaap de Haan } 11294260a7fSJaap de Haan 11394260a7fSJaap de Haan $zoom = (float) $zoom; 11494260a7fSJaap de Haan if ($zoom <= 0) { 11594260a7fSJaap de Haan return null; 11694260a7fSJaap de Haan } 11794260a7fSJaap de Haan 11894260a7fSJaap de Haan return rtrim(rtrim(number_format($zoom, 4, '.', ''), '0'), '.'); 11994260a7fSJaap de Haan } 12094260a7fSJaap de Haan 1214c812427SJaap de Haan private function getMedia($src) 1224c812427SJaap de Haan { 1234c812427SJaap de Haan global $ID; 1244c812427SJaap de Haan 1254c812427SJaap de Haan $id = (new MediaResolver($ID))->resolveId($src); 1264c812427SJaap de Haan if (auth_quickaclcheck($id) < AUTH_READ) { 1274c812427SJaap de Haan return "Error: Access denied for file $src"; 1284c812427SJaap de Haan } 1294c812427SJaap de Haan 1304c812427SJaap de Haan $file = mediaFN($id); 1314c812427SJaap de Haan if (!file_exists($file) || !is_readable($file)) { 1324c812427SJaap de Haan return "Error: Cannot load file $src"; 1334c812427SJaap de Haan } 1344c812427SJaap de Haan 1354c812427SJaap de Haan return file_get_contents($file); 1364c812427SJaap de Haan } 1374c812427SJaap de Haan 1389ff8d41cSJaap de Haan public function render($mode, Doku_Renderer $renderer, $data): bool 139fc2e1131SJaap de Haan { 14094260a7fSJaap de Haan [$state, $type, $match, $posStart, $posEnd, $inline, $zoom] = array_pad($data, 7, ''); 14134515d89SJaap de Haan 14234515d89SJaap de Haan if (is_a($renderer, 'renderer_plugin_dw2pdf')) { 14334515d89SJaap de Haan if ($state == DOKU_LEXER_EXIT) { 14434515d89SJaap de Haan $renderer->doc .= <<<HTML 14534515d89SJaap de Haan <div class="plugin-bpmnio"> 146962d7b81SJaap de Haan <a href="https://github.com/Color-Of-Code/dokuwiki-plugin-bpmnio/issues/4"> 147962d7b81SJaap de Haan DW2PDF support missing: Help wanted 148962d7b81SJaap de Haan </a> 14934515d89SJaap de Haan </div> 15034515d89SJaap de Haan HTML; 15134515d89SJaap de Haan } 15234515d89SJaap de Haan return true; 15334515d89SJaap de Haan } 15434515d89SJaap de Haan 15534515d89SJaap de Haan if ($mode == 'xhtml' || $mode == 'odt') { 156fc2e1131SJaap de Haan switch ($state) { 157fc2e1131SJaap de Haan case DOKU_LEXER_ENTER: 158ae85f1faSJaap de Haan $bpmnid = "__{$type}_js_{$posStart}"; 1598428abe8SJaap de Haan $renderer->doc .= <<<HTML 1608428abe8SJaap de Haan <div class="plugin-bpmnio" id="{$bpmnid}"> 1618428abe8SJaap de Haan HTML; 162fc2e1131SJaap de Haan break; 163fc2e1131SJaap de Haan 164fc2e1131SJaap de Haan case DOKU_LEXER_UNMATCHED: 165*36b712d8SJaap de Haan $xml = base64_decode($match, true); 166*36b712d8SJaap de Haan if ($xml === false) { 167*36b712d8SJaap de Haan $xml = $match; 168*36b712d8SJaap de Haan } 169*36b712d8SJaap de Haan 170*36b712d8SJaap de Haan $this->loadLinkProcessor(); 171*36b712d8SJaap de Haan $payload = plugin_bpmnio_link_processor::buildPayload($xml); 172*36b712d8SJaap de Haan $encodedXml = base64_encode($payload['xml']); 173*36b712d8SJaap de Haan $encodedLinks = base64_encode(json_encode($payload['links'])); 1748428abe8SJaap de Haan $renderer->doc .= <<<HTML 175f0ae282cSJaap de Haan <div class="{$type}_js_data"> 176*36b712d8SJaap de Haan {$encodedXml} 177*36b712d8SJaap de Haan </div> 178*36b712d8SJaap de Haan <div class="{$type}_js_links"> 179*36b712d8SJaap de Haan {$encodedLinks} 1808428abe8SJaap de Haan </div> 1818428abe8SJaap de Haan HTML; 1824c812427SJaap de Haan if ($inline) { 183962d7b81SJaap de Haan $target = "plugin_bpmnio_{$type}"; 184962d7b81SJaap de Haan $sectionEditData = ['target' => $target]; 185962d7b81SJaap de Haan $class = $renderer->startSectionEdit($posStart, $sectionEditData); 1864c812427SJaap de Haan } else { 1874c812427SJaap de Haan $class = ''; 1884c812427SJaap de Haan } 18994260a7fSJaap de Haan $zoomAttr = $zoom !== '' ? " data-zoom=\"{$zoom}\"" : ''; 190c4f02a6eSJaap de Haan $renderer->doc .= <<<HTML 191f0ae282cSJaap de Haan <div class="{$type}_js_canvas {$class}"> 19294260a7fSJaap de Haan <div class="{$type}_js_container"{$zoomAttr}></div> 193c4f02a6eSJaap de Haan </div> 194c4f02a6eSJaap de Haan HTML; 1954c812427SJaap de Haan if ($inline) { 196962d7b81SJaap de Haan $renderer->finishSectionEdit($posEnd); 1974c812427SJaap de Haan } 198c4f02a6eSJaap de Haan break; 199c4f02a6eSJaap de Haan 200c4f02a6eSJaap de Haan case DOKU_LEXER_EXIT: 201f0ae282cSJaap de Haan $renderer->doc .= <<<HTML 202f0ae282cSJaap de Haan </div> 203f0ae282cSJaap de Haan HTML; 204fc2e1131SJaap de Haan break; 205fc2e1131SJaap de Haan } 206fc2e1131SJaap de Haan return true; 207fc2e1131SJaap de Haan } 208fc2e1131SJaap de Haan return false; 209fc2e1131SJaap de Haan } 210fc2e1131SJaap de Haan} 211