xref: /plugin/struct/action/aggregationeditor.php (revision 308cc83fd5391df29d21d2bc1306c8da49fdb335) !
1*308cc83fSAndreas Gohr<?php
2*308cc83fSAndreas Gohr
3*308cc83fSAndreas Gohr/**
4*308cc83fSAndreas Gohr * DokuWiki Plugin struct (Action Component)
5*308cc83fSAndreas Gohr *
6*308cc83fSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7*308cc83fSAndreas Gohr * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
8*308cc83fSAndreas Gohr */
9*308cc83fSAndreas Gohr
10*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable;
11*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTableGlobal;
12*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\Column;
13*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\AggregationEditorTable;
14*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\Schema;
15*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\SearchConfig;
16*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\StructException;
17*308cc83fSAndreas Gohruse dokuwiki\plugin\struct\meta\Value;
18*308cc83fSAndreas Gohr
19*308cc83fSAndreas Gohr/**
20*308cc83fSAndreas Gohr * Class action_plugin_struct_lookup
21*308cc83fSAndreas Gohr *
22*308cc83fSAndreas Gohr * Handle global and serial data table editing
23*308cc83fSAndreas Gohr */
24*308cc83fSAndreas Gohrclass action_plugin_struct_aggregationeditor extends DokuWiki_Action_Plugin
25*308cc83fSAndreas Gohr{
26*308cc83fSAndreas Gohr
27*308cc83fSAndreas Gohr    /** @var  Column */
28*308cc83fSAndreas Gohr    protected $column = null;
29*308cc83fSAndreas Gohr
30*308cc83fSAndreas Gohr    /** @var string */
31*308cc83fSAndreas Gohr    protected $pid = '';
32*308cc83fSAndreas Gohr
33*308cc83fSAndreas Gohr    /** @var int */
34*308cc83fSAndreas Gohr    protected $rid = 0;
35*308cc83fSAndreas Gohr
36*308cc83fSAndreas Gohr    /**
37*308cc83fSAndreas Gohr     * Registers a callback function for a given event
38*308cc83fSAndreas Gohr     *
39*308cc83fSAndreas Gohr     * @param Doku_Event_Handler $controller DokuWiki's event controller object
40*308cc83fSAndreas Gohr     * @return void
41*308cc83fSAndreas Gohr     */
42*308cc83fSAndreas Gohr    public function register(Doku_Event_Handler $controller)
43*308cc83fSAndreas Gohr    {
44*308cc83fSAndreas Gohr        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjax');
45*308cc83fSAndreas Gohr    }
46*308cc83fSAndreas Gohr
47*308cc83fSAndreas Gohr    /**
48*308cc83fSAndreas Gohr     * @param Doku_Event $event
49*308cc83fSAndreas Gohr     * @param $param
50*308cc83fSAndreas Gohr     */
51*308cc83fSAndreas Gohr    public function handleAjax(Doku_Event $event, $param)
52*308cc83fSAndreas Gohr    {
53*308cc83fSAndreas Gohr        $len = strlen('plugin_struct_aggregationeditor_');
54*308cc83fSAndreas Gohr        if (substr($event->data, 0, $len) != 'plugin_struct_aggregationeditor_') {
55*308cc83fSAndreas Gohr            return;
56*308cc83fSAndreas Gohr        }
57*308cc83fSAndreas Gohr        $event->preventDefault();
58*308cc83fSAndreas Gohr        $event->stopPropagation();
59*308cc83fSAndreas Gohr
60*308cc83fSAndreas Gohr        try {
61*308cc83fSAndreas Gohr            if (substr($event->data, $len) == 'new') {
62*308cc83fSAndreas Gohr                $this->newRowEditor();
63*308cc83fSAndreas Gohr            }
64*308cc83fSAndreas Gohr
65*308cc83fSAndreas Gohr            if (substr($event->data, $len) == 'save') {
66*308cc83fSAndreas Gohr                $this->saveRow();
67*308cc83fSAndreas Gohr            }
68*308cc83fSAndreas Gohr
69*308cc83fSAndreas Gohr            if (substr($event->data, $len) == 'delete') {
70*308cc83fSAndreas Gohr                $this->deleteRow();
71*308cc83fSAndreas Gohr            }
72*308cc83fSAndreas Gohr        } catch (StructException $e) {
73*308cc83fSAndreas Gohr            http_status(500);
74*308cc83fSAndreas Gohr            header('Content-Type: text/plain');
75*308cc83fSAndreas Gohr            echo $e->getMessage();
76*308cc83fSAndreas Gohr        }
77*308cc83fSAndreas Gohr    }
78*308cc83fSAndreas Gohr
79*308cc83fSAndreas Gohr    /**
80*308cc83fSAndreas Gohr     * Deletes a row
81*308cc83fSAndreas Gohr     */
82*308cc83fSAndreas Gohr    protected function deleteRow()
83*308cc83fSAndreas Gohr    {
84*308cc83fSAndreas Gohr        global $INPUT;
85*308cc83fSAndreas Gohr        $tablename = $INPUT->str('schema');
86*308cc83fSAndreas Gohr        if (!$tablename) {
87*308cc83fSAndreas Gohr            throw new StructException('No schema given');
88*308cc83fSAndreas Gohr        }
89*308cc83fSAndreas Gohr
90*308cc83fSAndreas Gohr        $this->rid = $INPUT->int('rid');
91*308cc83fSAndreas Gohr        $this->validate();
92*308cc83fSAndreas Gohr
93*308cc83fSAndreas Gohr        action_plugin_struct_inline::checkCSRF();
94*308cc83fSAndreas Gohr
95*308cc83fSAndreas Gohr        $access = $this->getAccess($tablename);
96*308cc83fSAndreas Gohr        if (!$access->getSchema()->isEditable()) {
97*308cc83fSAndreas Gohr            throw new StructException('lookup delete error: no permission for schema');
98*308cc83fSAndreas Gohr        }
99*308cc83fSAndreas Gohr        $access->clearData();
100*308cc83fSAndreas Gohr    }
101*308cc83fSAndreas Gohr
102*308cc83fSAndreas Gohr    /**
103*308cc83fSAndreas Gohr     * Save one new row
104*308cc83fSAndreas Gohr     */
105*308cc83fSAndreas Gohr    protected function saveRow()
106*308cc83fSAndreas Gohr    {
107*308cc83fSAndreas Gohr        global $INPUT;
108*308cc83fSAndreas Gohr        $tablename = $INPUT->str('schema');
109*308cc83fSAndreas Gohr        $data = $INPUT->arr('entry');
110*308cc83fSAndreas Gohr        $this->pid = $INPUT->str('pid');
111*308cc83fSAndreas Gohr        action_plugin_struct_inline::checkCSRF();
112*308cc83fSAndreas Gohr
113*308cc83fSAndreas Gohr        // create a new row based on the original aggregation config
114*308cc83fSAndreas Gohr        $access = $this->getAccess($tablename);
115*308cc83fSAndreas Gohr
116*308cc83fSAndreas Gohr        /** @var helper_plugin_struct $helper */
117*308cc83fSAndreas Gohr        $helper = plugin_load('helper', 'struct');
118*308cc83fSAndreas Gohr        $helper->saveLookupData($access, $data);
119*308cc83fSAndreas Gohr
120*308cc83fSAndreas Gohr        $config = json_decode($INPUT->str('searchconf'), true);
121*308cc83fSAndreas Gohr        // update row id
122*308cc83fSAndreas Gohr        $this->rid = $access->getRid();
123*308cc83fSAndreas Gohr        $config = $this->addTypeFilter($config);
124*308cc83fSAndreas Gohr
125*308cc83fSAndreas Gohr        $editorTable = new AggregationEditorTable(
126*308cc83fSAndreas Gohr            $this->pid,
127*308cc83fSAndreas Gohr            'xhtml',
128*308cc83fSAndreas Gohr            new Doku_Renderer_xhtml(),
129*308cc83fSAndreas Gohr            new SearchConfig($config)
130*308cc83fSAndreas Gohr        );
131*308cc83fSAndreas Gohr
132*308cc83fSAndreas Gohr        echo $editorTable->getFirstRow();
133*308cc83fSAndreas Gohr    }
134*308cc83fSAndreas Gohr
135*308cc83fSAndreas Gohr    /**
136*308cc83fSAndreas Gohr     * Create the Editor for a new row
137*308cc83fSAndreas Gohr     */
138*308cc83fSAndreas Gohr    protected function newRowEditor()
139*308cc83fSAndreas Gohr    {
140*308cc83fSAndreas Gohr        global $INPUT;
141*308cc83fSAndreas Gohr        global $lang;
142*308cc83fSAndreas Gohr        $tablename = $INPUT->str('schema');
143*308cc83fSAndreas Gohr
144*308cc83fSAndreas Gohr        $schema = new Schema($tablename);
145*308cc83fSAndreas Gohr        if (!$schema->isEditable()) {
146*308cc83fSAndreas Gohr            return;
147*308cc83fSAndreas Gohr        } // no permissions, no editor
148*308cc83fSAndreas Gohr
149*308cc83fSAndreas Gohr        echo '<div class="struct_entry_form">';
150*308cc83fSAndreas Gohr        echo '<fieldset>';
151*308cc83fSAndreas Gohr        echo '<legend>' . $this->getLang('lookup new entry') . '</legend>';
152*308cc83fSAndreas Gohr        /** @var action_plugin_struct_edit $edit */
153*308cc83fSAndreas Gohr        $edit = plugin_load('action', 'struct_edit');
154*308cc83fSAndreas Gohr        foreach ($schema->getColumns(false) as $column) {
155*308cc83fSAndreas Gohr            $label = $column->getLabel();
156*308cc83fSAndreas Gohr            $field = new Value($column, '');
157*308cc83fSAndreas Gohr            echo $edit->makeField($field, "entry[$label]");
158*308cc83fSAndreas Gohr        }
159*308cc83fSAndreas Gohr        formSecurityToken(); // csrf protection
160*308cc83fSAndreas Gohr        echo '<input type="hidden" name="call" value="plugin_struct_aggregationeditor_save" />';
161*308cc83fSAndreas Gohr        echo '<input type="hidden" name="schema" value="' . hsc($tablename) . '" />';
162*308cc83fSAndreas Gohr
163*308cc83fSAndreas Gohr        echo '<button type="submit">' . $lang['btn_save'] . '</button>';
164*308cc83fSAndreas Gohr
165*308cc83fSAndreas Gohr        echo '<div class="err"></div>';
166*308cc83fSAndreas Gohr        echo '</fieldset>';
167*308cc83fSAndreas Gohr        echo '</div>';
168*308cc83fSAndreas Gohr    }
169*308cc83fSAndreas Gohr
170*308cc83fSAndreas Gohr    /**
171*308cc83fSAndreas Gohr     * Returns data accessor
172*308cc83fSAndreas Gohr     *
173*308cc83fSAndreas Gohr     * @param string $tablename
174*308cc83fSAndreas Gohr     * @return AccessTableGlobal
175*308cc83fSAndreas Gohr     */
176*308cc83fSAndreas Gohr    protected function getAccess($tablename)
177*308cc83fSAndreas Gohr    {
178*308cc83fSAndreas Gohr        if ($this->pid) {
179*308cc83fSAndreas Gohr            return AccessTable::getSerialAccess($tablename, $this->pid, $this->rid);
180*308cc83fSAndreas Gohr        }
181*308cc83fSAndreas Gohr        return AccessTable::getGlobalAccess($tablename);
182*308cc83fSAndreas Gohr    }
183*308cc83fSAndreas Gohr
184*308cc83fSAndreas Gohr    /**
185*308cc83fSAndreas Gohr     * Adds filter to search config to differentiate data types
186*308cc83fSAndreas Gohr     *
187*308cc83fSAndreas Gohr     * @param array $config
188*308cc83fSAndreas Gohr     * @return array
189*308cc83fSAndreas Gohr     */
190*308cc83fSAndreas Gohr    protected function addTypeFilter($config)
191*308cc83fSAndreas Gohr    {
192*308cc83fSAndreas Gohr        $config['filter'][] = ['%rowid%', '=', $this->rid, 'AND'];
193*308cc83fSAndreas Gohr        if ($this->pid) {
194*308cc83fSAndreas Gohr            $config['filter'][] = ['%pageid%', '=', $this->pid, 'AND'];
195*308cc83fSAndreas Gohr        }
196*308cc83fSAndreas Gohr        return $config;
197*308cc83fSAndreas Gohr    }
198*308cc83fSAndreas Gohr
199*308cc83fSAndreas Gohr    /**
200*308cc83fSAndreas Gohr     * Throws an exception if data is invalid
201*308cc83fSAndreas Gohr     */
202*308cc83fSAndreas Gohr    protected function validate()
203*308cc83fSAndreas Gohr    {
204*308cc83fSAndreas Gohr        if (!$this->rid) {
205*308cc83fSAndreas Gohr            throw new StructException('No row id given');
206*308cc83fSAndreas Gohr        }
207*308cc83fSAndreas Gohr    }
208*308cc83fSAndreas Gohr}
209