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