Project

General

Profile

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

    
56
##|+PRIV
57
##|*IDENT=page-package-settings
58
##|*NAME=Package: Settings
59
##|*DESCR=Allow access to the 'Package: Settings' page.
60
##|*MATCH=pkg.php*
61
##|-PRIV
62

    
63
require_once("guiconfig.inc");
64
require_once("pkg-utils.inc");
65

    
66
function domTT_title($title_msg) {
67
	print "onmouseout=\"this.style.color = ''; domTT_mouseout(this, event);\" onmouseover=\"domTT_activate(this, event, 'content', '".gettext($title_msg)."', 'trail', true, 'delay', 0, 'fade', 'both', 'fadeMax', 93, 'styleClass', 'niceTitle');\"";
68
}
69

    
70
$xml = $_REQUEST['xml'];
71

    
72
if ($xml == "") {
73
	$pgtitle = array(gettext("Package"), gettext("Editor"));
74
	include("head.inc");
75
	print_info_box(gettext("No valid package defined."), 'danger', false);
76
	include("foot.inc");
77
	exit;
78
} else {
79
	$pkg_xml_prefix = "/usr/local/pkg/";
80
	$pkg_full_path = "{$pkg_xml_prefix}/{$xml}";
81
	$pkg_realpath = realpath($pkg_full_path);
82
	if (empty($pkg_realpath)) {
83
		$path_error = sprintf(gettext("Package path %s not found."), htmlspecialchars($pkg_full_path));
84
	} else if (substr_compare($pkg_realpath, $pkg_xml_prefix, 0, strlen($pkg_xml_prefix))) {
85
		$path_error = sprintf(gettext("Invalid path %s specified."), htmlspecialchars($pkg_full_path));
86
	}
87

    
88
	if (!empty($path_error)) {
89
		include("head.inc");
90
		print_info_box($path_error . "<br />" . gettext("Try reinstalling the package."), 'danger', false);
91
		include("foot.inc");
92
		die;
93
	}
94

    
95
	if (file_exists($pkg_full_path)) {
96
		$pkg = parse_xml_config_pkg($pkg_full_path, "packagegui");
97
	} else {
98
		include("head.inc");
99
		print_info_box(sprintf(gettext("File not found %s."), htmlspecialchars($xml)), 'danger', false);
100
		include("foot.inc");
101
		exit;
102
	}
103
}
104

    
105
if ($pkg['donotsave'] != "") {
106
	header("Location: pkg_edit.php?xml=" . $xml);
107
	exit;
108
}
109

    
110
if ($pkg['include_file'] != "") {
111
	require_once($pkg['include_file']);
112
}
113

    
114
if ($_REQUEST['startdisplayingat']) {
115
	$startdisplayingat = $_REQUEST['startdisplayingat'];
116
}
117

    
118
if ($_REQUEST['display_maximum_rows']) {
119
	if ($_REQUEST['display_maximum_rows']) {
120
		$display_maximum_rows = $_REQUEST['display_maximum_rows'];
121
	}
122
}
123

    
124
$evaledvar = $config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'];
125

    
126
if ($_GET['act'] == "update") {
127

    
128
	if (is_array($config['installedpackages'][$pkg['name']]) && $pkg['name'] != "" && $_REQUEST['ids'] !="") {
129
		#get current values
130
		$current_values=$config['installedpackages'][$pkg['name']]['config'];
131
		#get updated ids
132
		parse_str($_REQUEST['ids'], $update_list);
133
		#sort ids to know what to change
134
		#useful to do not lose data when using sorting and paging
135
		$sort_list=$update_list['ids'];
136
		sort($sort_list);
137
		#apply updates
138
		foreach ($update_list['ids'] as $key=> $value) {
139
			$config['installedpackages'][$pkg['name']]['config'][$sort_list[$key]]=$current_values[$update_list['ids'][$key]];
140
		}
141
		#save current config
142
		write_config();
143
		#sync package
144
		eval ("{$pkg['custom_php_resync_config_command']}");
145
	}
146
	#function called via jquery, no need to continue after save changes.
147
	exit;
148
}
149
if ($_GET['act'] == "del") {
150
	// loop through our fieldnames and automatically setup the fieldnames
151
	// in the environment.	ie: a fieldname of username with a value of
152
	// testuser would automatically eval $username = "testuser";
153
	foreach ($evaledvar as $ip) {
154
		if ($pkg['adddeleteeditpagefields']['columnitem']) {
155
			foreach ($pkg['adddeleteeditpagefields']['columnitem'] as $column) {
156
				${xml_safe_fieldname($column['fielddescr'])} = $ip[xml_safe_fieldname($column['fieldname'])];
157
			}
158
		}
159
	}
160

    
161
	$a_pkg = &$config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'];
162

    
163
	if ($a_pkg[$_GET['id']]) {
164
		unset($a_pkg[$_GET['id']]);
165
		write_config();
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
		header("Location:  pkg.php?xml=" . $xml);
173
		exit;
174
	}
175
}
176

    
177
ob_start();
178

    
179
$iflist = get_configured_interface_with_descr(false, true);
180
$evaledvar = $config['installedpackages'][xml_safe_fieldname($pkg['name'])]['config'];
181

    
182
if ($pkg['custom_php_global_functions'] != "") {
183
	eval($pkg['custom_php_global_functions']);
184
}
185

    
186
if ($pkg['custom_php_command_before_form'] != "") {
187
	eval($pkg['custom_php_command_before_form']);
188
}
189

    
190
// Breadcrumb
191
if ($pkg['title'] != "") {
192
	/*if (!$only_edit) {						// Is any package still making use of this?? Is this something that is still wanted, considering the breadcrumb policy https://redmine.pfsense.org/issues/5527
193
 		$pkg['title'] = $pkg['title'] . '/Edit';		// If this needs to live on, then it has to be moved to run AFTER "foreach ($pkg['tabs']['tab'] as $tab)"-loop. This due to $pgtitle[] = $tab['text']; 
194
	}*/
195
	if (strpos($pkg['title'], '/')) {
196
		$title = explode('/', $pkg['title']);
197

    
198
		foreach ($title as $subtitle) {
199
			$pgtitle[] = gettext($subtitle);
200
		}
201
	} else {
202
		$pgtitle = array(gettext("Package"), gettext($pkg['title']));
203
	}
204
} else {
205
	$pgtitle = array(gettext("Package"), gettext("Editor"));
206
}
207

    
208
if ($pkg['tabs'] != "") {
209
	$tab_array = array();
210
	foreach ($pkg['tabs']['tab'] as $tab) {
211
		if ($tab['tab_level']) {
212
			$tab_level = $tab['tab_level'];
213
		} else {
214
			$tab_level = 1;
215
		}
216
		if (isset($tab['active'])) {
217
			$active = true;
218
			$pgtitle[] = $tab['text'];
219
		} else {
220
			$active = false;
221
		}
222
		if (isset($tab['no_drop_down'])) {
223
			$no_drop_down = true;
224
		}
225
		$urltmp = "";
226
		if ($tab['url'] != "") {
227
			$urltmp = $tab['url'];
228
		}
229
		if ($tab['xml'] != "") {
230
			$urltmp = "pkg_edit.php?xml=" . $tab['xml'];
231
		}
232

    
233
		$addresswithport = getenv("HTTP_HOST");
234
		$colonpos = strpos($addresswithport, ":");
235
		if ($colonpos !== False) {
236
			//my url is actually just the IP address of the pfsense box
237
			$myurl = substr($addresswithport, 0, $colonpos);
238
		} else {
239
			$myurl = $addresswithport;
240
		}
241
		// eval url so that above $myurl item can be processed if need be.
242
		$url = str_replace('$myurl', $myurl, $urltmp);
243

    
244
		$tab_array[$tab_level][] = array(
245
			$tab['text'],
246
			$active,
247
			$url
248
		);
249
	}
250

    
251
	ksort($tab_array);
252
}
253

    
254
include("head.inc");
255
if (isset($tab_array)) {
256
	foreach ($tab_array as $tabid => $tab) {
257
		display_top_tabs($tab); //, $no_drop_down, $tabid);
258
	}
259
}
260

    
261
?>
262

    
263
<script type="text/javascript">
264
//<![CDATA[
265
events.push(function() {
266

    
267
	function setFilter(filtertext) {
268
		$('#pkg_filter').val(filtertext);
269
		document.pkgform.submit();
270
	}
271

    
272
<?php
273
	if ($pkg['adddeleteeditpagefields']['movable']) {
274
?>
275
		$('#mainarea table tbody').sortable({
276
		items: 'tr.sortable',
277
			cursor: 'move',
278
			distance: 10,
279
			opacity: 0.8,
280
			helper: function(e, ui) {
281
				ui.children().each(function() {
282
					$(this).width($(this).width());
283
				});
284
			return ui;
285
			},
286
		});
287
<?php
288
	}
289
?>
290
});
291

    
292
function save_changes_to_xml(xml) {
293
	var ids = $('#mainarea table tbody').sortable('serialize', {key:"ids[]"});
294
	var strloading="<?=gettext('Saving changes...')?>";
295
	if (confirm("<?=gettext("Do you really want to save changes?")?>")) {
296
		$.ajax({
297
			type: 'get',
298
			cache: false,
299
			url: "<?=$_SERVER['SCRIPT_NAME']?>",
300
			data: {xml:'<?=$xml?>', act:'update', ids: ids},
301
			beforeSend: function() {
302
				$('#savemsg').empty().html(strloading);
303
			},
304
			error: function(data) {
305
				$('#savemsg').empty().html('Error:' + data);
306
			},
307
			success: function(data) {
308
				$('#savemsg').empty().html(data);
309
			}
310
		});
311
	}
312
}
313

    
314
//]]>
315
</script>
316

    
317
<?php
318
if ($_GET['savemsg'] != "") {
319
	$savemsg = htmlspecialchars($_GET['savemsg']);
320
}
321

    
322
if ($savemsg) {
323
	print_info_box($savemsg, 'success');
324
}
325
?>
326

    
327
<form action="pkg.php" name="pkgform" method="get">
328
	<input type='hidden' name='xml' value='<?=$_REQUEST['xml']?>' />
329
		<div id="mainarea" class="panel panel-default">
330
			<table id="mainarea" class="table table-striped table-hover table-condensed">
331
				<thead>
332
<?php
333
	/* Handle filtering bar A-Z */
334
	$include_filtering_inputbox = false;
335
	$colspan = 0;
336
	if ($pkg['adddeleteeditpagefields']['columnitem'] != "") {
337
		foreach ($pkg['adddeleteeditpagefields']['columnitem'] as $column) {
338
			$colspan++;
339
		}
340
	}
341
	if ($pkg['fields']['field']) {
342
		// First find the sorting type field if it exists
343
		foreach ($pkg['fields']['field'] as $field) {
344
			if ($field['type'] == "sorting") {
345
				if (isset($field['include_filtering_inputbox'])) {
346
					$include_filtering_inputbox = true;
347
				}
348
				if ($display_maximum_rows < 1) {
349
					if ($field['display_maximum_rows']) {
350
						$display_maximum_rows = $field['display_maximum_rows'];
351
					}
352
				}
353
				echo "<tr><td colspan='$colspan' class='text-center'>";
354
				echo gettext("Filter by: ");
355
				$isfirst = true;
356
				for ($char = 65; $char < 91; $char++) {
357
					if (!$isfirst) {
358
						echo " | ";
359
					}
360
					echo "<a href=\"#\" onclick=\"setFilter('" . chr($char) . "');\">" . chr($char) . "</a>";
361
					$isfirst = false;
362
				}
363
				echo "</td></tr>";
364
				echo "<tr><td colspan='$colspan' class='text-center'>";
365
				if ($field['sortablefields']) {
366
					echo gettext("Filter field: ") . "<select name='pkg_filter_type'>";
367
					foreach ($field['sortablefields']['item'] as $si) {
368
						if ($si['name'] == $_REQUEST['pkg_filter_type']) {
369
							$SELECTED = "selected";
370
						} else {
371
							$SELECTED = "";
372
						}
373
						echo "<option value='{$si['name']}' {$SELECTED}>{$si['name']}</option>";
374
					}
375
					echo "</select>";
376
				}
377
				if ($include_filtering_inputbox) {
378
					echo "&nbsp;&nbsp;" . gettext("Filter text: ") . "<input id='pkg_filter' name='pkg_filter' value='" . $_REQUEST['pkg_filter'] . "' /><input type='submit' value='Filter' />";
379
				}
380
				echo "</td></tr><tr><td><font size='-3'>&nbsp;</font></td></tr>";
381
			}
382
		}
383
	}
384
?>
385
				<tr>
386

    
387
<?php
388
	if ($display_maximum_rows) {
389
		$totalpages = ceil(round((count($evaledvar) / $display_maximum_rows), 9));
390
		$page = 1;
391
		$tmpcount = 0;
392
		$tmppp = 0;
393
		if (is_array($evaledvar)) {
394
			foreach ($evaledvar as $ipa) {
395
				if ($tmpcount == $display_maximum_rows) {
396
					$page++;
397
					$tmpcount = 0;
398
				}
399
				if ($tmppp == $startdisplayingat) {
400
					break;
401
				}
402
				$tmpcount++;
403
				$tmppp++;
404
			}
405
		}
406
		echo "<tr><th colspan='" . count($pkg['adddeleteeditpagefields']['columnitem']) . "'>";
407
		echo "<table width='100%' summary=''>";
408
		echo "<tr>";
409
		echo "<td class='text-left'>" . sprintf(gettext('Displaying page %1$s of %2$s'), $page, $totalpages) . "</b></td>";
410
		echo "<td class='text-right'>" . gettext("Rows per page: ") . "<select onchange='document.pkgform.submit();' name='display_maximum_rows'>";
411
		for ($x = 0; $x < 250; $x++) {
412
			if ($x == $display_maximum_rows) {
413
				$SELECTED = "selected";
414
			} else {
415
				$SELECTED = "";
416
			}
417
			echo "<option value='$x' $SELECTED>$x</option>\n";
418
			$x = $x + 4;
419
		}
420
		echo "</select></td></tr>";
421
		echo "</table>";
422
		echo "</th></tr>";
423
	}
424

    
425
	$cols = 0;
426
	if ($pkg['adddeleteeditpagefields']['columnitem'] != "") {
427
		foreach ($pkg['adddeleteeditpagefields']['columnitem'] as $column) {
428
			echo "<th class=\"listhdrr\">" . $column['fielddescr'] . "</th>";
429
			$cols++;
430
		}
431
	}
432
?>
433
				</tr>
434
				</thead>
435
				<tbody>
436
<?php
437
	$i = 0;
438
	$pagination_counter = 0;
439
	if ($evaledvar) {
440
		foreach ($evaledvar as $ip) {
441
			if ($startdisplayingat) {
442
				if ($i < $startdisplayingat) {
443
					$i++;
444
					continue;
445
				}
446
			}
447
			if ($_REQUEST['pkg_filter']) {
448
				// Handle filtered items
449
				if ($pkg['fields']['field'] && !$filter_regex) {
450
					// First find the sorting type field if it exists
451
					foreach ($pkg['fields']['field'] as $field) {
452
						if ($field['type'] == "sorting") {
453
							if ($field['sortablefields']['item']) {
454
								foreach ($field['sortablefields']['item'] as $sf) {
455
									if ($sf['name'] == $_REQUEST['pkg_filter_type']) {
456
										$filter_fieldname = $sf['fieldname'];
457
										#Use a default regex on sortable fields when none is declared
458
										if ($sf['regex']) {
459
											$filter_regex = str_replace("%FILTERTEXT%", $_REQUEST['pkg_filter'], trim($sf['regex']));
460
										} else {
461
											$filter_regex = "/{$_REQUEST['pkg_filter']}/i";
462
										}
463
									}
464
								}
465
							}
466
						}
467
					}
468
				}
469
				// Do we have something to filter on?
470
				unset($filter_matches);
471
				if ($pkg['adddeleteeditpagefields']['columnitem'] != "") {
472
					foreach ($pkg['adddeleteeditpagefields']['columnitem'] as $column) {
473
						$fieldname = $ip[xml_safe_fieldname($column['fieldname'])];
474
						if ($column['fieldname'] == $filter_fieldname) {
475
							if ($filter_regex) {
476
								//echo "$filter_regex - $fieldname<p/>";
477
								preg_match($filter_regex, $fieldname, $filter_matches);
478
								break;
479
							}
480
						}
481
					}
482
				}
483
				if (!$filter_matches) {
484
					$i++;
485
					continue;
486
				}
487
			}
488
			if ($pkg['adddeleteeditpagefields']['movable']) {
489
				echo "<tr valign=\"top\" class=\"sortable\" id=\"id_{$i}\">\n";
490
			} else {
491
				echo "<tr valign=\"top\">\n";
492
			}
493
			if ($pkg['adddeleteeditpagefields']['columnitem'] != "") {
494
				foreach ($pkg['adddeleteeditpagefields']['columnitem'] as $column) {
495
					if ($column['fieldname'] == "description") {
496
						$class = "listbg";
497
					} else {
498
						$class = "listlr";
499
					}
500
?>
501
					<td class="<?=$class?>" ondblclick="document.location='pkg_edit.php?xml=<?=$xml?>&amp;act=edit&amp;id=<?=$i?>';">
502
<?php
503
					$fieldname = $ip[xml_safe_fieldname($column['fieldname'])];
504
					#Check if columnitem has a type field declared
505
					if ($column['type'] == "checkbox") {
506
						if ($fieldname == "") {
507
							echo gettext("No");
508
						} else {
509
							echo gettext("Yes");
510
						}
511
					} else if ($column['type'] == "interface") {
512
						echo $column['prefix'] . $iflist[$fieldname] . $column['suffix'];
513
					} else {
514
						#Check if columnitem has an encoding field declared
515
						if ($column['encoding'] == "base64") {
516
							echo $column['prefix'] . base64_decode($fieldname) . $column['suffix'];
517
						#Check if there is a custom info to show when $fieldname is not empty
518
						} else if ($column['listmodeon'] && $fieldname != "") {
519
							echo $column['prefix'] . gettext($column['listmodeon']). $column['suffix'];
520
						#Check if there is a custom info to show when $fieldname is empty
521
						} else if ($column['listmodeoff'] && $fieldname == "") {
522
							echo $column['prefix'] .gettext($column['listmodeoff']). $column['suffix'];
523
						} else {
524
							echo $column['prefix'] . $fieldname ." ". $column['suffix'];
525
						}
526
					}
527
?>
528
					</td>
529
<?php
530
				} // foreach columnitem
531
			} // if columnitem
532
?>
533
					<td valign="middle" class="list text-nowrap">
534
						<table border="0" cellspacing="0" cellpadding="1" summary="icons">
535
							<tr>
536
<?php
537
			#Show custom description to edit button if defined
538
			$edit_msg=($pkg['adddeleteeditpagefields']['edittext']?$pkg['adddeleteeditpagefields']['edittext']:gettext("Edit this item"));
539
?>
540
								<td><a class="fa fa-pencil" href="pkg_edit.php?xml=<?=$xml?>&amp;act=edit&amp;id=<?=$i?>" title="<?=$edit_msg?>"></a></td>
541
<?php
542
			#Show custom description to delete button if defined
543
			$delete_msg=($pkg['adddeleteeditpagefields']['deletetext']?$pkg['adddeleteeditpagefields']['deletetext']:gettext("Delete this item"));
544
?>
545
								<td>&nbsp;<a class="fa fa-trash" href="pkg.php?xml=<?=$xml?>&amp;act=del&amp;id=<?=$i?>" title="<?=$delete_msg?>"></a></td>
546
							</tr>
547
						</tbody>
548
					</table>
549
				</td>
550
<?php
551
			echo "</tr>\n"; // Pairs with an echo tr some way above
552
			// Handle pagination and display_maximum_rows
553
			if ($display_maximum_rows) {
554
				if ($pagination_counter == ($display_maximum_rows-1) or
555
					$i == (count($evaledvar)-1)) {
556
					$colcount = count($pkg['adddeleteeditpagefields']['columnitem']);
557
					$final_footer = "";
558
					$final_footer .= "<tr><td colspan='$colcount'>";
559
					$final_footer .= "<table width='100%' summary=''><tr>";
560
					$final_footer .= "<td class='text-left'>";
561
					$startingat = $startdisplayingat - $display_maximum_rows;
562
					if ($startingat > -1) {
563
						$final_footer .= "<a href='pkg.php?xml=" . $_REQUEST['xml'] . "&amp;startdisplayingat={$startingat}&amp;display_maximum_rows={$display_maximum_rows}'>";
564
					} else if ($startdisplayingat > 1) {
565
						$final_footer .= "<a href='pkg.php?xml=" . $_REQUEST['xml'] . "&amp;startdisplayingat=0&amp;display_maximum_rows={$display_maximum_rows}'>";
566
					}
567
					$final_footer .= "<font size='2'><< " . gettext("Previous page") . "</font></a>";
568
					if ($tmppp + $display_maximum_rows > count($evaledvar)) {
569
						$endingrecord = count($evaledvar);
570
					} else {
571
						$endingrecord = $tmppp + $display_maximum_rows;
572
					}
573
					$final_footer .= "</td><td class='text-center'>";
574
					$tmppp++;
575
					$final_footer .= "<font size='2'>Displaying {$tmppp} - {$endingrecord} / " . count($evaledvar) . " records";
576
					$final_footer .= "</font></td><td class='text-right'>&nbsp;";
577
					if (($i+1) < count($evaledvar)) {
578
						$final_footer .= "<a href='pkg.php?xml=" . $_REQUEST['xml'] . "&amp;startdisplayingat=" . ($startdisplayingat + $display_maximum_rows) . "&amp;display_maximum_rows={$display_maximum_rows}'>";
579
					}
580
					$final_footer .= "<font size='2'>" . gettext("Next page") . " >></font></a>";
581
					$final_footer .= "</td></tr></table></td></tr>";
582
					$i = count($evaledvar);
583
					break;
584
				}
585
			}
586
			$i++;
587
			$pagination_counter++;
588
		} // foreach evaledvar
589
	} // if evaledvar
590
?>
591
				<tr>
592
					<td colspan="<?=$cols?>"></td>
593
					<td>
594
						<table border="0" cellspacing="0" cellpadding="1" summary="icons">
595
							<tr>
596
<?php
597
	#Show custom description to add button if defined
598
	$add_msg=($pkg['adddeleteeditpagefields']['addtext']?$pkg['adddeleteeditpagefields']['addtext']:gettext("Add a new item"));
599
?>
600
								<td><a href="pkg_edit.php?xml=<?=$xml?>&amp;id=<?=$i?>" class="btn btn-sm btn-success" title="<?=$add_msg?>"><?=gettext('Add')?></a></td>
601
<?php
602
	#Show description button and info if defined
603
	if ($pkg['adddeleteeditpagefields']['description']) {
604
?>
605
								<td>
606
									<i class="fa fa-info-circle"><?=$pkg['adddeleteeditpagefields']['description']?></i>
607
								</td>
608
<?php
609
	}
610
?>
611
							</tr>
612
						</table>
613
					</td>
614
				</tr>
615
				<?=$final_footer?>
616
			</table>
617
			</div>
618
		<input class="btn btn-primary" type="button" value="Save" name="Submit" onclick="save_changes_to_xml('<?=$xml?>')" />
619

    
620
</form>
621
<?php
622
echo "<!-- filter_fieldname: {$filter_fieldname} -->";
623
echo "<!-- filter_regex: {$filter_regex} -->";
624

    
625
include("foot.inc"); ?>
(100-100/229)