├── README.md ├── config.php ├── plugin.php └── radiobuttons.php /README.md: -------------------------------------------------------------------------------- 1 | # [osTicket](https://github.com/osTicket/) - Plugin Field Radiobuttons 2 | 3 | Enables the Radiobutton field type for osTicket forms. 4 | 5 | 6 | ## To install 7 | - Download master [zip](https://github.com/Micke1101/OSTicket-plugin-field-radiobuttons/archive/master.zip) and extract into `/include/plugins/field-radiobuttons` 8 | - Then Install and enable as per normal osTicket Plugins in the admin panel, "Manage => Plugins". 9 | 10 | ## To configure 11 | 12 | Visit the Admin-panel, select Manage => Plugins, choose the `Radiobuttons` plugin. The textbox allows you to move the field categorization to different groups within the admin form field type selector. 13 | Note: You probably don't need to change this. 14 | 15 | ## How to add a radio button 16 | 17 | Visit the admin panel, select Manage => Forms, choose the form you want to add a radiobutton form element to, 18 | Enter a Label for the field you want to add, select "Radiobuttons" from the Type selector, press "Save", then use the "Config" popup to configure the plugin. 19 | You can enter the possible options in the top "Choices" textbox, and if required you can enter the default option in the box in the middle. 20 | If your field requires a description, you can use the Help Text textbox to describe the element. 21 | The "Settings" tab of the config popup is the normal visibility/required options of other Fields. 22 | 23 | ## Screenshot 24 | 25 | Admin Screen: 26 | ![example_admin](http://osticket.com/forum/uploads/FileUpload/37/4f38ac84187d787d4e1a75a9bdb2a0.png) 27 | 28 | Once the plugin is installed and enabled, it is available from the list of available form field types. 29 | 30 | User Screen: 31 | ![example_user](http://osticket.com/forum/uploads/FileUpload/b6/814c409e5bc5f011945efeda9723ce.png) -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | new TextboxField(array( 25 | 'label' => $__('Choose category'), 26 | 'hint' => $__('What category do you want the field to appear under.'), 27 | 'default' => $__('Basic Fields'), 28 | 'configuration' => array('size'=>40, 'length'=>60), 29 | )), 30 | 'uninstall-method' => new ChoiceField([ 31 | 'label' => $__('Uninstall method'), 32 | 'required' => false, 33 | 'hint' => $__('Select what you want the plugin to do when uninstalled.'), 34 | 'default' => 'convert', 35 | 'choices' => array( 36 | 'convert' => __('Convert radiobuttons to choices'), 37 | 'prevent' => __('If radiobuttons remain prevent uninstall'), 38 | 'warn' => __('Inform the admin if instances remain'), 39 | 'nothing' => __('Just remove the plugin'), 40 | ) 41 | ]) 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /plugin.php: -------------------------------------------------------------------------------- 1 | 'field:radiobuttons', # notrans 4 | 'version' => '0.2', 5 | 'name' => /* trans */ 'Radiobuttons', 6 | 'author' => 'Micke1101', 7 | 'description' => /* trans */ 'Adds the possibility to use radiobuttons in your forms.', 8 | 'url' => 'https://github.com/Micke1101/OSTicket-plugin-field-radiobuttons', 9 | 'plugin' => 'radiobuttons.php:RadiobuttonsPlugin' 10 | ); 11 | -------------------------------------------------------------------------------- /radiobuttons.php: -------------------------------------------------------------------------------- 1 | new TextareaField(array( 12 | 'id'=>1, 'label'=>__('Choices'), 'required'=>true, 'default'=>'', 13 | 'hint'=>__('List choices, one per line. To protect against spelling changes, specify key:value names to preserve entries if the list item names change'), 14 | 'configuration'=>array('html'=>false) 15 | )), 16 | 'default' => new TextboxField(array( 17 | 'id'=>3, 'label'=>__('Default'), 'required'=>false, 'default'=>'', 18 | 'hint'=>__('(Enter a key). Value selected from the list initially'), 19 | 'configuration'=>array('size'=>20, 'length'=>40), 20 | )), 21 | ); 22 | } 23 | 24 | function parse($value) { 25 | return $this->to_php($value ?: null); 26 | } 27 | 28 | function to_database($value) { 29 | if (!is_array($value)) { 30 | $choices = $this->getChoices(); 31 | if (isset($choices[$value])) 32 | $value = array($value => $choices[$value]); 33 | } 34 | if (is_array($value)) 35 | $value = JsonDataEncoder::encode($value); 36 | 37 | return $value; 38 | } 39 | 40 | function to_php($value) { 41 | if (is_string($value)) 42 | $value = JsonDataParser::parse($value) ?: $value; 43 | 44 | // CDATA table may be built with comma-separated key,value,key,value 45 | if (is_string($value) && strpos($value, ',')) { 46 | $values = array(); 47 | $choices = $this->getChoices(); 48 | $vals = explode(',', $value); 49 | foreach ($vals as $V) { 50 | if (isset($choices[$V])) 51 | $values[$V] = $choices[$V]; 52 | } 53 | if (array_filter($values)) 54 | $value = $values; 55 | elseif($vals) 56 | list($value) = $vals; 57 | 58 | } 59 | $config = $this->getConfiguration(); 60 | if (is_array($value) && count($value) < 2) { 61 | reset($value); 62 | $value = key($value); 63 | } 64 | return $value; 65 | } 66 | 67 | function toString($value) { 68 | if (!is_array($value)) 69 | $value = $this->getChoice($value); 70 | if (is_array($value)) 71 | return implode(', ', $value); 72 | return (string) $value; 73 | } 74 | 75 | function getKeys($value) { 76 | if (!is_array($value)) 77 | $value = $this->getChoice($value); 78 | if (is_array($value)) 79 | return implode(', ', array_keys($value)); 80 | return (string) $value; 81 | } 82 | 83 | function whatChanged($before, $after) { 84 | $B = (array) $before; 85 | $A = (array) $after; 86 | $added = array_diff($A, $B); 87 | $deleted = array_diff($B, $A); 88 | $added = array_map(array($this, 'display'), $added); 89 | $deleted = array_map(array($this, 'display'), $deleted); 90 | 91 | if ($added && $deleted) { 92 | $desc = sprintf( 93 | __('added %1$s and removed %2$s'), 94 | implode(', ', $added), implode(', ', $deleted)); 95 | } 96 | elseif ($added) { 97 | $desc = sprintf( 98 | __('added %1$s'), 99 | implode(', ', $added)); 100 | } 101 | elseif ($deleted) { 102 | $desc = sprintf( 103 | __('removed %1$s'), 104 | implode(', ', $deleted)); 105 | } 106 | else { 107 | $desc = sprintf( 108 | __('changed from %1$s to %2$s'), 109 | $this->display($before), $this->display($after)); 110 | } 111 | return $desc; 112 | } 113 | 114 | function getCriteria() { 115 | $config = $this->getConfiguration(); 116 | $criteria = array(); 117 | if (isset($config['criteria'])) 118 | $criteria = $config['criteria']; 119 | 120 | return $criteria; 121 | } 122 | 123 | function getChoice($value) { 124 | 125 | $choices = $this->getChoices(); 126 | $selection = array(); 127 | if ($value && is_array($value)) { 128 | $selection = $value; 129 | } elseif (isset($choices[$value])) 130 | $selection[] = $choices[$value]; 131 | elseif ($this->get('default')) 132 | $selection[] = $choices[$this->get('default')]; 133 | 134 | return $selection; 135 | } 136 | 137 | function getChoices($verbose=false) { 138 | if ($this->_choices === null || $verbose) { 139 | // Allow choices to be set in this->ht (for configurationOptions) 140 | $this->_choices = $this->get('choices'); 141 | if (!$this->_choices) { 142 | $this->_choices = array(); 143 | $config = $this->getConfiguration(); 144 | $choices = explode("\n", $config['choices']); 145 | foreach ($choices as $choice) { 146 | // Allow choices to be key: value 147 | list($key, $val) = explode(':', $choice); 148 | if ($val == null) 149 | $val = $key; 150 | $this->_choices[trim($key)] = trim($val); 151 | } 152 | // Add old selections if nolonger available 153 | // This is necessary so choices made previously can be 154 | // retained 155 | $values = ($a=$this->getAnswer()) ? $a->getValue() : array(); 156 | if ($values && is_array($values)) { 157 | foreach ($values as $k => $v) { 158 | if (!isset($this->_choices[$k])) { 159 | if ($verbose) $v .= ' (retired)'; 160 | $this->_choices[$k] = $v; 161 | } 162 | } 163 | } 164 | } 165 | } 166 | return $this->_choices; 167 | } 168 | 169 | function lookupChoice($value) { 170 | return null; 171 | } 172 | 173 | function getSearchMethods() { 174 | return array( 175 | 'set' => __('has a value'), 176 | 'nset' => __('does not have a value'), 177 | 'includes' => __('includes'), 178 | '!includes' => __('does not include'), 179 | ); 180 | } 181 | 182 | function getSearchMethodWidgets() { 183 | return array( 184 | 'set' => null, 185 | 'nset' => null, 186 | 'includes' => array('RadioField', array( 187 | 'choices' => $this->getChoices(), 188 | )), 189 | '!includes' => array('RadioField', array( 190 | 'choices' => $this->getChoices(), 191 | )), 192 | ); 193 | } 194 | 195 | function getSearchQ($method, $value, $name=false) { 196 | $name = $name ?: $this->get('name'); 197 | switch ($method) { 198 | case '!includes': 199 | return Q::not(array("{$name}__in" => array_keys($value))); 200 | case 'includes': 201 | return new Q(array("{$name}__in" => array_keys($value))); 202 | default: 203 | return parent::getSearchQ($method, $value, $name); 204 | } 205 | } 206 | 207 | function describeSearchMethod($method) { 208 | switch ($method) { 209 | case 'includes': 210 | return __('%s includes %s'); 211 | case 'includes': 212 | return __('%s does not include %s' ); 213 | default: 214 | return parent::describeSearchMethod($method); 215 | } 216 | } 217 | } 218 | 219 | class RadioWidget extends Widget { 220 | 221 | function render($options=array()) { 222 | 223 | $config = $this->field->getConfiguration(); 224 | 225 | // Determine the value for the default (the one listed if nothing is 226 | // selected) 227 | $choices = $this->field->getChoices(true); 228 | 229 | $have_def = false; 230 | // We don't consider the 'default' when rendering in 'search' mode 231 | $def_key = $this->field->get('default'); 232 | if (!$def_key && $config['default']) 233 | $def_key = $config['default']; 234 | if (is_array($def_key)) 235 | $def_key = key($def_key); 236 | $have_def = isset($choices[$def_key]); 237 | $def_val = $have_def ? $choices[$def_key] : ''; 238 | 239 | $values = $this->value; 240 | if (!is_array($values) && isset($values)) { 241 | $values = array($values => $this->field->getChoice($values)); 242 | } 243 | 244 | if (!is_array($values)) 245 | $values = $have_def ? array($def_key => $choices[$def_key]) : array(); 246 | 247 | if (isset($config['classes'])) 248 | $classes = 'class="'.$config['classes'].'"'; 249 | 250 | $this->emitChoices($choices, $values, $have_def, $def_key); 251 | } 252 | 253 | function emitChoices($choices, $values=array(), $have_def=false, $def_key=null) { 254 | reset($choices); 255 | 256 | foreach ($choices as $key => $name) { 257 | if (!$have_def && $key == $def_key) 258 | continue; ?> 259 | > 262 | field->getChoices(); 277 | 278 | if ($choices && is_array($value)) { 279 | // Complex choices 280 | if (is_array(current($choices)) 281 | || current($choices) instanceof Traversable) { 282 | foreach ($choices as $label => $group) { 283 | foreach ($group as $k => $v) 284 | if (in_array($k, $value)) 285 | $values[$k] = $v; 286 | } 287 | } else { 288 | foreach($value as $k => $v) { 289 | if (isset($choices[$v])) 290 | $values[$v] = $choices[$v]; 291 | elseif (($i=$this->field->lookupChoice($v))) 292 | $values += $i; 293 | } 294 | } 295 | } 296 | 297 | return $values; 298 | } 299 | 300 | function getJsValueGetter() { 301 | return '%s.is(":checked").val()'; 302 | } 303 | } 304 | 305 | class RadiobuttonsPlugin extends Plugin { 306 | var $config_class = 'RadiobuttonsConfig'; 307 | 308 | function bootstrap() { 309 | $config = $this->getConfig(); 310 | FormField::$types[$config->get('category')]['radiobutton'] = array( /* @trans */ 'Radiobuttons', 'RadioField'); 311 | } 312 | 313 | function uninstall() { 314 | global $ost; 315 | $errors = array(); 316 | $config = $this->getConfig(); 317 | 318 | $fields = DynamicFormField::objects()->filter(array('type' => 'radiobutton'))->all(); 319 | if(count($fields) > 0){ 320 | switch($config->get('uninstall-method')){ 321 | case 'prevent': 322 | $ost->setWarning(sprintf(__('%d instance(s) of radiobuttons remaining.'), count($fields))); 323 | return false; 324 | break; 325 | case 'warn': 326 | $ost->alertAdmin(__('Error! Plugin Radiobuttons Field has been uninstalled but is in use!'), 327 | __('This field type has been added to a Form, you will have errors!'), 328 | true); 329 | break; 330 | case 'convert': 331 | for($i = 0; $i < count($fields); $i++){ 332 | $fields[$i]->set('type', 'choices'); 333 | $fields[$i]->save(); 334 | } 335 | break; 336 | } 337 | } 338 | return parent::uninstall($errors); 339 | } 340 | } 341 | --------------------------------------------------------------------------------