1<?php 2 3/** 4 * DokuWiki Plugin structsection (Syntax Component) 5 * 6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7 * @author Michael Große <mic.grosse@googlemail.com> 8 */ 9 10use dokuwiki\plugin\struct\meta\AccessTable; 11use dokuwiki\plugin\struct\meta\Assignments; 12use dokuwiki\plugin\struct\meta\StructException; 13 14class syntax_plugin_structsection extends \DokuWiki_Syntax_Plugin 15{ 16 protected $hasBeenRendered = false; 17 18 private const XHTML_OPEN = '<div id="plugin__structsection_output">'; 19 private const XHTML_CLOSE = '</div>'; 20 21 /** 22 * @return string Syntax mode type 23 */ 24 public function getType() 25 { 26 return 'substition'; 27 } 28 29 /** 30 * @return string Paragraph type 31 */ 32 public function getPType() 33 { 34 return 'block'; 35 } 36 37 /** 38 * @return int Sort order - Low numbers go before high numbers 39 */ 40 public function getSort() 41 { 42 return 155; 43 } 44 45 /** 46 * Connect lookup pattern to lexer. 47 * 48 * We do not connect any pattern here, because the call to this plugin is not 49 * triggered from syntax but our action component 50 * 51 * @asee action_plugin_structsection 52 * @param string $mode Parser mode 53 */ 54 public function connectTo($mode) 55 { 56 } 57 58 /** 59 * Handle matches of the struct syntax 60 * 61 * @param string $match The match of the syntax 62 * @param int $state The state of the handler 63 * @param int $pos The position in the document 64 * @param \Doku_Handler $handler The handler 65 * @return array Data for the renderer 66 */ 67 public function handle($match, $state, $pos, \Doku_Handler $handler) 68 { 69 // this is never called 70 return array(); 71 } 72 73 /** 74 * Render schema data 75 * 76 * Currently completely renderer agnostic 77 * 78 * @param string $mode Renderer mode 79 * @param \Doku_Renderer $R The renderer 80 * @param array $handlerData The data from the handler() function 81 * @return bool If rendering was successful. 82 */ 83 public function render($mode, \Doku_Renderer $R, $handlerData) 84 { 85 global $ID; 86 global $INFO; 87 global $REV; 88 if ($ID != $INFO['id']) { 89 return true; 90 } 91 if (!$INFO['exists']) { 92 return true; 93 } 94 if ($this->hasBeenRendered) { 95 return true; 96 } 97 98 // do not render the output twice on the same page, e.g. when another page has been included 99 $this->hasBeenRendered = true; 100 try { 101 $assignments = Assignments::getInstance(); 102 } catch (StructException $e) { 103 return false; 104 } 105 $tables = $assignments->getPageAssignments($ID); 106 if (!$tables) { 107 return true; 108 } 109 110 $pos = $handlerData['pos']; 111 if ($mode == 'xhtml') { 112 $R->finishSectionEdit($pos - 1); 113 $R->doc .= self::XHTML_OPEN; 114 } 115 116 117 $hasdata = false; 118 foreach ($tables as $table) { 119 try { 120 $schemadata = AccessTable::getPageAccess($table, $ID, $REV); 121 } catch (StructException $ignored) { 122 continue; // no such schema at this revision 123 } 124 $schemadata->optionSkipEmpty(false); 125 $data = $schemadata->getData(); 126 if (!count($data)) { 127 continue; 128 } 129 $hasdata = true; 130 131 foreach ($data as $field) { 132 if (!is_a($field->getColumn()->getType(), \dokuwiki\plugin\structsection\types\Section::class)) { 133 continue; 134 } 135 $lvl = 2; 136 $R->header($field->getColumn()->getTranslatedLabel(), $lvl, $pos); 137 $pos += strlen($field->getColumn()->getTranslatedLabel()); 138 $R->section_open($lvl); 139 if ($mode === 'xhtml') { 140 $structDataAttribute = 'data-struct="' . hsc($field->getColumn()->getFullQualifiedLabel()) . '"'; 141 $R->doc = substr($R->doc, 0, -2) . ' ' . $structDataAttribute . '>' . "\n"; 142 } 143 $field->render($R, $mode); 144 $R->section_close(); 145 } 146 } 147 148 if ($mode == 'xhtml') { 149 $R->finishSectionEdit($pos); 150 $R->doc .= self::XHTML_CLOSE; 151 } 152 153 // if no data has been output, remove empty wrapper again 154 if ($mode == 'xhtml' && !$hasdata) { 155 $R->doc = substr($R->doc, 0, -1 * strlen(self::XHTML_OPEN . self::XHTML_CLOSE)); 156 } 157 158 return true; 159 } 160} 161 162// vim:ts=4:sw=4:et: 163