xref: /plugin/struct/action/inline.php (revision 4731b875bb4fd88700d786e5fdd24b8d7bd56276)
1*4731b875SAndreas Gohr<?php
2*4731b875SAndreas Gohr/**
3*4731b875SAndreas Gohr * DokuWiki Plugin struct (Action Component)
4*4731b875SAndreas Gohr *
5*4731b875SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6*4731b875SAndreas Gohr * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
7*4731b875SAndreas Gohr */
8*4731b875SAndreas Gohr
9*4731b875SAndreas Gohr// must be run within Dokuwiki
10*4731b875SAndreas Gohruse dokuwiki\plugin\struct\meta\Column;
11*4731b875SAndreas Gohruse dokuwiki\plugin\struct\meta\SchemaData;
12*4731b875SAndreas Gohruse dokuwiki\plugin\struct\meta\StructException;
13*4731b875SAndreas Gohruse dokuwiki\plugin\struct\meta\Title;
14*4731b875SAndreas Gohruse dokuwiki\plugin\struct\meta\Validator;
15*4731b875SAndreas Gohr
16*4731b875SAndreas Gohrif(!defined('DOKU_INC')) die();
17*4731b875SAndreas Gohr
18*4731b875SAndreas Gohr/**
19*4731b875SAndreas Gohr * Class action_plugin_struct_inline
20*4731b875SAndreas Gohr *
21*4731b875SAndreas Gohr * Handle inline editing
22*4731b875SAndreas Gohr */
23*4731b875SAndreas Gohrclass action_plugin_struct_inline extends DokuWiki_Action_Plugin {
24*4731b875SAndreas Gohr
25*4731b875SAndreas Gohr    /** @var  SchemaData */
26*4731b875SAndreas Gohr    protected $schemadata = null;
27*4731b875SAndreas Gohr
28*4731b875SAndreas Gohr    /** @var  Column */
29*4731b875SAndreas Gohr    protected $column = null;
30*4731b875SAndreas Gohr
31*4731b875SAndreas Gohr    /** @var String */
32*4731b875SAndreas Gohr    protected $pid = '';
33*4731b875SAndreas Gohr
34*4731b875SAndreas Gohr    /**
35*4731b875SAndreas Gohr     * Registers a callback function for a given event
36*4731b875SAndreas Gohr     *
37*4731b875SAndreas Gohr     * @param Doku_Event_Handler $controller DokuWiki's event controller object
38*4731b875SAndreas Gohr     * @return void
39*4731b875SAndreas Gohr     */
40*4731b875SAndreas Gohr    public function register(Doku_Event_Handler $controller) {
41*4731b875SAndreas Gohr        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax');
42*4731b875SAndreas Gohr    }
43*4731b875SAndreas Gohr
44*4731b875SAndreas Gohr    /**
45*4731b875SAndreas Gohr     * @param Doku_Event $event
46*4731b875SAndreas Gohr     * @param $param
47*4731b875SAndreas Gohr     */
48*4731b875SAndreas Gohr    public function handle_ajax(Doku_Event $event, $param) {
49*4731b875SAndreas Gohr        $len = strlen('plugin_struct_inline_');
50*4731b875SAndreas Gohr        if(substr($event->data, 0,  $len) != 'plugin_struct_inline_') return;
51*4731b875SAndreas Gohr        $event->preventDefault();
52*4731b875SAndreas Gohr        $event->stopPropagation();
53*4731b875SAndreas Gohr
54*4731b875SAndreas Gohr        if(substr($event->data,$len) == 'editor') {
55*4731b875SAndreas Gohr            $this->inline_editor();
56*4731b875SAndreas Gohr        }
57*4731b875SAndreas Gohr
58*4731b875SAndreas Gohr        if(substr($event->data,$len) == 'save') {
59*4731b875SAndreas Gohr            try {
60*4731b875SAndreas Gohr                $this->inline_save();
61*4731b875SAndreas Gohr            } catch(StructException $e) {
62*4731b875SAndreas Gohr                http_status(500);
63*4731b875SAndreas Gohr                header('Content-Type: text/plain; charset=utf-8');
64*4731b875SAndreas Gohr                echo $e->getMessage();
65*4731b875SAndreas Gohr            }
66*4731b875SAndreas Gohr        }
67*4731b875SAndreas Gohr    }
68*4731b875SAndreas Gohr
69*4731b875SAndreas Gohr
70*4731b875SAndreas Gohr    protected function inline_editor() {
71*4731b875SAndreas Gohr        if(!$this->initFromInput()) return;
72*4731b875SAndreas Gohr
73*4731b875SAndreas Gohr
74*4731b875SAndreas Gohr        // FIXME check read permission
75*4731b875SAndreas Gohr
76*4731b875SAndreas Gohr        // FIXME lock page
77*4731b875SAndreas Gohr
78*4731b875SAndreas Gohr        $value = $this->schemadata->getDataColumn($this->column);
79*4731b875SAndreas Gohr        echo '<div>';
80*4731b875SAndreas Gohr        echo $value->getValueEditor('entry');
81*4731b875SAndreas Gohr        echo '</div>';
82*4731b875SAndreas Gohr
83*4731b875SAndreas Gohr        $hint = $this->column->getType()->getTranslatedHint();
84*4731b875SAndreas Gohr        if($hint) {
85*4731b875SAndreas Gohr            echo '<div class="hint">';
86*4731b875SAndreas Gohr            echo hsc($hint);
87*4731b875SAndreas Gohr            echo '</div>';
88*4731b875SAndreas Gohr        }
89*4731b875SAndreas Gohr    }
90*4731b875SAndreas Gohr
91*4731b875SAndreas Gohr    protected function inline_save() {
92*4731b875SAndreas Gohr        global $INPUT;
93*4731b875SAndreas Gohr
94*4731b875SAndreas Gohr        if(!$this->initFromInput()) {
95*4731b875SAndreas Gohr            throw new StructException('inline save error');
96*4731b875SAndreas Gohr        }
97*4731b875SAndreas Gohr
98*4731b875SAndreas Gohr        // FIXME
99*4731b875SAndreas Gohr
100*4731b875SAndreas Gohr        // FIXME handle CSRF protection
101*4731b875SAndreas Gohr        // FIXME check write permission
102*4731b875SAndreas Gohr        // FIXME make sure page still locked
103*4731b875SAndreas Gohr
104*4731b875SAndreas Gohr        // validate
105*4731b875SAndreas Gohr        $value = $INPUT->param('entry');
106*4731b875SAndreas Gohr        $validator = new Validator();
107*4731b875SAndreas Gohr        if(!$validator->validateValue($this->column, $value)) {
108*4731b875SAndreas Gohr            throw new StructException(join("\n", $validator->getErrors()));
109*4731b875SAndreas Gohr        }
110*4731b875SAndreas Gohr
111*4731b875SAndreas Gohr        // current data
112*4731b875SAndreas Gohr        $tosave = $this->schemadata->getDataArray();
113*4731b875SAndreas Gohr        $tosave[$this->column->getLabel()] = $value;
114*4731b875SAndreas Gohr        $tosave = array($this->schemadata->getTable() => $tosave);
115*4731b875SAndreas Gohr
116*4731b875SAndreas Gohr        // save
117*4731b875SAndreas Gohr        /** @var helper_plugin_struct $helper */
118*4731b875SAndreas Gohr        $helper = plugin_load('helper', 'struct');
119*4731b875SAndreas Gohr        $helper->saveData($this->pid, $tosave, 'inline edit');
120*4731b875SAndreas Gohr
121*4731b875SAndreas Gohr
122*4731b875SAndreas Gohr        // reinit then render
123*4731b875SAndreas Gohr        $this->initFromInput();
124*4731b875SAndreas Gohr        $value = $this->schemadata->getDataColumn($this->column);
125*4731b875SAndreas Gohr        $R = new Doku_Renderer_xhtml();
126*4731b875SAndreas Gohr        $value->render($R, 'xhtml'); // FIXME use configured default renderer
127*4731b875SAndreas Gohr
128*4731b875SAndreas Gohr        echo $R->doc;
129*4731b875SAndreas Gohr    }
130*4731b875SAndreas Gohr
131*4731b875SAndreas Gohr    /**
132*4731b875SAndreas Gohr     * Initialize internal state based on input variables
133*4731b875SAndreas Gohr     *
134*4731b875SAndreas Gohr     * @return bool if initialization was successfull
135*4731b875SAndreas Gohr     */
136*4731b875SAndreas Gohr    protected function initFromInput() {
137*4731b875SAndreas Gohr        global $INPUT;
138*4731b875SAndreas Gohr
139*4731b875SAndreas Gohr        $this->schemadata = null;
140*4731b875SAndreas Gohr        $this->column = null;
141*4731b875SAndreas Gohr
142*4731b875SAndreas Gohr        $pid = $INPUT->str('pid');
143*4731b875SAndreas Gohr        list($table, $field) = explode('.', $INPUT->str('field'));
144*4731b875SAndreas Gohr        if(blank($pid)) return false;
145*4731b875SAndreas Gohr        if(blank($table)) return false;
146*4731b875SAndreas Gohr        if(blank($field)) return false;
147*4731b875SAndreas Gohr
148*4731b875SAndreas Gohr        $this->pid = $pid;
149*4731b875SAndreas Gohr
150*4731b875SAndreas Gohr        $this->schemadata = new SchemaData($table, $pid, 0);
151*4731b875SAndreas Gohr        if(!$this->schemadata->getId()) {
152*4731b875SAndreas Gohr            $this->schemadata = null;
153*4731b875SAndreas Gohr            return false;
154*4731b875SAndreas Gohr        }
155*4731b875SAndreas Gohr
156*4731b875SAndreas Gohr
157*4731b875SAndreas Gohr        $this->column = $this->schemadata->findColumn($field);
158*4731b875SAndreas Gohr        if(!$this->column || !$this->column->isVisibleInEditor()) {
159*4731b875SAndreas Gohr            $this->schemadata = null;
160*4731b875SAndreas Gohr            $this->column = null;
161*4731b875SAndreas Gohr            return false;
162*4731b875SAndreas Gohr        }
163*4731b875SAndreas Gohr
164*4731b875SAndreas Gohr        return true;
165*4731b875SAndreas Gohr    }
166*4731b875SAndreas Gohr
167*4731b875SAndreas Gohr}
168