xref: /plugin/struct/action/edit.php (revision 733a4e9b074e8494f45189eb3600e4c98abd0940)
1<?php
2/**
3 * DokuWiki Plugin struct (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12use dokuwiki\plugin\struct\meta\AccessTable;
13use dokuwiki\plugin\struct\meta\Assignments;
14use dokuwiki\plugin\struct\meta\Value;
15
16/**
17 * Class action_plugin_struct_entry
18 *
19 * Handles adding struct forms to the default editor
20 */
21class action_plugin_struct_edit extends DokuWiki_Action_Plugin {
22
23    /**
24     * @var string The form name we use to transfer schema data
25     */
26    protected static $VAR = 'struct_schema_data';
27
28    /**
29     * Registers a callback function for a given event
30     *
31     * @param Doku_Event_Handler $controller DokuWiki's event controller object
32     * @return void
33     */
34    public function register(Doku_Event_Handler $controller) {
35        // add the struct editor to the edit form;
36        $controller->register_hook('HTML_EDITFORM_OUTPUT', 'BEFORE', $this, 'handle_editform');
37    }
38
39    /**
40     * Enhance the editing form with structural data editing
41     *
42     * @param Doku_Event $event event object by reference
43     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
44     *                           handler was registered]
45     * @return bool
46     */
47    public function handle_editform(Doku_Event $event, $param) {
48        global $ID;
49
50        $assignments = Assignments::getInstance();
51        $tables = $assignments->getPageAssignments($ID);
52
53        $html = '';
54        foreach($tables as $table) {
55            $html .= $this->createForm($table);
56        }
57
58        /** @var Doku_Form $form */
59        $form = $event->data;
60        $html = "<div class=\"struct_entry_form\">$html</div>";
61        $pos = $form->findElementById('wiki__editbar'); // insert the form before the main buttons
62        $form->insertElement($pos, $html);
63
64        return true;
65    }
66
67    /**
68     * Create the form to edit schemadata
69     *
70     * @param string $tablename
71     * @return string The HTML for this schema's form
72     */
73    protected function createForm($tablename) {
74        global $ID;
75        global $REV;
76        global $INPUT;
77        if(auth_quickaclcheck($ID) == AUTH_READ) return '';
78        if(checklock($ID)) return '';
79        $schema = AccessTable::byTableName($tablename, $ID, $REV);
80        if(!$schema->getSchema()->isEditable()) {
81            return '';
82        }
83        $schemadata = $schema->getData();
84
85        $structdata = $INPUT->arr(self::$VAR);
86        if(isset($structdata[$tablename])) {
87            $postdata = $structdata[$tablename];
88        } else {
89            $postdata = array();
90        }
91
92        // we need a short, unique identifier to use in the cookie. this should be good enough
93        $schemaid = 'SRCT' . substr(str_replace(array('+', '/'), '', base64_encode(sha1($tablename, true))), 0, 5);
94        $html = '<fieldset data-schema="' . $schemaid . '">';
95        $html .= '<legend>' . hsc($schema->getSchema()->getTranslatedLabel()) . '</legend>';
96        foreach($schemadata as $field) {
97            $label = $field->getColumn()->getLabel();
98            if(isset($postdata[$label])) {
99                // posted data trumps stored data
100                $data = $postdata[$label];
101                if (is_array($data)) {
102                    $data = array_map("cleanText", $data);
103                } else {
104                    $data = cleanText($data);
105                }
106                $field->setValue($data, true);
107            }
108            $html .= $this->makeField($field, self::$VAR . "[$tablename][$label]");
109        }
110        $html .= '</fieldset>';
111
112        return $html;
113    }
114
115    /**
116     * Create the input field
117     *
118     * @param Value $field
119     * @param String $name field's name
120     * @return string
121     */
122    public function makeField(Value $field, $name) {
123        $trans = hsc($field->getColumn()->getTranslatedLabel());
124        $hint = hsc($field->getColumn()->getTranslatedHint());
125        $class = $hint ? 'hashint' : '';
126        $colname = $field->getColumn()->getFullQualifiedLabel();
127
128        $id = uniqid('struct__', false);
129        $input = $field->getValueEditor($name, $id);
130
131        // we keep all the custom form stuff the field might produce, but hide it
132        if(!$field->getColumn()->isVisibleInEditor()) {
133            $hide = 'style="display:none"';
134        } else {
135            $hide = '';
136        }
137
138        $html = '<div class="field">';
139        $html .= "<label $hide data-column=\"$colname\" for=\"$id\">";
140        $html .= "<span class=\"label $class\" title=\"$hint\">$trans</span>";
141        $html .= '</label>';
142        $html .= "<span class=\"input\">$input</span>";
143        $html .= '</div>';
144
145        return $html;
146    }
147}
148
149// vim:ts=4:sw=4:et:
150