1<?php
2/**
3 * DokuWiki Plugin structstatus (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  A <gohr@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12class syntax_plugin_structstatus extends DokuWiki_Syntax_Plugin {
13    /**
14     * @return string Syntax mode type
15     */
16    public function getType() {
17        return 'substition';
18    }
19
20    /**
21     * @return string Paragraph type
22     */
23    public function getPType() {
24        return 'block';
25    }
26
27    /**
28     * @return int Sort order - Low numbers go before high numbers
29     */
30    public function getSort() {
31        return 155;
32    }
33
34    /**
35     * Connect lookup pattern to lexer.
36     *
37     * @param string $mode Parser mode
38     */
39    public function connectTo($mode) {
40        $this->Lexer->addSpecialPattern('{{struct-status>.*?}}', $mode, 'plugin_structstatus');
41    }
42
43    /**
44     * Handle matches of the structstatus syntax
45     *
46     * @param string $match The match of the syntax
47     * @param int $state The state of the handler
48     * @param int $pos The position in the document
49     * @param Doku_Handler $handler The handler
50     * @return array Data for the renderer
51     */
52    public function handle($match, $state, $pos, Doku_Handler $handler) {
53        $match = trim(substr($match, 16, -2));
54        list($table, $column) = explode('.', $match, 2);
55        return array($table, $column);
56    }
57
58    /**
59     * Render xhtml output or metadata
60     *
61     * @param string $mode Renderer mode (supported modes: xhtml)
62     * @param Doku_Renderer $renderer The renderer
63     * @param array $data The data from the handler() function
64     * @return bool If rendering was successful.
65     */
66    public function render($mode, Doku_Renderer $renderer, $data) {
67        if($mode != 'xhtml') return false;
68
69        $renderer->doc .= $this->tpl($data[0], $data[1]);
70
71        return true;
72    }
73
74    /**
75     * @param string $table
76     * @param string $field
77     * @return string
78     */
79    public function tpl($table, $field) {
80        global $INFO;
81        $id = $INFO['id'];
82        if( // abort early
83            blank($id) ||
84            blank($table) ||
85            blank($field) ||
86            is_null(plugin_load('helper', 'sqlite')) ||
87            is_null(plugin_load('helper', 'struct_db'))
88        ) return '';
89
90        // check if page has this schema
91        $assignments = \dokuwiki\plugin\struct\meta\Assignments::getInstance();
92        if(!in_array($table, $assignments->getPageAssignments($id))) return '';
93
94        // check if schema exists
95        $access = \dokuwiki\plugin\struct\meta\AccessTable::getPageAccess($table, $id);
96        $schema = $access->getSchema();
97        if(!$schema->getId()) return '';
98
99        // get the column
100        $col = $schema->findColumn($field);
101        if(!$col) return '';
102
103        // make sure its the correct type
104        /** @var  \dokuwiki\plugin\structstatus\Status $type */
105        $type = $col->getType();
106        if(!is_a($type, \dokuwiki\plugin\structstatus\Status::class)) {
107            msg(hsc("$table.$field is not a Status field"), -1);
108            return '';
109        }
110
111        // get current value
112        $rids = (array) $access->getDataColumn($col)->getRawValue();
113
114        // add meta data when writable
115        $args = array(
116            'class' => 'structstatus-full',
117        );
118        if(auth_quickaclcheck($id) >= AUTH_EDIT && $schema->isEditable()) {
119            $args['data-multi'] = (int) $type->isMulti();
120            $args['data-st'] = getSecurityToken();
121            $args['data-field'] = $col->getFullQualifiedLabel();
122            $args['data-page'] = $id;
123            $args['data-rev'] = time();
124            $args['data-rid'] = implode(',', $rids); // FIXME this is wrong for multi fields in the widget?
125            $args['class'] .= ' editable';
126        }
127
128        // output
129        $html = '<div ' . buildAttributes($args) . '>';
130        foreach($type->getAllStatuses() as $status) {
131            $color = $status['color'];
132            if(in_array($status['rid'], $rids)) {
133                $class = array();
134            } else {
135                $class = array('disabled');
136            }
137            $html .= $type->xhtmlStatus($status['label'], $color, $status['icon'], $status['rid'], $class, true);
138        }
139        $html .= '</div>';
140
141        return $html;
142    }
143
144}
145
146// vim:ts=4:sw=4:et:
147