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