├── 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 | 
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 | 
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------