xref: /plugin/structsection/syntax.php (revision 17c7556eb1712f494aa01ab89e613ea5944ebf08)
16b380169SMichael Große<?php
26a5d40b1SMichael Große
36b380169SMichael Große/**
4284f9fc3SMichael Große * DokuWiki Plugin structsection (Syntax Component)
56b380169SMichael Große *
66b380169SMichael Große * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
76b380169SMichael Große * @author  Michael Große <mic.grosse@googlemail.com>
86b380169SMichael Große */
96b380169SMichael Große
106b380169SMichael Großeuse dokuwiki\plugin\struct\meta\AccessTable;
116b380169SMichael Großeuse dokuwiki\plugin\struct\meta\Assignments;
126b380169SMichael Großeuse dokuwiki\plugin\struct\meta\StructException;
136b380169SMichael Große
14eadb8fe2SMichael Großeclass syntax_plugin_structsection extends \DokuWiki_Syntax_Plugin
156a5d40b1SMichael Große{
166b380169SMichael Große
176b380169SMichael Große    protected $hasBeenRendered = false;
186b380169SMichael Große
19*17c7556eSMichael Große    private const XHTML_OPEN = '<div id="plugin__structsection_output">';
20*17c7556eSMichael Große    private const XHTML_CLOSE = '</div>';
216b380169SMichael Große
226b380169SMichael Große    /**
236b380169SMichael Große     * @return string Syntax mode type
246b380169SMichael Große     */
256a5d40b1SMichael Große    public function getType()
266a5d40b1SMichael Große    {
276b380169SMichael Große        return 'substition';
286b380169SMichael Große    }
296b380169SMichael Große
306b380169SMichael Große    /**
316b380169SMichael Große     * @return string Paragraph type
326b380169SMichael Große     */
336a5d40b1SMichael Große    public function getPType()
346a5d40b1SMichael Große    {
356b380169SMichael Große        return 'block';
366b380169SMichael Große    }
376b380169SMichael Große
386b380169SMichael Große    /**
396b380169SMichael Große     * @return int Sort order - Low numbers go before high numbers
406b380169SMichael Große     */
416a5d40b1SMichael Große    public function getSort()
426a5d40b1SMichael Große    {
436b380169SMichael Große        return 155;
446b380169SMichael Große    }
456b380169SMichael Große
466b380169SMichael Große    /**
476b380169SMichael Große     * Connect lookup pattern to lexer.
486b380169SMichael Große     *
496b380169SMichael Große     * We do not connect any pattern here, because the call to this plugin is not
506b380169SMichael Große     * triggered from syntax but our action component
516b380169SMichael Große     *
52284f9fc3SMichael Große     * @asee action_plugin_structsection
536b380169SMichael Große     * @param string $mode Parser mode
546b380169SMichael Große     */
556a5d40b1SMichael Große    public function connectTo($mode)
566a5d40b1SMichael Große    {
576b380169SMichael Große    }
586b380169SMichael Große
596b380169SMichael Große    /**
606b380169SMichael Große     * Handle matches of the struct syntax
616b380169SMichael Große     *
626b380169SMichael Große     * @param string $match The match of the syntax
636b380169SMichael Große     * @param int $state The state of the handler
646b380169SMichael Große     * @param int $pos The position in the document
65eadb8fe2SMichael Große     * @param \Doku_Handler $handler The handler
666b380169SMichael Große     * @return array Data for the renderer
676b380169SMichael Große     */
68eadb8fe2SMichael Große    public function handle($match, $state, $pos, \Doku_Handler $handler)
696a5d40b1SMichael Große    {
706b380169SMichael Große        // this is never called
716b380169SMichael Große        return array();
726b380169SMichael Große    }
736b380169SMichael Große
746b380169SMichael Große    /**
756b380169SMichael Große     * Render schema data
766b380169SMichael Große     *
776b380169SMichael Große     * Currently completely renderer agnostic
786b380169SMichael Große     *
796b380169SMichael Große     * @param string $mode Renderer mode
80eadb8fe2SMichael Große     * @param \Doku_Renderer $R The renderer
816b380169SMichael Große     * @param array $handlerData The data from the handler() function
826b380169SMichael Große     * @return bool If rendering was successful.
836b380169SMichael Große     */
84eadb8fe2SMichael Große    public function render($mode, \Doku_Renderer $R, $handlerData)
856a5d40b1SMichael Große    {
866b380169SMichael Große        global $ID;
876b380169SMichael Große        global $INFO;
886b380169SMichael Große        global $REV;
896a5d40b1SMichael Große        if ($ID != $INFO['id']) {
906a5d40b1SMichael Große            return true;
916a5d40b1SMichael Große        }
926a5d40b1SMichael Große        if (!$INFO['exists']) {
936a5d40b1SMichael Große            return true;
946a5d40b1SMichael Große        }
956a5d40b1SMichael Große        if ($this->hasBeenRendered) {
966a5d40b1SMichael Große            return true;
976a5d40b1SMichael Große        }
986b380169SMichael Große
996b380169SMichael Große        // do not render the output twice on the same page, e.g. when another page has been included
1006b380169SMichael Große        $this->hasBeenRendered = true;
1016b380169SMichael Große        try {
1026b380169SMichael Große            $assignments = Assignments::getInstance();
1036b380169SMichael Große        } catch (StructException $e) {
1046b380169SMichael Große            return false;
1056b380169SMichael Große        }
1066b380169SMichael Große        $tables = $assignments->getPageAssignments($ID);
1076a5d40b1SMichael Große        if (!$tables) {
1086a5d40b1SMichael Große            return true;
1096a5d40b1SMichael Große        }
1106b380169SMichael Große
1116b380169SMichael Große        $pos = $handlerData['pos'];
1126b380169SMichael Große        if ($mode == 'xhtml') {
1136b380169SMichael Große            $R->finishSectionEdit($pos - 1);
1146b380169SMichael Große            $R->doc .= self::XHTML_OPEN;
1156b380169SMichael Große        }
1166b380169SMichael Große
1176b380169SMichael Große
1186b380169SMichael Große        $hasdata = false;
1196b380169SMichael Große        foreach ($tables as $table) {
1206b380169SMichael Große            try {
121cb058b5aSMichael Große                $schemadata = AccessTable::getPageAccess($table, $ID, $REV);
1226b380169SMichael Große            } catch (StructException $ignored) {
1236b380169SMichael Große                continue; // no such schema at this revision
1246b380169SMichael Große            }
1256b380169SMichael Große            $schemadata->optionSkipEmpty(false);
1266b380169SMichael Große            $data = $schemadata->getData();
1276a5d40b1SMichael Große            if (!count($data)) {
1286a5d40b1SMichael Große                continue;
1296a5d40b1SMichael Große            }
1306b380169SMichael Große            $hasdata = true;
1316b380169SMichael Große
1326b380169SMichael Große            foreach ($data as $field) {
133284f9fc3SMichael Große                if (!is_a($field->getColumn()->getType(), \dokuwiki\plugin\structsection\types\Section::class)) {
1346b380169SMichael Große                    continue;
1356b380169SMichael Große                }
1366b380169SMichael Große                $lvl = 2;
1376b380169SMichael Große                $R->header($field->getColumn()->getTranslatedLabel(), $lvl, $pos);
1386b380169SMichael Große                $pos += strlen($field->getColumn()->getTranslatedLabel());
1396b380169SMichael Große                $R->section_open($lvl);
1406b380169SMichael Große                if ($mode === 'xhtml') {
14127fdceffSMichael Große                    $structDataAttribute = 'data-struct="' . hsc($field->getColumn()->getFullQualifiedLabel()) . '"';
14227fdceffSMichael Große                    $R->doc = substr($R->doc, 0, -2) . ' ' . $structDataAttribute . '>' . "\n";
1436b380169SMichael Große                }
1446b380169SMichael Große                $field->render($R, $mode);
1456b380169SMichael Große                $R->section_close();
1466b380169SMichael Große            }
1476b380169SMichael Große        }
1486b380169SMichael Große
1496b380169SMichael Große        if ($mode == 'xhtml') {
1506b380169SMichael Große            $R->finishSectionEdit($pos);
1516b380169SMichael Große            $R->doc .= self::XHTML_CLOSE;
1526b380169SMichael Große        }
1536b380169SMichael Große
1546b380169SMichael Große        // if no data has been output, remove empty wrapper again
1556b380169SMichael Große        if ($mode == 'xhtml' && !$hasdata) {
1566b380169SMichael Große            $R->doc = substr($R->doc, 0, -1 * strlen(self::XHTML_OPEN . self::XHTML_CLOSE));
1576b380169SMichael Große        }
1586b380169SMichael Große
1596b380169SMichael Große        return true;
1606b380169SMichael Große    }
1616b380169SMichael Große}
1626b380169SMichael Große
1636b380169SMichael Große// vim:ts=4:sw=4:et:
164