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