1<?php 2 3namespace ComboStrap; 4 5use Doku_Renderer; 6use PHPUnit\Exception; 7 8/** 9 * 10 * Adaptation of the function {@link p_render()} 11 * for dynamic rendering because the {@link \Doku_Renderer_xhtml Renderer} has also state 12 * such as the `counter_row` for the function {@link \Doku_Renderer_xhtml::table_open()} 13 * 14 * If {@link p_render()} is used multiple time, the renderer is recreated and the counter is reset to zero and the 15 * row of each table is lost. 16 * 17 */ 18class MarkupDynamicRender 19{ 20 /** 21 * @var MarkupDynamicRender[] 22 */ 23 static array $DYNAMIC_RENDERERS_CACHE = array(); 24 25 26 /** 27 * @var string the format (xhtml, ...) 28 */ 29 private string $format; 30 31 32 /** 33 * @var Doku_Renderer the renderer that calls the render function 34 */ 35 private Doku_Renderer $renderer; 36 37 /** 38 * @throws ExceptionNotFound 39 */ 40 public function __construct($format) 41 { 42 $this->format = $format; 43 $renderer = p_get_renderer($format); 44 if (is_null($renderer)) { 45 throw new ExceptionNotFound("No renderer was found for the format $format"); 46 } 47 48 $this->renderer = $renderer; 49 $this->renderer->reset(); 50 $this->renderer->smileys = getSmileys(); 51 $this->renderer->entities = getEntities(); 52 $this->renderer->acronyms = getAcronyms(); 53 $this->renderer->interwiki = getInterwiki(); 54 } 55 56 /** 57 * @throws ExceptionNotFound 58 */ 59 public static function create($format): MarkupDynamicRender 60 { 61 /** 62 * Don't create a static object 63 * to preserve the build because 64 * the instructions may also recursively render. 65 * 66 * Therefore, a small instructions rendering such as a tooltip 67 * would take the actual rendering and close the previous. 68 */ 69 return new MarkupDynamicRender($format); 70 } 71 72 public static function createXhtml(): MarkupDynamicRender 73 { 74 try { 75 return self::create("xhtml"); 76 } catch (ExceptionNotFound $e) { 77 throw new ExceptionRuntimeInternal("xhtml should be available"); 78 } 79 } 80 81 public function setDateAt($date_at) 82 { 83 if ($this->renderer instanceof \Doku_Renderer_xhtml) { 84 $this->renderer->date_at = $date_at; 85 } 86 87 } 88 89 /** 90 * @throws ExceptionCompile 91 * @throws ExceptionBadState 92 */ 93 public function processInstructions($callStackHeaderInstructions): string 94 { 95 96 try { 97 98 // Loop through the instructions 99 foreach ($callStackHeaderInstructions as $instruction) { 100 // Execute the callback against the Renderer 101 if (method_exists($this->renderer, $instruction[0])) { 102 call_user_func_array(array(&$this->renderer, $instruction[0]), $instruction[1] ?: array()); 103 } 104 } 105 106 // Post process 107 // $data = array($this->format, & $this->renderer->doc); 108 // \dokuwiki\Extension\Event::createAndTrigger('RENDERER_CONTENT_POSTPROCESS', $data); 109 $string = $this->renderer->doc; 110 $this->renderer->doc = ''; 111 return $string; 112 113 } /** @noinspection PhpRedundantCatchClauseInspection */ catch (Exception $e) { 114 /** 115 * Example of errors; 116 * method_exists() expects parameter 2 to be string, array given 117 * inc\parserutils.php:672 118 */ 119 throw new ExceptionCompile("Error while rendering instructions. Error was: {$e->getMessage()}", "dynamic renderer", 1, $e); 120 } 121 } 122 123 public function __toString() 124 { 125 return "Dynamic $this->format renderer"; 126 } 127 128 129} 130