1<?php 2 3use dokuwiki\plugin\struct\meta\Column; 4use dokuwiki\plugin\struct\meta\Schema; 5use dokuwiki\plugin\struct\meta\StructException; 6use dokuwiki\plugin\struct\meta\Value; 7use dokuwiki\plugin\struct\meta\ValueValidator; 8use dokuwiki\plugin\struct\types\Lookup; 9use dokuwiki\plugin\struct\types\Page; 10 11/** 12 * Allows adding a single struct field as a bureaucracy field 13 * 14 * This class is used when a field of the type struct_field is encountered in the 15 * bureaucracy syntax. 16 */ 17class helper_plugin_struct_field extends helper_plugin_bureaucracy_field 18{ 19 /** @var Column */ 20 public $column; 21 22 /** 23 * Initialize the appropriate column 24 * 25 * @param array $args 26 */ 27 public function initialize($args) 28 { 29 $this->init($args); 30 31 // find the column 32 try { 33 $this->column = $this->findColumn($this->opt['label']); 34 } catch (StructException $e) { 35 msg(hsc($e->getMessage()), -1); 36 } 37 38 $this->standardArgs($args); 39 } 40 41 /** 42 * Sets the value and validates it 43 * 44 * @param mixed $value 45 * @return bool value was set successfully validated 46 */ 47 protected function setVal($value) 48 { 49 if (!$this->column) { 50 $value = ''; 51 //don't validate placeholders here 52 } elseif ($this->replace($value) == $value) { 53 $validator = new ValueValidator(); 54 $this->error = !$validator->validateValue($this->column, $value); 55 if ($this->error) { 56 foreach ($validator->getErrors() as $error) { 57 msg(hsc($error), -1); 58 } 59 } 60 } 61 62 if ($value === array() || $value === '') { 63 if (!isset($this->opt['optional'])) { 64 $this->error = true; 65 if ($this->column) { 66 $label = $this->column->getTranslatedLabel(); 67 } else { 68 $label = $this->opt['label']; 69 } 70 msg(sprintf($this->getLang('e_required'), hsc($label)), -1); 71 } 72 } 73 74 $this->opt['value'] = $value; 75 return !$this->error; 76 } 77 78 /** 79 * Creates the HTML for the field 80 * 81 * @param array $params 82 * @param Doku_Form $form 83 * @param int $formid 84 */ 85 public function renderfield($params, Doku_Form $form, $formid) 86 { 87 if (!$this->column) return; 88 89 // this is what parent does 90 $this->_handlePreload(); 91 if (!$form->_infieldset) { 92 $form->startFieldset(''); 93 } 94 if ($this->error) { 95 $params['class'] = 'bureaucracy_error'; 96 } 97 98 // output the field 99 $value = $this->createValue(); 100 $field = $this->makeField($value, $params['name']); 101 $form->addElement($field); 102 } 103 104 /** 105 * Returns a Value object for the current column. 106 * Special handling for Page and Lookup literal form values. 107 * 108 * @return Value 109 */ 110 protected function createValue() 111 { 112 $preparedValue = $this->opt['value'] ?? ''; 113 114 // page fields might need to be JSON encoded depending on usetitles config 115 if ( 116 $this->column->getType() instanceof Page 117 && $this->column->getType()->getConfig()['usetitles'] 118 ) { 119 $preparedValue = json_encode([$preparedValue, null]); 120 } 121 122 $value = new Value($this->column, $preparedValue); 123 124 // no way to pass $israw parameter to constructor, so re-set the Lookup value 125 if ($this->column->getType() instanceof Lookup) { 126 $value->setValue($preparedValue, true); 127 } 128 129 return $value; 130 } 131 132 /** 133 * Create the input field 134 * 135 * @param Value $field 136 * @param String $name field's name 137 * @return string 138 */ 139 protected function makeField(Value $field, $name) 140 { 141 $trans = hsc($field->getColumn()->getTranslatedLabel()); 142 $hint = hsc($field->getColumn()->getTranslatedHint()); 143 $class = $hint ? 'hashint' : ''; 144 $lclass = $this->error ? 'bureaucracy_error' : ''; 145 $colname = $field->getColumn()->getFullQualifiedLabel(); 146 $required = !empty($this->opt['optional']) ? '' : ' <sup>*</sup>'; 147 148 $id = uniqid('struct__', true); 149 $input = $field->getValueEditor($name, $id); 150 151 $html = '<div class="field">'; 152 $html .= "<label class=\"$lclass\" data-column=\"$colname\" for=\"$id\">"; 153 $html .= "<span class=\"label $class\" title=\"$hint\">$trans$required</span>"; 154 $html .= '</label>'; 155 $html .= "<span class=\"input\">$input</span>"; 156 $html .= '</div>'; 157 158 return $html; 159 } 160 161 /** 162 * Tries to find the correct column and schema 163 * 164 * @param string $colname 165 * @return \dokuwiki\plugin\struct\meta\Column 166 * @throws StructException 167 */ 168 protected function findColumn($colname) 169 { 170 list($table, $label) = explode('.', $colname, 2); 171 if (!$table || !$label) { 172 throw new StructException('Field \'%s\' not given in schema.field form', $colname); 173 } 174 $schema = new Schema($table); 175 return $schema->findColumn($label); 176 } 177 178 /** 179 * This ensures all language strings are still working 180 * 181 * @return string always 'bureaucracy' 182 */ 183 public function getPluginName() 184 { 185 return 'bureaucracy'; 186 } 187} 188