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($_GET['xml']);
43
if ($_POST['xml']) {
44
	$xml = htmlspecialchars($_POST['xml']);
45
}
46

    
47
$xml_fullpath = realpath('/usr/local/pkg/' . $xml);
48

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

    
60
if ($pkg['include_file'] != "") {
61
	require_once($pkg['include_file']);
62
}
63

    
64
if (!isset($pkg['adddeleteeditpagefields'])) {
65
	$only_edit = true;
66
} else {
67
	$only_edit = false;
68
}
69

    
70
$id = $_GET['id'];
71
if (isset($_POST['id'])) {
72
	$id = htmlspecialchars($_POST['id']);
73
}
74

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

    
81
if (!is_numeric($id)) {
82
	header("Location: /");
83
	exit;
84
}
85

    
86
if ($pkg['custom_php_global_functions'] != "") {
87
	eval($pkg['custom_php_global_functions']);
88
}
89

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

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

    
102
$a_pkg = &$config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'];
103

    
104
if ($_GET['savemsg'] != "") {
105
	$savemsg = htmlspecialchars($_GET['savemsg']);
106
}
107

    
108
if ($pkg['custom_php_command_before_form'] != "") {
109
	eval($pkg['custom_php_command_before_form']);
110
}
111

    
112
if ($_POST) {
113
	$rows = 0;
114

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

    
130
	if ($pkg['custom_php_validation_command']) {
131
		eval($pkg['custom_php_validation_command']);
132
	}
133

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

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

    
165
	// donotsave is enabled.  lets simply exit.
166
	if (empty($pkg['donotsave'])) {
167

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

    
204
			if (isset($id) && $a_pkg[$id]) {
205
				$a_pkg[$id] = $pkgarr;
206
			} else {
207
				$a_pkg[] = $pkgarr;
208
			}
209

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

    
216
			if (isset($pkg['filter_rules_needed'])) {
217
				filter_configure();
218
			}
219

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

    
225
			parse_package_templates();
226

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

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

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

    
253

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

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

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

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

    
282
			$inpt->setHelp($description);
283

    
284
			if ($ewidth) {
285
				$inpt->setWidth($ewidth);
286
			}
287

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

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

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

    
322
			$grp = new Form_Select(
323
				$fieldname . $trc,
324
				null,
325
				$value,
326
				$options
327
			);
328

    
329
			$grp->setHelp($description);
330

    
331
			if ($ewidth) {
332
				$grp->setWidth($ewidth);
333
			}
334

    
335
			$group->add($grp);
336

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

    
351
			if (is_array($value)) {
352
				$values = $value;
353
			} else {
354
				$values = explode(',', $value);
355
			}
356

    
357
			$ifaces["lo0"] = "loopback";
358
			$options = array();
359
			$selected = array();
360

    
361
			foreach ($ifaces as $ifname => $iface) {
362
				$options[$ifname] = $iface;
363

    
364
				if (in_array($ifname, $values)) {
365
					array_push($selected, $ifname);
366
				}
367
			}
368

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

    
377
			//echo "</select>\n";
378
			break;
379
		case "select_source":
380
			$options = array();
381
			$selected = array();
382

    
383
			if (isset($rowhelper['show_disable_value'])) {
384
				$options[$rowhelper['show_disable_value']] = $rowhelper['show_disable_value'];
385
			}
386

    
387
			$source_url = $rowhelper['source'];
388
			eval("\$pkg_source_txt = &$source_url;");
389

    
390
			foreach ($pkg_source_txt as $opt) {
391
				$source_name = ($rowhelper['source_name'] ? $opt[$rowhelper['source_name']] : $opt[$rowhelper['name']]);
392
				$source_value = ($rowhelper['source_value'] ? $opt[$rowhelper['source_value']] : $opt[$rowhelper['value']]);
393
				$options[$source_value] = $source_name;
394

    
395
				if ($source_value == $value) {
396
					array_push($selected, $value);
397
				}
398
			}
399

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

    
408
			break;
409
	}
410
}
411

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

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

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

    
487
			/* replace cr's */
488
			$template_text = str_replace("\\n", "\n", $template_text);
489

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

    
498
//breadcrumb
499
if ($pkg['title'] != "") {
500
	if (!$only_edit) {
501
		$pkg['title'] = $pkg['title'] . '/Edit';
502
	}
503

    
504
	if (strpos($pkg['title'], '/')) {
505
		$title = explode('/', $pkg['title']);
506

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

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

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

    
538
		if (isset($tab['no_drop_down'])) {
539
			$no_drop_down = true;
540
		}
541

    
542
		$urltmp = "";
543
		if ($tab['url'] != "") {
544
			$urltmp = $tab['url'];
545
		}
546

    
547
		if ($tab['xml'] != "") {
548
			$urltmp = "pkg_edit.php?xml=" . $tab['xml'];
549
		}
550

    
551
		$addresswithport = getenv("HTTP_HOST");
552
		$colonpos = strpos($addresswithport, ":");
553

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

    
561
		// eval url so that above $myurl item can be processed if need be.
562
		$url = str_replace('$myurl', $myurl, $urltmp);
563

    
564
		$tab_array[$tab_level][] = array(
565
			$tab['text'],
566
			$active,
567
			$url
568
		);
569
	}
570

    
571
	ksort($tab_array);
572
}
573

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

    
584
// Start of page display
585
if ($input_errors) {
586
	print_input_errors($input_errors);
587
}
588

    
589
if ($savemsg) {
590
	print_info_box($savemsg, 'success');
591
}
592

    
593
$cols = 0;
594
$savevalue = gettext("Save");
595
if ($pkg['savetext'] != "") {
596
	$savevalue = $pkg['savetext'];
597
}
598

    
599
$savehelp = "";
600
if ($pkg['savehelp'] != "") {
601
	$savehelp = $pkg['savehelp'];
602
}
603

    
604
$saveicon = "fa-save";
605
if ($pkg['saveicon'] != "") {
606
	$saveicon = $pkg['saveicon'];
607
}
608

    
609
$savebtnclass = "btn-primary";
610
if ($pkg['savebtnclass'] != "") {
611
	$savebtnclass = $pkg['savebtnclass'];
612
}
613

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

    
616
$savebutton = new Form_Button(
617
	'submit',
618
	$savevalue,
619
	null,
620
	$saveicon
621
);
622
$savebutton->addClass($savebtnclass);
623

    
624
if ($savehelp) {
625
	$savebutton->setHelp($savehelp);
626
}
627

    
628
$form = new Form($savebutton);
629

    
630
$form->addGlobal(new Form_Input(
631
	'xml',
632
	null,
633
	'hidden',
634
	$xml
635
));
636

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

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

    
649
$js_array = array();
650

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

    
657
	$action = "";
658
	$uid = "";
659

    
660
	if ($pkga['type'] == "sorting") {
661
		continue;
662
	}
663

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

    
672
			$advfield_count++;
673
		}  else {
674
			if (isset($section)) {
675
				$form->add($section);
676
			}
677

    
678
			if (isset($pkga['collapse'])) {
679
				$uid = uniqid("section");
680

    
681
				$action = COLLAPSIBLE;
682

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

    
690
			$section = new Form_Section(strip_tags($pkga['name']), $uid, $action);
691
		}
692

    
693
		continue;
694
	}
695

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

    
702
	$size = "";
703
	$colspan="";
704

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

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

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

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

    
743
			$grp = new Form_Input(
744
					$pkga['fieldname'],
745
					$pkga['fielddescr'],
746
					'text',
747
					$value
748
				);
749

    
750
			$grp->setHelp($pkga['description']);
751

    
752
			if ($pkga['width']) {
753
				$grp->setWidth($pkga['width']);
754
			}
755

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

    
766
			break;
767

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

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

    
799
			break;
800

    
801
		case "info":
802
			// If the info contains a table we should detect and Bootstrap it
803

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

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

    
822
			break;
823

    
824
		case "select":
825
			// Create a select element
826
			$optionlist = array();
827
			$selectedlist = array();
828

    
829
			$fieldname = $pkga['fieldname'];
830

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

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

    
842
			foreach ($pkga['options']['option'] as $opt) {
843
				$optionlist[$opt['value']] = $opt['name'];
844

    
845
				if (in_array($opt['value'], $items)) {
846
					array_push($selectedlist, $opt['value']);
847
				}
848
			}
849

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

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

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

    
866
			if ($pkga['width']) {
867
				$grp->setWidth($pkga['width']);
868
			}
869

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

    
880
			break;
881

    
882
		case "select_source":
883

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

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

    
893
			$source_url = $pkga['source'];
894
			eval("\$pkg_source_txt = &$source_url;");
895

    
896
			#check if show disable option is present on xml
897
			if (!is_array($pkg_source_txt)) {
898
				$pkg_source_txt = array();
899
			}
900
			if (isset($pkga['show_disable_value'])) {
901
				array_push($pkg_source_txt,
902
					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']));
903
			}
904

    
905
			$srcoptions = array();
906
			$srcselected = array();
907

    
908
			foreach ($pkg_source_txt as $opt) {
909
				$source_name =($pkga['source_name']? $opt[$pkga['source_name']] : $opt[$pkga['name']]);
910
				$source_value =($pkga['source_value'] ? $opt[$pkga['source_value']] : $opt[$pkga['value']]);
911
				$srcoptions[$source_value] = $source_name;
912

    
913
				if (in_array($source_value, $items)) {
914
					array_push($srcselected, $source_value);
915
				}
916
			}
917

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

    
947
			break;
948

    
949
		case "vpn_selection" :
950
			$vpnlist = array();
951

    
952
			foreach ($config['ipsec']['phase1'] as $vpn) {
953
				$vpnlist[$vpn['descr']] = $vpn['descr'];
954

    
955
			}
956

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

    
982
			break;
983

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

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

    
1027
			break;
1028

    
1029
		// Create a textarea element
1030
		case "textarea":
1031
			$rows = $cols = 0;
1032

    
1033
			if ($pkga['rows']) {
1034
				$rows = $pkga['rows'];
1035
			}
1036
			if ($pkga['cols']) {
1037
				$cols = $pkga['cols'];
1038
			}
1039

    
1040
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
1041
				$value = base64_decode($value);
1042
			}
1043

    
1044
			$grp = new Form_Textarea(
1045
					$pkga['fieldname'],
1046
					$pkga['fielddescr'],
1047
					$value
1048
			);
1049

    
1050
			$grp->setHelp(fixup_string($pkga['description']));
1051

    
1052
			if ($rows > 0) {
1053
				$grp->setRows($rows);
1054
			}
1055

    
1056
			if ($cols > 0) {
1057
				$grp->setCols($cols);
1058
			}
1059

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

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

    
1077
			break;
1078

    
1079
		case "aliases":
1080

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

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

    
1110
			$grp = new Form_Input(
1111
					$pkga['fieldname'],
1112
					$pkga['fielddescr'],
1113
					'text',
1114
					$value
1115
				);
1116

    
1117
			$grp->setHelp($pkga['description']);
1118

    
1119
			if ($pkga['width']) {
1120
				$grp->setWidth($pkga['width']);
1121
			}
1122

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

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

    
1144
			echo $script;
1145

    
1146
			break;
1147

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

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

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

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

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

    
1209
			$selectedlist = array();
1210
			$optionlist = array();
1211

    
1212
			if (is_array($value)) {
1213
				$values = $value;
1214
			} else {
1215
				$values = explode(',', $value);
1216
			}
1217

    
1218
			foreach ($ips as $iface) {
1219
				if (in_array($iface['ip'], $values)) {
1220
					array_push($selectedlist, $iface['ip']);
1221
				}
1222

    
1223
				$optionlist[$iface['ip']] = $iface['description'];
1224
			}
1225

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

    
1254
			break;
1255

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

    
1286
			break;
1287

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

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

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

    
1326
			break;
1327

    
1328
		case "schedule_selection":
1329

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

    
1341
			foreach ($schedules as $schedule) {
1342
				if ($schedule == "none") {
1343
					$schedlist[""] = $schedule;
1344
				} else {
1345
					$schedlist[$schedule] = $schedule;
1346
				}
1347
			}
1348

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

    
1374
			break;
1375

    
1376
		case "rowhelper":
1377

    
1378
			$rowhelpername="row";
1379

    
1380
				$rowcounter = 0;
1381
				$trc = 0;
1382

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

    
1390
				$numrows = count($saved_rows) - 1;
1391

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

    
1396
					foreach ($pkga['rowhelper']['rowhelperfield'] as $rowhelper) {
1397
						unset($value);
1398
						$width = null;
1399

    
1400
						$fieldname = $rowhelper['fieldname'];
1401
						$fielddescr = $rowhelper['fielddescr'];
1402

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

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

    
1419

    
1420
						if ($rowhelper['size']) {
1421
							$size = $rowhelper['size'];
1422
						} else if ($pkga['size']) {
1423
							$size = $pkga['size'];
1424
						} else {
1425
							$size = "8";
1426
						}
1427

    
1428
						if ($rowhelper['width']) {
1429
							$width = $rowhelper['width'];
1430
						}
1431

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

    
1434
						$text = "";
1435
						$trc++;
1436
					}
1437

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

    
1446
					$rowcounter++;
1447
					$section->add($group);
1448
				}
1449

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

    
1458
			break;
1459

    
1460
	}
1461

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

    
1468
			if ($advanced) {
1469
				$advanced->add($group);
1470
			} else {
1471
				$section->add($group);
1472
			}
1473

    
1474
			$grouping = false;
1475
		}
1476

    
1477
	#increment counter
1478
	$i++;
1479
} // e-o-foreach field described in the XML
1480

    
1481
if ($section) {
1482
	$form->add($section);
1483
}
1484

    
1485
$form->addGlobal(new Form_Input(
1486
	'id',
1487
	null,
1488
	'hidden',
1489
	$id
1490
));
1491

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

    
1501
	$form->add($advanced);
1502
}
1503

    
1504
print($form);
1505

    
1506
if ($pkg['note'] != "") {
1507
	print_info_box($pkg['note'], 'info');
1508
}
1509

    
1510
if ($pkg['custom_php_after_form_command']) {
1511
	eval($pkg['custom_php_after_form_command']);
1512
}
1513

    
1514

    
1515
$hidemsg = gettext("Show Advanced Options");
1516
$showmsg = gettext("Hide Advanced Options");
1517

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

    
1523
	// Hide the advanced section
1524
	var advanced_visible = false;
1525

    
1526
	// Hide on page load
1527
	$('.advancedoptions').hide();
1528

    
1529
	// Suppress "Delete row" button if there are fewer than two rows
1530
	checkLastRow();
1531

    
1532
	// Show advanced section if you click the showadv button
1533
	$("#showadv").click(function() {
1534
		advanced_visible = !advanced_visible;
1535

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

    
1545
	// Call enablechange function
1546
	enablechange();
1547
});
1548

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

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

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

    
1571
			echo "\t}\n\telse {\n";
1572

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

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

    
1589
			echo "\t}\n";
1590
		}
1591
	}
1592
	?>
1593
	}
1594
//]]>
1595
</script>
1596

    
1597
<?php
1598
}
1599

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