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 24*94260a7fSJaap de Haan protected string $zoom = ''; // optional scaling factor 25f0ae282cSJaap de Haan 269ff8d41cSJaap de Haan public function getPType(): string 27fc2e1131SJaap de Haan { 28fc2e1131SJaap de Haan return 'block'; 29fc2e1131SJaap de Haan } 30fc2e1131SJaap de Haan 319ff8d41cSJaap de Haan public function getType(): string 32fc2e1131SJaap de Haan { 33fc2e1131SJaap de Haan return 'protected'; 34fc2e1131SJaap de Haan } 35fc2e1131SJaap de Haan 369ff8d41cSJaap de Haan public function getSort(): int 37fc2e1131SJaap de Haan { 38fc2e1131SJaap de Haan return 0; 39fc2e1131SJaap de Haan } 40fc2e1131SJaap de Haan 419ff8d41cSJaap de Haan public function connectTo($mode): void 42fc2e1131SJaap de Haan { 43fc2e1131SJaap de Haan $this->Lexer->addEntryPattern('<bpmnio.*?>(?=.*?</bpmnio>)', $mode, 'plugin_bpmnio_bpmnio'); 44fc2e1131SJaap de Haan } 45fc2e1131SJaap de Haan 469ff8d41cSJaap de Haan public function postConnect(): void 47fc2e1131SJaap de Haan { 48fc2e1131SJaap de Haan $this->Lexer->addExitPattern('</bpmnio>', 'plugin_bpmnio_bpmnio'); 49fc2e1131SJaap de Haan } 50fc2e1131SJaap de Haan 519ff8d41cSJaap de Haan public function handle($match, $state, $pos, Doku_Handler $handler): array 52fc2e1131SJaap de Haan { 53f0ae282cSJaap de Haan switch ($state) { 54f0ae282cSJaap de Haan case DOKU_LEXER_ENTER: 554c812427SJaap de Haan $matched = []; 564c812427SJaap de Haan preg_match('/<bpmnio\s+([^>]+)>/', $match, $matched); 574c812427SJaap de Haan 584c812427SJaap de Haan $attrs = []; 594c812427SJaap de Haan if (!empty($matched[1])) { 604c812427SJaap de Haan $attrs = $this->buildAttributes($matched[1]); 614c812427SJaap de Haan } 624c812427SJaap de Haan 634c812427SJaap de Haan $this->type = $attrs['type'] ?? 'bpmn'; 644c812427SJaap de Haan $this->src = $attrs['src'] ?? ''; 65*94260a7fSJaap de Haan $this->zoom = $this->normalizeZoom($attrs['zoom'] ?? null) ?? ''; 664c812427SJaap de Haan 67*94260a7fSJaap de Haan return [$state, $this->type, '', $pos, '', false, $this->zoom]; 68f0ae282cSJaap de Haan 69f0ae282cSJaap de Haan case DOKU_LEXER_UNMATCHED: 70c4f02a6eSJaap de Haan $posStart = $pos; 71c4f02a6eSJaap de Haan $posEnd = $pos + strlen($match); 724c812427SJaap de Haan 734c812427SJaap de Haan $inline = empty($this->src); 744c812427SJaap de Haan if (!$inline) { 754c812427SJaap de Haan $match = $this->getMedia($this->src); 764c812427SJaap de Haan } 77*94260a7fSJaap de Haan return [$state, $this->type, base64_encode($match), $posStart, $posEnd, $inline, $this->zoom]; 78f0ae282cSJaap de Haan 79f0ae282cSJaap de Haan case DOKU_LEXER_EXIT: 80ae85f1faSJaap de Haan $this->type = ''; 814c812427SJaap de Haan $this->src = ''; 82*94260a7fSJaap de Haan $this->zoom = ''; 83*94260a7fSJaap de Haan return [$state, '', '', '', '', '', false, '']; 84fc2e1131SJaap de Haan } 85a494ddccSgithub-actions[bot] return []; 86fc2e1131SJaap de Haan } 87fc2e1131SJaap de Haan 884c812427SJaap de Haan private function buildAttributes($string) 894c812427SJaap de Haan { 904c812427SJaap de Haan $attrs = []; 914c812427SJaap de Haan preg_match_all('/(\w+)=["\'](.*?)["\']/', $string, $matches, PREG_SET_ORDER); 924c812427SJaap de Haan foreach ($matches as $match) { 934c812427SJaap de Haan $attrs[$match[1]] = $match[2]; 944c812427SJaap de Haan } 954c812427SJaap de Haan return $attrs; 964c812427SJaap de Haan } 974c812427SJaap de Haan 98*94260a7fSJaap de Haan private function normalizeZoom($zoom): ?string 99*94260a7fSJaap de Haan { 100*94260a7fSJaap de Haan if ($zoom === null || $zoom === '') { 101*94260a7fSJaap de Haan return null; 102*94260a7fSJaap de Haan } 103*94260a7fSJaap de Haan 104*94260a7fSJaap de Haan if (!is_numeric($zoom)) { 105*94260a7fSJaap de Haan return null; 106*94260a7fSJaap de Haan } 107*94260a7fSJaap de Haan 108*94260a7fSJaap de Haan $zoom = (float) $zoom; 109*94260a7fSJaap de Haan if ($zoom <= 0) { 110*94260a7fSJaap de Haan return null; 111*94260a7fSJaap de Haan } 112*94260a7fSJaap de Haan 113*94260a7fSJaap de Haan return rtrim(rtrim(number_format($zoom, 4, '.', ''), '0'), '.'); 114*94260a7fSJaap de Haan } 115*94260a7fSJaap de Haan 1164c812427SJaap de Haan private function getMedia($src) 1174c812427SJaap de Haan { 1184c812427SJaap de Haan global $ID; 1194c812427SJaap de Haan 1204c812427SJaap de Haan $id = (new MediaResolver($ID))->resolveId($src); 1214c812427SJaap de Haan if (auth_quickaclcheck($id) < AUTH_READ) { 1224c812427SJaap de Haan return "Error: Access denied for file $src"; 1234c812427SJaap de Haan } 1244c812427SJaap de Haan 1254c812427SJaap de Haan $file = mediaFN($id); 1264c812427SJaap de Haan if (!file_exists($file) || !is_readable($file)) { 1274c812427SJaap de Haan return "Error: Cannot load file $src"; 1284c812427SJaap de Haan } 1294c812427SJaap de Haan 1304c812427SJaap de Haan return file_get_contents($file); 1314c812427SJaap de Haan } 1324c812427SJaap de Haan 1339ff8d41cSJaap de Haan public function render($mode, Doku_Renderer $renderer, $data): bool 134fc2e1131SJaap de Haan { 135*94260a7fSJaap de Haan [$state, $type, $match, $posStart, $posEnd, $inline, $zoom] = array_pad($data, 7, ''); 13634515d89SJaap de Haan 13734515d89SJaap de Haan if (is_a($renderer, 'renderer_plugin_dw2pdf')) { 13834515d89SJaap de Haan if ($state == DOKU_LEXER_EXIT) { 13934515d89SJaap de Haan $renderer->doc .= <<<HTML 14034515d89SJaap de Haan <div class="plugin-bpmnio"> 141962d7b81SJaap de Haan <a href="https://github.com/Color-Of-Code/dokuwiki-plugin-bpmnio/issues/4"> 142962d7b81SJaap de Haan DW2PDF support missing: Help wanted 143962d7b81SJaap de Haan </a> 14434515d89SJaap de Haan </div> 14534515d89SJaap de Haan HTML; 14634515d89SJaap de Haan } 14734515d89SJaap de Haan return true; 14834515d89SJaap de Haan } 14934515d89SJaap de Haan 15034515d89SJaap de Haan if ($mode == 'xhtml' || $mode == 'odt') { 151fc2e1131SJaap de Haan switch ($state) { 152fc2e1131SJaap de Haan case DOKU_LEXER_ENTER: 153ae85f1faSJaap de Haan $bpmnid = "__{$type}_js_{$posStart}"; 1548428abe8SJaap de Haan $renderer->doc .= <<<HTML 1558428abe8SJaap de Haan <div class="plugin-bpmnio" id="{$bpmnid}"> 1568428abe8SJaap de Haan HTML; 157fc2e1131SJaap de Haan break; 158fc2e1131SJaap de Haan 159fc2e1131SJaap de Haan case DOKU_LEXER_UNMATCHED: 1608428abe8SJaap de Haan $renderer->doc .= <<<HTML 161f0ae282cSJaap de Haan <div class="{$type}_js_data"> 162c4f02a6eSJaap de Haan {$match} 1638428abe8SJaap de Haan </div> 1648428abe8SJaap de Haan HTML; 1654c812427SJaap de Haan if ($inline) { 166962d7b81SJaap de Haan $target = "plugin_bpmnio_{$type}"; 167962d7b81SJaap de Haan $sectionEditData = ['target' => $target]; 168962d7b81SJaap de Haan $class = $renderer->startSectionEdit($posStart, $sectionEditData); 1694c812427SJaap de Haan } else { 1704c812427SJaap de Haan $class = ''; 1714c812427SJaap de Haan } 172*94260a7fSJaap de Haan $zoomAttr = $zoom !== '' ? " data-zoom=\"{$zoom}\"" : ''; 173c4f02a6eSJaap de Haan $renderer->doc .= <<<HTML 174f0ae282cSJaap de Haan <div class="{$type}_js_canvas {$class}"> 175*94260a7fSJaap de Haan <div class="{$type}_js_container"{$zoomAttr}></div> 176c4f02a6eSJaap de Haan </div> 177c4f02a6eSJaap de Haan HTML; 1784c812427SJaap de Haan if ($inline) { 179962d7b81SJaap de Haan $renderer->finishSectionEdit($posEnd); 1804c812427SJaap de Haan } 181c4f02a6eSJaap de Haan break; 182c4f02a6eSJaap de Haan 183c4f02a6eSJaap de Haan case DOKU_LEXER_EXIT: 184f0ae282cSJaap de Haan $renderer->doc .= <<<HTML 185f0ae282cSJaap de Haan </div> 186f0ae282cSJaap de Haan HTML; 187fc2e1131SJaap de Haan break; 188fc2e1131SJaap de Haan } 189fc2e1131SJaap de Haan return true; 190fc2e1131SJaap de Haan } 191fc2e1131SJaap de Haan return false; 192fc2e1131SJaap de Haan } 193fc2e1131SJaap de Haan} 194