|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* ****************************************************************************** |
|
5
|
|
|
* Copyright 2011-2017 DANTE Ltd. and GÉANT on behalf of the GN3, GN3+, GN4-1 |
|
6
|
|
|
* and GN4-2 consortia |
|
7
|
|
|
* |
|
8
|
|
|
* License: see the web/copyright.php file in the file structure |
|
9
|
|
|
* ****************************************************************************** |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace web\lib\admin; |
|
13
|
|
|
|
|
14
|
|
|
use Exception; |
|
15
|
|
|
|
|
16
|
|
|
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . "/config/_config.php"); |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* We need to display previously set options in various forms. This class covers |
|
20
|
|
|
* the ways to do that; the generated page content can then be parsed with |
|
21
|
|
|
* OptionParser. |
|
22
|
|
|
* |
|
23
|
|
|
* @author Stefan Winter <[email protected]> |
|
24
|
|
|
*/ |
|
25
|
|
|
class OptionDisplay { |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* stores all the options we are caring about |
|
29
|
|
|
* |
|
30
|
|
|
* @var array |
|
31
|
|
|
*/ |
|
32
|
|
|
private $listOfOptions; |
|
33
|
|
|
|
|
34
|
|
|
/** |
|
35
|
|
|
* on which level are we operating? |
|
36
|
|
|
* |
|
37
|
|
|
* @var string |
|
38
|
|
|
*/ |
|
39
|
|
|
private $level; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* a counter storing how many locations are to be displayed |
|
43
|
|
|
* |
|
44
|
|
|
* @var int |
|
45
|
|
|
*/ |
|
46
|
|
|
private $allLocationCount; |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* When "fresh" options are displayed (HTML select/otion fields, optionally |
|
50
|
|
|
* with language, and of varying data types) we want to give each option |
|
51
|
|
|
* the same prominence and iterate over all options in the list. This |
|
52
|
|
|
* variable keeps track how many option HTML code we've already sent, so |
|
53
|
|
|
* that we can iterate correctly. |
|
54
|
|
|
* |
|
55
|
|
|
* Only used inside noPrefillText variant of the optiontext() call |
|
56
|
|
|
* |
|
57
|
|
|
* @var int |
|
58
|
|
|
*/ |
|
59
|
|
|
private $optionIterator; |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* Which attributes are we talking about? |
|
63
|
|
|
* @param array $options the options of interest |
|
64
|
|
|
* @param string $level the level on which these options were defined by the user |
|
65
|
|
|
*/ |
|
66
|
|
|
public function __construct(array $options, string $level) { |
|
67
|
|
|
$this->listOfOptions = $options; |
|
68
|
|
|
$this->level = $level; |
|
69
|
|
|
$this->allLocationCount = 0; |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
/** |
|
73
|
|
|
* creates a table with all the set options prefilled. Only displays options |
|
74
|
|
|
* of the category indicated. |
|
75
|
|
|
* @param string $attributePrefix category of option to display |
|
76
|
|
|
* @return string HTML code <table> |
|
77
|
|
|
*/ |
|
78
|
|
|
public function prefilledOptionTable(string $attributePrefix) { |
|
79
|
|
|
$retval = "<table id='expandable_$attributePrefix" . "_options'>"; |
|
80
|
|
|
|
|
81
|
|
|
$prepopulate = []; |
|
82
|
|
|
foreach ($this->listOfOptions as $existingAttribute) { |
|
83
|
|
|
if ($existingAttribute['level'] == $this->level) { |
|
84
|
|
|
$prepopulate[] = $existingAttribute; |
|
85
|
|
|
} |
|
86
|
|
|
} |
|
87
|
|
|
$retval .= $this->addOption($attributePrefix, $prepopulate); |
|
88
|
|
|
$retval .= "</table>"; |
|
89
|
|
|
return $retval; |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* Displays options for a given option class. |
|
94
|
|
|
* |
|
95
|
|
|
* @param string $class the class of options that is to be displayed |
|
96
|
|
|
* @param array $prepopulate should an empty set of fillable options be displayed, or do we have existing data to prefill with |
|
97
|
|
|
*/ |
|
98
|
|
|
private function addOption(string $class, array $prepopulate = []) { // no GET class ? we've been called directly: |
|
99
|
|
|
// this can mean either a new object (list all options with empty values) |
|
100
|
|
|
// or that an object is to be edited. In that case, $prepopulated has to |
|
101
|
|
|
// contain the array of existing variables |
|
102
|
|
|
// we expect the variable $class to contain the class of options |
|
103
|
|
|
$retval = ""; |
|
104
|
|
|
|
|
105
|
|
|
$optioninfo = \core\Options::instance(); |
|
106
|
|
|
|
|
107
|
|
|
if (is_array($prepopulate) && ( count($prepopulate) > 1 || $class == "device-specific" || $class == "eap-specific")) { // editing... fill with values |
|
108
|
|
|
foreach ($prepopulate as $option) { |
|
109
|
|
|
if (preg_match("/$class:/", $option['name']) && !preg_match("/(user:fedadmin)/", $option['name'])) { |
|
110
|
|
|
$optiontypearray = $optioninfo->optionType($option['name']); |
|
111
|
|
|
$loggerInstance = new \core\common\Logging(); |
|
112
|
|
|
$loggerInstance->debug(5, "About to execute optiontext with PREFILL!\n"); |
|
113
|
|
|
$retval .= $this->optiontext([$option['name']], ($optiontypearray["type"] == "file" ? 'ROWID-' . $option['level'] . '-' . $option['row'] : $option['value']), $option['lang']); |
|
114
|
|
|
} |
|
115
|
|
|
} |
|
116
|
|
|
} else { // not editing exist, this in new: add empty list |
|
117
|
|
|
$list = $optioninfo->availableOptions($class); |
|
118
|
|
|
switch ($class) { |
|
119
|
|
|
case "general": |
|
120
|
|
|
$blacklistItem = array_search("general:geo_coordinates", $list); |
|
121
|
|
|
break; |
|
122
|
|
|
case "profile": |
|
123
|
|
|
$blacklistItem = array_search("profile:QR-user", $list); |
|
124
|
|
|
break; |
|
125
|
|
|
case "user": |
|
126
|
|
|
$blacklistItem = array_search("user:fedadmin", $list); |
|
127
|
|
|
break; |
|
128
|
|
|
default: |
|
129
|
|
|
$blacklistItem = FALSE; |
|
130
|
|
|
} |
|
131
|
|
|
if ($blacklistItem !== FALSE) { |
|
132
|
|
|
unset($list[$blacklistItem]); |
|
133
|
|
|
$list = array_values($list); |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
// add as many options as there are different option types |
|
137
|
|
|
$numberOfOptions = count($list); |
|
138
|
|
|
for ($this->optionIterator = 0; $this->optionIterator < $numberOfOptions; $this->optionIterator++) { |
|
139
|
|
|
$retval .= $this->optiontext($list); |
|
140
|
|
|
} |
|
141
|
|
|
} |
|
142
|
|
|
return $retval; |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
private function tooltip($rowid, $input, $isVisible) { |
|
146
|
|
|
$descriptions = []; |
|
147
|
|
|
if (count(CONFIG_CONFASSISTANT['CONSORTIUM']['ssid']) > 0) { |
|
148
|
|
|
$descriptions["media:SSID"] = sprintf(_("This attribute can be set if you want to configure an additional SSID besides the default SSIDs for %s. It is almost always a bad idea not to use the default SSIDs. The only exception is if you have premises with an overlap of the radio signal with another %s hotspot. Typical misconceptions about additional SSIDs include: I want to have a local SSID for my own users. It is much better to use the default SSID and separate user groups with VLANs. That approach has two advantages: 1) your users will configure %s properly because it is their everyday SSID; 2) if you use a custom name and advertise this one as extra secure, your users might at some point roam to another place which happens to have the same SSID name. They might then be misled to believe that they are connecting to an extra secure network while they are not."), CONFIG_CONFASSISTANT['CONSORTIUM']['display_name'], CONFIG_CONFASSISTANT['CONSORTIUM']['display_name'], CONFIG_CONFASSISTANT['CONSORTIUM']['display_name']); |
|
149
|
|
|
} |
|
150
|
|
|
$descriptions["media:force_proxy"] = sprintf(_("The format of this option is: IPv4|IPv6|hostname:port . Forcing your users through a content filter of your own is a significant invasion of user self-determination. It also has technical issues. Please throughly read the discussion at %s before specifying a proxy with this option."), "https://github.com/GEANT/CAT/issues/96"); |
|
151
|
|
|
|
|
152
|
|
|
if (!isset($descriptions[$input])) { |
|
153
|
|
|
return ""; |
|
154
|
|
|
} |
|
155
|
|
|
return "<span class='tooltip' id='S$rowid-tooltip-$input' style='display:" . ($isVisible ? "block" : "none") . "' onclick='alert(\"" . $descriptions[$input] . "\")'><img src='../resources/images/icons/question-mark-icon.png" . "'></span>"; |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
private function selectElement($rowid, $list) { |
|
159
|
|
|
$jsmagic = "onchange=' |
|
160
|
|
|
if (/#ML#/.test(document.getElementById(\"option-S" . $rowid . "-select\").value)) { |
|
161
|
|
|
document.getElementById(\"S$rowid-input-langselect\").style.display = \"block\"; |
|
162
|
|
|
} else { |
|
163
|
|
|
document.getElementById(\"S$rowid-input-langselect\").style.display = \"none\"; |
|
164
|
|
|
}"; |
|
165
|
|
|
foreach (array_keys(OptionDisplay::HTML_DATATYPE_TEXTS) as $key) { |
|
166
|
|
|
$jsmagic .= "if (/#" . $key . "#/.test(document.getElementById(\"option-S" . $rowid . "-select\").value)) { |
|
167
|
|
|
document.getElementById(\"S$rowid-input-file\").style.display = \"" . ($key == \core\Options::TYPECODE_FILE ? "block" : "none") . "\"; |
|
168
|
|
|
document.getElementById(\"S$rowid-input-text\").style.display = \"" . ($key == \core\Options::TYPECODE_TEXT ? "block" : "none") . "\"; |
|
169
|
|
|
document.getElementById(\"S$rowid-input-string\").style.display = \"" . ($key == \core\Options::TYPECODE_STRING ? "block" : "none") . "\"; |
|
170
|
|
|
document.getElementById(\"S$rowid-input-boolean\").style.display = \"" . ($key == \core\Options::TYPECODE_BOOLEAN ? "block" : "none") . "\"; |
|
171
|
|
|
document.getElementById(\"S$rowid-input-integer\").style.display = \"" . ($key == \core\Options::TYPECODE_INTEGER ? "block" : "none") . "\"; |
|
172
|
|
|
} |
|
173
|
|
|
"; |
|
174
|
|
|
// hide all tooltips (each is a <span>, and there are no other <span>s) |
|
175
|
|
|
$jsmagic .= <<< FOO |
|
176
|
|
|
var ourtooltips = document.querySelectorAll("[id^='S$rowid-tooltip-']"); |
|
177
|
|
|
for (var i=0; i<ourtooltips.length; i++) { |
|
178
|
|
|
ourtooltips[i].style.display = "none"; |
|
179
|
|
|
} |
|
180
|
|
|
var optionnamefull = document.getElementById("option-S$rowid-select").value; |
|
181
|
|
|
var firstdelimiter = optionnamefull.indexOf("#"); |
|
182
|
|
|
var optionname = optionnamefull.substring(0,firstdelimiter); |
|
183
|
|
|
var tooltipifany = document.getElementById("S$rowid-tooltip-"+optionname); |
|
184
|
|
|
if (tooltipifany != null) { |
|
185
|
|
|
tooltipifany.style.display = "block"; |
|
186
|
|
|
} |
|
187
|
|
|
FOO; |
|
188
|
|
|
} |
|
189
|
|
|
$jsmagic .= "'"; |
|
190
|
|
|
|
|
191
|
|
|
$optioninfo = \core\Options::instance(); |
|
192
|
|
|
$retval = "<span style='display:flex';>"; |
|
193
|
|
|
$retval .= "<select id='option-S$rowid-select' name='option[S$rowid]' $jsmagic>"; |
|
194
|
|
|
$iterator = 0; |
|
195
|
|
|
$tooltips = ""; |
|
196
|
|
|
$uiElements = new UIElements(); |
|
197
|
|
|
$activelisttype = []; |
|
198
|
|
|
foreach ($list as $value) { |
|
199
|
|
|
$listtype = $optioninfo->optionType($value); |
|
200
|
|
|
$retval .= "<option id='option-S$rowid-v-$value' value='$value#" . $listtype["type"] . "#" . $listtype["flag"] . "#' "; |
|
201
|
|
|
if ($iterator == $this->optionIterator) { |
|
202
|
|
|
$retval .= "selected='selected'"; |
|
203
|
|
|
$activelisttype = $listtype; |
|
204
|
|
|
$tooltips .= $this->tooltip($rowid, $value, TRUE); |
|
205
|
|
|
} else { |
|
206
|
|
|
$tooltips .= $this->tooltip($rowid, $value, FALSE); |
|
207
|
|
|
} |
|
208
|
|
|
$retval .= ">" . $uiElements->displayName($value) . "</option>"; |
|
209
|
|
|
$iterator++; |
|
210
|
|
|
} |
|
211
|
|
|
if (count($activelisttype) == 0) { |
|
212
|
|
|
throw new \Exception("We should have found the active list type by now!"); |
|
213
|
|
|
} |
|
214
|
|
|
$retval .= "</select>"; |
|
215
|
|
|
$retval .= $tooltips; |
|
216
|
|
|
$retval .= "</span>"; |
|
217
|
|
|
|
|
218
|
|
|
return ["TEXT" => $retval, "ACTIVE" => $activelisttype]; |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
private function selectLanguage($rowid, $makeVisible) { |
|
222
|
|
|
$retval = "<select style='display:" . ($makeVisible ? "block" : "none") . "' name='value[S$rowid-lang]' id='S" . $rowid . "-input-langselect'> |
|
223
|
|
|
<option value='' name='select_language' selected>" . _("select language") . "</option> |
|
224
|
|
|
<option value='C' name='all_languages'>" . _("default/other languages") . "</option>"; |
|
225
|
|
|
foreach (CONFIG['LANGUAGES'] as $langindex => $possibleLang) { |
|
226
|
|
|
$thislang = $possibleLang['display']; |
|
227
|
|
|
$retval .= "<option value='$langindex' name='$langindex'>$thislang</option>"; |
|
228
|
|
|
} |
|
229
|
|
|
$retval .= "</select>"; |
|
230
|
|
|
return $retval; |
|
231
|
|
|
} |
|
232
|
|
|
|
|
233
|
|
|
const HTML_DATATYPE_TEXTS = [ |
|
234
|
|
|
\core\Options::TYPECODE_FILE => ["html" => "input type='file'", "tail" => ' size=\'10\''], |
|
235
|
|
|
\core\Options::TYPECODE_BOOLEAN => ["html" => "input type='checkbox'", "tail" => ''], |
|
236
|
|
|
\core\Options::TYPECODE_INTEGER => ["html" => "input type='number'", "tail" => ''], |
|
237
|
|
|
\core\Options::TYPECODE_STRING => ["html" => "input type='string'", "tail" => ''], |
|
238
|
|
|
\core\Options::TYPECODE_TEXT => ["html" => "textarea cols='30' rows='3'", "tail" => '></textarea'], |
|
239
|
|
|
]; |
|
240
|
|
|
|
|
241
|
|
|
private function inputFields($rowid, $activetype) { |
|
242
|
|
|
$retval = ""; |
|
243
|
|
|
foreach (OptionDisplay::HTML_DATATYPE_TEXTS as $key => $type) { |
|
244
|
|
|
$retval .= "<" . $type['html'] . " style='display:" . ($activetype['type'] == $key ? "block" : "none") . "' name='value[S$rowid-$key]' id='S" . $rowid . "-input-" . $key . "'" . $type['tail'] . ">"; |
|
245
|
|
|
} |
|
246
|
|
|
return $retval; |
|
247
|
|
|
} |
|
248
|
|
|
|
|
249
|
|
|
/** |
|
250
|
|
|
* HTML code to display a "fresh" option (including type selector and JavaScript to show/hide relevant input fields) |
|
251
|
|
|
* @param int $rowid the HTML field base name of the option to be displayed |
|
252
|
|
|
* @param array $list the list of option names to include in the type selector |
|
253
|
|
|
* @return string HTML code |
|
254
|
|
|
* @throws Exception |
|
255
|
|
|
*/ |
|
256
|
|
|
private function noPrefillText(int $rowid, array $list) { |
|
257
|
|
|
// first column: the <select> element with the names of options and their field-toggling JS magic |
|
258
|
|
|
$selectorInfo = $this->selectElement($rowid, $list); |
|
259
|
|
|
$retval = "<td>" . $selectorInfo["TEXT"] . "</td>"; |
|
260
|
|
|
// second column: the <select> element for language selection - only visible if the active option is multi-lang |
|
261
|
|
|
$retval .= "<td>" . $this->selectLanguage($rowid, $selectorInfo['ACTIVE']['flag'] == "ML") . "</td>"; |
|
262
|
|
|
// third column: the actual input fields; the data type of the active option is visible, all others hidden |
|
263
|
|
|
$retval .= "<td>" . $this->inputFields($rowid, $selectorInfo['ACTIVE']) . "</td>"; |
|
264
|
|
|
return $retval; |
|
265
|
|
|
} |
|
266
|
|
|
|
|
267
|
|
|
/** |
|
268
|
|
|
* generates HTML code that displays an already set option. |
|
269
|
|
|
* |
|
270
|
|
|
* @param int $rowid the HTML field base name of the option to be displayed |
|
271
|
|
|
* @param string $optionName the name of the option to display |
|
272
|
|
|
* @param string $optionValue the value of the option to display |
|
273
|
|
|
* @param mixed $optionLang the language of the option to display |
|
274
|
|
|
* @return string HTML code |
|
275
|
|
|
* @throws Exception |
|
276
|
|
|
*/ |
|
277
|
|
|
private function prefillText(int $rowid, string $optionName, string $optionValue, $optionLang) { |
|
278
|
|
|
$retval = ""; |
|
279
|
|
|
$optioninfo = \core\Options::instance(); |
|
280
|
|
|
$loggerInstance = new \core\common\Logging(); |
|
281
|
|
|
$loggerInstance->debug(5, "Executed with PREFILL $optionValue!\n"); |
|
282
|
|
|
$retval .= "<td>"; |
|
283
|
|
|
$uiElements = new UIElements(); |
|
284
|
|
|
$listtype = $optioninfo->optionType($optionName); |
|
285
|
|
|
$retval .= "<span style='display:flex;'>" . $uiElements->displayName($optionName); |
|
286
|
|
|
$retval .= $this->tooltip($rowid, $optionName, TRUE) . "</span>"; |
|
287
|
|
|
$retval .= "<input type='hidden' id='option-S$rowid-select' name='option[S$rowid]' value='$optionName#" . $listtype["type"] . "#" . $listtype["flag"] . "#' ></td>"; |
|
288
|
|
|
|
|
289
|
|
|
// language tag if any |
|
290
|
|
|
$retval .= "<td>"; |
|
291
|
|
|
if ($listtype["flag"] == "ML") { |
|
292
|
|
|
|
|
293
|
|
|
$language = "(" . strtoupper($optionLang) . ")"; |
|
294
|
|
|
if ($optionLang == 'C') { |
|
295
|
|
|
$language = _("(default/other languages)"); |
|
296
|
|
|
} |
|
297
|
|
|
$retval .= $language; |
|
298
|
|
|
$retval .= "<input type='hidden' name='value[S$rowid-lang]' id='S" . $rowid . "-input-langselect' value='" . $optionLang . "' style='display:block'>"; |
|
299
|
|
|
} |
|
300
|
|
|
$retval .= "</td>"; |
|
301
|
|
|
// attribute content |
|
302
|
|
|
$retval .= "<td>"; |
|
303
|
|
|
$displayedVariant = ""; |
|
304
|
|
|
switch ($listtype["type"]) { |
|
305
|
|
|
case \core\Options::TYPECODE_COORDINATES: |
|
306
|
|
|
$this->allLocationCount = $this->allLocationCount + 1; |
|
307
|
|
|
// display of the locations varies by map provider |
|
308
|
|
|
$classname = "\web\lib\admin\Map".CONFIG_CONFASSISTANT['MAPPROVIDER']['PROVIDER']; |
|
309
|
|
|
$link = $classname::optionListDisplayCode($optionValue, $this->allLocationCount); |
|
310
|
|
|
$retval .= "<input readonly style='display:none' type='text' name='value[S$rowid-" . \core\Options::TYPECODE_TEXT . "]' id='S$rowid-input-text' value='$optionValue'>$link"; |
|
311
|
|
|
break; |
|
312
|
|
|
case \core\Options::TYPECODE_FILE: |
|
313
|
|
|
$retval .= "<input readonly type='text' name='value[S$rowid-" . \core\Options::TYPECODE_STRING . "]' id='S" . $rowid . "-input-string' style='display:none' value='" . urlencode($optionValue) . "'>"; |
|
314
|
|
|
$uiElements = new UIElements(); |
|
315
|
|
|
switch ($optionName) { |
|
316
|
|
|
case "eap:ca_file": |
|
317
|
|
|
// fall-through intentional: display both types the same way |
|
318
|
|
|
case "fed:minted_ca_file": |
|
319
|
|
|
$retval .= $uiElements->previewCAinHTML($optionValue); |
|
320
|
|
|
break; |
|
321
|
|
|
case "general:logo_file": |
|
322
|
|
|
// fall-through intentional: display both types the same way |
|
323
|
|
|
case "fed:logo_file": |
|
324
|
|
|
$retval .= $uiElements->previewImageinHTML($optionValue); |
|
325
|
|
|
break; |
|
326
|
|
|
case "support:info_file": |
|
327
|
|
|
$retval .= $uiElements->previewInfoFileinHTML($optionValue); |
|
328
|
|
|
break; |
|
329
|
|
|
default: |
|
330
|
|
|
$retval .= _("file content"); |
|
331
|
|
|
} |
|
332
|
|
|
break; |
|
333
|
|
|
case \core\Options::TYPECODE_STRING: |
|
334
|
|
|
// fall-thorugh is intentional; mostly identical HTML code for the three types |
|
335
|
|
|
case \core\Options::TYPECODE_INTEGER: |
|
336
|
|
|
// fall-thorugh is intentional; mostly identical HTML code for the three types |
|
337
|
|
|
case \core\Options::TYPECODE_TEXT: |
|
338
|
|
|
$displayedVariant = $optionValue; // for all three types, value tag and actual display are identical |
|
339
|
|
|
case \core\Options::TYPECODE_BOOLEAN: |
|
340
|
|
|
if ($listtype['type'] == \core\Options::TYPECODE_BOOLEAN) {// only modify in this one case |
|
341
|
|
|
$displayedVariant = ($optionValue == "on" ? _("on") : _("off")); |
|
342
|
|
|
} |
|
343
|
|
|
$retval .= "<strong>$displayedVariant</strong><input type='hidden' name='value[S$rowid-" . $listtype['type'] . "]' id='S" . $rowid . "-input-" . $listtype["type"] . "' value=\"" . htmlspecialchars($optionValue) . "\" style='display:block'>"; |
|
344
|
|
|
break; |
|
345
|
|
|
default: |
|
346
|
|
|
// this should never happen! |
|
347
|
|
|
throw new Exception("Internal Error: unknown attribute type $listtype!"); |
|
348
|
|
|
} |
|
349
|
|
|
$retval .= "</td>"; |
|
350
|
|
|
return $retval; |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
|
|
/** |
|
354
|
|
|
* Displays a container for options. Either with prefilled data or empty; if |
|
355
|
|
|
* empty then has HTML <input> tags with clever javaScript to allow selection |
|
356
|
|
|
* of different option names and types |
|
357
|
|
|
* @param array $list options which should be displayed; can be only exactly one if existing option, or multiple if new option type |
|
358
|
|
|
* @param string $prefillValue for an existing option, it's value to be displayed |
|
359
|
|
|
* @param string $prefillLang for an existing option, the language of the value to be displayed |
|
360
|
|
|
* @return string HTML code <tr> |
|
361
|
|
|
*/ |
|
362
|
|
|
public function optiontext(array $list, string $prefillValue = NULL, string $prefillLang = NULL) { |
|
363
|
|
|
$rowid = mt_rand(); |
|
364
|
|
|
|
|
365
|
|
|
$retval = "<tr id='option-S$rowid' style='vertical-align:top'>"; |
|
366
|
|
|
|
|
367
|
|
|
$item = "MULTIPLE"; |
|
368
|
|
|
if ($prefillValue === NULL) { |
|
369
|
|
|
$retval .= $this->noPrefillText($rowid, $list); |
|
370
|
|
|
} |
|
371
|
|
|
|
|
372
|
|
|
if ($prefillValue !== NULL) { |
|
373
|
|
|
// prefill is always only called with a list with exactly one element. |
|
374
|
|
|
// if we see anything else here, get excited. |
|
375
|
|
|
if (count($list) != 1) { |
|
376
|
|
|
throw new Exception("Optiontext prefilled display only can work with exactly one option!"); |
|
377
|
|
|
} |
|
378
|
|
|
$item = array_pop($list); |
|
379
|
|
|
$retval .= $this->prefillText($rowid, $item, $prefillValue, $prefillLang); |
|
380
|
|
|
} |
|
381
|
|
|
$retval .= " |
|
382
|
|
|
|
|
383
|
|
|
<td> |
|
384
|
|
|
<button type='button' class='delete' onclick='"; |
|
385
|
|
|
if ($prefillValue !== NULL && $item == "general:geo_coordinates") { |
|
386
|
|
|
$funcname = "Map".CONFIG_CONFASSISTANT['MAPPROVIDER']['PROVIDER'].'DeleteCoord'; |
|
387
|
|
|
$retval .= 'if (typeof '.$funcname.' === "function") { '.$funcname.'('.$this->allLocationCount.'); } '; |
|
388
|
|
|
|
|
389
|
|
|
} |
|
390
|
|
|
$retval .= 'deleteOption("option-S'.$rowid.'")'; |
|
391
|
|
|
$retval .= "'>-</button> |
|
392
|
|
|
</td> |
|
393
|
|
|
</tr>"; |
|
394
|
|
|
return $retval; |
|
395
|
|
|
} |
|
396
|
|
|
|
|
397
|
|
|
} |
|
398
|
|
|
|