xref: /plugin/struct/action/entry.php (revision 17560ecbb3470cf2f90ee861205d92f6adf36b5b)
1549a0837SAndreas Gohr<?php
2549a0837SAndreas Gohr/**
3549a0837SAndreas Gohr * DokuWiki Plugin struct (Action Component)
4549a0837SAndreas Gohr *
5549a0837SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6549a0837SAndreas Gohr * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
7549a0837SAndreas Gohr */
8549a0837SAndreas Gohr
9549a0837SAndreas Gohr// must be run within Dokuwiki
10549a0837SAndreas Gohrif(!defined('DOKU_INC')) die();
11549a0837SAndreas Gohr
12fb31ca9fSAndreas Gohruse plugin\struct\meta\Assignments;
13c2fd0bf0SMichael Großeuse plugin\struct\meta\SchemaData;
14*17560ecbSAndreas Gohruse plugin\struct\meta\ValidationException;
15*17560ecbSAndreas Gohruse plugin\struct\types\AbstractBaseType;
16c2fd0bf0SMichael Große
17549a0837SAndreas Gohrclass action_plugin_struct_entry extends DokuWiki_Action_Plugin {
18549a0837SAndreas Gohr
19*17560ecbSAndreas Gohr    /**
20*17560ecbSAndreas Gohr     * @var string The form name we use to transfer schema data
21*17560ecbSAndreas Gohr     */
22*17560ecbSAndreas Gohr    protected static $VAR = 'struct_schema_data';
23c2fd0bf0SMichael Große
24c2fd0bf0SMichael Große    /** @var helper_plugin_sqlite */
25c2fd0bf0SMichael Große    protected $sqlite;
26c2fd0bf0SMichael Große
27549a0837SAndreas Gohr    /**
28549a0837SAndreas Gohr     * Registers a callback function for a given event
29549a0837SAndreas Gohr     *
30549a0837SAndreas Gohr     * @param Doku_Event_Handler $controller DokuWiki's event controller object
31549a0837SAndreas Gohr     * @return void
32549a0837SAndreas Gohr     */
33549a0837SAndreas Gohr    public function register(Doku_Event_Handler $controller) {
34549a0837SAndreas Gohr
35c2fd0bf0SMichael Große        $controller->register_hook('HTML_EDITFORM_OUTPUT', 'BEFORE', $this, 'handle_editform');
3604641d56SMichael Große        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_pagesave');
37549a0837SAndreas Gohr
38549a0837SAndreas Gohr    }
39549a0837SAndreas Gohr
40549a0837SAndreas Gohr    /**
41*17560ecbSAndreas Gohr     * Validate the input data and save on ACT=save.
4204641d56SMichael Große     *
4304641d56SMichael Große     * @param Doku_Event $event event object by reference
4404641d56SMichael Große     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
4504641d56SMichael Große     *                           handler was registered]
4604641d56SMichael Große     * @return bool
4704641d56SMichael Große     */
4804641d56SMichael Große    public function handle_pagesave(Doku_Event &$event, $param) {
493ece9074SMichael Große        global $ID, $INPUT;
50*17560ecbSAndreas Gohr        $act = act_clean($event->data);
51*17560ecbSAndreas Gohr        if(!in_array($act, array('save', 'preview'))) return false;
5204641d56SMichael Große
53a8b9fb5bSAndreas Gohr        $assignments = new Assignments();
54a8b9fb5bSAndreas Gohr        $tables = $assignments->getPageAssignments($ID);
55*17560ecbSAndreas Gohr        $structData = $INPUT->arr(self::$VAR);
56bd92cd68SAndreas Gohr        $timestamp = time(); //FIXME we should use the time stamp used to save the page data
5704641d56SMichael Große
58*17560ecbSAndreas Gohr        $ok = true;
5904641d56SMichael Große        foreach($tables as $table) {
6004641d56SMichael Große            $schema = new SchemaData($table, $ID, $timestamp);
61bd92cd68SAndreas Gohr            if(!$schema->getId()) {
62bd92cd68SAndreas Gohr                // this schema is not available for some reason. skip it
63bd92cd68SAndreas Gohr                continue;
64bd92cd68SAndreas Gohr            }
65bd92cd68SAndreas Gohr
6604641d56SMichael Große            $schemaData = $structData[$table];
6704641d56SMichael Große            foreach($schema->getColumns() as $col) {
68*17560ecbSAndreas Gohr                // fix multi value types
69afbd4e60SMichael Große                $type = $col->getType();
70afbd4e60SMichael Große                $label = $type->getLabel();
71*17560ecbSAndreas Gohr                $trans = $type->getTranslatedLabel();
72afbd4e60SMichael Große                if($type->isMulti() && !is_array($schemaData[$label])) {
73afbd4e60SMichael Große                    $schemaData[$label] = $type->splitValues($schemaData[$label]);
7404641d56SMichael Große                }
75*17560ecbSAndreas Gohr
76*17560ecbSAndreas Gohr                // validate data
77*17560ecbSAndreas Gohr                $ok = $ok & $this->validate($type, $trans, $schemaData[$label]);
7804641d56SMichael Große            }
79*17560ecbSAndreas Gohr
80*17560ecbSAndreas Gohr            // save if validated okay
81*17560ecbSAndreas Gohr            if($ok && $act == 'save') {
8204641d56SMichael Große                $schema->saveData($schemaData);
8304641d56SMichael Große            }
84*17560ecbSAndreas Gohr
85*17560ecbSAndreas Gohr            // write back cleaned up schemaData
86*17560ecbSAndreas Gohr            $structData[$table] = $schemaData;
87*17560ecbSAndreas Gohr        }
88*17560ecbSAndreas Gohr        // write back cleaned up structData
89*17560ecbSAndreas Gohr        $INPUT->post->set('Schema', $structData);
90*17560ecbSAndreas Gohr
91*17560ecbSAndreas Gohr        // did validation go through? other wise abort saving
92*17560ecbSAndreas Gohr        if(!$ok && $act == 'save') {
93*17560ecbSAndreas Gohr            $event->data = 'edit';
94*17560ecbSAndreas Gohr        }
95*17560ecbSAndreas Gohr
9604641d56SMichael Große        return false;
9704641d56SMichael Große    }
9804641d56SMichael Große
99*17560ecbSAndreas Gohr    /**
100*17560ecbSAndreas Gohr     * Validate the given data
101*17560ecbSAndreas Gohr     *
102*17560ecbSAndreas Gohr     * Catches the Validation exceptions and transforms them into proper messages.
103*17560ecbSAndreas Gohr     *
104*17560ecbSAndreas Gohr     * Blank values are not validated and always pass
105*17560ecbSAndreas Gohr     *
106*17560ecbSAndreas Gohr     * @param AbstractBaseType $type
107*17560ecbSAndreas Gohr     * @param string $label
108*17560ecbSAndreas Gohr     * @param array|string|int $data
109*17560ecbSAndreas Gohr     * @return bool true if the data validates, otherwise false
110*17560ecbSAndreas Gohr     */
111*17560ecbSAndreas Gohr    protected function validate(AbstractBaseType $type, $label, $data) {
112*17560ecbSAndreas Gohr        $prefix = sprintf($this->getLang('validation_prefix'), $label);
113*17560ecbSAndreas Gohr
114*17560ecbSAndreas Gohr        $ok = true;
115*17560ecbSAndreas Gohr        if(is_array($data)) {
116*17560ecbSAndreas Gohr            foreach($data as $value) {
117*17560ecbSAndreas Gohr                if(!blank($value)) {
118*17560ecbSAndreas Gohr                    try {
119*17560ecbSAndreas Gohr                        $type->validate($value);
120*17560ecbSAndreas Gohr                    } catch (ValidationException $e) {
121*17560ecbSAndreas Gohr                        msg($prefix . $e->getMessage(), -1);
122*17560ecbSAndreas Gohr                        $ok = false;
123*17560ecbSAndreas Gohr                    }
124*17560ecbSAndreas Gohr                }
125*17560ecbSAndreas Gohr            }
126*17560ecbSAndreas Gohr        } else {
127*17560ecbSAndreas Gohr            if(!blank($data)) {
128*17560ecbSAndreas Gohr                try {
129*17560ecbSAndreas Gohr                    $type->validate($data);
130*17560ecbSAndreas Gohr                } catch (ValidationException $e) {
131*17560ecbSAndreas Gohr                    msg($prefix . $e->getMessage(), -1);
132*17560ecbSAndreas Gohr                    $ok = false;
133*17560ecbSAndreas Gohr                }
134*17560ecbSAndreas Gohr            }
135*17560ecbSAndreas Gohr        }
136*17560ecbSAndreas Gohr
137*17560ecbSAndreas Gohr        return $ok;
138*17560ecbSAndreas Gohr    }
139*17560ecbSAndreas Gohr
140*17560ecbSAndreas Gohr
141016bf382SMichael Große    /*
142f36fda9dSAndreas Gohr     * Enhance the editing form with structural data editing
143549a0837SAndreas Gohr     *
144549a0837SAndreas Gohr     * @param Doku_Event $event  event object by reference
145549a0837SAndreas Gohr     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
146549a0837SAndreas Gohr     *                           handler was registered]
147c2fd0bf0SMichael Große     * @return bool
148549a0837SAndreas Gohr     */
149c07703d4SAndreas Gohr    public function handle_editform(Doku_Event $event, $param) {
15065598e4aSAndreas Gohr        global $ID;
151c2fd0bf0SMichael Große
152fb31ca9fSAndreas Gohr        $assignments = new Assignments();
153fb31ca9fSAndreas Gohr        $tables = $assignments->getPageAssignments($ID);
154c2fd0bf0SMichael Große
15565598e4aSAndreas Gohr        $html = '';
156c2fd0bf0SMichael Große        foreach($tables as $table) {
15765598e4aSAndreas Gohr            $html .= $this->createForm($table);
158c2fd0bf0SMichael Große        }
159c2fd0bf0SMichael Große
16065598e4aSAndreas Gohr        /** @var Doku_Form $form */
16165598e4aSAndreas Gohr        $form = $event->data;
16265598e4aSAndreas Gohr        $html = "<div class=\"struct\">$html</div>";
16365598e4aSAndreas Gohr        $pos = $form->findElementById('wiki__editbar'); // insert the form before the main buttons
16465598e4aSAndreas Gohr        $form->insertElement($pos, $html);
16565598e4aSAndreas Gohr
166c2fd0bf0SMichael Große        return true;
167c2fd0bf0SMichael Große    }
168c2fd0bf0SMichael Große
169c2fd0bf0SMichael Große    /**
17065598e4aSAndreas Gohr     * Create the form to edit schemadata
171f36fda9dSAndreas Gohr     *
172c2fd0bf0SMichael Große     * @param string $tablename
17365598e4aSAndreas Gohr     * @return string The HTML for this schema's form
174c2fd0bf0SMichael Große     */
17565598e4aSAndreas Gohr    protected function createForm($tablename) {
176c2fd0bf0SMichael Große        global $ID;
17783beda18SAndreas Gohr        global $REV;
178*17560ecbSAndreas Gohr        global $INPUT;
17983beda18SAndreas Gohr        $schema = new SchemaData($tablename, $ID, $REV);
180c2fd0bf0SMichael Große        $schemadata = $schema->getData();
181c2fd0bf0SMichael Große
182*17560ecbSAndreas Gohr        $structdata = $INPUT->arr(self::$VAR);
183*17560ecbSAndreas Gohr        if(isset($structdata[$tablename])) {
184*17560ecbSAndreas Gohr            $postdata = $structdata[$tablename];
185*17560ecbSAndreas Gohr        } else {
186*17560ecbSAndreas Gohr            $postdata = array();
187*17560ecbSAndreas Gohr        }
188*17560ecbSAndreas Gohr
18965598e4aSAndreas Gohr        $html = "<h3>$tablename</h3>";
190053212b1SAndreas Gohr        foreach($schemadata as $field) {
191053212b1SAndreas Gohr            $label = $field->getColumn()->getLabel();
192*17560ecbSAndreas Gohr            if(isset($postdata[$label])) {
193*17560ecbSAndreas Gohr                // posted data trumps stored data
194*17560ecbSAndreas Gohr                $field->setValue($postdata[$label]);
195*17560ecbSAndreas Gohr            }
1969e9bee91SAndreas Gohr            $trans = hsc($field->getColumn()->getTranslatedLabel());
197*17560ecbSAndreas Gohr            $name = self::$VAR . "[$tablename][$label]";
198053212b1SAndreas Gohr            $input = $field->getValueEditor($name);
1999e9bee91SAndreas Gohr            $element = "<label>$trans $input</label><br />";
20065598e4aSAndreas Gohr            $html .= $element;
201c2fd0bf0SMichael Große        }
20265598e4aSAndreas Gohr
20365598e4aSAndreas Gohr        return $html;
204549a0837SAndreas Gohr    }
205549a0837SAndreas Gohr
206549a0837SAndreas Gohr}
207549a0837SAndreas Gohr
208549a0837SAndreas Gohr// vim:ts=4:sw=4:et:
209