xref: /plugin/struct/action/entry.php (revision d6d97f6064c3b0f90310be8341edc9585520ee54)
1549a0837SAndreas Gohr<?php
2*d6d97f60SAnna Dabrowska
3549a0837SAndreas Gohr/**
4549a0837SAndreas Gohr * DokuWiki Plugin struct (Action Component)
5549a0837SAndreas Gohr *
6549a0837SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7549a0837SAndreas Gohr * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
8549a0837SAndreas Gohr */
9549a0837SAndreas Gohr
10549a0837SAndreas Gohr// must be run within Dokuwiki
11549a0837SAndreas Gohrif (!defined('DOKU_INC')) die();
12549a0837SAndreas Gohr
13f411d872SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable;
1487dc1344SAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments;
1593ca6f4fSAndreas Gohruse dokuwiki\plugin\struct\meta\AccessDataValidator;
16ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Value;
17c2fd0bf0SMichael Große
183c2e6844SAndreas Gohr/**
193c2e6844SAndreas Gohr * Class action_plugin_struct_entry
203c2e6844SAndreas Gohr *
2169f7ec8fSAnna Dabrowska * Handles the entry process of struct data with type "page"
223c2e6844SAndreas Gohr */
23*d6d97f60SAnna Dabrowskaclass action_plugin_struct_entry extends DokuWiki_Action_Plugin
24*d6d97f60SAnna Dabrowska{
25549a0837SAndreas Gohr
2617560ecbSAndreas Gohr    /**
2717560ecbSAndreas Gohr     * @var string The form name we use to transfer schema data
2817560ecbSAndreas Gohr     */
2917560ecbSAndreas Gohr    protected static $VAR = 'struct_schema_data';
30c2fd0bf0SMichael Große
31c2fd0bf0SMichael Große    /** @var helper_plugin_sqlite */
32c2fd0bf0SMichael Große    protected $sqlite;
33c2fd0bf0SMichael Große
343c2e6844SAndreas Gohr    /** @var  bool has the data been validated correctly? */
353c2e6844SAndreas Gohr    protected $validated;
363c2e6844SAndreas Gohr
3793ca6f4fSAndreas Gohr    /** @var  AccessDataValidator[] these schemas are validated and have changed data and need to be saved */
383c2e6844SAndreas Gohr    protected $tosave;
393c2e6844SAndreas Gohr
40549a0837SAndreas Gohr    /**
41549a0837SAndreas Gohr     * Registers a callback function for a given event
42549a0837SAndreas Gohr     *
43549a0837SAndreas Gohr     * @param Doku_Event_Handler $controller DokuWiki's event controller object
44549a0837SAndreas Gohr     * @return void
45549a0837SAndreas Gohr     */
46*d6d97f60SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
47*d6d97f60SAnna Dabrowska    {
483c2e6844SAndreas Gohr        // validate data on preview and save;
493c2e6844SAndreas Gohr        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_validation');
503c2e6844SAndreas Gohr        // ensure a page revision is created when struct data changes:
513c2e6844SAndreas Gohr        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_pagesave_before');
523c2e6844SAndreas Gohr        // save struct data after page has been saved:
533c2e6844SAndreas Gohr        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'handle_pagesave_after');
54549a0837SAndreas Gohr    }
55549a0837SAndreas Gohr
56549a0837SAndreas Gohr    /**
573c2e6844SAndreas Gohr     * Clean up and validate the input data
583c2e6844SAndreas Gohr     *
593c2e6844SAndreas Gohr     * @param Doku_Event $event event object by reference
603c2e6844SAndreas Gohr     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
613c2e6844SAndreas Gohr     *                           handler was registered]
623c2e6844SAndreas Gohr     * @return bool
633c2e6844SAndreas Gohr     */
64*d6d97f60SAnna Dabrowska    public function handle_validation(Doku_Event $event, $param)
65*d6d97f60SAnna Dabrowska    {
663ece9074SMichael Große        global $ID, $INPUT;
6717560ecbSAndreas Gohr        $act = act_clean($event->data);
6817560ecbSAndreas Gohr        if (!in_array($act, array('save', 'preview'))) return false;
6967036dabSAndreas Gohr        $this->tosave = array();
7004641d56SMichael Große
7187dc1344SAndreas Gohr        // run the validation for each assignded schema
7293ca6f4fSAndreas Gohr        $valid = AccessDataValidator::validateDataForPage($INPUT->arr(self::$VAR), $ID, $errors);
7393ca6f4fSAndreas Gohr        if ($valid === false) {
7487dc1344SAndreas Gohr            $this->validated = false;
7593ca6f4fSAndreas Gohr            foreach ($errors as $error) {
76c8a548a8SAndreas Gohr                msg(hsc($error), -1);
77bd92cd68SAndreas Gohr            }
7887dc1344SAndreas Gohr        } else {
7993ca6f4fSAndreas Gohr            $this->validated = true;
8093ca6f4fSAndreas Gohr            $this->tosave = $valid;
8187dc1344SAndreas Gohr        }
8287dc1344SAndreas Gohr
8387dc1344SAndreas Gohr        // FIXME we used to set the cleaned data as new input data. this caused #140
8487dc1344SAndreas Gohr        // could we just not do that, and keep the cleaning to saving only? and fix that bug this way?
85bd92cd68SAndreas Gohr
8617560ecbSAndreas Gohr        // did validation go through? otherwise abort saving
873c2e6844SAndreas Gohr        if (!$this->validated && $act == 'save') {
8817560ecbSAndreas Gohr            $event->data = 'edit';
8917560ecbSAndreas Gohr        }
9017560ecbSAndreas Gohr
9187dc1344SAndreas Gohr        return true;
9204641d56SMichael Große    }
9304641d56SMichael Große
9417560ecbSAndreas Gohr    /**
953c2e6844SAndreas Gohr     * Check if the page has to be changed
963c2e6844SAndreas Gohr     *
973c2e6844SAndreas Gohr     * @param Doku_Event $event event object by reference
983c2e6844SAndreas Gohr     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
993c2e6844SAndreas Gohr     *                           handler was registered]
1003c2e6844SAndreas Gohr     * @return bool
1013c2e6844SAndreas Gohr     */
102*d6d97f60SAnna Dabrowska    public function handle_pagesave_before(Doku_Event $event, $param)
103*d6d97f60SAnna Dabrowska    {
10487dc1344SAndreas Gohr        if ($event->data['contentChanged']) return false; // will be saved for page changes
105d683a527SAndreas Gohr        global $ACT;
10687dc1344SAndreas Gohr        if ($ACT == 'revert') return false; // this is handled in revert.php
1077dac04ffSAndreas Gohr
108df8d9fffSMichael Große        if ((is_array($this->tosave) && count($this->tosave)) || isset($GLOBALS['struct_plugin_force_page_save'])) {
1093c2e6844SAndreas Gohr            if (trim($event->data['newContent']) === '') {
1103c2e6844SAndreas Gohr                // this happens when a new page is tried to be created with only struct data
1113c2e6844SAndreas Gohr                msg($this->getLang('emptypage'), -1);
1123c2e6844SAndreas Gohr            } else {
1133c2e6844SAndreas Gohr                $event->data['contentChanged'] = true; // save for data changes
11448010be8SAndreas Gohr
11548010be8SAndreas Gohr                // add a summary
11648010be8SAndreas Gohr                if (empty($event->data['summary'])) {
11748010be8SAndreas Gohr                    $event->data['summary'] = $this->getLang('summary');
11848010be8SAndreas Gohr                }
1193c2e6844SAndreas Gohr            }
120d683a527SAndreas Gohr        }
12187dc1344SAndreas Gohr
12287dc1344SAndreas Gohr        return true;
1233c2e6844SAndreas Gohr    }
1243c2e6844SAndreas Gohr
1253c2e6844SAndreas Gohr    /**
1263c2e6844SAndreas Gohr     * Save the data
1273c2e6844SAndreas Gohr     *
12887dc1344SAndreas Gohr     * When this is called, INPUT data has been validated already.
12956672c36SAndreas Gohr     *
1303c2e6844SAndreas Gohr     * @param Doku_Event $event event object by reference
1313c2e6844SAndreas Gohr     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
1323c2e6844SAndreas Gohr     *                           handler was registered]
1333c2e6844SAndreas Gohr     * @return bool
1343c2e6844SAndreas Gohr     */
135*d6d97f60SAnna Dabrowska    public function handle_pagesave_after(Doku_Event $event, $param)
136*d6d97f60SAnna Dabrowska    {
13756672c36SAndreas Gohr        global $ACT;
13887dc1344SAndreas Gohr        if ($ACT == 'revert') return false; // handled in revert
1393c2e6844SAndreas Gohr
140025cb9daSAndreas Gohr        $assignments = Assignments::getInstance();
14158cb1498SAndreas Gohr        if ($event->data['changeType'] == DOKU_CHANGE_TYPE_DELETE && empty($GLOBALS['PLUGIN_MOVE_WORKING'])) {
14258cb1498SAndreas Gohr            // clear all data on delete unless it's a move operation
143eeb8d29fSAndreas Gohr            $tables = $assignments->getPageAssignments($event->data['id']);
144eeb8d29fSAndreas Gohr            foreach ($tables as $table) {
145f392071eSAndreas Gohr                $schemaData = AccessTable::byTableName($table, $event->data['id'], time());
1466ebbbb8eSAndreas Gohr                if ($schemaData->getSchema()->isEditable()) {
147eeb8d29fSAndreas Gohr                    $schemaData->clearData();
1483c2e6844SAndreas Gohr                }
1496ebbbb8eSAndreas Gohr            }
150eeb8d29fSAndreas Gohr        } else {
151eeb8d29fSAndreas Gohr            // save the provided data
15287dc1344SAndreas Gohr            if ($this->tosave) foreach ($this->tosave as $validation) {
1536ebbbb8eSAndreas Gohr                if ($validation->getAccessTable()->getSchema()->isEditable()) {
15487dc1344SAndreas Gohr                    $validation->saveData($event->data['newRevision']);
155956fa7d4SAndreas Gohr
156956fa7d4SAndreas Gohr                    // make sure this schema is assigned
15787dc1344SAndreas Gohr                    $assignments->assignPageSchema(
15887dc1344SAndreas Gohr                        $event->data['id'],
15987dc1344SAndreas Gohr                        $validation->getAccessTable()->getSchema()->getTable()
16087dc1344SAndreas Gohr                    );
1613c2e6844SAndreas Gohr                }
1623c2e6844SAndreas Gohr            }
1636ebbbb8eSAndreas Gohr        }
16487dc1344SAndreas Gohr        return true;
165eeb8d29fSAndreas Gohr    }
166549a0837SAndreas Gohr}
167549a0837SAndreas Gohr
168549a0837SAndreas Gohr// vim:ts=4:sw=4:et:
169