1257dd7f8SAndreas Gohr<?php 2d6d97f60SAnna Dabrowska 3257dd7f8SAndreas Gohr/** 4257dd7f8SAndreas Gohr * DokuWiki Plugin struct (Syntax Component) 5257dd7f8SAndreas Gohr * 6257dd7f8SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7257dd7f8SAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 8257dd7f8SAndreas Gohr */ 9257dd7f8SAndreas Gohr 10fa5b7b69SAndreas Gohruse dokuwiki\plugin\struct\meta\Value; 117234bfb1Ssplitbrainuse dokuwiki\Extension\SyntaxPlugin; 127234bfb1Ssplitbrainuse dokuwiki\Extension\Event; 13f411d872SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable; 14ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments; 157cbcfbdbSAndreas Gohruse dokuwiki\plugin\struct\meta\StructException; 16257dd7f8SAndreas Gohr 177234bfb1Ssplitbrainclass syntax_plugin_struct_output extends SyntaxPlugin 18d6d97f60SAnna Dabrowska{ 1987050b53SMichael Grosse protected $hasBeenRendered = false; 2087050b53SMichael Grosse 2117a3a578SAndreas Gohr protected const XHTML_OPEN = '<div id="plugin__struct_output">'; 2217a3a578SAndreas Gohr protected const XHTML_CLOSE = '</div>'; 237938ca48SAndreas Gohr 24257dd7f8SAndreas Gohr /** 25979b16f8SAndreas Gohr * Regexp to check on which actions the struct data may be rendered 26979b16f8SAndreas Gohr */ 2717a3a578SAndreas Gohr protected const WHITELIST_ACTIONS = '/^(show|export_.*)$/'; 28979b16f8SAndreas Gohr 29979b16f8SAndreas Gohr /** 30257dd7f8SAndreas Gohr * @return string Syntax mode type 31257dd7f8SAndreas Gohr */ 32d6d97f60SAnna Dabrowska public function getType() 33d6d97f60SAnna Dabrowska { 34257dd7f8SAndreas Gohr return 'substition'; 35257dd7f8SAndreas Gohr } 36da30fdd3SAndreas Gohr 37257dd7f8SAndreas Gohr /** 38257dd7f8SAndreas Gohr * @return string Paragraph type 39257dd7f8SAndreas Gohr */ 40d6d97f60SAnna Dabrowska public function getPType() 41d6d97f60SAnna Dabrowska { 42257dd7f8SAndreas Gohr return 'block'; 43257dd7f8SAndreas Gohr } 44da30fdd3SAndreas Gohr 45257dd7f8SAndreas Gohr /** 46257dd7f8SAndreas Gohr * @return int Sort order - Low numbers go before high numbers 47257dd7f8SAndreas Gohr */ 48d6d97f60SAnna Dabrowska public function getSort() 49d6d97f60SAnna Dabrowska { 50257dd7f8SAndreas Gohr return 155; 51257dd7f8SAndreas Gohr } 52257dd7f8SAndreas Gohr 53257dd7f8SAndreas Gohr /** 54257dd7f8SAndreas Gohr * Connect lookup pattern to lexer. 55257dd7f8SAndreas Gohr * 5682c064c1SAndreas Gohr * We do not connect any pattern here, because the call to this plugin is not 5782c064c1SAndreas Gohr * triggered from syntax but our action component 5882c064c1SAndreas Gohr * 5982c064c1SAndreas Gohr * @asee action_plugin_struct_output 60257dd7f8SAndreas Gohr * @param string $mode Parser mode 61257dd7f8SAndreas Gohr */ 62d6d97f60SAnna Dabrowska public function connectTo($mode) 63d6d97f60SAnna Dabrowska { 64257dd7f8SAndreas Gohr } 65257dd7f8SAndreas Gohr 66257dd7f8SAndreas Gohr /** 67257dd7f8SAndreas Gohr * Handle matches of the struct syntax 68257dd7f8SAndreas Gohr * 69257dd7f8SAndreas Gohr * @param string $match The match of the syntax 70257dd7f8SAndreas Gohr * @param int $state The state of the handler 71257dd7f8SAndreas Gohr * @param int $pos The position in the document 72257dd7f8SAndreas Gohr * @param Doku_Handler $handler The handler 73257dd7f8SAndreas Gohr * @return array Data for the renderer 74257dd7f8SAndreas Gohr */ 75d6d97f60SAnna Dabrowska public function handle($match, $state, $pos, Doku_Handler $handler) 76d6d97f60SAnna Dabrowska { 7782c064c1SAndreas Gohr // this is never called 787234bfb1Ssplitbrain return []; 79257dd7f8SAndreas Gohr } 80257dd7f8SAndreas Gohr 81257dd7f8SAndreas Gohr /** 8282c064c1SAndreas Gohr * Render schema data 83257dd7f8SAndreas Gohr * 84564e138bSAnna Dabrowska * Currently completely renderer agnostic 8582c064c1SAndreas Gohr * 8634ea6e10SAnna Dabrowska * @param string $format Renderer format 8734ea6e10SAnna Dabrowska * @param Doku_Renderer $renderer The renderer 88257dd7f8SAndreas Gohr * @param array $data The data from the handler() function 89257dd7f8SAndreas Gohr * @return bool If rendering was successful. 90257dd7f8SAndreas Gohr */ 9134ea6e10SAnna Dabrowska public function render($format, Doku_Renderer $renderer, $data) 92d6d97f60SAnna Dabrowska { 930e4a3e7cSMichael Große global $ACT; 94257dd7f8SAndreas Gohr global $ID; 9582c064c1SAndreas Gohr global $INFO; 96257dd7f8SAndreas Gohr global $REV; 97bdefb930SAnna Dabrowska 9834ea6e10SAnna Dabrowska foreach (helper_plugin_struct::BLACKLIST_RENDERER as $blacklisted) { 9934ea6e10SAnna Dabrowska if ($renderer instanceof $blacklisted) { 1000e4a3e7cSMichael Große return true; 1010e4a3e7cSMichael Große } 102bdefb930SAnna Dabrowska } 103be4dde77SAndreas Gohr if (!isset($INFO['id']) || ($ID != $INFO['id'])) return true; 1042f1a213bSAndreas Gohr if (!$INFO['exists']) return true; 10587050b53SMichael Grosse if ($this->hasBeenRendered) return true; 106979b16f8SAndreas Gohr if (!preg_match(self::WHITELIST_ACTIONS, act_clean($ACT))) return true; 10787050b53SMichael Grosse 10887050b53SMichael Grosse // do not render the output twice on the same page, e.g. when another page has been included 10987050b53SMichael Grosse $this->hasBeenRendered = true; 1107cbcfbdbSAndreas Gohr try { 111025cb9daSAndreas Gohr $assignments = Assignments::getInstance(); 1127cbcfbdbSAndreas Gohr } catch (StructException $e) { 1137cbcfbdbSAndreas Gohr return false; 1147cbcfbdbSAndreas Gohr } 115257dd7f8SAndreas Gohr $tables = $assignments->getPageAssignments($ID); 116257dd7f8SAndreas Gohr if (!$tables) return true; 117257dd7f8SAndreas Gohr 11834ea6e10SAnna Dabrowska if ($format == 'xhtml') $renderer->doc .= self::XHTML_OPEN; 1195a1eab78SAndreas Gohr 1207938ca48SAndreas Gohr $hasdata = false; 121257dd7f8SAndreas Gohr foreach ($tables as $table) { 122a28d6152SAndreas Gohr try { 1234cd5cc28SAnna Dabrowska $schemadata = AccessTable::getPageAccess($table, $ID, (int)$REV); 124a28d6152SAndreas Gohr } catch (StructException $ignored) { 125a28d6152SAndreas Gohr continue; // no such schema at this revision 126a28d6152SAndreas Gohr } 127b1ab837dSFrieder Schrempf 1287fe2cdf2SAndreas Gohr $rendercontext = [ 1297fe2cdf2SAndreas Gohr 'renderer' => $renderer, 1307fe2cdf2SAndreas Gohr 'format' => $format, 1317fe2cdf2SAndreas Gohr 'meta' => p_get_metadata($ID), 1327fe2cdf2SAndreas Gohr 'schemadata' => $schemadata, 1337fe2cdf2SAndreas Gohr 'hasdata' => &$hasdata 1347fe2cdf2SAndreas Gohr ]; 135b1ab837dSFrieder Schrempf 1367234bfb1Ssplitbrain $event = new Event( 137b1ab837dSFrieder Schrempf 'PLUGIN_STRUCT_RENDER_SCHEMA_DATA', 1382dbe71f8SAnna Dabrowska $rendercontext 139b1ab837dSFrieder Schrempf ); 1402dbe71f8SAnna Dabrowska $event->trigger([$this, 'renderSchemaData']); 141b1ab837dSFrieder Schrempf } 142b1ab837dSFrieder Schrempf 143b1ab837dSFrieder Schrempf if ($format == 'xhtml') $renderer->doc .= self::XHTML_CLOSE; 144b1ab837dSFrieder Schrempf 145b1ab837dSFrieder Schrempf // if no data has been output, remove empty wrapper again 146b1ab837dSFrieder Schrempf if ($format == 'xhtml' && !$hasdata) { 147b1ab837dSFrieder Schrempf $renderer->doc = substr($renderer->doc, 0, -1 * strlen(self::XHTML_OPEN . self::XHTML_CLOSE)); 148b1ab837dSFrieder Schrempf } 149b1ab837dSFrieder Schrempf 150b1ab837dSFrieder Schrempf return true; 151b1ab837dSFrieder Schrempf } 152b1ab837dSFrieder Schrempf 153b1ab837dSFrieder Schrempf /** 154b1ab837dSFrieder Schrempf * Default schema data rendering (simple table view) 155b1ab837dSFrieder Schrempf * 156b1ab837dSFrieder Schrempf * @param array The render context including renderer and data 157b1ab837dSFrieder Schrempf */ 158b1ab837dSFrieder Schrempf public function renderSchemaData($rendercontext) 159b1ab837dSFrieder Schrempf { 160b1ab837dSFrieder Schrempf $schemadata = $rendercontext['schemadata']; 161b1ab837dSFrieder Schrempf $renderer = $rendercontext['renderer']; 162b1ab837dSFrieder Schrempf $format = $rendercontext['format']; 163b1ab837dSFrieder Schrempf 1640dd23cefSAndreas Gohr $schemadata->optionSkipEmpty(true); 1650dd23cefSAndreas Gohr $data = $schemadata->getData(); 166b1ab837dSFrieder Schrempf if (!count($data)) 167b1ab837dSFrieder Schrempf return; 168b1ab837dSFrieder Schrempf 169b1ab837dSFrieder Schrempf $rendercontext['hasdata'] = true; 170257dd7f8SAndreas Gohr 1713f594db8SAndreas Gohr if ($format == 'xhtml') { 1723f594db8SAndreas Gohr $renderer->doc .= '<div class="struct_output_' . $schemadata->getSchema()->getTable() . '">'; 1733f594db8SAndreas Gohr } 1743f594db8SAndreas Gohr 17534ea6e10SAnna Dabrowska $renderer->table_open(); 17634ea6e10SAnna Dabrowska $renderer->tablethead_open(); 17734ea6e10SAnna Dabrowska $renderer->tablerow_open(); 17834ea6e10SAnna Dabrowska $renderer->tableheader_open(2); 17934ea6e10SAnna Dabrowska $renderer->cdata($schemadata->getSchema()->getTranslatedLabel()); 18034ea6e10SAnna Dabrowska $renderer->tableheader_close(); 18134ea6e10SAnna Dabrowska $renderer->tablerow_close(); 18234ea6e10SAnna Dabrowska $renderer->tablethead_close(); 183da30fdd3SAndreas Gohr 18434ea6e10SAnna Dabrowska $renderer->tabletbody_open(); 185257dd7f8SAndreas Gohr foreach ($data as $field) { 186fa5b7b69SAndreas Gohr /** @var Value $field */ 18734ea6e10SAnna Dabrowska $renderer->tablerow_open(); 188fa5b7b69SAndreas Gohr if ($format == 'xhtml') { 189fa5b7b69SAndreas Gohr // add data attributes to the row for inline editing 190fa5b7b69SAndreas Gohr $renderer->doc = substr(trim($renderer->doc), 0, -1); // remove the last > 191fa5b7b69SAndreas Gohr $renderer->doc .= ' data-pid="' . hsc($schemadata->getPid()) . '"'; 192*35b9b794SAndreas Gohr $renderer->doc .= ' data-rev="' . hsc($schemadata->getTimestamp()) . '"'; 193fa5b7b69SAndreas Gohr $renderer->doc .= ' data-rid="' . hsc($schemadata->getRid()) . '"'; 194fa5b7b69SAndreas Gohr $renderer->doc .= ' data-field="' . hsc($field->getColumn()->getFullQualifiedLabel()) . '"'; 1953235fa1cSSzymon Olewniczak $renderer->doc .= '>'; 196fa5b7b69SAndreas Gohr } 197fa5b7b69SAndreas Gohr 19834ea6e10SAnna Dabrowska $renderer->tableheader_open(); 19934ea6e10SAnna Dabrowska $renderer->cdata($field->getColumn()->getTranslatedLabel()); 20034ea6e10SAnna Dabrowska $renderer->tableheader_close(); 20134ea6e10SAnna Dabrowska $renderer->tablecell_open(); 20234ea6e10SAnna Dabrowska if ($format == 'xhtml') { 20334ea6e10SAnna Dabrowska $renderer->doc = substr($renderer->doc, 0, -1) . 204748e747fSAnna Dabrowska ' data-struct="' . hsc($field->getColumn()->getFullQualifiedLabel()) . 205748e747fSAnna Dabrowska '">'; 20625852712SAndreas Gohr } 20734ea6e10SAnna Dabrowska $field->render($renderer, $format); 20834ea6e10SAnna Dabrowska $renderer->tablecell_close(); 20934ea6e10SAnna Dabrowska $renderer->tablerow_close(); 210257dd7f8SAndreas Gohr } 21134ea6e10SAnna Dabrowska $renderer->tabletbody_close(); 21234ea6e10SAnna Dabrowska $renderer->table_close(); 2133f594db8SAndreas Gohr 2143f594db8SAndreas Gohr if ($format == 'xhtml') { 2153f594db8SAndreas Gohr $renderer->doc .= '</div>'; 2163f594db8SAndreas Gohr } 217da30fdd3SAndreas Gohr } 218257dd7f8SAndreas Gohr} 219257dd7f8SAndreas Gohr 220257dd7f8SAndreas Gohr// vim:ts=4:sw=4:et: 221