104fd306cSNickeau<?php 204fd306cSNickeau 304fd306cSNickeaunamespace ComboStrap; 404fd306cSNickeau 504fd306cSNickeauuse Doku_Renderer; 604fd306cSNickeauuse PHPUnit\Exception; 704fd306cSNickeau 804fd306cSNickeau/** 904fd306cSNickeau * 1004fd306cSNickeau * Adaptation of the function {@link p_render()} 1104fd306cSNickeau * for dynamic rendering because the {@link \Doku_Renderer_xhtml Renderer} has also state 1204fd306cSNickeau * such as the `counter_row` for the function {@link \Doku_Renderer_xhtml::table_open()} 1304fd306cSNickeau * 1404fd306cSNickeau * If {@link p_render()} is used multiple time, the renderer is recreated and the counter is reset to zero and the 1504fd306cSNickeau * row of each table is lost. 1604fd306cSNickeau * 1704fd306cSNickeau */ 1804fd306cSNickeauclass MarkupDynamicRender 1904fd306cSNickeau{ 2004fd306cSNickeau /** 2104fd306cSNickeau * @var MarkupDynamicRender[] 2204fd306cSNickeau */ 2304fd306cSNickeau static array $DYNAMIC_RENDERERS_CACHE = array(); 2404fd306cSNickeau 2504fd306cSNickeau 2604fd306cSNickeau /** 2704fd306cSNickeau * @var string the format (xhtml, ...) 2804fd306cSNickeau */ 2904fd306cSNickeau private string $format; 3004fd306cSNickeau 3104fd306cSNickeau 3204fd306cSNickeau /** 3304fd306cSNickeau * @var Doku_Renderer the renderer that calls the render function 3404fd306cSNickeau */ 3504fd306cSNickeau private Doku_Renderer $renderer; 3604fd306cSNickeau 3704fd306cSNickeau /** 3804fd306cSNickeau * @throws ExceptionNotFound 3904fd306cSNickeau */ 4004fd306cSNickeau public function __construct($format) 4104fd306cSNickeau { 4204fd306cSNickeau $this->format = $format; 4304fd306cSNickeau $renderer = p_get_renderer($format); 4404fd306cSNickeau if (is_null($renderer)) { 4504fd306cSNickeau throw new ExceptionNotFound("No renderer was found for the format $format"); 4604fd306cSNickeau } 4704fd306cSNickeau 4804fd306cSNickeau $this->renderer = $renderer; 4904fd306cSNickeau $this->renderer->reset(); 5004fd306cSNickeau $this->renderer->smileys = getSmileys(); 5104fd306cSNickeau $this->renderer->entities = getEntities(); 5204fd306cSNickeau $this->renderer->acronyms = getAcronyms(); 5304fd306cSNickeau $this->renderer->interwiki = getInterwiki(); 5404fd306cSNickeau } 5504fd306cSNickeau 5604fd306cSNickeau /** 5704fd306cSNickeau * @throws ExceptionNotFound 5804fd306cSNickeau */ 5904fd306cSNickeau public static function create($format): MarkupDynamicRender 6004fd306cSNickeau { 6104fd306cSNickeau /** 6204fd306cSNickeau * Don't create a static object 6304fd306cSNickeau * to preserve the build because 6404fd306cSNickeau * the instructions may also recursively render. 6504fd306cSNickeau * 6604fd306cSNickeau * Therefore, a small instructions rendering such as a tooltip 6704fd306cSNickeau * would take the actual rendering and close the previous. 6804fd306cSNickeau */ 6904fd306cSNickeau return new MarkupDynamicRender($format); 7004fd306cSNickeau } 7104fd306cSNickeau 7204fd306cSNickeau public static function createXhtml(): MarkupDynamicRender 7304fd306cSNickeau { 7404fd306cSNickeau try { 7504fd306cSNickeau return self::create("xhtml"); 7604fd306cSNickeau } catch (ExceptionNotFound $e) { 7704fd306cSNickeau throw new ExceptionRuntimeInternal("xhtml should be available"); 7804fd306cSNickeau } 7904fd306cSNickeau } 8004fd306cSNickeau 8104fd306cSNickeau public function setDateAt($date_at) 8204fd306cSNickeau { 8304fd306cSNickeau if ($this->renderer instanceof \Doku_Renderer_xhtml) { 8404fd306cSNickeau $this->renderer->date_at = $date_at; 8504fd306cSNickeau } 8604fd306cSNickeau 8704fd306cSNickeau } 8804fd306cSNickeau 8904fd306cSNickeau /** 9004fd306cSNickeau * @throws ExceptionCompile 9104fd306cSNickeau * @throws ExceptionBadState 9204fd306cSNickeau */ 9304fd306cSNickeau public function processInstructions($callStackHeaderInstructions): string 9404fd306cSNickeau { 9504fd306cSNickeau 9604fd306cSNickeau try { 9704fd306cSNickeau 9804fd306cSNickeau // Loop through the instructions 9904fd306cSNickeau foreach ($callStackHeaderInstructions as $instruction) { 10004fd306cSNickeau // Execute the callback against the Renderer 10104fd306cSNickeau if (method_exists($this->renderer, $instruction[0])) { 10204fd306cSNickeau call_user_func_array(array(&$this->renderer, $instruction[0]), $instruction[1] ?: array()); 10304fd306cSNickeau } 10404fd306cSNickeau } 10504fd306cSNickeau 10604fd306cSNickeau // Post process 10704fd306cSNickeau // $data = array($this->format, & $this->renderer->doc); 10804fd306cSNickeau // \dokuwiki\Extension\Event::createAndTrigger('RENDERER_CONTENT_POSTPROCESS', $data); 109*70bbd7f1Sgerardnico $string = $this->renderer->doc; 110*70bbd7f1Sgerardnico $this->renderer->doc = ''; 111*70bbd7f1Sgerardnico return $string; 11204fd306cSNickeau 11304fd306cSNickeau } /** @noinspection PhpRedundantCatchClauseInspection */ catch (Exception $e) { 11404fd306cSNickeau /** 11504fd306cSNickeau * Example of errors; 11604fd306cSNickeau * method_exists() expects parameter 2 to be string, array given 11704fd306cSNickeau * inc\parserutils.php:672 11804fd306cSNickeau */ 11904fd306cSNickeau throw new ExceptionCompile("Error while rendering instructions. Error was: {$e->getMessage()}", "dynamic renderer", 1, $e); 12004fd306cSNickeau } 12104fd306cSNickeau } 12204fd306cSNickeau 12304fd306cSNickeau public function __toString() 12404fd306cSNickeau { 12504fd306cSNickeau return "Dynamic $this->format renderer"; 12604fd306cSNickeau } 12704fd306cSNickeau 12804fd306cSNickeau 12904fd306cSNickeau} 130