1<?php 2 3/** 4 * DokuWiki Plugin struct (Action Component) 5 * 6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7 * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 8 */ 9 10use dokuwiki\Extension\ActionPlugin; 11use dokuwiki\Extension\EventHandler; 12use dokuwiki\Extension\Event; 13use dokuwiki\Form\Form; 14use dokuwiki\plugin\struct\meta\AccessTable; 15use dokuwiki\plugin\struct\meta\Assignments; 16use dokuwiki\plugin\struct\meta\Value; 17 18/** 19 * Class action_plugin_struct_entry 20 * 21 * Handles adding struct forms to the default editor 22 */ 23class action_plugin_struct_edit extends ActionPlugin 24{ 25 /** 26 * @var string The form name we use to transfer schema data 27 */ 28 protected static $VAR = 'struct_schema_data'; 29 30 /** 31 * Registers a callback function for a given event 32 * 33 * @param EventHandler $controller DokuWiki's event controller object 34 * @return void 35 */ 36 public function register(EventHandler $controller) 37 { 38 // add the struct editor to the edit form; 39 $controller->register_hook('HTML_EDITFORM_OUTPUT', 'BEFORE', $this, 'handleEditform'); 40 $controller->register_hook('FORM_EDIT_OUTPUT', 'BEFORE', $this, 'addFromData'); 41 } 42 43 /** 44 * Adds the html for the struct editors to the edit from 45 * 46 * Handles the FORM_EDIT_OUTPUT event 47 * 48 * @return bool 49 */ 50 public function addFromData(Event $event, $_param) 51 { 52 $html = $this->getEditorHtml(); 53 54 /** @var Form $form */ 55 $form = $event->data; 56 $pos = $form->findPositionByAttribute('id', 'wiki__editbar'); // insert the form before the main buttons 57 $form->addHTML($html, $pos); 58 59 return true; 60 } 61 62 /** 63 * Enhance the editing form with structural data editing 64 * 65 * TODO: Remove this after HTML_EDITFORM_OUTPUT is no longer released in DokuWiki stable 66 * 67 * @param Event $event event object by reference 68 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 69 * handler was registered] 70 * @return bool 71 */ 72 public function handleEditform(Event $event, $param) 73 { 74 $html = $this->getEditorHtml(); 75 76 /** @var Doku_Form $form */ 77 $form = $event->data; 78 $pos = $form->findElementById('wiki__editbar'); // insert the form before the main buttons 79 $form->insertElement($pos, $html); 80 81 return true; 82 } 83 84 /** 85 * @return string 86 */ 87 private function getEditorHtml() 88 { 89 global $ID; 90 91 $assignments = Assignments::getInstance(); 92 $tables = $assignments->getPageAssignments($ID); 93 94 $html = ''; 95 foreach ($tables as $table) { 96 $html .= $this->createForm($table); 97 } 98 99 return "<div class=\"struct_entry_form\">$html</div>"; 100 } 101 102 /** 103 * Create the form to edit schemadata 104 * 105 * @param string $tablename 106 * @return string The HTML for this schema's form 107 */ 108 protected function createForm($tablename) 109 { 110 global $ID; 111 global $REV; 112 global $INPUT; 113 if (auth_quickaclcheck($ID) == AUTH_READ) return ''; 114 if (checklock($ID)) return ''; 115 $ts = $REV ?: time(); 116 $schema = AccessTable::getPageAccess($tablename, $ID, $ts); 117 if (!$schema->getSchema()->isEditable()) { 118 return ''; 119 } 120 $schemadata = $schema->getData(); 121 122 $structdata = $INPUT->arr(self::$VAR); 123 if (isset($structdata[$tablename])) { 124 $postdata = $structdata[$tablename]; 125 } else { 126 $postdata = []; 127 } 128 129 // we need a short, unique identifier to use in the cookie. this should be good enough 130 $schemaid = 'SRCT' . substr(str_replace(['+', '/'], '', base64_encode(sha1($tablename, true))), 0, 5); 131 $html = '<fieldset data-schema="' . $schemaid . '">'; 132 $html .= '<legend>' . hsc($schema->getSchema()->getTranslatedLabel()) . '</legend>'; 133 foreach ($schemadata as $field) { 134 $label = $field->getColumn()->getLabel(); 135 if (isset($postdata[$label])) { 136 // posted data trumps stored data 137 $data = $postdata[$label]; 138 if (is_array($data)) { 139 $data = array_map("cleanText", $data); 140 } else { 141 $data = cleanText($data); 142 } 143 $field->setValue($data, true); 144 } 145 $html .= $this->makeField($field, self::$VAR . "[$tablename][$label]"); 146 } 147 $html .= '</fieldset>'; 148 149 return $html; 150 } 151 152 /** 153 * Create the input field 154 * 155 * @param Value $field 156 * @param String $name field's name 157 * @return string 158 */ 159 public function makeField(Value $field, $name) 160 { 161 $trans = hsc($field->getColumn()->getTranslatedLabel()); 162 $hint = hsc($field->getColumn()->getTranslatedHint()); 163 $class = $hint ? 'hashint' : ''; 164 $colname = $field->getColumn()->getFullQualifiedLabel(); 165 166 $id = uniqid('struct__', false); 167 $input = $field->getValueEditor($name, $id); 168 169 // we keep all the custom form stuff the field might produce, but hide it 170 if (!$field->getColumn()->isVisibleInEditor()) { 171 $hide = 'style="display:none"'; 172 } else { 173 $hide = ''; 174 } 175 176 $html = '<div class="field">'; 177 $html .= "<label $hide data-column=\"$colname\" for=\"$id\">"; 178 $html .= "<span class=\"label $class\" title=\"$hint\">$trans</span>"; 179 $html .= '</label>'; 180 $html .= "<span class=\"input\">$input</span>"; 181 $html .= '</div>'; 182 183 return $html; 184 } 185} 186 187// vim:ts=4:sw=4:et: 188