Project

General

Profile

Download (40.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * pkg_edit.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * All rights reserved.
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 * http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21

    
22
##|+PRIV
23
##|*IDENT=page-package-edit
24
##|*NAME=Package: Edit
25
##|*DESCR=Allow access to the 'Package: Edit' page.
26
##|*MATCH=pkg_edit.php*
27
##|-PRIV
28

    
29
ini_set('max_execution_time', '0');
30

    
31
require_once("guiconfig.inc");
32
require_once("functions.inc");
33
require_once("filter.inc");
34
require_once("shaper.inc");
35
require_once("pkg-utils.inc");
36

    
37
/* dummy stubs needed by some code that was MFC'd */
38
function pfSenseHeader($location) {
39
	header("Location: " . $location);
40
}
41

    
42
$xml = htmlspecialchars($_REQUEST['xml']);
43

    
44
$xml_fullpath = realpath('/usr/local/pkg/' . $xml);
45

    
46
if ($xml == "" || $xml_fullpath === false || substr($xml_fullpath, 0, strlen('/usr/local/pkg/')) != '/usr/local/pkg/') {
47
	$pgtitle = array(gettext("Package"), gettext("Editor"));
48
	$pglinks = array("", "@self");
49
	include("head.inc");
50
	print_info_box(gettext("No valid package defined."), 'danger', false);
51
	include("foot.inc");
52
	die;
53
} else {
54
	$pkg = parse_xml_config_pkg($xml_fullpath, "packagegui");
55
}
56

    
57
if ($pkg['include_file'] != "") {
58
	require_once($pkg['include_file']);
59
}
60

    
61
if (!isset($pkg['adddeleteeditpagefields'])) {
62
	$only_edit = true;
63
} else {
64
	$only_edit = false;
65
}
66

    
67
$id = $_REQUEST['id'];
68
if (isset($_POST['id'])) {
69
	$id = htmlspecialchars($_POST['id']);
70
}
71

    
72
// Not posting?	 Then user is editing a record. There must be a valid id
73
// when editing a record.
74
if (!$id && !$_POST) {
75
	$id = "0";
76
}
77

    
78
if (!is_numeric($id)) {
79
	header("Location: /");
80
	exit;
81
}
82

    
83
if ($pkg['custom_php_global_functions'] != "") {
84
	eval($pkg['custom_php_global_functions']);
85
}
86

    
87
// grab the installedpackages->package_name section.
88
if ($config['installedpackages'] && !is_array($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'])) {
89
	$config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'] = array();
90
}
91

    
92
// If the first entry in the array is an empty <config/> tag, kill it.
93
if ($config['installedpackages'] &&
94
    (count($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config']) > 0) &&
95
    ($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'][0] == "")) {
96
	array_shift($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config']);
97
}
98

    
99
$a_pkg = &$config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'];
100

    
101
if ($_REQUEST['savemsg'] != "") {
102
	$savemsg = htmlspecialchars($_REQUEST['savemsg']);
103
}
104

    
105
if ($pkg['custom_php_command_before_form'] != "") {
106
	eval($pkg['custom_php_command_before_form']);
107
}
108

    
109
if ($_POST) {
110
	$rows = 0;
111

    
112
	$input_errors = array();
113
	$reqfields = array();
114
	$reqfieldsn = array();
115
	foreach ($pkg['fields']['field'] as $field) {
116
		if (isset($field['required'])) {
117
			if ($field['fieldname']) {
118
				$reqfields[] = $field['fieldname'];
119
			}
120
			if ($field['fielddescr']) {
121
				$reqfieldsn[] = $field['fielddescr'];
122
			}
123
		}
124
	}
125
	do_input_validation($_POST, $reqfields, $reqfieldsn, $input_errors);
126

    
127
	if ($pkg['custom_php_validation_command']) {
128
		eval($pkg['custom_php_validation_command']);
129
	}
130

    
131
	if ($_POST['act'] == "del") {
132
		if ($pkg['custom_delete_php_command']) {
133
			if ($pkg['custom_php_command_before_form'] != "") {
134
				eval($pkg['custom_php_command_before_form']);
135
			}
136
			eval($pkg['custom_delete_php_command']);
137
		}
138
		write_config($pkg['delete_string']);
139
		// resync the configuration file code if defined.
140
		if ($pkg['custom_php_resync_config_command'] != "") {
141
			if ($pkg['custom_php_command_before_form'] != "") {
142
				eval($pkg['custom_php_command_before_form']);
143
			}
144
			eval($pkg['custom_php_resync_config_command']);
145
		}
146
	} else {
147
		if (!$input_errors && $pkg['custom_add_php_command']) {
148
			if ($pkg['donotsave'] != "" or $pkg['preoutput'] != "") {
149
				include("head.inc");
150
			}
151

    
152
			if ($pkg['preoutput']) {
153
				echo "<pre>";
154
			}
155
			eval($pkg['custom_add_php_command']);
156
			if ($pkg['preoutput']) {
157
				echo "</pre>";
158
			}
159
		}
160
	}
161

    
162
	// donotsave is enabled.  lets simply exit.
163
	if (empty($pkg['donotsave'])) {
164

    
165
		// store values in xml configuration file.
166
		if (!$input_errors) {
167
			$pkgarr = array();
168
			foreach ($pkg['fields']['field'] as $fields) {
169
				switch ($fields['type']) {
170
					case "rowhelper":
171
						// save rowhelper items.
172
						#$rowhelpername=($fields['fieldname'] ? $fields['fieldname'] : "row");
173
						$rowhelpername="row";
174
						foreach ($fields['rowhelper']['rowhelperfield'] as $rowhelperfield) {
175
							foreach ($_POST as $key => $value) {
176
								$matches = array();
177
								if (preg_match("/^{$rowhelperfield['fieldname']}(\d+)$/", $key, $matches)) {
178
									$pkgarr[$rowhelpername][$matches[1]][$rowhelperfield['fieldname']] = $value;
179
								}
180
							}
181
						}
182
						break;
183
					default:
184
						$fieldname = $fields['fieldname'];
185
						if ($fieldname == "interface_array") {
186
							$fieldvalue = $_POST[$fieldname];
187
						} elseif (is_array($_POST[$fieldname])) {
188
							$fieldvalue = implode(',', $_POST[$fieldname]);
189
						} else {
190
							$fieldvalue = trim($_POST[$fieldname]);
191
							if ($fields['encoding'] == 'base64') {
192
								$fieldvalue = base64_encode($fieldvalue);
193
							}
194
						}
195
						if ($fieldname) {
196
							$pkgarr[$fieldname] = $fieldvalue;
197
						}
198
					}
199
			}
200

    
201
			if (isset($id) && $a_pkg[$id]) {
202
				$a_pkg[$id] = $pkgarr;
203
			} else {
204
				$a_pkg[] = $pkgarr;
205
			}
206

    
207
			write_config($pkg['addedit_string']);
208
			// late running code
209
			if ($pkg['custom_add_php_command_late'] != "") {
210
				eval($pkg['custom_add_php_command_late']);
211
			}
212

    
213
			if (isset($pkg['filter_rules_needed'])) {
214
				filter_configure();
215
			}
216

    
217
			// resync the configuration file code if defined.
218
			if ($pkg['custom_php_resync_config_command'] != "") {
219
				eval($pkg['custom_php_resync_config_command']);
220
			}
221

    
222
			parse_package_templates();
223

    
224
			/* if start_command is defined, restart w/ this */
225
			if ($pkg['start_command'] != "") {
226
				exec($pkg['start_command'] . ">/dev/null 2&>1");
227
			}
228

    
229
			/* if restart_command is defined, restart w/ this */
230
			if ($pkg['restart_command'] != "") {
231
				exec($pkg['restart_command'] . ">/dev/null 2&>1");
232
			}
233

    
234
			if ($pkg['aftersaveredirect'] != "") {
235
				pfSenseHeader($pkg['aftersaveredirect']);
236
			} elseif (!$pkg['adddeleteeditpagefields']) {
237
				pfSenseHeader("pkg_edit.php?xml={$xml}&id=0");
238
			} elseif (!$pkg['preoutput']) {
239
				pfSenseHeader("pkg.php?xml=" . $xml);
240
			}
241
			exit;
242
		} else {
243
			$get_from_post = true;
244
		}
245
	} elseif (!$input_errors) {
246
		exit;
247
	}
248
}
249

    
250

    
251
// Turn an embedded table into a bootstrap class table. This is for backward compatibility.
252
// We remove any table attributes in the XML and replace them with Bootstrap table classes
253
function bootstrapTable($text) {
254
	$t = strpos($text, '<table') + strlen('<table');	// Find the <table tag
255
	$c = strpos($text, '>', $t);						// And its closing bracket
256

    
257
	// Substitute everything inbetween with our new classes
258
	if ($t && $c && (($c - $t) < 200)) {
259
		return(substr_replace($text, ' class="table table-striped table-hover table-condensed"', $t, ($c - $t)));
260
	}
261
}
262

    
263
/*
264
 * ROW helper function. Creates one element in the row from a PHP table by adding
265
 * the specified element to $group
266
 */
267
function display_row($trc, $value, $fieldname, $type, $rowhelper, $description, $ewidth = null) {
268
	global $text, $group, $config;
269

    
270
	switch ($type) {
271
		case "input":
272
			$inpt = new Form_Input(
273
				$fieldname . $trc,
274
				null,
275
				'text',
276
				$value
277
			);
278

    
279
			$inpt->setHelp($description);
280

    
281
			if ($ewidth) {
282
				$inpt->setWidth($ewidth);
283
			}
284

    
285
			$group->add($inpt);
286
			break;
287
		case "checkbox":
288
			$group->add(new Form_Checkbox(
289
				$fieldname . $trc,
290
				null,
291
				null,
292
				$value,
293
				'ON'
294
			))->setHelp($description);
295

    
296
			break;
297
		case "password":
298
			$group->add(new Form_Input(
299
				$fieldname . $trc,
300
				null,
301
				'password',
302
				$value
303
			))->setHelp($description);
304
			break;
305
		case "textarea":
306
			$group->add(new Form_Textarea(
307
				$fieldname . $trc,
308
				null,
309
				$value
310
			))->setHelp($description);
311

    
312
			break;
313
		case "select":
314
			$options = array();
315
			foreach ($rowhelper['options']['option'] as $rowopt) {
316
				$options[$rowopt['value']] = $rowopt['name'];
317
			}
318

    
319
			$grp = new Form_Select(
320
				$fieldname . $trc,
321
				null,
322
				$value,
323
				$options
324
			);
325

    
326
			$grp->setHelp($description);
327

    
328
			if ($ewidth) {
329
				$grp->setWidth($ewidth);
330
			}
331

    
332
			$group->add($grp);
333

    
334
			break;
335
		case "interfaces_selection":
336
			$size = ($size ? "size=\"{$size}\"" : '');
337
			$multiple = '';
338
			if (isset($rowhelper['multiple'])) {
339
				$multiple = "multiple";
340
			}
341
			echo "<select style='height:22px;' id='{$fieldname}{$trc}' name='{$fieldname}{$trc}' {$size} {$multiple}>\n";
342
			$ifaces = get_configured_interface_with_descr();
343
			$additional_ifaces = $rowhelper['add_to_interfaces_selection'];
344
			if (!empty($additional_ifaces)) {
345
				$ifaces = array_merge($ifaces, explode(',', $additional_ifaces));
346
			}
347

    
348
			if (is_array($value)) {
349
				$values = $value;
350
			} else {
351
				$values = explode(',', $value);
352
			}
353

    
354
			$ifaces["lo0"] = "loopback";
355
			$options = array();
356
			$selected = array();
357

    
358
			foreach ($ifaces as $ifname => $iface) {
359
				$options[$ifname] = $iface;
360

    
361
				if (in_array($ifname, $values)) {
362
					array_push($selected, $ifname);
363
				}
364
			}
365

    
366
			$group->add(new Form_Select(
367
				$fieldname . $trc,
368
				null,
369
				($multiple) ? $selected:$selected[0],
370
				$options,
371
				$multiple
372
			))->setHelp($description);
373

    
374
			//echo "</select>\n";
375
			break;
376
		case "select_source":
377
			$options = array();
378
			$selected = array();
379

    
380
			if (isset($rowhelper['show_disable_value'])) {
381
				$options[$rowhelper['show_disable_value']] = $rowhelper['show_disable_value'];
382
			}
383

    
384
			$source_url = $rowhelper['source'];
385
			eval("\$pkg_source_txt = &$source_url;");
386

    
387
			foreach ($pkg_source_txt as $opt) {
388
				$source_name = ($rowhelper['source_name'] ? $opt[$rowhelper['source_name']] : $opt[$rowhelper['name']]);
389
				$source_value = ($rowhelper['source_value'] ? $opt[$rowhelper['source_value']] : $opt[$rowhelper['value']]);
390
				$options[$source_value] = $source_name;
391

    
392
				if ($source_value == $value) {
393
					array_push($selected, $value);
394
				}
395
			}
396

    
397
			$group->add(new Form_Select(
398
				$fieldname . $trc,
399
				null,
400
				($multiple) ? $selected:$selected[0],
401
				$options,
402
				$multiple
403
			))->setHelp($description);
404

    
405
			break;
406
	}
407
}
408

    
409
function fixup_string($string) {
410
	global $config;
411
	// fixup #1: $myurl -> http[s]://ip_address:port/
412
	$https = "";
413
	$port = $config['system']['webguiport'];
414
	if ($port != "443" and $port != "80") {
415
		$urlport = ":" . $port;
416
	} else {
417
		$urlport = "";
418
	}
419

    
420
	if ($config['system']['webgui']['protocol'] == "https") {
421
		$https = "s";
422
	}
423
	$myurl = "http" . $https . "://" . getenv("HTTP_HOST") . $urlport;
424
	$newstring = str_replace("\$myurl", $myurl, $string);
425
	$string = $newstring;
426
	// fixup #2: $wanip
427
	$curwanip = get_interface_ip();
428
	$newstring = str_replace("\$wanip", $curwanip, $string);
429
	$string = $newstring;
430
	// fixup #3: $lanip
431
	$lancfg = $config['interfaces']['lan'];
432
	$lanip = $lancfg['ipaddr'];
433
	$newstring = str_replace("\$lanip", $lanip, $string);
434
	$string = $newstring;
435
	// fixup #4: fix'r'up here.
436
	return $newstring;
437
}
438

    
439
/*
440
 *	Parse templates if they are defined
441
 */
442
function parse_package_templates() {
443
	global $pkg;
444
	if ($pkg['templates']['template'] != "") {
445
		foreach ($pkg['templates']['template'] as $pkg_template_row) {
446
			$filename = $pkg_template_row['filename'];
447
			$template_text = $pkg_template_row['templatecontents'];
448
			/* calculate total row helpers count and */
449
			/* change fields defined as fieldname_fieldvalue to their value */
450
			foreach ($pkg['fields']['field'] as $fields) {
451
				switch ($fields['type']) {
452
					case "rowhelper":
453
						// save rowhelper items.
454
						$row_helper_total_rows = 0;
455
						$row_helper_data = "";
456
						foreach ($fields['rowhelper']['rowhelperfield'] as $rowhelperfield) {
457
							foreach ($_POST as $key => $value) {
458
								if (preg_match("/^{$rowhelperfield['fieldname']}(\d+)$/", $key, $matches)) {
459
									$row_helper_total_rows++;
460
									$row_helper_data .= $value;
461
									$sep = "";
462
									ereg($rowhelperfield['fieldname'] . "_fieldvalue\[(.*)\]", $template_text, $sep);
463
									foreach ($sep as $se) {
464
										$separator = $se;
465
									}
466
									if ($separator != "") {
467
										$row_helper_data = ereg_replace("  ", $separator, $row_helper_data);
468
										$template_text = ereg_replace("\[{$separator}\]", "", $template_text);
469
									}
470
									$template_text = str_replace($rowhelperfield['fieldname'] . "_fieldvalue", $row_helper_data, $template_text);
471
								}
472
							}
473
						}
474
						break;
475
					default:
476
						$fieldname = $fields['fieldname'];
477
						$fieldvalue = $_POST[$fieldname];
478
						$template_text = str_replace($fieldname . "_fieldvalue", $fieldvalue, $template_text);
479
				}
480
			}
481
			/* replace $domain_total_rows with total rows */
482
			$template_text = str_replace("$domain_total_rows", $row_helper_total_rows, $template_text);
483

    
484
			/* replace cr's */
485
			$template_text = str_replace("\\n", "\n", $template_text);
486

    
487
			/* write out new template file */
488
			$fout = fopen($filename, "w");
489
			fwrite($fout, $template_text);
490
			fclose($fout);
491
		}
492
	}
493
}
494

    
495
//breadcrumb
496
if ($pkg['title'] != "") {
497
	if (!$only_edit) {
498
		$pkg['title'] = $pkg['title'] . '/Edit';
499
	}
500

    
501
	if (strpos($pkg['title'], '/')) {
502
		$title = explode('/', $pkg['title']);
503

    
504
		foreach ($title as $subtitle) {
505
			$pgtitle[] = gettext($subtitle);
506
			$pglinks[] = ((($subtitle == "Edit") || (strlen($pkg['menu'][0]['url']) == 0)) ? "@self" : $pkg['menu'][0]['url']);
507
		}
508
	} else {
509
		$pgtitle = array(gettext("Package"), gettext($pkg['title']));
510
		$pglinks = array("", ((($subtitle == "Edit") || (strlen($pkg['menu'][0]['url']) == 0)) ? "@self" : $pkg['menu'][0]['url']));
511
	}
512
} else {
513
	$pgtitle = array(gettext("Package"), gettext("Editor"));
514
	$pglinks = array("", "@self");
515
}
516

    
517
// Create any required tabs
518
if ($pkg['tabs'] != "") {
519
	$tab_array = array();
520
	foreach ($pkg['tabs']['tab'] as $tab) {
521
		if ($tab['tab_level']) {
522
			$tab_level = $tab['tab_level'];
523
		} else {
524
			$tab_level = 1;
525
		}
526

    
527
		if (isset($tab['active'])) {
528
			$active = true;
529
			$pgtitle[] = $tab['text'] ;
530
			$pglinks[] = ((strlen($tab['url']) > 0) ? $tab['url'] : "@self");
531
		} else {
532
			$active = false;
533
		}
534

    
535
		if (isset($tab['no_drop_down'])) {
536
			$no_drop_down = true;
537
		}
538

    
539
		$urltmp = "";
540
		if ($tab['url'] != "") {
541
			$urltmp = $tab['url'];
542
		}
543

    
544
		if ($tab['xml'] != "") {
545
			$urltmp = "pkg_edit.php?xml=" . $tab['xml'];
546
		}
547

    
548
		$addresswithport = getenv("HTTP_HOST");
549
		$colonpos = strpos($addresswithport, ":");
550

    
551
		if ($colonpos !== False) {
552
			//my url is actually just the IP address of the pfsense box
553
			$myurl = substr($addresswithport, 0, $colonpos);
554
		} else {
555
			$myurl = $addresswithport;
556
		}
557

    
558
		// eval url so that above $myurl item can be processed if need be.
559
		$url = str_replace('$myurl', $myurl, $urltmp);
560

    
561
		$tab_array[$tab_level][] = array(
562
			$tab['text'],
563
			$active,
564
			$url
565
		);
566
	}
567

    
568
	ksort($tab_array);
569
}
570

    
571
include("head.inc");
572
if ($pkg['custom_php_after_head_command']) {
573
	eval($pkg['custom_php_after_head_command']);
574
}
575
if (isset($tab_array)) {
576
	foreach ($tab_array as $tabid => $tab) {
577
		display_top_tabs($tab); //, $no_drop_down, $tabid);
578
	}
579
}
580

    
581
// Start of page display
582
if ($input_errors) {
583
	print_input_errors($input_errors);
584
}
585

    
586
if ($savemsg) {
587
	print_info_box($savemsg, 'success');
588
}
589

    
590
$cols = 0;
591
$savevalue = gettext("Save");
592
if ($pkg['savetext'] != "") {
593
	$savevalue = $pkg['savetext'];
594
}
595

    
596
$savehelp = "";
597
if ($pkg['savehelp'] != "") {
598
	$savehelp = $pkg['savehelp'];
599
}
600

    
601
$saveicon = "fa-save";
602
if ($pkg['saveicon'] != "") {
603
	$saveicon = $pkg['saveicon'];
604
}
605

    
606
$savebtnclass = "btn-primary";
607
if ($pkg['savebtnclass'] != "") {
608
	$savebtnclass = $pkg['savebtnclass'];
609
}
610

    
611
$grouping = false; // Indicates the elements we are composing are part of a combined group
612

    
613
$savebutton = new Form_Button(
614
	'submit',
615
	$savevalue,
616
	null,
617
	$saveicon
618
);
619
$savebutton->addClass($savebtnclass);
620

    
621
if ($savehelp) {
622
	$savebutton->setHelp($savehelp);
623
}
624

    
625
$form = new Form($savebutton);
626

    
627
$form->addGlobal(new Form_Input(
628
	'xml',
629
	null,
630
	'hidden',
631
	$xml
632
));
633

    
634
/* If a package's XML has <advanced_options/> configured, then setup
635
 * the section for the fields that have <advancedfield/> set.
636
 * These fields will be placed below other fields in a separate area titled 'Advanced Features'.
637
 * These advanced fields are not normally configured and generally left to default to 'default settings'.
638
 */
639

    
640
if ($pkg['advanced_options'] == "enabled") {
641
	$advfield_count = 0;
642
	$advanced = new Form_Section("Advanced Features");
643
	$advanced->addClass('advancedoptions');
644
}
645

    
646
$js_array = array();
647

    
648
// Now loop through all of the fields defined in the XML
649
if (!is_array($pkg['fields']['field'])) {
650
	$pkg['fields']['field'] = array();
651
}
652
foreach ($pkg['fields']['field'] as $pkga) {
653

    
654
	$action = "";
655
	$uid = "";
656

    
657
	if ($pkga['type'] == "sorting") {
658
		continue;
659
	}
660

    
661
	// Generate a new section
662
	if ($pkga['type'] == "listtopic") {
663
		if (isset($pkga['advancedfield']) && isset($advfield_count)) {
664
			$advanced->addInput(new Form_StaticText(
665
				strip_tags($pkga['name']),
666
				null
667
			));
668

    
669
			$advfield_count++;
670
		}  else {
671
			if (isset($section)) {
672
				$form->add($section);
673
			}
674

    
675
			if (isset($pkga['collapse'])) {
676
				$uid = uniqid("section");
677

    
678
				$action = COLLAPSIBLE;
679

    
680
				if ($pkga['collapse'] == "open") {
681
					$action |= SEC_OPEN;
682
				} else {
683
					$action |= SEC_CLOSED;
684
				}
685
			}
686

    
687
			$section = new Form_Section(strip_tags($pkga['name']), $uid, $action);
688
		}
689

    
690
		continue;
691
	}
692

    
693
	// 'begin' starts a form group. ('end' ends it)
694
	if ($pkga['combinefields'] == "begin") {
695
		$group = new Form_Group(strip_tags($pkga['fielddescr']));
696
		$grouping = true;
697
	}
698

    
699
	$size = "";
700
	$colspan="";
701

    
702
	// if user is editing a record, load in the data.
703
	$fieldname = $pkga['fieldname'];
704
	unset($value);
705
	if ($get_from_post) {
706
		$value = $_POST[$fieldname];
707
		if (is_array($value)) {
708
			$value = implode(',', $value);
709
		}
710
	} else {
711
		if (isset($id) && isset($a_pkg[$id][$fieldname])) {
712
			$value = $a_pkg[$id][$fieldname];
713
		} else {
714
			if (isset($pkga['default_value'])) {
715
				$value = $pkga['default_value'];
716
			}
717
		}
718
	}
719

    
720
	// If we get here but have no $section, the package config file probably had no listtopic field
721
	// We can create a section with a generic name to fix that
722
	if (!$section) {
723
		$section = new Form_Section('General Options');
724
	}
725

    
726
	// If this is a required field, pre-pend a "*" to the field description
727
	// This tells the system to add "element-required" class text decoration to the field label
728
	if (isset($pkga['required'])) {
729
		$pkga['fielddescr'] = "*" . $pkga['fielddescr'];
730
	}
731

    
732
	switch ($pkga['type']) {
733
		// Create an input element. The format is slightly different depending on whether we are composing a group,
734
		// section, or advanced section. This is true for every element type
735
		case "input":
736
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
737
				$value = base64_decode($value);
738
			}
739

    
740
			$grp = new Form_Input(
741
					$pkga['fieldname'],
742
					$pkga['fielddescr'],
743
					'text',
744
					$value
745
				);
746

    
747
			$grp->setHelp($pkga['description']);
748

    
749
			if ($pkga['width']) {
750
				$grp->setWidth($pkga['width']);
751
			}
752

    
753
			if ($grouping) {
754
				$group->add($grp);
755
			} else {
756
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
757
					$advanced->addInput($grp);
758
				} else {
759
					$section->addInput($grp);
760
				}
761
			}
762

    
763
			break;
764

    
765
		case "password":
766
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
767
				$value = base64_decode($value);
768
			}
769

    
770
			// Create a password element
771
			if ($grouping) {
772
				$group->add(new Form_Input(
773
					$pkga['fieldname'],
774
					$pkga['fielddescr'],
775
					'password',
776
					$value
777
				))->setHelp($pkga['description']);
778
			} else {
779
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
780
					$advanced->addInput(new Form_Input(
781
						$pkga['fieldname'],
782
						$pkga['fielddescr'],
783
						'password',
784
						$value
785
					))->setHelp($pkga['description']);
786
				} else {
787
					$section->addInput(new Form_Input(
788
						$pkga['fieldname'],
789
						$pkga['fielddescr'],
790
						'password',
791
						$value
792
					))->setHelp($pkga['description']);
793
				}
794
			}
795

    
796
			break;
797

    
798
		case "info":
799
			// If the info contains a table we should detect and Bootstrap it
800

    
801
			if (strpos($pkga['description'], '<table') !== FALSE) {
802
				$info = bootstrapTable($pkga['description']);
803
			} else {
804
				$info = $pkga['description'];
805
			}
806

    
807
			if (isset($pkga['advancedfield']) && isset($advfield_count)) {
808
				$advanced->addInput(new Form_StaticText(
809
					strip_tags($pkga['fielddescr']),
810
					$info
811
				));
812
			} else {
813
				$section->addInput(new Form_StaticText(
814
					strip_tags($pkga['fielddescr']),
815
					$info
816
				));
817
			}
818

    
819
			break;
820

    
821
		case "select":
822
			// Create a select element
823
			$optionlist = array();
824
			$selectedlist = array();
825

    
826
			$fieldname = $pkga['fieldname'];
827

    
828
			if (isset($pkga['multiple'])) {
829
				$multiple = 'multiple';
830
				$items = explode(',', $value);
831
				$fieldname .= "[]";
832
			} else {
833
				$multiple = '';
834
				$items = array($value);
835
			}
836

    
837
			$onchange = (isset($pkga['onchange']) ? "{$pkga['onchange']}" : '');
838

    
839
			foreach ($pkga['options']['option'] as $opt) {
840
				$optionlist[$opt['value']] = $opt['name'];
841

    
842
				if (in_array($opt['value'], $items)) {
843
					array_push($selectedlist, $opt['value']);
844
				}
845
			}
846

    
847
			if (isset($pkga['advancedfield']) && isset($advfield_count)) {
848
				$function = $grouping ? $advanced->add:$advanced->addInput;
849
			} else {
850
				$function = ($grouping) ? $section->add:$section->addInput;
851
			}
852

    
853
			$grp = new Form_Select(
854
						$pkga['fieldname'],
855
						strip_tags($pkga['fielddescr']),
856
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
857
						$optionlist,
858
						isset($pkga['multiple'])
859
					);
860

    
861
			$grp ->setHelp($pkga['description'])->setOnchange($onchange)->setAttribute('size', $pkga['size']);
862

    
863
			if ($pkga['width']) {
864
				$grp->setWidth($pkga['width']);
865
			}
866

    
867
			if ($grouping) {
868
				$group->add($grp);
869
			} else {
870
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
871
					$advanced->addInput($grp);
872
				} else {
873
					$section->addInput($grp);
874
				}
875
			}
876

    
877
			break;
878

    
879
		case "select_source":
880

    
881
			if (isset($pkga['multiple'])) {
882
				$items = explode(',', $value);
883
				$fieldname .= "[]";
884
			} else {
885
				$items = array($value);
886
			}
887

    
888
			$onchange = (isset($pkga['onchange']) ? "{$pkga['onchange']}" : '');
889

    
890
			$source_url = $pkga['source'];
891
			eval("\$pkg_source_txt = &$source_url;");
892

    
893
			#check if show disable option is present on xml
894
			if (!is_array($pkg_source_txt)) {
895
				$pkg_source_txt = array();
896
			}
897
			if (isset($pkga['show_disable_value'])) {
898
				array_push($pkg_source_txt,
899
					array(($pkga['source_name']? $pkga['source_name'] : $pkga['name'])=> $pkga['show_disable_value'], ($pkga['source_value']? $pkga['source_value'] : $pkga['value'])=> $pkga['show_disable_value']));
900
			}
901

    
902
			$srcoptions = array();
903
			$srcselected = array();
904

    
905
			foreach ($pkg_source_txt as $opt) {
906
				$source_name =($pkga['source_name']? $opt[$pkga['source_name']] : $opt[$pkga['name']]);
907
				$source_value =($pkga['source_value'] ? $opt[$pkga['source_value']] : $opt[$pkga['value']]);
908
				$srcoptions[$source_value] = $source_name;
909

    
910
				if (in_array($source_value, $items)) {
911
					array_push($srcselected, $source_value);
912
				}
913
			}
914

    
915
			$descr = (isset($pkga['description'])) ? $pkga['description'] : "";
916
			if ($grouping) {
917
				$group->add(new Form_Select(
918
					$pkga['fieldname'],
919
					strip_tags($pkga['fielddescr']),
920
					isset($pkga['multiple']) ? $srcselected:$srcselected[0],
921
					$srcoptions,
922
					isset($pkga['multiple'])
923
				))->setHelp($descr)->setOnchange($onchange);
924
			} else {
925
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
926
					$advanced->addInput(new Form_Select(
927
						$pkga['fieldname'],
928
						strip_tags($pkga['fielddescr']),
929
						isset($pkga['multiple']) ? $srcselected:$srcselected[0],
930
						$srcoptions,
931
						isset($pkga['multiple'])
932
					))->setHelp($descr)->setOnchange($onchange);
933
				} else {
934
					$section->addInput(new Form_Select(
935
						$pkga['fieldname'],
936
						strip_tags($pkga['fielddescr']),
937
						isset($pkga['multiple']) ? $srcselected:$srcselected[0],
938
						$srcoptions,
939
						isset($pkga['multiple'])
940
					))->setHelp($descr)->setOnchange($onchange);
941
				}
942
			}
943

    
944
			break;
945

    
946
		case "vpn_selection" :
947
			$vpnlist = array();
948

    
949
			foreach ($config['ipsec']['phase1'] as $vpn) {
950
				$vpnlist[$vpn['descr']] = $vpn['descr'];
951

    
952
			}
953

    
954
			if ($grouping) {
955
				$group->add(new Form_Select(
956
					$pkga['fieldname'],
957
					null,
958
					false,
959
					$vpnlist
960
				))->setHelp(fixup_string($pkga['description']));
961
			} else {
962
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
963
					$advanced->addInput(new Form_Select(
964
						$pkga['fieldname'],
965
						null,
966
						false,
967
						$vpnlist
968
					))->setHelp(fixup_string($pkga['description']));
969
				} else {
970
					$section->addInput(new Form_Select(
971
						$pkga['fieldname'],
972
						null,
973
						false,
974
						$vpnlist
975
					))->setHelp(fixup_string($pkga['description']));
976
				}
977
			}
978

    
979
			break;
980

    
981
		// Create a checkbox element
982
		case "checkbox":
983
			$onchange = (isset($pkga['onchange']) ? "{$pkga['onchange']}" : '');
984
			if (isset($pkga['enablefields']) || isset($pkga['checkenablefields'])) {
985
				$onclick = 'javascript:enablechange();';
986
			} else {
987
				$onclick = '';
988
			}
989

    
990
			if ($grouping) {
991
				$group->add(new Form_Checkbox(
992
					$pkga['fieldname'],
993
					$pkga['fielddescr'],
994
					fixup_string($pkga['description']),
995
					($value == "on"),
996
					'on'
997
				))->setOnclick($onclick)
998
				  ->setOnchange($onchange)
999
				  ->setHelp($pkga['sethelp']);
1000
			} else {
1001
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1002
					$advanced->addInput(new Form_Checkbox(
1003
						$pkga['fieldname'],
1004
						$pkga['fielddescr'],
1005
						fixup_string($pkga['description']),
1006
						($value == "on"),
1007
						'on'
1008
					))->setOnclick($onclick)
1009
					  ->setOnchange($onchange)
1010
					  ->setHelp($pkga['sethelp']);
1011
				} else {
1012
					$section->addInput(new Form_Checkbox(
1013
						$pkga['fieldname'],
1014
						$pkga['fielddescr'],
1015
						fixup_string($pkga['description']),
1016
						($value == "on"),
1017
						'on'
1018
					))->setOnclick($onclick)
1019
					  ->setOnchange($onchange)
1020
					  ->setHelp($pkga['sethelp']);
1021
				}
1022
			}
1023

    
1024
			break;
1025

    
1026
		// Create a textarea element
1027
		case "textarea":
1028
			$rows = $cols = 0;
1029

    
1030
			if ($pkga['rows']) {
1031
				$rows = $pkga['rows'];
1032
			}
1033
			if ($pkga['cols']) {
1034
				$cols = $pkga['cols'];
1035
			}
1036

    
1037
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
1038
				$value = base64_decode($value);
1039
			}
1040

    
1041
			$grp = new Form_Textarea(
1042
					$pkga['fieldname'],
1043
					$pkga['fielddescr'],
1044
					$value
1045
			);
1046

    
1047
			$grp->setHelp(fixup_string($pkga['description']));
1048

    
1049
			if ($rows > 0) {
1050
				$grp->setRows($rows);
1051
			}
1052

    
1053
			if ($cols > 0) {
1054
				$grp->setCols($cols);
1055
			}
1056

    
1057
			if ($pkga['wrap'] == "off") {
1058
				$grp->setAttribute("wrap", "off");
1059
				$grp->setAttribute("style", "white-space:nowrap; width: auto;");
1060
			} else {
1061
				$grp->setAttribute("style", "width: auto;");
1062
			}
1063

    
1064
			if ($grouping) {
1065
				$group->add($grp);
1066
			} else {
1067
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1068
					$advanced->addInput($grp);
1069
				} else {
1070
					$section->addInput($grp);
1071
				}
1072
			}
1073

    
1074
			break;
1075

    
1076
		case "aliases":
1077

    
1078
			// Use xml tag <typealiases> to filter type aliases
1079
			$size = ($pkga['size'] ? "size=\"{$pkga['size']}\"" : '');
1080
			$fieldname = $pkga['fieldname'];
1081
			$a_aliases = &$config['aliases']['alias'];
1082
			$addrisfirst = 0;
1083
			$aliasesaddr = "";
1084

    
1085
			if (isset($a_aliases)) {
1086
				if (!empty($pkga['typealiases'])) {
1087
					foreach ($a_aliases as $alias) {
1088
						if ($alias['type'] == $pkga['typealiases']) {
1089
							if ($addrisfirst == 1) {
1090
								$aliasesaddr .= ",";
1091
							}
1092
							$aliasesaddr .= "'" . $alias['name'] . "'";
1093
							$addrisfirst = 1;
1094
						}
1095
					}
1096
				} else {
1097
					foreach ($a_aliases as $alias) {
1098
						if ($addrisfirst == 1) {
1099
							$aliasesaddr .= ",";
1100
						}
1101
						$aliasesaddr .= "'" . $alias['name'] . "'";
1102
						$addrisfirst = 1;
1103
					}
1104
				}
1105
			}
1106

    
1107
			$grp = new Form_Input(
1108
					$pkga['fieldname'],
1109
					$pkga['fielddescr'],
1110
					'text',
1111
					$value
1112
				);
1113

    
1114
			$grp->setHelp($pkga['description']);
1115

    
1116
			if ($pkga['width']) {
1117
				$grp->setWidth($pkga['width']);
1118
			}
1119

    
1120
			if ($grouping) {
1121
				$group->add($grp);
1122
			} else {
1123
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1124
					$advanced->addInput($grp);
1125
				} else {
1126
					$section->addInput($grp);
1127
				}
1128
			}
1129

    
1130
			$script = "<script type='text/javascript'>\n";
1131
			$script .= "//<![CDATA[\n";
1132
			$script .= "events.push(function(){\n";
1133
			$script .= "	var aliasarray = new Array({$aliasesaddr})\n";
1134
			$script .= "	$('#' + '{$fieldname}').autocomplete({\n";
1135
			$script .= "		source: aliasarray\n";
1136
			$script .= "	})\n";
1137
			$script .= "});\n";
1138
			$script .= "//]]>\n";
1139
			$script .= "</script>";
1140

    
1141
			echo $script;
1142

    
1143
			break;
1144

    
1145
		case "interfaces_selection":
1146
			$ips = array();
1147
			$interface_regex=(isset($pkga['hideinterfaceregex']) ? $pkga['hideinterfaceregex'] : "nointerfacestohide");
1148
			if (is_array($config['interfaces'])) {
1149
				foreach ($config['interfaces'] as $iface_key=>$iface_value) {
1150
					if (isset($iface_value['enable']) && !preg_match("/$interface_regex/", $iface_key)) {
1151
						$iface_description=($iface_value['descr'] !="" ? strtoupper($iface_value['descr']) : strtoupper($iface_key));
1152
						if (isset($pkga['showips'])) {
1153
							$iface_description .= " address";
1154
						}
1155
						$ips[] = array('ip'=> $iface_key, 'description'=> $iface_description);
1156
					}
1157
				}
1158
			}
1159

    
1160
			if (is_array($config['virtualip']) && isset($pkga['showvirtualips'])) {
1161
				foreach ($config['virtualip']['vip'] as $vip) {
1162
					if (!preg_match("/$interface_regex/", $vip['interface'])) {
1163
						$vip_description=($vip['descr'] !="" ? " ({$vip['descr']}) " : " ");
1164
					}
1165
					switch ($vip['mode']) {
1166
						case "ipalias":
1167
						case "carp":
1168
							$ips[] = array('ip' => $vip['subnet'], 'description' => "{$vip['subnet']} $vip_description");
1169
							break;
1170
						case "proxyarp":
1171
							if ($vip['type'] == "network") {
1172
								$start = ip2long32(gen_subnet($vip['subnet'], $vip['subnet_bits']));
1173
								$end = ip2long32(gen_subnet_max($vip['subnet'], $vip['subnet_bits']));
1174
								$len = $end - $start;
1175
								for ($i = 0; $i <= $len; $i++) {
1176
									$ips[]= array('ip' => long2ip32($start+$i), 'description' => long2ip32($start+$i)." from {$vip['subnet']}/{$vip['subnet_bits']} {$vip_description}");
1177
								}
1178
							} else {
1179
								$ips[]= array('ip' => $vip['subnet'], 'description' => "{$vip['subnet']} $vip_description");
1180
							}
1181
							break;
1182
					}
1183
				}
1184
			}
1185

    
1186
			sort($ips);
1187
			if (isset($pkga['showlistenall'])) {
1188
				array_unshift($ips, array('ip' => gettext('All'), 'description' => gettext('Listen on All interfaces/ip addresses ')));
1189
			}
1190

    
1191
			if (!preg_match("/$interface_regex/", "loopback")) {
1192
				$loopback_text = gettext("loopback");
1193
				$iface_description=(isset($pkga['showips']) ? "127.0.0.1 (" . $loopback_text . ")" : $loopback_text);
1194
				array_push($ips, array('ip' => 'lo0', 'description' => $iface_description));
1195
			}
1196

    
1197
			#show interfaces array on gui
1198
			$size = ($pkga['size'] ? "size=\"{$pkga['size']}\"" : '');
1199
			$multiple = '';
1200
			$fieldname = $pkga['fieldname'];
1201
			if (isset($pkga['multiple'])) {
1202
				$fieldname .= '[]';
1203
				$multiple = 'multiple';
1204
			}
1205

    
1206
			$selectedlist = array();
1207
			$optionlist = array();
1208

    
1209
			if (is_array($value)) {
1210
				$values = $value;
1211
			} else {
1212
				$values = explode(',', $value);
1213
			}
1214

    
1215
			foreach ($ips as $iface) {
1216
				if (in_array($iface['ip'], $values)) {
1217
					array_push($selectedlist, $iface['ip']);
1218
				}
1219

    
1220
				$optionlist[$iface['ip']] = $iface['description'];
1221
			}
1222

    
1223
			if ($grouping) {
1224
				$group->add(new Form_Select(
1225
					$pkga['fieldname'],
1226
					$pkga['fielddescr'],
1227
					isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1228
					$optionlist,
1229
					isset($pkga['multiple'])
1230
				))->setHelp($pkga['description']);
1231
			} else {
1232
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1233
					$advanced->addInput(new Form_Select(
1234
						$pkga['fieldname'],
1235
						$pkga['fielddescr'],
1236
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1237
						$optionlist,
1238
						isset($pkga['multiple'])
1239
					))->setHelp($pkga['description']);
1240
				} else {
1241
					$section->addInput(new Form_Select(
1242
						$pkga['fieldname'],
1243
						$pkga['fielddescr'],
1244
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1245
						$optionlist,
1246
						isset($pkga['multiple'])
1247
					))->setHelp($pkga['description']);
1248
				}
1249
			}
1250

    
1251
			break;
1252

    
1253
		// Create radio button
1254
		case "radio":
1255
			if ($grouping) {
1256
				$group->add(new Form_Checkbox(
1257
					$pkga['fieldname'],
1258
					$pkga['fielddescr'],
1259
					fixup_string($pkga['description']),
1260
					($value == "on"),
1261
					'on'
1262
				))->displayAsRadio();
1263
			} else {
1264
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1265
					$advanced->addInput(new Form_Checkbox(
1266
						$pkga['fieldname'],
1267
						$pkga['fielddescr'],
1268
						fixup_string($pkga['description']),
1269
						($value == "on"),
1270
						'on'
1271
					))->displayAsRadio();
1272
				} else {
1273
					$section->addInput(new Form_Checkbox(
1274
						$pkga['fieldname'],
1275
						$pkga['fielddescr'],
1276
						fixup_string($pkga['description']),
1277
						($value == "on"),
1278
						'on'
1279
					))->displayAsRadio();
1280
				}
1281
			}
1282

    
1283
			break;
1284

    
1285
		// Create form button
1286
		case "button":
1287
			$newbtnicon = "fa-save";
1288
			if ($pkga['buttonicon'] != "") {
1289
				$newbtnicon = $pkga['buttonicon'];
1290
			}
1291
			$newbtnclass = "btn-primary";
1292
			if ($pkga['buttonclass'] != "") {
1293
				$newbtnclass = $pkga['buttonclass'];
1294
			}
1295

    
1296
			$newbtn = new Form_Button(
1297
				$pkga['fieldname'],
1298
				$pkga['fieldname'],
1299
				null,
1300
				$newbtnicon
1301
			);
1302
			$newbtn->addClass($newbtnclass);
1303

    
1304
			if ($grouping) {
1305
				$group->add(new Form_StaticText(
1306
					null,
1307
					$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1308
				));
1309
			} else {
1310
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1311
					$advanced->addInput(new Form_StaticText(
1312
						null,
1313
						$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1314
					));
1315
				} else {
1316
					$section->addInput(new Form_StaticText(
1317
						null,
1318
						$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1319
					));
1320
				}
1321
			}
1322

    
1323
			break;
1324

    
1325
		case "schedule_selection":
1326

    
1327
			$input = "<select id='{$pkga['fieldname']}' name='{$pkga['fieldname']}'>\n";
1328
			$schedules = array();
1329
			$schedules[] = "none";
1330
			if (is_array($config['schedules']['schedule'])) {
1331
				foreach ($config['schedules']['schedule'] as $schedule) {
1332
					if ($schedule['name'] != "") {
1333
						$schedules[] = $schedule['name'];
1334
					}
1335
				}
1336
			}
1337

    
1338
			foreach ($schedules as $schedule) {
1339
				if ($schedule == "none") {
1340
					$schedlist[""] = $schedule;
1341
				} else {
1342
					$schedlist[$schedule] = $schedule;
1343
				}
1344
			}
1345

    
1346
			if ($grouping) {
1347
				$group->add(new Form_Select(
1348
					$pkga['fieldname'],
1349
					$pkga['fielddescr'],
1350
					$value,
1351
					$schedlist
1352
				))->setHelp(fixup_string($pkga['description']));
1353
			} else {
1354
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1355
					$advanced->addInput(new Form_Select(
1356
						$pkga['fieldname'],
1357
						$pkga['fielddescr'],
1358
						$value,
1359
						$schedlist
1360
					))->setHelp(fixup_string($pkga['description']));
1361
				} else {
1362
					$section->addInput(new Form_Select(
1363
						$pkga['fieldname'],
1364
						$pkga['fielddescr'],
1365
						$value,
1366
						$schedlist
1367
					))->setHelp(fixup_string($pkga['description']));
1368
				}
1369
			}
1370

    
1371
			break;
1372

    
1373
		case "rowhelper":
1374

    
1375
			$rowhelpername="row";
1376

    
1377
				$rowcounter = 0;
1378
				$trc = 0;
1379

    
1380
				//Use assigned $a_pkg or create an empty array to enter loop
1381
				if (isset($a_pkg[$id][$rowhelpername])) {
1382
					$saved_rows=$a_pkg[$id][$rowhelpername];
1383
				} else {
1384
					$saved_rows[] = array();
1385
				}
1386

    
1387
				$numrows = count($saved_rows) - 1;
1388

    
1389
				foreach ($saved_rows as $row) {
1390
					$group = new Form_Group(($rowcounter == 0) ? $pkga['fielddescr']:null);
1391
					$group->addClass('repeatable');
1392

    
1393
					foreach ($pkga['rowhelper']['rowhelperfield'] as $rowhelper) {
1394
						unset($value);
1395
						$width = null;
1396

    
1397
						$fieldname = $rowhelper['fieldname'];
1398
						$fielddescr = $rowhelper['fielddescr'];
1399

    
1400
						// If input validation failed, read the value from the POST data so that the user's input is not lost
1401
						if ($get_from_post && isset($_POST[$fieldname.$rowcounter])) {
1402
							$value = $_POST[$fieldname.$rowcounter];
1403
						} elseif (isset($id) && $a_pkg[$id]) {
1404
							$value = $row[$fieldname];
1405
						} elseif ($rowhelper['value'] != "") {
1406
							$value = $rowhelper['value'];
1407
						}
1408

    
1409
						$type = $rowhelper['type'];
1410
						if ($type == "input" || $type == "password" || $type == "textarea") {
1411
							if (($rowhelper['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
1412
								$value = base64_decode($value);
1413
							}
1414
						}
1415

    
1416

    
1417
						if ($rowhelper['size']) {
1418
							$size = $rowhelper['size'];
1419
						} else if ($pkga['size']) {
1420
							$size = $pkga['size'];
1421
						} else {
1422
							$size = "8";
1423
						}
1424

    
1425
						if ($rowhelper['width']) {
1426
							$width = $rowhelper['width'];
1427
						}
1428

    
1429
						display_row($rowcounter, $value, $fieldname, $type, $rowhelper, ($numrows == $rowcounter) ? $fielddescr:null, $width);
1430

    
1431
						$text = "";
1432
						$trc++;
1433
					}
1434

    
1435
					// Delete row button
1436
					$group->add(new Form_Button(
1437
						'deleterow' . $rowcounter,
1438
						'Delete',
1439
						null,
1440
						'fa-trash'
1441
					))->removeClass('btn-primary')->addClass('btn-warning btn-sm');
1442

    
1443
					$rowcounter++;
1444
					$section->add($group);
1445
				}
1446

    
1447
			// Add row button
1448
			$section->addInput(new Form_Button(
1449
				'addrow',
1450
				'Add',
1451
				null,
1452
				'fa-plus'
1453
			))->addClass('btn-success');
1454

    
1455
			break;
1456

    
1457
	}
1458

    
1459
		if ($pkga['combinefields'] == "end") {
1460
			$group->add(new Form_StaticText(
1461
				null,
1462
				null
1463
			));
1464

    
1465
			if ($advanced) {
1466
				$advanced->add($group);
1467
			} else {
1468
				$section->add($group);
1469
			}
1470

    
1471
			$grouping = false;
1472
		}
1473

    
1474
	#increment counter
1475
	$i++;
1476
} // e-o-foreach field described in the XML
1477

    
1478
if ($section) {
1479
	$form->add($section);
1480
}
1481

    
1482
$form->addGlobal(new Form_Input(
1483
	'id',
1484
	null,
1485
	'hidden',
1486
	$id
1487
));
1488

    
1489
// If we created an advanced section, add it (and a button) to the form here
1490
if (!empty($advanced)) {
1491
	$form->addGlobal(new Form_Button(
1492
		'showadv',
1493
		'Show Advanced Options',
1494
		null,
1495
		'fa-cog'
1496
	))->setAttribute('type','button')->addClass('btn-info');
1497

    
1498
	$form->add($advanced);
1499
}
1500

    
1501
print($form);
1502

    
1503
if ($pkg['note'] != "") {
1504
	print_info_box($pkg['note'], 'info');
1505
}
1506

    
1507
if ($pkg['custom_php_after_form_command']) {
1508
	eval($pkg['custom_php_after_form_command']);
1509
}
1510

    
1511

    
1512
$hidemsg = gettext("Show Advanced Options");
1513
$showmsg = gettext("Hide Advanced Options");
1514

    
1515
if ($pkg['fields']['field'] != "") { ?>
1516
<script type="text/javascript">
1517
//<![CDATA[
1518
	events.push(function() {
1519

    
1520
	// Hide the advanced section
1521
	var advanced_visible = false;
1522

    
1523
	// Hide on page load
1524
	$('.advancedoptions').hide();
1525

    
1526
	// Suppress "Delete row" button if there are fewer than two rows
1527
	checkLastRow();
1528

    
1529
	// Show advanced section if you click the showadv button
1530
	$("#showadv").click(function() {
1531
		advanced_visible = !advanced_visible;
1532

    
1533
		if (advanced_visible) {
1534
			$('.advancedoptions').show();
1535
			$("#showadv").html('<i class="fa fa-cog icon-embed-btn"></i>' + "<?=$showmsg?>");
1536
		} else {
1537
			$('.advancedoptions').hide();
1538
			$("#showadv").html('<i class="fa fa-cog icon-embed-btn"></i>' + "<?=$hidemsg?>");
1539
		}
1540
	});
1541

    
1542
	// Call enablechange function
1543
	enablechange();
1544
});
1545

    
1546
	function enablechange() {
1547
<?php
1548
	foreach ($pkg['fields']['field'] as $field) {
1549
		if (isset($field['enablefields']) or isset($field['checkenablefields'])) {
1550
			echo "\tif ($('input[name=\"{$field['fieldname']}\"]').prop('checked') == false) {\n";
1551

    
1552
			if (isset($field['enablefields'])) {
1553
				foreach (explode(',', $field['enablefields']) as $enablefield) {
1554
					echo "\t\tif ($('input[name=\"{$enablefield}\"]').length > 0) {\n";
1555
					echo "\t\t\t$('input[name=\"{$enablefield}\"]').prop('disabled',true);\n";
1556
					echo "\t\t}\n";
1557
				}
1558
			}
1559

    
1560
			if (isset($field['checkenablefields'])) {
1561
				foreach (explode(',', $field['checkenablefields']) as $checkenablefield) {
1562
					echo "\t\tif ($('input[name=\"{$checkenablefield}\"]').length > 0) {\n";
1563
					echo "\t\t\t$('input[name=\"{$checkenablefield}\"]').prop('checked',true);\n";
1564
					echo "\t\t}\n";
1565
				}
1566
			}
1567

    
1568
			echo "\t}\n\telse {\n";
1569

    
1570
			if (isset($field['enablefields'])) {
1571
				foreach (explode(',', $field['enablefields']) as $enablefield) {
1572
					echo "\t\tif ($('input[name=\"{$enablefield}\"]').length > 0) {\n";
1573
					echo "\t\t\t$('input[name=\"{$enablefield}\"]').prop('disabled',false);\n";
1574
					echo "\t\t}\n";
1575
				}
1576
			}
1577

    
1578
			if (isset($field['checkenablefields'])) {
1579
				foreach (explode(',', $field['checkenablefields']) as $checkenablefield) {
1580
					echo "\t\tif ($('input[name=\"{$checkenablefield}\"]').length > 0) {\n";
1581
					echo "\t\t\t$('input[name=\"{$checkenablefield}\"]').prop('checked',false);\n";
1582
					echo "\t\t}\n";
1583
				}
1584
			}
1585

    
1586
			echo "\t}\n";
1587
		}
1588
	}
1589
	?>
1590
	}
1591
//]]>
1592
</script>
1593

    
1594
<?php
1595
}
1596

    
1597
include("foot.inc");
(97-97/223)