Project

General

Profile

Download (41.1 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
require_once("util.inc");
37

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
163
	if (empty($pkg['donotsave'])) {
164

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

    
214
			if (isset($id) && $a_pkg[$id]) {
215
				$a_pkg[$id] = $pkgarr;
216
			} else {
217
				$a_pkg[] = $pkgarr;
218
			}
219

    
220
			write_config($pkg['addedit_string']);
221
			// late running code
222
			if ($pkg['custom_add_php_command_late'] != "") {
223
				eval($pkg['custom_add_php_command_late']);
224
			}
225

    
226
			if (isset($pkg['filter_rules_needed'])) {
227
				filter_configure();
228
			}
229

    
230
			// resync the configuration file code if defined.
231
			if ($pkg['custom_php_resync_config_command'] != "") {
232
				eval($pkg['custom_php_resync_config_command']);
233
			}
234

    
235
			parse_package_templates();
236

    
237
			/* if start_command is defined, restart w/ this */
238
			if ($pkg['start_command'] != "") {
239
				exec($pkg['start_command'] . ">/dev/null 2&>1");
240
			}
241

    
242
			/* if restart_command is defined, restart w/ this */
243
			if ($pkg['restart_command'] != "") {
244
				exec($pkg['restart_command'] . ">/dev/null 2&>1");
245
			}
246

    
247
			if ($pkg['aftersaveredirect'] != "") {
248
				pfSenseHeader($pkg['aftersaveredirect']);
249
			} elseif (!$pkg['adddeleteeditpagefields']) {
250
				pfSenseHeader("pkg_edit.php?xml={$xml}&id=0");
251
			} elseif (!$pkg['preoutput']) {
252
				pfSenseHeader("pkg.php?xml=" . $xml);
253
			}
254
			exit;
255
		} else {
256
			$get_from_post = true;
257
		}
258
	} elseif (!$input_errors) {
259
		// donotsave is enabled.  lets simply exit.
260
		exit;
261
	}
262
}
263

    
264

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

    
271
	// Substitute everything inbetween with our new classes
272
	if ($t && $c && (($c - $t) < 200)) {
273
		return(substr_replace($text, ' class="table table-striped table-hover table-condensed"', $t, ($c - $t)));
274
	}
275
}
276

    
277
/*
278
 * ROW helper function. Creates one element in the row from a PHP table by adding
279
 * the specified element to $group
280
 */
281
function display_row($trc, $value, $fieldname, $type, $rowhelper, $description, $ewidth = null) {
282
	global $text, $group, $config;
283

    
284
	switch ($type) {
285
		case "input":
286
			$inpt = new Form_Input(
287
				$fieldname . $trc,
288
				null,
289
				'text',
290
				$value
291
			);
292

    
293
			$inpt->setHelp($description);
294

    
295
			if ($ewidth) {
296
				$inpt->setWidth($ewidth);
297
			}
298

    
299
			$group->add($inpt);
300
			break;
301
		case "checkbox":
302
			$group->add(new Form_Checkbox(
303
				$fieldname . $trc,
304
				null,
305
				null,
306
				$value,
307
				'ON'
308
			))->setHelp($description);
309

    
310
			break;
311
		case "password":
312
			$group->add(new Form_Input(
313
				$fieldname . $trc,
314
				null,
315
				'password',
316
				$value
317
			))->setHelp($description);
318
			break;
319
		case "textarea":
320
			$group->add(new Form_Textarea(
321
				$fieldname . $trc,
322
				null,
323
				$value
324
			))->setHelp($description);
325

    
326
			break;
327
		case "select":
328
			$options = array();
329
			foreach ($rowhelper['options']['option'] as $rowopt) {
330
				$options[$rowopt['value']] = $rowopt['name'];
331
			}
332

    
333
			$grp = new Form_Select(
334
				$fieldname . $trc,
335
				null,
336
				$value,
337
				$options
338
			);
339

    
340
			$grp->setHelp($description);
341

    
342
			if ($ewidth) {
343
				$grp->setWidth($ewidth);
344
			}
345

    
346
			$group->add($grp);
347

    
348
			break;
349
		case "interfaces_selection":
350
			$size = ($size ? "size=\"{$size}\"" : '');
351
			$multiple = '';
352
			if (isset($rowhelper['multiple'])) {
353
				$multiple = "multiple";
354
			}
355
			echo "<select style='height:22px;' id='{$fieldname}{$trc}' name='{$fieldname}{$trc}' {$size} {$multiple}>\n";
356
			$ifaces = get_configured_interface_with_descr();
357
			$additional_ifaces = $rowhelper['add_to_interfaces_selection'];
358
			if (!empty($additional_ifaces)) {
359
				$ifaces = array_merge($ifaces, explode(',', $additional_ifaces));
360
			}
361

    
362
			if (is_array($value)) {
363
				$values = $value;
364
			} else {
365
				$values = explode(',', $value);
366
			}
367

    
368
			$ifaces["lo0"] = "loopback";
369
			$options = array();
370
			$selected = array();
371

    
372
			foreach ($ifaces as $ifname => $iface) {
373
				$options[$ifname] = $iface;
374

    
375
				if (in_array($ifname, $values)) {
376
					array_push($selected, $ifname);
377
				}
378
			}
379

    
380
			$group->add(new Form_Select(
381
				$fieldname . $trc,
382
				null,
383
				($multiple) ? $selected:$selected[0],
384
				$options,
385
				$multiple
386
			))->setHelp($description);
387

    
388
			//echo "</select>\n";
389
			break;
390
		case "select_source":
391
			$options = array();
392
			$selected = array();
393

    
394
			if (isset($rowhelper['show_disable_value'])) {
395
				$options[$rowhelper['show_disable_value']] = $rowhelper['show_disable_value'];
396
			}
397

    
398
			$source_url = $rowhelper['source'];
399
			eval("\$pkg_source_txt = &$source_url;");
400

    
401
			foreach ($pkg_source_txt as $opt) {
402
				$source_name = ($rowhelper['source_name'] ? $opt[$rowhelper['source_name']] : $opt[$rowhelper['name']]);
403
				$source_value = ($rowhelper['source_value'] ? $opt[$rowhelper['source_value']] : $opt[$rowhelper['value']]);
404
				$options[$source_value] = $source_name;
405

    
406
				if ($source_value == $value) {
407
					array_push($selected, $value);
408
				}
409
			}
410

    
411
			$group->add(new Form_Select(
412
				$fieldname . $trc,
413
				null,
414
				($multiple) ? $selected:$selected[0],
415
				$options,
416
				$multiple
417
			))->setHelp($description);
418

    
419
			break;
420
	}
421
}
422

    
423
function fixup_string($string) {
424
	global $config;
425
	// fixup #1: $myurl -> http[s]://ip_address:port/
426
	$https = "";
427
	$port = $config['system']['webguiport'];
428
	if ($port != "443" and $port != "80") {
429
		$urlport = ":" . $port;
430
	} else {
431
		$urlport = "";
432
	}
433

    
434
	if ($config['system']['webgui']['protocol'] == "https") {
435
		$https = "s";
436
	}
437
	$myurl = "http" . $https . "://" . getenv("HTTP_HOST") . $urlport;
438
	$newstring = str_replace("\$myurl", $myurl, $string);
439
	$string = $newstring;
440
	// fixup #2: $wanip
441
	$curwanip = get_interface_ip();
442
	$newstring = str_replace("\$wanip", $curwanip, $string);
443
	$string = $newstring;
444
	// fixup #3: $lanip
445
	$lancfg = $config['interfaces']['lan'];
446
	$lanip = $lancfg['ipaddr'];
447
	$newstring = str_replace("\$lanip", $lanip, $string);
448
	$string = $newstring;
449
	// fixup #4: fix'r'up here.
450
	return $newstring;
451
}
452

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

    
498
			/* replace cr's */
499
			$template_text = str_replace("\\n", "\n", $template_text);
500

    
501
			/* write out new template file */
502
			$fout = fopen($filename, "w");
503
			fwrite($fout, $template_text);
504
			fclose($fout);
505
		}
506
	}
507
}
508

    
509
//breadcrumb
510
if ($pkg['title'] != "") {
511
	if (!$only_edit) {
512
		$pkg['title'] = $pkg['title'] . '/Edit';
513
	}
514

    
515
	if (strpos($pkg['title'], '/')) {
516
		$title = explode('/', $pkg['title']);
517

    
518
		foreach ($title as $subtitle) {
519
			$pgtitle[] = gettext($subtitle);
520
			$pglinks[] = ((($subtitle == "Edit") || (strlen($pkg['menu'][0]['url']) == 0)) ? "@self" : $pkg['menu'][0]['url']);
521
		}
522
	} else {
523
		$pgtitle = array(gettext("Package"), gettext($pkg['title']));
524
		$pglinks = array("", ((($subtitle == "Edit") || (strlen($pkg['menu'][0]['url']) == 0)) ? "@self" : $pkg['menu'][0]['url']));
525
	}
526
} else {
527
	$pgtitle = array(gettext("Package"), gettext("Editor"));
528
	$pglinks = array("", "@self");
529
}
530

    
531
// Create any required tabs
532
if ($pkg['tabs'] != "") {
533
	$tab_array = array();
534
	foreach ($pkg['tabs']['tab'] as $tab) {
535
		if ($tab['tab_level']) {
536
			$tab_level = $tab['tab_level'];
537
		} else {
538
			$tab_level = 1;
539
		}
540

    
541
		if (isset($tab['active'])) {
542
			$active = true;
543
			$pgtitle[] = $tab['text'] ;
544
			$pglinks[] = ((strlen($tab['url']) > 0) ? $tab['url'] : "@self");
545
		} else {
546
			$active = false;
547
		}
548

    
549
		if (isset($tab['no_drop_down'])) {
550
			$no_drop_down = true;
551
		}
552

    
553
		$urltmp = "";
554
		if ($tab['url'] != "") {
555
			$urltmp = $tab['url'];
556
		}
557

    
558
		if ($tab['xml'] != "") {
559
			$urltmp = "pkg_edit.php?xml=" . $tab['xml'];
560
		}
561

    
562
		$addresswithport = getenv("HTTP_HOST");
563
		$colonpos = strpos($addresswithport, ":");
564

    
565
		if ($colonpos !== False) {
566
			//my url is actually just the IP address of the pfsense box
567
			$myurl = substr($addresswithport, 0, $colonpos);
568
		} else {
569
			$myurl = $addresswithport;
570
		}
571

    
572
		// eval url so that above $myurl item can be processed if need be.
573
		$url = str_replace('$myurl', $myurl, $urltmp);
574

    
575
		$tab_array[$tab_level][] = array(
576
			$tab['text'],
577
			$active,
578
			$url
579
		);
580
	}
581

    
582
	ksort($tab_array);
583
}
584

    
585
include("head.inc");
586
if ($pkg['custom_php_after_head_command']) {
587
	eval($pkg['custom_php_after_head_command']);
588
}
589
if (isset($tab_array)) {
590
	foreach ($tab_array as $tabid => $tab) {
591
		display_top_tabs($tab); //, $no_drop_down, $tabid);
592
	}
593
}
594

    
595
// Start of page display
596
if ($input_errors) {
597
	print_input_errors($input_errors);
598
}
599

    
600
if ($savemsg) {
601
	print_info_box($savemsg, 'success');
602
}
603

    
604
$cols = 0;
605
$savevalue = gettext("Save");
606
if ($pkg['savetext'] != "") {
607
	$savevalue = $pkg['savetext'];
608
}
609

    
610
$savehelp = "";
611
if ($pkg['savehelp'] != "") {
612
	$savehelp = $pkg['savehelp'];
613
}
614

    
615
$saveicon = "fa-save";
616
if ($pkg['saveicon'] != "") {
617
	$saveicon = $pkg['saveicon'];
618
}
619

    
620
$savebtnclass = "btn-primary";
621
if ($pkg['savebtnclass'] != "") {
622
	$savebtnclass = $pkg['savebtnclass'];
623
}
624

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

    
627
$savebutton = new Form_Button(
628
	'submit',
629
	$savevalue,
630
	null,
631
	$saveicon
632
);
633
$savebutton->addClass($savebtnclass);
634

    
635
if ($savehelp) {
636
	$savebutton->setHelp($savehelp);
637
}
638

    
639
$form = new Form($savebutton);
640

    
641
$form->addGlobal(new Form_Input(
642
	'xml',
643
	null,
644
	'hidden',
645
	$xml
646
));
647

    
648
/* If a package's XML has <advanced_options/> configured, then setup
649
 * the section for the fields that have <advancedfield/> set.
650
 * These fields will be placed below other fields in a separate area titled 'Advanced Features'.
651
 * These advanced fields are not normally configured and generally left to default to 'default settings'.
652
 */
653

    
654
if ($pkg['advanced_options'] == "enabled") {
655
	$advfield_count = 0;
656
	$advanced = new Form_Section("Advanced Features");
657
	$advanced->addClass('advancedoptions');
658
}
659

    
660
$js_array = array();
661

    
662
// Now loop through all of the fields defined in the XML
663
if (!is_array($pkg['fields']['field'])) {
664
	$pkg['fields']['field'] = array();
665
}
666
foreach ($pkg['fields']['field'] as $pkga) {
667

    
668
	$action = "";
669
	$uid = "";
670

    
671
	if ($pkga['type'] == "sorting") {
672
		continue;
673
	}
674

    
675
	// Generate a new section
676
	if ($pkga['type'] == "listtopic") {
677
		if (isset($pkga['advancedfield']) && isset($advfield_count)) {
678
			$advanced->addInput(new Form_StaticText(
679
				strip_tags($pkga['name']),
680
				null
681
			));
682

    
683
			$advfield_count++;
684
		}  else {
685
			if (isset($section)) {
686
				$form->add($section);
687
			}
688

    
689
			if (isset($pkga['collapse'])) {
690
				$uid = uniqid("section");
691

    
692
				$action = COLLAPSIBLE;
693

    
694
				if ($pkga['collapse'] == "open") {
695
					$action |= SEC_OPEN;
696
				} else {
697
					$action |= SEC_CLOSED;
698
				}
699
			}
700

    
701
			$section = new Form_Section(strip_tags($pkga['name']), $uid, $action);
702
		}
703

    
704
		continue;
705
	}
706

    
707
	// 'begin' starts a form group. ('end' ends it)
708
	if ($pkga['combinefields'] == "begin") {
709
		$group = new Form_Group(strip_tags($pkga['fielddescr']));
710
		$grouping = true;
711
	}
712

    
713
	$size = "";
714
	$colspan="";
715

    
716
	// if user is editing a record, load in the data.
717
	$fieldname = $pkga['fieldname'];
718
	unset($value);
719
	if ($get_from_post) {
720
		$value = $_POST[$fieldname];
721
		if (is_array($value)) {
722
			$value = implode(',', $value);
723
		}
724
	} else {
725
		if (isset($id) && isset($a_pkg[$id][$fieldname])) {
726
			$value = $a_pkg[$id][$fieldname];
727
		} else {
728
			if (isset($pkga['default_value'])) {
729
				$value = $pkga['default_value'];
730
			}
731
		}
732
	}
733

    
734
	// If we get here but have no $section, the package config file probably had no listtopic field
735
	// We can create a section with a generic name to fix that
736
	if (!$section) {
737
		$section = new Form_Section('General Options');
738
	}
739

    
740
	// If this is a required field, pre-pend a "*" to the field description
741
	// This tells the system to add "element-required" class text decoration to the field label
742
	if (isset($pkga['required'])) {
743
		$pkga['fielddescr'] = "*" . $pkga['fielddescr'];
744
	}
745

    
746
	switch ($pkga['type']) {
747
		// Create an input element. The format is slightly different depending on whether we are composing a group,
748
		// section, or advanced section. This is true for every element type
749
		case "input":
750
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
751
				$value = base64_decode($value);
752
			}
753

    
754
			$grp = new Form_Input(
755
					$pkga['fieldname'],
756
					$pkga['fielddescr'],
757
					'text',
758
					$value
759
				);
760

    
761
			$grp->setHelp($pkga['description']);
762

    
763
			if ($pkga['width']) {
764
				$grp->setWidth($pkga['width']);
765
			}
766

    
767
			if ($grouping) {
768
				$group->add($grp);
769
			} else {
770
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
771
					$advanced->addInput($grp);
772
				} else {
773
					$section->addInput($grp);
774
				}
775
			}
776

    
777
			break;
778

    
779
		case "password":
780
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
781
				$value = base64_decode($value);
782
			}
783

    
784
			// Create a password element
785
			if ($grouping) {
786
				$group->add(new Form_Input(
787
					$pkga['fieldname'],
788
					$pkga['fielddescr'],
789
					'password',
790
					$value
791
				))->setHelp($pkga['description']);
792
			} else {
793
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
794
					$advanced->addInput(new Form_Input(
795
						$pkga['fieldname'],
796
						$pkga['fielddescr'],
797
						'password',
798
						$value
799
					))->setHelp($pkga['description']);
800
				} else {
801
					$section->addInput(new Form_Input(
802
						$pkga['fieldname'],
803
						$pkga['fielddescr'],
804
						'password',
805
						$value
806
					))->setHelp($pkga['description']);
807
				}
808
			}
809

    
810
			break;
811

    
812
		case "info":
813
			// If the info contains a table we should detect and Bootstrap it
814

    
815
			if (strpos($pkga['description'], '<table') !== FALSE) {
816
				$info = bootstrapTable($pkga['description']);
817
			} else {
818
				$info = $pkga['description'];
819
			}
820

    
821
			if (isset($pkga['advancedfield']) && isset($advfield_count)) {
822
				$advanced->addInput(new Form_StaticText(
823
					strip_tags($pkga['fielddescr']),
824
					$info
825
				));
826
			} else {
827
				$section->addInput(new Form_StaticText(
828
					strip_tags($pkga['fielddescr']),
829
					$info
830
				));
831
			}
832

    
833
			break;
834

    
835
		case "select":
836
			// Create a select element
837
			$optionlist = array();
838
			$selectedlist = array();
839

    
840
			$fieldname = $pkga['fieldname'];
841

    
842
			if (isset($pkga['multiple'])) {
843
				$multiple = 'multiple';
844
				$items = explode(',', $value);
845
				$fieldname .= "[]";
846
			} else {
847
				$multiple = '';
848
				$items = array($value);
849
			}
850

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

    
853
			foreach ($pkga['options']['option'] as $opt) {
854
				$optionlist[$opt['value']] = $opt['name'];
855

    
856
				if (in_array($opt['value'], $items)) {
857
					array_push($selectedlist, $opt['value']);
858
				}
859
			}
860

    
861
			if (isset($pkga['advancedfield']) && isset($advfield_count)) {
862
				$function = $grouping ? $advanced->add:$advanced->addInput;
863
			} else {
864
				$function = ($grouping) ? $section->add:$section->addInput;
865
			}
866

    
867
			$grp = new Form_Select(
868
						$pkga['fieldname'],
869
						strip_tags($pkga['fielddescr']),
870
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
871
						$optionlist,
872
						isset($pkga['multiple'])
873
					);
874

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

    
877
			if ($pkga['width']) {
878
				$grp->setWidth($pkga['width']);
879
			}
880

    
881
			if ($grouping) {
882
				$group->add($grp);
883
			} else {
884
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
885
					$advanced->addInput($grp);
886
				} else {
887
					$section->addInput($grp);
888
				}
889
			}
890

    
891
			break;
892

    
893
		case "select_source":
894

    
895
			if (isset($pkga['multiple'])) {
896
				$items = explode(',', $value);
897
				$fieldname .= "[]";
898
			} else {
899
				$items = array($value);
900
			}
901

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

    
904
			$source_url = $pkga['source'];
905
			eval("\$pkg_source_txt = &$source_url;");
906

    
907
			#check if show disable option is present on xml
908
			if (!is_array($pkg_source_txt)) {
909
				$pkg_source_txt = array();
910
			}
911
			if (isset($pkga['show_disable_value'])) {
912
				array_push($pkg_source_txt,
913
					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']));
914
			}
915

    
916
			$srcoptions = array();
917
			$srcselected = array();
918

    
919
			foreach ($pkg_source_txt as $opt) {
920
				$source_name =($pkga['source_name']? $opt[$pkga['source_name']] : $opt[$pkga['name']]);
921
				$source_value =($pkga['source_value'] ? $opt[$pkga['source_value']] : $opt[$pkga['value']]);
922
				$srcoptions[$source_value] = $source_name;
923

    
924
				if (in_array($source_value, $items)) {
925
					array_push($srcselected, $source_value);
926
				}
927
			}
928

    
929
			$descr = (isset($pkga['description'])) ? $pkga['description'] : "";
930
			if ($grouping) {
931
				$group->add(new Form_Select(
932
					$pkga['fieldname'],
933
					strip_tags($pkga['fielddescr']),
934
					isset($pkga['multiple']) ? $srcselected:$srcselected[0],
935
					$srcoptions,
936
					isset($pkga['multiple'])
937
				))->setHelp($descr)->setOnchange($onchange);
938
			} else {
939
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
940
					$advanced->addInput(new Form_Select(
941
						$pkga['fieldname'],
942
						strip_tags($pkga['fielddescr']),
943
						isset($pkga['multiple']) ? $srcselected:$srcselected[0],
944
						$srcoptions,
945
						isset($pkga['multiple'])
946
					))->setHelp($descr)->setOnchange($onchange);
947
				} else {
948
					$section->addInput(new Form_Select(
949
						$pkga['fieldname'],
950
						strip_tags($pkga['fielddescr']),
951
						isset($pkga['multiple']) ? $srcselected:$srcselected[0],
952
						$srcoptions,
953
						isset($pkga['multiple'])
954
					))->setHelp($descr)->setOnchange($onchange);
955
				}
956
			}
957

    
958
			break;
959

    
960
		case "vpn_selection" :
961
			$vpnlist = array();
962

    
963
			foreach ($config['ipsec']['phase1'] as $vpn) {
964
				$vpnlist[$vpn['descr']] = $vpn['descr'];
965

    
966
			}
967

    
968
			if ($grouping) {
969
				$group->add(new Form_Select(
970
					$pkga['fieldname'],
971
					null,
972
					false,
973
					$vpnlist
974
				))->setHelp(fixup_string($pkga['description']));
975
			} else {
976
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
977
					$advanced->addInput(new Form_Select(
978
						$pkga['fieldname'],
979
						null,
980
						false,
981
						$vpnlist
982
					))->setHelp(fixup_string($pkga['description']));
983
				} else {
984
					$section->addInput(new Form_Select(
985
						$pkga['fieldname'],
986
						null,
987
						false,
988
						$vpnlist
989
					))->setHelp(fixup_string($pkga['description']));
990
				}
991
			}
992

    
993
			break;
994

    
995
		// Create a checkbox element
996
		case "checkbox":
997
			$onchange = (isset($pkga['onchange']) ? "{$pkga['onchange']}" : '');
998
			if (isset($pkga['enablefields']) || isset($pkga['checkenablefields'])) {
999
				$onclick = 'javascript:enablechange();';
1000
			} else {
1001
				$onclick = '';
1002
			}
1003

    
1004
			if ($grouping) {
1005
				$group->add(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
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1016
					$advanced->addInput(new Form_Checkbox(
1017
						$pkga['fieldname'],
1018
						$pkga['fielddescr'],
1019
						fixup_string($pkga['description']),
1020
						($value == "on"),
1021
						'on'
1022
					))->setOnclick($onclick)
1023
					  ->setOnchange($onchange)
1024
					  ->setHelp($pkga['sethelp']);
1025
				} else {
1026
					$section->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
				}
1036
			}
1037

    
1038
			break;
1039

    
1040
		// Create a textarea element
1041
		case "textarea":
1042
			$rows = $cols = 0;
1043

    
1044
			if ($pkga['rows']) {
1045
				$rows = $pkga['rows'];
1046
			}
1047
			if ($pkga['cols']) {
1048
				$cols = $pkga['cols'];
1049
			}
1050

    
1051
			if (($pkga['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
1052
				$value = base64_decode($value);
1053
			}
1054

    
1055
			$grp = new Form_Textarea(
1056
					$pkga['fieldname'],
1057
					$pkga['fielddescr'],
1058
					$value
1059
			);
1060

    
1061
			$grp->setHelp(fixup_string($pkga['description']));
1062

    
1063
			if ($rows > 0) {
1064
				$grp->setRows($rows);
1065
			}
1066

    
1067
			if ($cols > 0) {
1068
				$grp->setCols($cols);
1069
			}
1070

    
1071
			if ($pkga['wrap'] == "off") {
1072
				$grp->setAttribute("wrap", "off");
1073
				$grp->setAttribute("style", "white-space:nowrap; width: auto;");
1074
			} else {
1075
				$grp->setAttribute("style", "width: auto;");
1076
			}
1077

    
1078
			if ($grouping) {
1079
				$group->add($grp);
1080
			} else {
1081
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1082
					$advanced->addInput($grp);
1083
				} else {
1084
					$section->addInput($grp);
1085
				}
1086
			}
1087

    
1088
			break;
1089

    
1090
		case "aliases":
1091

    
1092
			// Use xml tag <typealiases> to filter type aliases
1093
			$size = ($pkga['size'] ? "size=\"{$pkga['size']}\"" : '');
1094
			$fieldname = $pkga['fieldname'];
1095
			$a_aliases = &$config['aliases']['alias'];
1096
			$addrisfirst = 0;
1097
			$aliasesaddr = "";
1098

    
1099
			if (isset($a_aliases)) {
1100
				if (!empty($pkga['typealiases'])) {
1101
					foreach ($a_aliases as $alias) {
1102
						if ($alias['type'] == $pkga['typealiases']) {
1103
							if ($addrisfirst == 1) {
1104
								$aliasesaddr .= ",";
1105
							}
1106
							$aliasesaddr .= "'" . $alias['name'] . "'";
1107
							$addrisfirst = 1;
1108
						}
1109
					}
1110
				} else {
1111
					foreach ($a_aliases as $alias) {
1112
						if ($addrisfirst == 1) {
1113
							$aliasesaddr .= ",";
1114
						}
1115
						$aliasesaddr .= "'" . $alias['name'] . "'";
1116
						$addrisfirst = 1;
1117
					}
1118
				}
1119
			}
1120

    
1121
			$grp = new Form_Input(
1122
					$pkga['fieldname'],
1123
					$pkga['fielddescr'],
1124
					'text',
1125
					$value
1126
				);
1127

    
1128
			$grp->setHelp($pkga['description']);
1129

    
1130
			if ($pkga['width']) {
1131
				$grp->setWidth($pkga['width']);
1132
			}
1133

    
1134
			if ($grouping) {
1135
				$group->add($grp);
1136
			} else {
1137
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1138
					$advanced->addInput($grp);
1139
				} else {
1140
					$section->addInput($grp);
1141
				}
1142
			}
1143

    
1144
			$script = "<script type='text/javascript'>\n";
1145
			$script .= "//<![CDATA[\n";
1146
			$script .= "events.push(function(){\n";
1147
			$script .= "	var aliasarray = new Array({$aliasesaddr})\n";
1148
			$script .= "	$('#' + '{$fieldname}').autocomplete({\n";
1149
			$script .= "		source: aliasarray\n";
1150
			$script .= "	})\n";
1151
			$script .= "});\n";
1152
			$script .= "//]]>\n";
1153
			$script .= "</script>";
1154

    
1155
			echo $script;
1156

    
1157
			break;
1158

    
1159
		case "interfaces_selection":
1160
			$ips = array();
1161
			$interface_regex=(isset($pkga['hideinterfaceregex']) ? $pkga['hideinterfaceregex'] : "nointerfacestohide");
1162
			if (is_array($config['interfaces'])) {
1163
				foreach ($config['interfaces'] as $iface_key=>$iface_value) {
1164
					if (isset($iface_value['enable']) && !preg_match("/$interface_regex/", $iface_key)) {
1165
						$iface_description=($iface_value['descr'] !="" ? strtoupper($iface_value['descr']) : strtoupper($iface_key));
1166
						if (isset($pkga['showips'])) {
1167
							$iface_description .= " address";
1168
						}
1169
						$ips[] = array('ip'=> $iface_key, 'description'=> $iface_description);
1170
					}
1171
				}
1172
			}
1173

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

    
1200
			sort($ips);
1201
			if (isset($pkga['showlistenall'])) {
1202
				array_unshift($ips, array('ip' => gettext('All'), 'description' => gettext('Listen on All interfaces/ip addresses ')));
1203
			}
1204

    
1205
			if (!preg_match("/$interface_regex/", "loopback")) {
1206
				$loopback_text = gettext("loopback");
1207
				$iface_description=(isset($pkga['showips']) ? "127.0.0.1 (" . $loopback_text . ")" : $loopback_text);
1208
				array_push($ips, array('ip' => 'lo0', 'description' => $iface_description));
1209
			}
1210

    
1211
			#show interfaces array on gui
1212
			$size = ($pkga['size'] ? "size=\"{$pkga['size']}\"" : '');
1213
			$multiple = '';
1214
			$fieldname = $pkga['fieldname'];
1215
			if (isset($pkga['multiple'])) {
1216
				$fieldname .= '[]';
1217
				$multiple = 'multiple';
1218
			}
1219

    
1220
			$selectedlist = array();
1221
			$optionlist = array();
1222

    
1223
			if (is_array($value)) {
1224
				$values = $value;
1225
			} else {
1226
				$values = explode(',', $value);
1227
			}
1228

    
1229
			foreach ($ips as $iface) {
1230
				if (in_array($iface['ip'], $values)) {
1231
					array_push($selectedlist, $iface['ip']);
1232
				}
1233

    
1234
				$optionlist[$iface['ip']] = $iface['description'];
1235
			}
1236

    
1237
			if ($grouping) {
1238
				$group->add(new Form_Select(
1239
					$pkga['fieldname'],
1240
					$pkga['fielddescr'],
1241
					isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1242
					$optionlist,
1243
					isset($pkga['multiple'])
1244
				))->setHelp($pkga['description']);
1245
			} else {
1246
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1247
					$advanced->addInput(new Form_Select(
1248
						$pkga['fieldname'],
1249
						$pkga['fielddescr'],
1250
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1251
						$optionlist,
1252
						isset($pkga['multiple'])
1253
					))->setHelp($pkga['description']);
1254
				} else {
1255
					$section->addInput(new Form_Select(
1256
						$pkga['fieldname'],
1257
						$pkga['fielddescr'],
1258
						isset($pkga['multiple']) ? $selectedlist:$selectedlist[0],
1259
						$optionlist,
1260
						isset($pkga['multiple'])
1261
					))->setHelp($pkga['description']);
1262
				}
1263
			}
1264

    
1265
			break;
1266

    
1267
		// Create radio button
1268
		case "radio":
1269
			if ($grouping) {
1270
				$group->add(new Form_Checkbox(
1271
					$pkga['fieldname'],
1272
					$pkga['fielddescr'],
1273
					fixup_string($pkga['description']),
1274
					($value == "on"),
1275
					'on'
1276
				))->displayAsRadio();
1277
			} else {
1278
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1279
					$advanced->addInput(new Form_Checkbox(
1280
						$pkga['fieldname'],
1281
						$pkga['fielddescr'],
1282
						fixup_string($pkga['description']),
1283
						($value == "on"),
1284
						'on'
1285
					))->displayAsRadio();
1286
				} else {
1287
					$section->addInput(new Form_Checkbox(
1288
						$pkga['fieldname'],
1289
						$pkga['fielddescr'],
1290
						fixup_string($pkga['description']),
1291
						($value == "on"),
1292
						'on'
1293
					))->displayAsRadio();
1294
				}
1295
			}
1296

    
1297
			break;
1298

    
1299
		// Create form button
1300
		case "button":
1301
			$newbtnicon = "fa-save";
1302
			if ($pkga['buttonicon'] != "") {
1303
				$newbtnicon = $pkga['buttonicon'];
1304
			}
1305
			$newbtnclass = "btn-primary";
1306
			if ($pkga['buttonclass'] != "") {
1307
				$newbtnclass = $pkga['buttonclass'];
1308
			}
1309

    
1310
			$newbtn = new Form_Button(
1311
				$pkga['fieldname'],
1312
				$pkga['fieldname'],
1313
				null,
1314
				$newbtnicon
1315
			);
1316
			$newbtn->addClass($newbtnclass);
1317

    
1318
			if ($grouping) {
1319
				$group->add(new Form_StaticText(
1320
					null,
1321
					$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1322
				));
1323
			} else {
1324
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1325
					$advanced->addInput(new Form_StaticText(
1326
						null,
1327
						$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1328
					));
1329
				} else {
1330
					$section->addInput(new Form_StaticText(
1331
						null,
1332
						$newbtn . '<br />' . '<div class="help-block">' . fixup_string($pkga['description']) . '</div>'
1333
					));
1334
				}
1335
			}
1336

    
1337
			break;
1338

    
1339
		case "schedule_selection":
1340

    
1341
			$input = "<select id='{$pkga['fieldname']}' name='{$pkga['fieldname']}'>\n";
1342
			$schedules = array();
1343
			$schedules[] = "none";
1344
			if (is_array($config['schedules']['schedule'])) {
1345
				foreach ($config['schedules']['schedule'] as $schedule) {
1346
					if ($schedule['name'] != "") {
1347
						$schedules[] = $schedule['name'];
1348
					}
1349
				}
1350
			}
1351

    
1352
			foreach ($schedules as $schedule) {
1353
				if ($schedule == "none") {
1354
					$schedlist[""] = $schedule;
1355
				} else {
1356
					$schedlist[$schedule] = $schedule;
1357
				}
1358
			}
1359

    
1360
			if ($grouping) {
1361
				$group->add(new Form_Select(
1362
					$pkga['fieldname'],
1363
					$pkga['fielddescr'],
1364
					$value,
1365
					$schedlist
1366
				))->setHelp(fixup_string($pkga['description']));
1367
			} else {
1368
				if (isset($pkga['advancedfield']) && isset($advfield_count)) {
1369
					$advanced->addInput(new Form_Select(
1370
						$pkga['fieldname'],
1371
						$pkga['fielddescr'],
1372
						$value,
1373
						$schedlist
1374
					))->setHelp(fixup_string($pkga['description']));
1375
				} else {
1376
					$section->addInput(new Form_Select(
1377
						$pkga['fieldname'],
1378
						$pkga['fielddescr'],
1379
						$value,
1380
						$schedlist
1381
					))->setHelp(fixup_string($pkga['description']));
1382
				}
1383
			}
1384

    
1385
			break;
1386

    
1387
		case "rowhelper":
1388

    
1389
			$rowhelpername="row";
1390

    
1391
				$rowcounter = 0;
1392
				$trc = 0;
1393

    
1394
				//Use assigned $a_pkg or create an empty array to enter loop
1395
				if (isset($a_pkg[$id][$rowhelpername])) {
1396
					$saved_rows=$a_pkg[$id][$rowhelpername];
1397
				} else {
1398
					$saved_rows[] = array();
1399
				}
1400

    
1401
				$numrows = count($saved_rows) - 1;
1402

    
1403
				foreach ($saved_rows as $row) {
1404
					$group = new Form_Group(($rowcounter == 0) ? $pkga['fielddescr']:null);
1405
					$group->addClass('repeatable');
1406

    
1407
					foreach ($pkga['rowhelper']['rowhelperfield'] as $rowhelper) {
1408
						unset($value);
1409
						$width = null;
1410

    
1411
						$fieldname = $rowhelper['fieldname'];
1412
						$fielddescr = $rowhelper['fielddescr'];
1413

    
1414
						// If input validation failed, read the value from the POST data so that the user's input is not lost
1415
						if ($get_from_post && isset($_POST[$fieldname.$rowcounter])) {
1416
							$value = $_POST[$fieldname.$rowcounter];
1417
						} elseif (isset($id) && $a_pkg[$id]) {
1418
							$value = $row[$fieldname];
1419
						} elseif ($rowhelper['value'] != "") {
1420
							$value = $rowhelper['value'];
1421
						}
1422

    
1423
						$type = $rowhelper['type'];
1424
						if ($type == "input" || $type == "password" || $type == "textarea") {
1425
							if (($rowhelper['encoding'] == 'base64') && !$get_from_post && !empty($value)) {
1426
								$value = base64_decode($value);
1427
							}
1428
						}
1429

    
1430

    
1431
						if ($rowhelper['size']) {
1432
							$size = $rowhelper['size'];
1433
						} else if ($pkga['size']) {
1434
							$size = $pkga['size'];
1435
						} else {
1436
							$size = "8";
1437
						}
1438

    
1439
						if ($rowhelper['width']) {
1440
							$width = $rowhelper['width'];
1441
						}
1442

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

    
1445
						$text = "";
1446
						$trc++;
1447
					}
1448

    
1449
					// Delete row button
1450
					$group->add(new Form_Button(
1451
						'deleterow' . $rowcounter,
1452
						'Delete',
1453
						null,
1454
						'fa-trash'
1455
					))->removeClass('btn-primary')->addClass('btn-warning btn-sm');
1456

    
1457
					$rowcounter++;
1458
					$section->add($group);
1459
				}
1460

    
1461
			// Add row button
1462
			$section->addInput(new Form_Button(
1463
				'addrow',
1464
				'Add',
1465
				null,
1466
				'fa-plus'
1467
			))->addClass('btn-success');
1468

    
1469
			break;
1470

    
1471
	}
1472

    
1473
		if ($pkga['combinefields'] == "end") {
1474
			$group->add(new Form_StaticText(
1475
				null,
1476
				null
1477
			));
1478

    
1479
			if ($advanced) {
1480
				$advanced->add($group);
1481
			} else {
1482
				$section->add($group);
1483
			}
1484

    
1485
			$grouping = false;
1486
		}
1487

    
1488
	#increment counter
1489
	$i++;
1490
} // e-o-foreach field described in the XML
1491

    
1492
if ($section) {
1493
	$form->add($section);
1494
}
1495

    
1496
$form->addGlobal(new Form_Input(
1497
	'id',
1498
	null,
1499
	'hidden',
1500
	$id
1501
));
1502

    
1503
// If we created an advanced section, add it (and a button) to the form here
1504
if (!empty($advanced)) {
1505
	$form->addGlobal(new Form_Button(
1506
		'showadv',
1507
		'Show Advanced Options',
1508
		null,
1509
		'fa-cog'
1510
	))->setAttribute('type','button')->addClass('btn-info');
1511

    
1512
	$form->add($advanced);
1513
}
1514

    
1515
print($form);
1516

    
1517
if ($pkg['note'] != "") {
1518
	print_info_box($pkg['note'], 'info');
1519
}
1520

    
1521
if ($pkg['custom_php_after_form_command']) {
1522
	eval($pkg['custom_php_after_form_command']);
1523
}
1524

    
1525

    
1526
$hidemsg = gettext("Show Advanced Options");
1527
$showmsg = gettext("Hide Advanced Options");
1528

    
1529
if ($pkg['fields']['field'] != "") { ?>
1530
<script type="text/javascript">
1531
//<![CDATA[
1532
	events.push(function() {
1533

    
1534
	// Hide the advanced section
1535
	var advanced_visible = false;
1536

    
1537
	// Hide on page load
1538
	$('.advancedoptions').hide();
1539

    
1540
	// Suppress "Delete row" button if there are fewer than two rows
1541
	checkLastRow();
1542

    
1543
	// Show advanced section if you click the showadv button
1544
	$("#showadv").click(function() {
1545
		advanced_visible = !advanced_visible;
1546

    
1547
		if (advanced_visible) {
1548
			$('.advancedoptions').show();
1549
			$("#showadv").html('<i class="fa fa-cog icon-embed-btn"></i>' + "<?=$showmsg?>");
1550
		} else {
1551
			$('.advancedoptions').hide();
1552
			$("#showadv").html('<i class="fa fa-cog icon-embed-btn"></i>' + "<?=$hidemsg?>");
1553
		}
1554
	});
1555

    
1556
	// Call enablechange function
1557
	enablechange();
1558
});
1559

    
1560
	function enablechange() {
1561
<?php
1562
	foreach ($pkg['fields']['field'] as $field) {
1563
		if (isset($field['enablefields']) or isset($field['checkenablefields'])) {
1564
			echo "\tif ($('input[name=\"{$field['fieldname']}\"]').prop('checked') == false) {\n";
1565

    
1566
			if (isset($field['enablefields'])) {
1567
				foreach (explode(',', $field['enablefields']) as $enablefield) {
1568
					echo "\t\tif ($('input[name=\"{$enablefield}\"]').length > 0) {\n";
1569
					echo "\t\t\t$('input[name=\"{$enablefield}\"]').prop('disabled',true);\n";
1570
					echo "\t\t}\n";
1571
				}
1572
			}
1573

    
1574
			if (isset($field['checkenablefields'])) {
1575
				foreach (explode(',', $field['checkenablefields']) as $checkenablefield) {
1576
					echo "\t\tif ($('input[name=\"{$checkenablefield}\"]').length > 0) {\n";
1577
					echo "\t\t\t$('input[name=\"{$checkenablefield}\"]').prop('checked',true);\n";
1578
					echo "\t\t}\n";
1579
				}
1580
			}
1581

    
1582
			echo "\t}\n\telse {\n";
1583

    
1584
			if (isset($field['enablefields'])) {
1585
				foreach (explode(',', $field['enablefields']) as $enablefield) {
1586
					echo "\t\tif ($('input[name=\"{$enablefield}\"]').length > 0) {\n";
1587
					echo "\t\t\t$('input[name=\"{$enablefield}\"]').prop('disabled',false);\n";
1588
					echo "\t\t}\n";
1589
				}
1590
			}
1591

    
1592
			if (isset($field['checkenablefields'])) {
1593
				foreach (explode(',', $field['checkenablefields']) as $checkenablefield) {
1594
					echo "\t\tif ($('input[name=\"{$checkenablefield}\"]').length > 0) {\n";
1595
					echo "\t\t\t$('input[name=\"{$checkenablefield}\"]').prop('checked',false);\n";
1596
					echo "\t\t}\n";
1597
				}
1598
			}
1599

    
1600
			echo "\t}\n";
1601
		}
1602
	}
1603
	?>
1604
	}
1605
//]]>
1606
</script>
1607

    
1608
<?php
1609
}
1610

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