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