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