1<?php 2 3use dokuwiki\plugin\diagrams\Diagrams; 4 5/** 6 * DokuWiki Plugin diagrams (Syntax Component) 7 * 8 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 9 * @author Innovakom + CosmoCode <dokuwiki@cosmocode.de> 10 */ 11class syntax_plugin_diagrams_embed extends syntax_plugin_diagrams_mediafile 12{ 13 /** @var int count the current embedded diagram */ 14 protected $count = 0; 15 16 /** @inheritDoc */ 17 public function connectTo($mode) 18 { 19 // only register if embed mode is enabled 20 if (!($this->getConf('mode') & Diagrams::MODE_EMBED)) return; 21 $this->Lexer->addSpecialPattern('<diagram(?: .*?)?>.*?(?:</diagram>)', $mode, 'plugin_diagrams_embed'); 22 } 23 24 /** @inheritDoc */ 25 public function handle($match, $state, $pos, Doku_Handler $handler) 26 { 27 [$open, $rest] = sexplode('>', $match, 2); 28 $params = substr($open, 9); 29 $svg = substr($rest, 0, -10); 30 31 // embed positions 32 $svglen = strlen($svg); 33 $svgpos = $pos + strpos($match, '>'); 34 35 /** @var helper_plugin_diagrams $helper */ 36 $helper = plugin_load('helper', 'diagrams'); 37 if (!$helper->isDiagram($svg)) return false; 38 39 $data = [ 40 'svg' => $svg, 41 'title' => '', 42 'align' => '', 43 'width' => '', 44 'height' => '', 45 'pos' => $svgpos, 46 'len' => $svglen, 47 ]; 48 49 [$params, $data['title']] = sexplode('|', $params, 2); 50 51 if (preg_match('/\b(left|right|center)\b/', $params, $matches)) { 52 $data['align'] = $matches[1]; 53 } 54 55 if (preg_match('/\b(\d+)x(\d+)\b/', $params, $matches)) { 56 $data['width'] = (int)$matches[1]; 57 $data['height'] = (int)$matches[2]; 58 } 59 60 return $data; 61 } 62 63 /** @inheritDoc */ 64 public function render($format, Doku_Renderer $renderer, $data) 65 { 66 if (!$data) return false; 67 global $ID; 68 global $ACT; 69 global $INPUT; 70 global $REV; 71 72 switch ($format) { 73 case 'xhtml': 74 if (act_clean($ACT) !== 'preview' && page_exists($ID)) { 75 // this is "normal" rendering, we reference the diagram through the export 76 // this applies the same CSP as media files and will also show the exact behaviours 77 $data['url'] = wl($ID, ['do' => 'export_diagrams', 'svg' => $this->count++, 'rev' => $REV], true, '&'); 78 } else { 79 // we're in preview and the diagram may not have been saved, yet. So we 80 // reference it as data uri to prevent cross-origin access XSS 81 $data['url'] = 'data:image/svg+xml;base64,' . base64_encode($data['svg']); 82 } 83 84 parent::render($format, $renderer, $data); 85 return true; 86 case 'diagrams': 87 // This exports a single SVG during the export_diagrams action 88 if ($INPUT->int('svg') === $this->count++) { 89 $renderer->doc = $data['svg']; 90 } 91 return true; 92 } 93 return false; 94 } 95 96 97} 98 99