Project

General

Profile

Download (41.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
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright notice,
13
 *    this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this software
21
 *    must display the following acknowledgment:
22
 *    "This product includes software developed by the pfSense Project
23
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
24
 *
25
 * 4. The names "pfSense" and "pfSense Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    coreteam@pfsense.org.
29
 *
30
 * 5. Products derived from this software may not be called "pfSense"
31
 *    nor may "pfSense" appear in their names without prior written
32
 *    permission of the Electric Sheep Fencing, LLC.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *
37
 * "This product includes software developed by the pfSense Project
38
 * for use in the pfSense software distribution (http://www.pfsense.org/).
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
41
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
44
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51
 * OF THE POSSIBILITY OF SUCH DAMAGE.
52
 */
53

    
54
##|+PRIV
55
##|*IDENT=page-package-edit
56
##|*NAME=Package: Edit
57
##|*DESCR=Allow access to the 'Package: Edit' page.
58
##|*MATCH=pkg_edit.php*
59
##|-PRIV
60

    
61
ini_set('max_execution_time', '0');
62

    
63
require_once("guiconfig.inc");
64
require_once("functions.inc");
65
require_once("filter.inc");
66
require_once("shaper.inc");
67
require_once("pkg-utils.inc");
68

    
69
/* dummy stubs needed by some code that was MFC'd */
70
function pfSenseHeader($location) {
71
	header("Location: " . $location);
72
}
73

    
74
$xml = htmlspecialchars($_GET['xml']);
75
if ($_POST['xml']) {
76
	$xml = htmlspecialchars($_POST['xml']);
77
}
78

    
79
$xml_fullpath = realpath('/usr/local/pkg/' . $xml);
80

    
81
if ($xml == "" || $xml_fullpath === false || substr($xml_fullpath, 0, strlen('/usr/local/pkg/')) != '/usr/local/pkg/') {
82
	$pgtitle = array(gettext("Package"), gettext("Editor"));
83
	include("head.inc");
84
	print_info_box(gettext("No valid package defined."), 'danger', false);
85
	include("foot.inc");
86
	die;
87
} else {
88
	$pkg = parse_xml_config_pkg($xml_fullpath, "packagegui");
89
}
90

    
91
if ($pkg['include_file'] != "") {
92
	require_once($pkg['include_file']);
93
}
94

    
95
if (!isset($pkg['adddeleteeditpagefields'])) {
96
	$only_edit = true;
97
} else {
98
	$only_edit = false;
99
}
100

    
101
$id = $_GET['id'];
102
if (isset($_POST['id'])) {
103
	$id = htmlspecialchars($_POST['id']);
104
}
105

    
106
// Not posting?	 Then user is editing a record. There must be a valid id
107
// when editing a record.
108
if (!$id && !$_POST) {
109
	$id = "0";
110
}
111

    
112
if (!is_numeric($id)) {
113
	header("Location: /");
114
	exit;
115
}
116

    
117
if ($pkg['custom_php_global_functions'] != "") {
118
	eval($pkg['custom_php_global_functions']);
119
}
120

    
121
// grab the installedpackages->package_name section.
122
if ($config['installedpackages'] && !is_array($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'])) {
123
	$config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'] = array();
124
}
125

    
126
// If the first entry in the array is an empty <config/> tag, kill it.
127
if ($config['installedpackages'] &&
128
    (count($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config']) > 0) &&
129
    ($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'][0] == "")) {
130
	array_shift($config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config']);
131
}
132

    
133
$a_pkg = &$config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'];
134

    
135
if ($_GET['savemsg'] != "") {
136
	$savemsg = htmlspecialchars($_GET['savemsg']);
137
}
138

    
139
if ($pkg['custom_php_command_before_form'] != "") {
140
	eval($pkg['custom_php_command_before_form']);
141
}
142

    
143
if ($_POST) {
144
	$rows = 0;
145

    
146
	$input_errors = array();
147
	$reqfields = array();
148
	$reqfieldsn = array();
149
	foreach ($pkg['fields']['field'] as $field) {
150
		if (isset($field['required'])) {
151
			if ($field['fieldname']) {
152
				$reqfields[] = $field['fieldname'];
153
			}
154
			if ($field['fielddescr']) {
155
				$reqfieldsn[] = $field['fielddescr'];
156
			}
157
		}
158
	}
159
	do_input_validation($_POST, $reqfields, $reqfieldsn, $input_errors);
160

    
161
	if ($pkg['custom_php_validation_command']) {
162
		eval($pkg['custom_php_validation_command']);
163
	}
164

    
165
	if ($_POST['act'] == "del") {
166
		if ($pkg['custom_delete_php_command']) {
167
			if ($pkg['custom_php_command_before_form'] != "") {
168
				eval($pkg['custom_php_command_before_form']);
169
			}
170
			eval($pkg['custom_delete_php_command']);
171
		}
172
		write_config($pkg['delete_string']);
173
		// resync the configuration file code if defined.
174
		if ($pkg['custom_php_resync_config_command'] != "") {
175
			if ($pkg['custom_php_command_before_form'] != "") {
176
				eval($pkg['custom_php_command_before_form']);
177
			}
178
			eval($pkg['custom_php_resync_config_command']);
179
		}
180
	} else {
181
		if (!$input_errors && $pkg['custom_add_php_command']) {
182
			if ($pkg['donotsave'] != "" or $pkg['preoutput'] != "") {
183
				include("head.inc");
184
			}
185

    
186
			if ($pkg['preoutput']) {
187
				echo "<pre>";
188
			}
189
			eval($pkg['custom_add_php_command']);
190
			if ($pkg['preoutput']) {
191
				echo "</pre>";
192
			}
193
		}
194
	}
195

    
196
	// donotsave is enabled.  lets simply exit.
197
	if (empty($pkg['donotsave'])) {
198

    
199
		// store values in xml configuration file.
200
		if (!$input_errors) {
201
			$pkgarr = array();
202
			foreach ($pkg['fields']['field'] as $fields) {
203
				switch ($fields['type']) {
204
					case "rowhelper":
205
						// save rowhelper items.
206
						#$rowhelpername=($fields['fieldname'] ? $fields['fieldname'] : "row");
207
						$rowhelpername="row";
208
						foreach ($fields['rowhelper']['rowhelperfield'] as $rowhelperfield) {
209
							foreach ($_POST as $key => $value) {
210
								$matches = array();
211
								if (preg_match("/^{$rowhelperfield['fieldname']}(\d+)$/", $key, $matches)) {
212
									$pkgarr[$rowhelpername][$matches[1]][$rowhelperfield['fieldname']] = $value;
213
								}
214
							}
215
						}
216
						break;
217
					default:
218
						$fieldname = $fields['fieldname'];
219
						if ($fieldname == "interface_array") {
220
							$fieldvalue = $_POST[$fieldname];
221
						} elseif (is_array($_POST[$fieldname])) {
222
							$fieldvalue = implode(',', $_POST[$fieldname]);
223
						} else {
224
							$fieldvalue = trim($_POST[$fieldname]);
225
							if ($fields['encoding'] == 'base64') {
226
								$fieldvalue = base64_encode($fieldvalue);
227
							}
228
						}
229
						if ($fieldname) {
230
							$pkgarr[$fieldname] = $fieldvalue;
231
						}
232
					}
233
			}
234

    
235
			if (isset($id) && $a_pkg[$id]) {
236
				$a_pkg[$id] = $pkgarr;
237
			} else {
238
				$a_pkg[] = $pkgarr;
239
			}
240

    
241
			write_config($pkg['addedit_string']);
242
			// late running code
243
			if ($pkg['custom_add_php_command_late'] != "") {
244
				eval($pkg['custom_add_php_command_late']);
245
			}
246

    
247
			if (isset($pkg['filter_rules_needed'])) {
248
				filter_configure();
249
			}
250

    
251
			// resync the configuration file code if defined.
252
			if ($pkg['custom_php_resync_config_command'] != "") {
253
				eval($pkg['custom_php_resync_config_command']);
254
			}
255

    
256
			parse_package_templates();
257

    
258
			/* if start_command is defined, restart w/ this */
259
			if ($pkg['start_command'] != "") {
260
				exec($pkg['start_command'] . ">/dev/null 2&>1");
261
			}
262

    
263
			/* if restart_command is defined, restart w/ this */
264
			if ($pkg['restart_command'] != "") {
265
				exec($pkg['restart_command'] . ">/dev/null 2&>1");
266
			}
267

    
268
			if ($pkg['aftersaveredirect'] != "") {
269
				pfSenseHeader($pkg['aftersaveredirect']);
270
			} elseif (!$pkg['adddeleteeditpagefields']) {
271
				pfSenseHeader("pkg_edit.php?xml={$xml}&id=0");
272
			} elseif (!$pkg['preoutput']) {
273
				pfSenseHeader("pkg.php?xml=" . $xml);
274
			}
275
			exit;
276
		} else {
277
			$get_from_post = true;
278
		}
279
	} elseif (!$input_errors) {
280
		exit;
281
	}
282
}
283

    
284

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

    
291
	// Substitute everything inbetween with our new classes
292
	if ($t && $c && (($c - $t) < 200)) {
293
		return(substr_replace($text, ' class="table table-striped table-hover table-condensed"', $t, ($c - $t)));
294
	}
295
}
296

    
297
/*
298
 * ROW helper function. Creates one element in the row from a PHP table by adding
299
 * the specified element to $group
300
 */
301
function display_row($trc, $value, $fieldname, $type, $rowhelper, $description, $ewidth = null) {
302
	global $text, $group, $config;
303

    
304
	switch ($type) {
305
		case "input":
306
			$inpt = new Form_Input(
307
				$fieldname . $trc,
308
				null,
309
				'text',
310
				$value
311
			);
312

    
313
			$inpt->setHelp($description);
314

    
315
			if ($ewidth) {
316
				$inpt->setWidth($ewidth);
317
			}
318

    
319
			$group->add($inpt);
320
			break;
321
		case "checkbox":
322
			$group->add(new Form_Checkbox(
323
				$fieldname . $trc,
324
				null,
325
				null,
326
				$value,
327
				'ON'
328
			))->setHelp($description);
329

    
330
			break;
331
		case "password":
332
			$group->add(new Form_Input(
333
				$fieldname . $trc,
334
				null,
335
				'password',
336
				$value
337
			))->setHelp($description);
338
			break;
339
		case "textarea":
340
			$group->add(new Form_Textarea(
341
				$fieldname . $trc,
342
				null,
343
				$value
344
			))->setHelp($description);
345

    
346
			break;
347
		case "select":
348
			$options = array();
349
			foreach ($rowhelper['options']['option'] as $rowopt) {
350
				$options[$rowopt['value']] = $rowopt['name'];
351
			}
352

    
353
			$grp = new Form_Select(
354
				$fieldname . $trc,
355
				null,
356
				$value,
357
				$options
358
			);
359

    
360
			$grp->setHelp($description);
361

    
362
			if ($ewidth) {
363
				$grp->setWidth($ewidth);
364
			}
365

    
366
			$group->add($grp);
367

    
368
			break;
369
		case "interfaces_selection":
370
			$size = ($size ? "size=\"{$size}\"" : '');
371
			$multiple = '';
372
			if (isset($rowhelper['multiple'])) {
373
				$multiple = "multiple";
374
			}
375
			echo "<select style='height:22px;' id='{$fieldname}{$trc}' name='{$fieldname}{$trc}' {$size} {$multiple}>\n";
376
			$ifaces = get_configured_interface_with_descr();
377
			$additional_ifaces = $rowhelper['add_to_interfaces_selection'];
378
			if (!empty($additional_ifaces)) {
379
				$ifaces = array_merge($ifaces, explode(',', $additional_ifaces));
380
			}
381

    
382
			if (is_array($value)) {
383
				$values = $value;
384
			} else {
385
				$values = explode(',', $value);
386
			}
387

    
388
			$ifaces["lo0"] = "loopback";
389
			$options = array();
390
			$selected = array();
391

    
392
			foreach ($ifaces as $ifname => $iface) {
393
				$options[$ifname] = $iface;
394

    
395
				if (in_array($ifname, $values)) {
396
					array_push($selected, $ifname);
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
			//echo "</select>\n";
409
			break;
410
		case "select_source":
411
			$options = array();
412
			$selected = array();
413

    
414
			if (isset($rowhelper['show_disable_value'])) {
415
				$options[$rowhelper['show_disable_value']] = $rowhelper['show_disable_value'];
416
			}
417

    
418
			$source_url = $rowhelper['source'];
419
			eval("\$pkg_source_txt = &$source_url;");
420

    
421
			foreach ($pkg_source_txt as $opt) {
422
				$source_name = ($rowhelper['source_name'] ? $opt[$rowhelper['source_name']] : $opt[$rowhelper['name']]);
423
				$source_value = ($rowhelper['source_value'] ? $opt[$rowhelper['source_value']] : $opt[$rowhelper['value']]);
424
				$options[$source_value] = $source_name;
425

    
426
				if ($source_value == $value) {
427
					array_push($selected, $value);
428
				}
429
			}
430

    
431
			$group->add(new Form_Select(
432
				$fieldname . $trc,
433
				null,
434
				($multiple) ? $selected:$selected[0],
435
				$options,
436
				$multiple
437
			))->setHelp($description);
438

    
439
			break;
440
	}
441
}
442

    
443
function fixup_string($string) {
444
	global $config;
445
	// fixup #1: $myurl -> http[s]://ip_address:port/
446
	$https = "";
447
	$port = $config['system']['webguiport'];
448
	if ($port != "443" and $port != "80") {
449
		$urlport = ":" . $port;
450
	} else {
451
		$urlport = "";
452
	}
453

    
454
	if ($config['system']['webgui']['protocol'] == "https") {
455
		$https = "s";
456
	}
457
	$myurl = "http" . $https . "://" . getenv("HTTP_HOST") . $urlport;
458
	$newstring = str_replace("\$myurl", $myurl, $string);
459
	$string = $newstring;
460
	// fixup #2: $wanip
461
	$curwanip = get_interface_ip();
462
	$newstring = str_replace("\$wanip", $curwanip, $string);
463
	$string = $newstring;
464
	// fixup #3: $lanip
465
	$lancfg = $config['interfaces']['lan'];
466
	$lanip = $lancfg['ipaddr'];
467
	$newstring = str_replace("\$lanip", $lanip, $string);
468
	$string = $newstring;
469
	// fixup #4: fix'r'up here.
470
	return $newstring;
471
}
472

    
473
/*
474
 *	Parse templates if they are defined
475
 */
476
function parse_package_templates() {
477
	global $pkg;
478
	if ($pkg['templates']['template'] != "") {
479
		foreach ($pkg['templates']['template'] as $pkg_template_row) {
480
			$filename = $pkg_template_row['filename'];
481
			$template_text = $pkg_template_row['templatecontents'];
482
			/* calculate total row helpers count and */
483
			/* change fields defined as fieldname_fieldvalue to their value */
484
			foreach ($pkg['fields']['field'] as $fields) {
485
				switch ($fields['type']) {
486
					case "rowhelper":
487
						// save rowhelper items.
488
						$row_helper_total_rows = 0;
489
						$row_helper_data = "";
490
						foreach ($fields['rowhelper']['rowhelperfield'] as $rowhelperfield) {
491
							foreach ($_POST as $key => $value) {
492
								if (preg_match("/^{$rowhelperfield['fieldname']}(\d+)$/", $key, $matches)) {
493
									$row_helper_total_rows++;
494
									$row_helper_data .= $value;
495
									$sep = "";
496
									ereg($rowhelperfield['fieldname'] . "_fieldvalue\[(.*)\]", $template_text, $sep);
497
									foreach ($sep as $se) {
498
										$separator = $se;
499
									}
500
									if ($separator != "") {
501
										$row_helper_data = ereg_replace("  ", $separator, $row_helper_data);
502
										$template_text = ereg_replace("\[{$separator}\]", "", $template_text);
503
									}
504
									$template_text = str_replace($rowhelperfield['fieldname'] . "_fieldvalue", $row_helper_data, $template_text);
505
								}
506
							}
507
						}
508
						break;
509
					default:
510
						$fieldname = $fields['fieldname'];
511
						$fieldvalue = $_POST[$fieldname];
512
						$template_text = str_replace($fieldname . "_fieldvalue", $fieldvalue, $template_text);
513
				}
514
			}
515
			/* replace $domain_total_rows with total rows */
516
			$template_text = str_replace("$domain_total_rows", $row_helper_total_rows, $template_text);
517

    
518
			/* replace cr's */
519
			$template_text = str_replace("\\n", "\n", $template_text);
520

    
521
			/* write out new template file */
522
			$fout = fopen($filename, "w");
523
			fwrite($fout, $template_text);
524
			fclose($fout);
525
		}
526
	}
527
}
528

    
529
//breadcrumb
530
if ($pkg['title'] != "") {
531
	if (!$only_edit) {
532
		$pkg['title'] = $pkg['title'] . '/Edit';
533
	}
534

    
535
	if (strpos($pkg['title'], '/')) {
536
		$title = explode('/', $pkg['title']);
537

    
538
		foreach ($title as $subtitle) {
539
			$pgtitle[] = gettext($subtitle);
540
		}
541
	} else {
542
		$pgtitle = array(gettext("Package"), gettext($pkg['title']));
543
	}
544
} else {
545
	$pgtitle = array(gettext("Package"), gettext("Editor"));
546
}
547

    
548
// Create any required tabs
549
if ($pkg['tabs'] != "") {
550
	$tab_array = array();
551
	foreach ($pkg['tabs']['tab'] as $tab) {
552
		if ($tab['tab_level']) {
553
			$tab_level = $tab['tab_level'];
554
		} else {
555
			$tab_level = 1;
556
		}
557

    
558
		if (isset($tab['active'])) {
559
			$active = true;
560
			$pgtitle[] = $tab['text'] ;
561
		} else {
562
			$active = false;
563
		}
564

    
565
		if (isset($tab['no_drop_down'])) {
566
			$no_drop_down = true;
567
		}
568

    
569
		$urltmp = "";
570
		if ($tab['url'] != "") {
571
			$urltmp = $tab['url'];
572
		}
573

    
574
		if ($tab['xml'] != "") {
575
			$urltmp = "pkg_edit.php?xml=" . $tab['xml'];
576
		}
577

    
578
		$addresswithport = getenv("HTTP_HOST");
579
		$colonpos = strpos($addresswithport, ":");
580

    
581
		if ($colonpos !== False) {
582
			//my url is actually just the IP address of the pfsense box
583
			$myurl = substr($addresswithport, 0, $colonpos);
584
		} else {
585
			$myurl = $addresswithport;
586
		}
587

    
588
		// eval url so that above $myurl item can be processed if need be.
589
		$url = str_replace('$myurl', $myurl, $urltmp);
590

    
591
		$tab_array[$tab_level][] = array(
592
			$tab['text'],
593
			$active,
594
			$url
595
		);
596
	}
597

    
598
	ksort($tab_array);
599
}
600

    
601
include("head.inc");
602
if ($pkg['custom_php_after_head_command']) {
603
	eval($pkg['custom_php_after_head_command']);
604
}
605
if (isset($tab_array)) {
606
	foreach ($tab_array as $tabid => $tab) {
607
		display_top_tabs($tab); //, $no_drop_down, $tabid);
608
	}
609
}
610

    
611
// Start of page display
612
if ($input_errors) {
613
	print_input_errors($input_errors);
614
}
615

    
616
if ($savemsg) {
617
	print_info_box($savemsg, 'success');
618
}
619

    
620
$cols = 0;
621
$savevalue = gettext("Save");
622
if ($pkg['savetext'] != "") {
623
	$savevalue = $pkg['savetext'];
624
}
625

    
626
$savehelp = "";
627
if ($pkg['savehelp'] != "") {
628
	$savehelp = $pkg['savehelp'];
629
}
630

    
631
$saveicon = "fa-save";
632
if ($pkg['saveicon'] != "") {
633
	$saveicon = $pkg['saveicon'];
634
}
635

    
636
$savebtnclass = "btn-primary";
637
if ($pkg['savebtnclass'] != "") {
638
	$savebtnclass = $pkg['savebtnclass'];
639
}
640

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

    
643
$savebutton = new Form_Button(
644
	'submit',
645
	$savevalue,
646
	null,
647
	$saveicon
648
);
649
$savebutton->addClass($savebtnclass);
650

    
651
if ($savehelp) {
652
	$savebutton->setHelp($savehelp);
653
}
654

    
655
$form = new Form($savebutton);
656

    
657
$form->addGlobal(new Form_Input(
658
	'xml',
659
	null,
660
	'hidden',
661
	$xml
662
));
663

    
664
/* If a package's XML has <advanced_options/> configured, then setup
665
 * the section for the fields that have <advancedfield/> set.
666
 * These fields will be placed below other fields in a separate area titled 'Advanced Features'.
667
 * These advanced fields are not normally configured and generally left to default to 'default settings'.
668
 */
669

    
670
if ($pkg['advanced_options'] == "enabled") {
671
	$advfield_count = 0;
672
	$advanced = new Form_Section("Advanced Features");
673
	$advanced->addClass('advancedoptions');
674
}
675

    
676
$js_array = array();
677

    
678
// Now loop through all of the fields defined in the XML
679
if (!is_array($pkg['fields']['field'])) {
680
	$pkg['fields']['field'] = array();
681
}
682
foreach ($pkg['fields']['field'] as $pkga) {
683

    
684
	$action = "";
685
	$uid = "";
686

    
687
	if ($pkga['type'] == "sorting") {
688
		continue;
689
	}
690

    
691
	// Generate a new section
692
	if ($pkga['type'] == "listtopic") {
693
		if (isset($pkga['advancedfield']) && isset($advfield_count)) {
694
			$advanced->addInput(new Form_StaticText(
695
				strip_tags($pkga['name']),
696
				null
697
			));
698

    
699
			$advfield_count++;
700
		}  else {
701
			if (isset($section)) {
702
				$form->add($section);
703
			}
704

    
705
			if (isset($pkga['collapse'])) {
706
				$uid = uniqid("section");
707

    
708
				$action = COLLAPSIBLE;
709

    
710
				if ($pkga['collapse'] == "open") {
711
					$action |= SEC_OPEN;
712
				} else {
713
					$action |= SEC_CLOSED;
714
				}
715
			}
716

    
717
			$section = new Form_Section(strip_tags($pkga['name']), $uid, $action);
718
		}
719

    
720
		continue;
721
	}
722

    
723
	// 'begin' starts a form group. ('end' ends it)
724
	if ($pkga['combinefields'] == "begin") {
725
		$group = new Form_Group(strip_tags($pkga['fielddescr']));
726
		$grouping = true;
727
	}
728

    
729
	$size = "";
730
	$colspan="";
731

    
732
	// if user is editing a record, load in the data.
733
	$fieldname = $pkga['fieldname'];
734
	unset($value);
735
	if ($get_from_post) {
736
		$value = $_POST[$fieldname];
737
		if (is_array($value)) {
738
			$value = implode(',', $value);
739
		}
740
	} else {
741
		if (isset($id) && isset($a_pkg[$id][$fieldname])) {
742
			$value = $a_pkg[$id][$fieldname];
743
		} else {
744
			if (isset($pkga['default_value'])) {
745
				$value = $pkga['default_value'];
746
			}
747
		}
748
	}
749

    
750
	// If we get here but have no $section, the package config file probably had no listtopic field
751
	// We can create a section with a generic name to fix that
752
	if (!$section) {
753
		$section = new Form_Section('General Options');
754
	}
755

    
756
	switch ($pkga['type']) {
757
		// Create an input element. The format is slightly different depending on whether we are composing a group,
758
		// section, or advanced section. This is true for every element type
759
		case "input":
760
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
761
				$value = base64_decode($value);
762
			}
763

    
764
			$grp = new Form_Input(
765
					$pkga['fieldname'],
766
					$pkga['fielddescr'],
767
					'text',
768
					$value
769
				);
770

    
771
			$grp->setHelp($pkga['description']);
772

    
773
			if ($pkga['width']) {
774
				$grp->setWidth($pkga['width']);
775
			}
776

    
777
			if ($grouping) {
778
				$group->add($grp);
779
			} else {
780
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
781
					$advanced->addInput($grp);
782
				} else {
783
					$section->addInput($grp);
784
				}
785
			}
786

    
787
			break;
788

    
789
		case "password":
790
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
791
				$value = base64_decode($value);
792
			}
793

    
794
			// Create a password element
795
			if ($grouping) {
796
				$group->add(new Form_Input(
797
					$pkga['fieldname'],
798
					$pkga['fielddescr'],
799
					'password',
800
					$value
801
				))->setHelp($pkga['description']);
802
			} else {
803
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
804
					$advanced->addInput(new Form_Input(
805
						$pkga['fieldname'],
806
						$pkga['fielddescr'],
807
						'password',
808
						$value
809
					))->setHelp($pkga['description']);
810
				} else {
811
					$section->addInput(new Form_Input(
812
						$pkga['fieldname'],
813
						$pkga['fielddescr'],
814
						'password',
815
						$value
816
					))->setHelp($pkga['description']);
817
				}
818
			}
819

    
820
			break;
821

    
822
		case "info":
823
			// If the info contains a table we should detect and Bootstrap it
824

    
825
			if (strpos($pkga['description'], '<table') !== FALSE) {
826
				$info = bootstrapTable($pkga['description']);
827
			} else {
828
				$info = $pkga['description'];
829
			}
830

    
831
			if (isset($pkga['advancedfield']) && isset($advfield_count)) {
832
				$advanced->addInput(new Form_StaticText(
833
					strip_tags($pkga['fielddescr']),
834
					$info
835
				));
836
			} else {
837
				$section->addInput(new Form_StaticText(
838
					strip_tags($pkga['fielddescr']),
839
					$info
840
				));
841
			}
842

    
843
			break;
844

    
845
		case "select":
846
			// Create a select element
847
			$optionlist = array();
848
			$selectedlist = array();
849

    
850
			$fieldname = $pkga['fieldname'];
851

    
852
			if (isset($pkga['multiple'])) {
853
				$multiple = 'multiple';
854
				$items = explode(',', $value);
855
				$fieldname .= "[]";
856
			} else {
857
				$multiple = '';
858
				$items = array($value);
859
			}
860

    
861
			$onchange = (isset($pkga['onchange']) ? "onchange=\"{$pkga['onchange']}\"" : '');
862

    
863
			foreach ($pkga['options']['option'] as $opt) {
864
				$optionlist[$opt['value']] = $opt['name'];
865

    
866
				if (in_array($opt['value'], $items)) {
867
					array_push($selectedlist, $opt['value']);
868
				}
869
			}
870

    
871
			if (isset($pkga['advancedfield']) && isset($advfield_count)) {
872
				$function = $grouping ? $advanced->add:$advanced->addInput;
873
			} else {
874
				$function = ($grouping) ? $section->add:$section->addInput;
875
			}
876

    
877
			$grp = new Form_Select(
878
						$pkga['fieldname'],
879
						strip_tags($pkga['fielddescr']),
880
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
881
						$optionlist,
882
						isset($pkga['multiple'])
883
					);
884

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

    
887
			if ($pkga['width']) {
888
				$grp->setWidth($pkga['width']);
889
			}
890

    
891
			if ($grouping) {
892
				$group->add($grp);
893
			} else {
894
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
895
					$advanced->addInput($grp);
896
				} else {
897
					$section->addInput($grp);
898
				}
899
			}
900

    
901
			break;
902

    
903
		case "select_source":
904

    
905
			if (isset($pkga['multiple'])) {
906
				$items = explode(',', $value);
907
				$fieldname .= "[]";
908
			} else {
909
				$items = array($value);
910
			}
911

    
912
			$onchange = (isset($pkga['onchange']) ? "onchange=\"{$pkga['onchange']}\"" : '');
913

    
914
			$source_url = $pkga['source'];
915
			eval("\$pkg_source_txt = &$source_url;");
916

    
917
			#check if show disable option is present on xml
918
			if (!is_array($pkg_source_txt)) {
919
				$pkg_source_txt = array();
920
			}
921
			if (isset($pkga['show_disable_value'])) {
922
				array_push($pkg_source_txt,
923
					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']));
924
			}
925

    
926
			$srcoptions = array();
927
			$srcselected = array();
928

    
929
			foreach ($pkg_source_txt as $opt) {
930
				$source_name =($pkga['source_name']? $opt[$pkga['source_name']] : $opt[$pkga['name']]);
931
				$source_value =($pkga['source_value'] ? $opt[$pkga['source_value']] : $opt[$pkga['value']]);
932
				$srcoptions[$source_value] = $source_name;
933

    
934
				if (in_array($source_value, $items)) {
935
					array_push($srcselected, $source_value);
936
				}
937
			}
938

    
939
			$descr = (isset($pkga['description'])) ? $pkga['description'] : "";
940
			if ($grouping) {
941
				$group->add(new Form_Select(
942
					$pkga['fieldname'],
943
					strip_tags($pkga['fielddescr']),
944
					isset($pkga['multiple']) ? $srcselected:$srcselected[0],
945
					$srcoptions,
946
					isset($pkga['multiple'])
947
				))->setHelp($descr)->setOnchange($onchange);
948
			} else {
949
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
950
					$advanced->addInput(new Form_Select(
951
						$pkga['fieldname'],
952
						strip_tags($pkga['fielddescr']),
953
						isset($pkga['multiple']) ? $srcselected:$srcselected[0],
954
						$srcoptions,
955
						isset($pkga['multiple'])
956
					))->setHelp($descr)->setOnchange($onchange);
957
				} else {
958
					$section->addInput(new Form_Select(
959
						$pkga['fieldname'],
960
						strip_tags($pkga['fielddescr']),
961
						isset($pkga['multiple']) ? $srcselected:$srcselected[0],
962
						$srcoptions,
963
						isset($pkga['multiple'])
964
					))->setHelp($descr)->setOnchange($onchange);
965
				}
966
			}
967

    
968
			break;
969

    
970
		case "vpn_selection" :
971
			$vpnlist = array();
972

    
973
			foreach ($config['ipsec']['phase1'] as $vpn) {
974
				$vpnlist[$vpn['descr']] = $vpn['descr'];
975

    
976
			}
977

    
978
			if ($grouping) {
979
				$group->add(new Form_Select(
980
					$pkga['fieldname'],
981
					null,
982
					false,
983
					$vpnlist
984
				))->setHelp(fixup_string($pkga['description']));
985
			} else {
986
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
987
					$advanced->addInput(new Form_Select(
988
						$pkga['fieldname'],
989
						null,
990
						false,
991
						$vpnlist
992
					))->setHelp(fixup_string($pkga['description']));
993
				} else {
994
					$section->addInput(new Form_Select(
995
						$pkga['fieldname'],
996
						null,
997
						false,
998
						$vpnlist
999
					))->setHelp(fixup_string($pkga['description']));
1000
				}
1001
			}
1002

    
1003
			break;
1004

    
1005
		// Create a checkbox element
1006
		case "checkbox":
1007
			$onchange = (isset($pkga['onchange']) ? "{$pkga['onchange']}" : '');
1008
			if (isset($pkga['enablefields']) || isset($pkga['checkenablefields'])) {
1009
				$onclick = 'javascript:enablechange();';
1010
			} else {
1011
				$onclick = '';
1012
			}
1013

    
1014
			if ($grouping) {
1015
				$group->add(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
			} else {
1025
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1026
					$advanced->addInput(new Form_Checkbox(
1027
						$pkga['fieldname'],
1028
						$pkga['fielddescr'],
1029
						fixup_string($pkga['description']),
1030
						($value == "on"),
1031
						'on'
1032
					))->setOnclick($onclick)
1033
					  ->setOnchange($onchange)
1034
					  ->setHelp($pkga['sethelp']);
1035
				} else {
1036
					$section->addInput(new Form_Checkbox(
1037
						$pkga['fieldname'],
1038
						$pkga['fielddescr'],
1039
						fixup_string($pkga['description']),
1040
						($value == "on"),
1041
						'on'
1042
					))->setOnclick($onclick)
1043
					  ->setOnchange($onchange)
1044
					  ->setHelp($pkga['sethelp']);
1045
				}
1046
			}
1047

    
1048
			break;
1049

    
1050
		// Create a textarea element
1051
		case "textarea":
1052
			$rows = $cols = 0;
1053

    
1054
			if ($pkga['rows']) {
1055
				$rows = $pkga['rows'];
1056
			}
1057
			if ($pkga['cols']) {
1058
				$cols = $pkga['cols'];
1059
			}
1060

    
1061
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
1062
				$value = base64_decode($value);
1063
			}
1064

    
1065
			$grp = new Form_Textarea(
1066
					$pkga['fieldname'],
1067
					$pkga['fielddescr'],
1068
					$value
1069
			);
1070

    
1071
			$grp->setHelp(fixup_string($pkga['description']));
1072

    
1073
			if ($rows > 0) {
1074
				$grp->setRows($rows);
1075
			}
1076

    
1077
			if ($cols > 0) {
1078
				$grp->setCols($cols);
1079
			}
1080

    
1081
			if ($pkga['wrap'] == "off") {
1082
				$grp->setAttribute("wrap", "off");
1083
				$grp->setAttribute("style", "white-space:nowrap; width: auto;");
1084
			} else {
1085
				$grp->setAttribute("style", "width: auto;");
1086
			}
1087

    
1088
			if ($grouping) {
1089
				$group->add($grp);
1090
			} else {
1091
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1092
					$advanced->addInput($grp);
1093
				} else {
1094
					$section->addInput($grp);
1095
				}
1096
			}
1097

    
1098
			break;
1099

    
1100
		case "aliases":
1101

    
1102
			// Use xml tag <typealiases> to filter type aliases
1103
			$size = ($pkga['size'] ? "size=\"{$pkga['size']}\"" : '');
1104
			$fieldname = $pkga['fieldname'];
1105
			$a_aliases = &$config['aliases']['alias'];
1106
			$addrisfirst = 0;
1107
			$aliasesaddr = "";
1108

    
1109
			if (isset($a_aliases)) {
1110
				if (!empty($pkga['typealiases'])) {
1111
					foreach ($a_aliases as $alias) {
1112
						if ($alias['type'] == $pkga['typealiases']) {
1113
							if ($addrisfirst == 1) {
1114
								$aliasesaddr .= ",";
1115
							}
1116
							$aliasesaddr .= "'" . $alias['name'] . "'";
1117
							$addrisfirst = 1;
1118
						}
1119
					}
1120
				} else {
1121
					foreach ($a_aliases as $alias) {
1122
						if ($addrisfirst == 1) {
1123
							$aliasesaddr .= ",";
1124
						}
1125
						$aliasesaddr .= "'" . $alias['name'] . "'";
1126
						$addrisfirst = 1;
1127
					}
1128
				}
1129
			}
1130

    
1131
			$grp = new Form_Input(
1132
					$pkga['fieldname'],
1133
					$pkga['fielddescr'],
1134
					'text',
1135
					$value
1136
				);
1137

    
1138
			$grp->setHelp($pkga['description']);
1139

    
1140
			if ($pkga['width']) {
1141
				$grp->setWidth($pkga['width']);
1142
			}
1143

    
1144
			if (grouping) {
1145
				$group->add($grp);
1146
			} else {
1147
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1148
					$advanced->addInput($grp);
1149
				} else {
1150
					$section->addInput($grp);
1151
				}
1152
			}
1153

    
1154
			$script = "<script type='text/javascript'>\n";
1155
			$script .= "//<![CDATA[\n";
1156
			$script .= "events.push(function(){\n";
1157
			$script .= "	var aliasarray = new Array({$aliasesaddr})\n";
1158
			$script .= "	$('#' + '{$fieldname}').autocomplete({\n";
1159
			$script .= "		source: aliasarray\n";
1160
			$script .= "	})\n";
1161
			$script .= "});\n";
1162
			$script .= "//]]>\n";
1163
			$script .= "</script>";
1164

    
1165
			echo $script;
1166

    
1167
			break;
1168

    
1169
		case "interfaces_selection":
1170
			$ips = array();
1171
			$interface_regex=(isset($pkga['hideinterfaceregex']) ? $pkga['hideinterfaceregex'] : "nointerfacestohide");
1172
			if (is_array($config['interfaces'])) {
1173
				foreach ($config['interfaces'] as $iface_key=>$iface_value) {
1174
					if (isset($iface_value['enable']) && !preg_match("/$interface_regex/", $iface_key)) {
1175
						$iface_description=($iface_value['descr'] !="" ? strtoupper($iface_value['descr']) : strtoupper($iface_key));
1176
						if (isset($pkga['showips'])) {
1177
							$iface_description .= " address";
1178
						}
1179
						$ips[] = array('ip'=> $iface_key, 'description'=> $iface_description);
1180
					}
1181
				}
1182
			}
1183

    
1184
			if (is_array($config['virtualip']) && isset($pkga['showvirtualips'])) {
1185
				foreach ($config['virtualip']['vip'] as $vip) {
1186
					if (!preg_match("/$interface_regex/", $vip['interface'])) {
1187
						$vip_description=($vip['descr'] !="" ? " ({$vip['descr']}) " : " ");
1188
					}
1189
					switch ($vip['mode']) {
1190
						case "ipalias":
1191
						case "carp":
1192
							$ips[] = array('ip' => $vip['subnet'], 'description' => "{$vip['subnet']} $vip_description");
1193
							break;
1194
						case "proxyarp":
1195
							if ($vip['type'] == "network") {
1196
								$start = ip2long32(gen_subnet($vip['subnet'], $vip['subnet_bits']));
1197
								$end = ip2long32(gen_subnet_max($vip['subnet'], $vip['subnet_bits']));
1198
								$len = $end - $start;
1199
								for ($i = 0; $i <= $len; $i++) {
1200
									$ips[]= array('ip' => long2ip32($start+$i), 'description' => long2ip32($start+$i)." from {$vip['subnet']}/{$vip['subnet_bits']} {$vip_description}");
1201
								}
1202
							} else {
1203
								$ips[]= array('ip' => $vip['subnet'], 'description' => "{$vip['subnet']} $vip_description");
1204
							}
1205
							break;
1206
					}
1207
				}
1208
			}
1209

    
1210
			sort($ips);
1211
			if (isset($pkga['showlistenall'])) {
1212
				array_unshift($ips, array('ip' => gettext('All'), 'description' => gettext('Listen on All interfaces/ip addresses ')));
1213
			}
1214

    
1215
			if (!preg_match("/$interface_regex/", "loopback")) {
1216
				$loopback_text = gettext("loopback");
1217
				$iface_description=(isset($pkga['showips']) ? "127.0.0.1 (" . $loopback_text . ")" : $loopback_text);
1218
				array_push($ips, array('ip' => 'lo0', 'description' => $iface_description));
1219
			}
1220

    
1221
			#show interfaces array on gui
1222
			$size = ($pkga['size'] ? "size=\"{$pkga['size']}\"" : '');
1223
			$multiple = '';
1224
			$fieldname = $pkga['fieldname'];
1225
			if (isset($pkga['multiple'])) {
1226
				$fieldname .= '[]';
1227
				$multiple = 'multiple';
1228
			}
1229

    
1230
			$selectedlist = array();
1231
			$optionlist = array();
1232

    
1233
			if (is_array($value)) {
1234
				$values = $value;
1235
			} else {
1236
				$values = explode(',', $value);
1237
			}
1238

    
1239
			foreach ($ips as $iface) {
1240
				if (in_array($iface['ip'], $values)) {
1241
					array_push($selectedlist, $iface['ip']);
1242
				}
1243

    
1244
				$optionlist[$iface['ip']] = $iface['description'];
1245
			}
1246

    
1247
			if ($grouping) {
1248
				$group->add(new Form_Select(
1249
					$pkga['fieldname'],
1250
					$pkga['fielddescr'],
1251
					isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1252
					$optionlist,
1253
					isset($pkga['multiple'])
1254
				))->setHelp($pkga['description']);
1255
			} else {
1256
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1257
					$advanced->addInput(new Form_Select(
1258
						$pkga['fieldname'],
1259
						$pkga['fielddescr'],
1260
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1261
						$optionlist,
1262
						isset($pkga['multiple'])
1263
					))->setHelp($pkga['description']);
1264
				} else {
1265
					$section->addInput(new Form_Select(
1266
						$pkga['fieldname'],
1267
						$pkga['fielddescr'],
1268
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1269
						$optionlist,
1270
						isset($pkga['multiple'])
1271
					))->setHelp($pkga['description']);
1272
				}
1273
			}
1274

    
1275
			break;
1276

    
1277
		// Create radio button
1278
		case "radio":
1279
			if ($grouping) {
1280
				$group->add(new Form_Checkbox(
1281
					$pkga['fieldname'],
1282
					$pkga['fielddescr'],
1283
					fixup_string($pkga['description']),
1284
					($value == "on"),
1285
					'on'
1286
				))->displayAsRadio();
1287
			} else {
1288
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1289
					$advanced->addInput(new Form_Checkbox(
1290
						$pkga['fieldname'],
1291
						$pkga['fielddescr'],
1292
						fixup_string($pkga['description']),
1293
						($value == "on"),
1294
						'on'
1295
					))->displayAsRadio();
1296
				} else {
1297
					$section->addInput(new Form_Checkbox(
1298
						$pkga['fieldname'],
1299
						$pkga['fielddescr'],
1300
						fixup_string($pkga['description']),
1301
						($value == "on"),
1302
						'on'
1303
					))->displayAsRadio();
1304
				}
1305
			}
1306

    
1307
			break;
1308

    
1309
		// Create form button
1310
		case "button":
1311
			$newbtnicon = "fa-save";
1312
			if ($pkga['buttonicon'] != "") {
1313
				$newbtnicon = $pkga['buttonicon'];
1314
			}
1315
			$newbtnclass = "btn-primary";
1316
			if ($pkga['buttonclass'] != "") {
1317
				$newbtnclass = $pkga['buttonclass'];
1318
			}
1319

    
1320
			$newbtn = new Form_Button(
1321
				$pkga['fieldname'],
1322
				$pkga['fieldname'],
1323
				null,
1324
				$newbtnicon
1325
			);
1326
			$newbtn->addClass($newbtnclass);
1327

    
1328
			if (grouping) {
1329
				$group->add(new Form_StaticText(
1330
					null,
1331
					$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1332
				));
1333
			} else {
1334
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1335
					$advanced->addInput(new Form_StaticText(
1336
						null,
1337
						$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1338
					));
1339
				} else {
1340
					$section->addInput(new Form_StaticText(
1341
						null,
1342
						$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1343
					));
1344
				}
1345
			}
1346

    
1347
			break;
1348

    
1349
		case "schedule_selection":
1350

    
1351
			$input = "<select id='{$pkga['fieldname']}' name='{$pkga['fieldname']}'>\n";
1352
			$schedules = array();
1353
			$schedules[] = "none";
1354
			if (is_array($config['schedules']['schedule'])) {
1355
				foreach ($config['schedules']['schedule'] as $schedule) {
1356
					if ($schedule['name'] != "") {
1357
						$schedules[] = $schedule['name'];
1358
					}
1359
				}
1360
			}
1361

    
1362
			foreach ($schedules as $schedule) {
1363
				if ($schedule == "none") {
1364
					$schedlist[""] = $schedule;
1365
				} else {
1366
					$schedlist[$schedule] = $schedule;
1367
				}
1368
			}
1369

    
1370
			if ($grouping) {
1371
				$group->add(new Form_Select(
1372
					$pkga['fieldname'],
1373
					$pkga['fielddescr'],
1374
					$value,
1375
					$schedlist
1376
				))->setHelp(fixup_string($pkga['description']));
1377
			} else {
1378
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1379
					$advanced->addInput(new Form_Select(
1380
						$pkga['fieldname'],
1381
						$pkga['fielddescr'],
1382
						$value,
1383
						$schedlist
1384
					))->setHelp(fixup_string($pkga['description']));
1385
				} else {
1386
					$section->addInput(new Form_Select(
1387
						$pkga['fieldname'],
1388
						$pkga['fielddescr'],
1389
						$value,
1390
						$schedlist
1391
					))->setHelp(fixup_string($pkga['description']));
1392
				}
1393
			}
1394

    
1395
			break;
1396

    
1397
		case "rowhelper":
1398

    
1399
			$rowhelpername="row";
1400

    
1401
				$rowcounter = 0;
1402
				$trc = 0;
1403

    
1404
				//Use assigned $a_pkg or create an empty array to enter loop
1405
				if (isset($a_pkg[$id][$rowhelpername])) {
1406
					$saved_rows=$a_pkg[$id][$rowhelpername];
1407
				} else {
1408
					$saved_rows[] = array();
1409
				}
1410

    
1411
				$numrows = count($saved_rows) - 1;
1412

    
1413
				foreach ($saved_rows as $row) {
1414
					$group = new Form_Group(($rowcounter == 0) ? $pkga['fielddescr']:null);
1415
					$group->addClass('repeatable');
1416

    
1417
					foreach ($pkga['rowhelper']['rowhelperfield'] as $rowhelper) {
1418
						unset($value);
1419
						$width = null;
1420

    
1421
						$fieldname = $rowhelper['fieldname'];
1422
						$fielddescr = $rowhelper['fielddescr'];
1423

    
1424
						// If input validation failed, read the value from the POST data so that the user's input is not lost
1425
						if ($get_from_post && isset($_POST[$fieldname.$rowcounter])) {
1426
							$value = $_POST[$fieldname.$rowcounter];
1427
						} elseif (isset($id) && $a_pkg[$id]) {
1428
							$value = $row[$fieldname];
1429
						} elseif ($rowhelper['value'] != "") {
1430
							$value = $rowhelper['value'];
1431
						}
1432

    
1433
						$type = $rowhelper['type'];
1434
						if ($type == "input" || $type == "password" || $type == "textarea") {
1435
							if (($rowhelper['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
1436
								$value = base64_decode($value);
1437
							}
1438
						}
1439

    
1440

    
1441
						if ($rowhelper['size']) {
1442
							$size = $rowhelper['size'];
1443
						} else if ($pkga['size']) {
1444
							$size = $pkga['size'];
1445
						} else {
1446
							$size = "8";
1447
						}
1448

    
1449
						if ($rowhelper['width']) {
1450
							$width = $rowhelper['width'];
1451
						}
1452

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

    
1455
						$text = "";
1456
						$trc++;
1457
					}
1458

    
1459
					// Delete row button
1460
					$group->add(new Form_Button(
1461
						'deleterow' . $rowcounter,
1462
						'Delete',
1463
						null,
1464
						'fa-trash'
1465
					))->removeClass('btn-primary')->addClass('btn-warning btn-sm');
1466

    
1467
					$rowcounter++;
1468
					$section->add($group);
1469
				}
1470

    
1471
			// Add row button
1472
			$section->addInput(new Form_Button(
1473
				'addrow',
1474
				'Add',
1475
				null,
1476
				'fa-plus'
1477
			))->addClass('btn-success');
1478

    
1479
			break;
1480

    
1481
	}
1482

    
1483
		if ($pkga['combinefields'] == "end") {
1484
			$group->add(new Form_StaticText(
1485
				null,
1486
				null
1487
			));
1488

    
1489
			if ($advanced) {
1490
				$advanced->add($group);
1491
			} else {
1492
				$section->add($group);
1493
			}
1494

    
1495
			$grouping = false;
1496
		}
1497

    
1498
	#increment counter
1499
	$i++;
1500
} // e-o-foreach field described in the XML
1501

    
1502
if ($section) {
1503
	$form->add($section);
1504
}
1505

    
1506
$form->addGlobal(new Form_Input(
1507
	'id',
1508
	null,
1509
	'hidden',
1510
	$id
1511
));
1512

    
1513
// If we created an advanced section, add it (and a button) to the form here
1514
if (!empty($advanced)) {
1515
	$form->addGlobal(new Form_Button(
1516
		'showadv',
1517
		'Show Advanced Options',
1518
		null,
1519
		'fa-cog'
1520
	))->setAttribute('type','button')->addClass('btn-info');
1521

    
1522
	$form->add($advanced);
1523
}
1524

    
1525
print($form);
1526

    
1527
if ($pkg['note'] != "") {
1528
	print_info_box($pkg['note'], 'info');
1529
}
1530

    
1531
if ($pkg['custom_php_after_form_command']) {
1532
	eval($pkg['custom_php_after_form_command']);
1533
}
1534

    
1535
if ($pkg['fields']['field'] != "") { ?>
1536
<script type="text/javascript">
1537
//<![CDATA[
1538
	events.push(function() {
1539

    
1540
	// Hide the advanced section
1541
	var advanced_visible = false;
1542

    
1543
	// Hide on page load
1544
	$('.advancedoptions').hide();
1545

    
1546
	// Suppress "Delete row" button if there are fewer than two rows
1547
	checkLastRow();
1548

    
1549
	// Show advanced section if you click the showadv button
1550
	$("#showadv").click(function() {
1551
		advanced_visible = !advanced_visible;
1552

    
1553
		if (advanced_visible) {
1554
			$('.advancedoptions').show();
1555
			$("#showadv").prop('value', 'Hide advanced Options');
1556
		} else {
1557
			$('.advancedoptions').hide();
1558
			$("#showadv").prop('value', 'Show advanced Options');
1559
		}
1560
	});
1561

    
1562
	// Call enablechange function
1563
	enablechange();
1564
});
1565

    
1566
	function enablechange() {
1567
<?php
1568
	foreach ($pkg['fields']['field'] as $field) {
1569
		if (isset($field['enablefields']) or isset($field['checkenablefields'])) {
1570
			echo "\tif ($('input[name=\"{$field['fieldname']}\"]').prop('checked') == false) {\n";
1571

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

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

    
1588
			echo "\t}\n\telse {\n";
1589

    
1590
			if (isset($field['enablefields'])) {
1591
				foreach (explode(',', $field['enablefields']) as $enablefield) {
1592
					echo "\t\tif ($('input[name=\"{$enablefield}\"]').length > 0) {\n";
1593
					echo "\t\t\t$('input[name=\"{$enablefield}\"]').prop('disabled',false);\n";
1594
					echo "\t\t}\n";
1595
				}
1596
			}
1597

    
1598
			if (isset($field['checkenablefields'])) {
1599
				foreach (explode(',', $field['checkenablefields']) as $checkenablefield) {
1600
					echo "\t\tif ($('input[name=\"{$checkenablefield}\"]').length > 0) {\n";
1601
					echo "\t\t\t$('input[name=\"{$checkenablefield}\"]').prop('checked',false);\n";
1602
					echo "\t\t}\n";
1603
				}
1604
			}
1605

    
1606
			echo "\t}\n";
1607
		}
1608
	}
1609
	?>
1610
	}
1611
//]]>
1612
</script>
1613

    
1614
<?php
1615
}
1616

    
1617
include("foot.inc");
(100-100/227)