Project

General

Profile

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

    
25
##|+PRIV
26
##|*IDENT=page-system-packagemanager
27
##|*NAME=System: Package Manager
28
##|*DESCR=Allow access to the 'System: Package Manager' page.
29
##|*MATCH=pkg_mgr.php*
30
##|-PRIV
31

    
32
ini_set('max_execution_time', '0');
33

    
34
require_once("globals.inc");
35
require_once("guiconfig.inc");
36
require_once("pkg-utils.inc");
37

    
38
// if upgrade in progress, alert user
39
if (is_subsystem_dirty('packagelock')) {
40
	$pgtitle = array(gettext("System"), gettext("Package Manager"));
41
	$pglinks = array("", "@self");
42
	include("head.inc");
43
	print_info_box("Please wait while packages are reinstalled in the background.");
44
	include("foot.inc");
45
	exit;
46
}
47

    
48
// We are being called only to get the package data, not to display anything
49
if (($_REQUEST) && ($_REQUEST['ajax'])) {
50
	print(get_pkg_table());
51
	exit;
52
}
53

    
54
// The content for the table of packages is created here and fetched by Ajax. This allows us to draw the page and display
55
// any required messages while the table is being downloaded/populated. On very small/slow systems, that can take a while
56
function get_pkg_table() {
57
	$pkg_info = get_pkg_info('all', true, false);
58

    
59
	if (!$pkg_info) {
60
		print("error");
61
		exit;
62
	}
63

    
64
	$pkgtbl = 	'<table id="pkgtable" class="table table-striped table-hover">' . "\n";
65
	$pkgtbl .= 		'<thead>' . "\n";
66
	$pkgtbl .= 			'<tr>' . "\n";
67
	$pkgtbl .= 				'<th>' . gettext("Name") . "</th>\n";
68
	$pkgtbl .= 				'<th>' . gettext("Version") . "</th>\n";
69
	$pkgtbl .= 				'<th>' . gettext("Description") . "</th>\n";
70
	$pkgtbl .= 				'<th></th>' . "\n";
71
	$pkgtbl .= 			'</tr>' . "\n";
72
	$pkgtbl .= 		'</thead>' . "\n";
73
	$pkgtbl .= 		'<tbody>' . "\n";
74

    
75
	foreach ($pkg_info as $index) {
76
		//AutoConfigBackup not to be installed >= v 2.4.4
77
		if (isset($index['installed']) || ($index['shortname'] == "AutoConfigBackup")) {
78
			continue;
79
		}
80

    
81
		$pkgtbl .= 	'<tr>' . "\n";
82
		$pkgtbl .= 	'<td>' . "\n";
83

    
84
		if (($index['www']) && ($index['www'] != "UNKNOWN")) {
85
			$pkgtbl .= 	'<a title="' . gettext("Visit official website") . '" target="_blank" href="' . htmlspecialchars($index['www']) . '">' . "\n";
86
			$pkgtbl .= htmlspecialchars($index['shortname']) . '</a>' . "\n";
87
		} else {
88
			$pkgtbl .= htmlspecialchars($index['shortname']);
89
		}
90
		$pkgtbl .= 	'</td>' . "\n";
91
		$pkgtbl .= 	'<td>' . "\n";
92

    
93
		if (!g_get('disablepackagehistory')) {
94
			$pkgtbl .= '<a target="_blank" title="' . gettext("View changelog") . '" href="' . htmlspecialchars($index['changeloglink']) . '">' . "\n";
95
			$pkgtbl .= htmlspecialchars($index['version']) . '</a>' . "\n";
96
		} else {
97
			$pkgtbl .= htmlspecialchars($index['version']);
98
		}
99

    
100
		$pkgtbl .= 	'</td>' . "\n";
101
		$pkgtbl .= 	'<td>' . "\n";
102
		$pkgtbl .= 		$index['desc'];
103

    
104
		if (is_array($index['deps']) && count($index['deps'])) {
105
			$pkgtbl .= 	'<br /><br />' . gettext("Package Dependencies") . ":<br/>\n";
106

    
107
			foreach ($index['deps'] as $pdep) {
108
				$pkgtbl .= '<a target="_blank" href="https://freshports.org/' . $pdep['origin'] . '">&nbsp;<i class="fa-solid fa-paperclip"></i> ' . basename($pdep['origin']) . '-' . $pdep['version'] . '</a>&emsp;' . "\n";
109
			}
110

    
111
			$pkgtbl .= "\n";
112
		}
113

    
114
		$pkgtbl .= 	'</td>' . "\n";
115
		$pkgtbl .= '<td>' . "\n";
116
		$pkgtbl .= '<a title="' . gettext("Click to install") . '" href="pkg_mgr_install.php?pkg=' . $index['name'] . '" class="btn btn-success btn-sm"><i class="fa-solid fa-plus icon-embed-btn"></i>Install</a>' . "\n";
117

    
118
		if (!g_get('disablepackageinfo') && $index['pkginfolink'] && $index['pkginfolink'] != $index['www']) {
119
			$pkgtbl .= '<a target="_blank" title="' . gettext("View more information") . '" href="' . htmlspecialchars($index['pkginfolink']) . '" class="btn btn-default btn-sm">info</a>' . "\n";
120
		}
121

    
122
		$pkgtbl .= 	'</td>' . "\n";
123
		$pkgtbl .= 	'</tr>' . "\n";
124
	}
125

    
126
	$pkgtbl .= 	'</tbody>' . "\n";
127
	$pkgtbl .= '</table>' . "\n";
128

    
129
	return ($pkgtbl);
130
}
131

    
132
$pgtitle = array(gettext("System"), gettext("Package Manager"), gettext("Available Packages"));
133
$pglinks = array("", "pkg_mgr_installed.php", "@self");
134
include("head.inc");
135

    
136
$tab_array = array();
137
$tab_array[] = array(gettext("Installed Packages"), false, "pkg_mgr_installed.php");
138
$tab_array[] = array(gettext("Available Packages"), true, "pkg_mgr.php");
139
display_top_tabs($tab_array);
140
?>
141
<div class="panel panel-default" id="search-panel" style="display: none;">
142
	<div class="panel-heading">
143
		<h2 class="panel-title">
144
			<?=gettext('Search')?>
145
			<span class="widget-heading-icon pull-right">
146
				<a data-toggle="collapse" href="#search-panel_panel-body">
147
					<i class="fa-solid fa-plus-circle"></i>
148
				</a>
149
			</span>
150
		</h2>
151
	</div>
152
	<div id="search-panel_panel-body" class="panel-body collapse in">
153
		<div class="form-group">
154
			<label class="col-sm-2 control-label">
155
				<?=gettext("Search term")?>
156
			</label>
157
			<div class="col-sm-5"><input class="form-control" name="searchstr" id="searchstr" type="text"/></div>
158
			<div class="col-sm-2">
159
				<select id="where" class="form-control">
160
					<option value="0"><?=gettext("Name")?></option>
161
					<option value="1"><?=gettext("Description")?></option>
162
					<option value="2" selected><?=gettext("Both")?></option>
163
				</select>
164
			</div>
165
			<div class="col-sm-3">
166
				<a id="btnsearch" title="<?=gettext("Search")?>" class="btn btn-primary btn-sm"><i class="fa-solid fa-search icon-embed-btn"></i><?=gettext("Search")?></a>
167
				<a id="btnclear" title="<?=gettext("Clear")?>" class="btn btn-info btn-sm"><i class="fa-solid fa-undo icon-embed-btn"></i><?=gettext("Clear")?></a>
168
			</div>
169
			<div class="col-sm-10 col-sm-offset-2">
170
				<span class="help-block"><?=gettext('Enter a search string or *nix regular expression to search package names and descriptions.')?></span>
171
			</div>
172
		</div>
173
	</div>
174
</div>
175

    
176
<div class="panel panel-default">
177
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Packages')?></h2></div>
178
	<div id="pkgtbl" class="panel-body table-responsive">
179
		<div id="waitmsg">
180
			<?php print_info_box(gettext("Please wait while the list of packages is retrieved and formatted.") . '&nbsp;<i class="fa-solid fa-cog fa-spin"></i>'); ?>
181
		</div>
182

    
183
		<div id="errmsg" style="display: none;">
184
			<?php print_info_box("<ul><li>" . gettext("Unable to retrieve package information.") . "</li></ul>", 'danger'); ?>
185
		</div>
186
	</div>
187
</div>
188

    
189
<script type="text/javascript">
190
//<![CDATA[
191

    
192
events.push(function() {
193

    
194
	// Initial state & toggle icons of collapsed panel
195
	$('.panel-heading a[data-toggle="collapse"]').each(function (idx, el) {
196
		var body = $(el).parents('.panel').children('.panel-body')
197
		var isOpen = body.hasClass('in');
198

    
199
		$(el).children('i').toggleClass('fa-plus-circle', !isOpen);
200
		$(el).children('i').toggleClass('fa-minus-circle', isOpen);
201

    
202
		body.on('shown.bs.collapse', function() {
203
			$(el).children('i').toggleClass('fa-minus-circle', true);
204
			$(el).children('i').toggleClass('fa-plus-circle', false);
205
		});
206
	});
207

    
208
	// Make these controls plain buttons
209
	$("#btnsearch").prop('type', 'button');
210
	$("#btnclear").prop('type', 'button');
211

    
212
	// Search for a term in the package name and/or description
213
	$("#btnsearch").click(function() {
214
		var searchstr = $('#searchstr').val().toLowerCase();
215
		var table = $("table tbody");
216
		var where = $('#where').val();
217

    
218
		table.find('tr').each(function (i) {
219
			var $tds = $(this).find('td'),
220
				shortname = $tds.eq(0).text().trim().toLowerCase(),
221
				descr = $tds.eq(2).text().trim().toLowerCase();
222

    
223
			regexp = new RegExp(searchstr);
224
			if (searchstr.length > 0) {
225
				if (!(regexp.test(shortname) && (where != 1)) && !(regexp.test(descr) && (where != 0))) {
226
					$(this).hide();
227
				} else {
228
					$(this).show();
229
				}
230
			} else {
231
				$(this).show();	// A blank search string shows all
232
			}
233
		});
234
	});
235

    
236
	// Clear the search term and unhide all rows (that were hidden during a previous search)
237
	$("#btnclear").click(function() {
238
		var table = $("table tbody");
239

    
240
		$('#searchstr').val("");
241

    
242
		table.find('tr').each(function (i) {
243
			$(this).show();
244
		});
245
	});
246

    
247
	// Hitting the enter key will do the same as clicking the search button
248
	$("#searchstr").on("keyup", function (event) {
249
	    if (event.keyCode == 13) {
250
	        $("#btnsearch").get(0).click();
251
	    }
252
	});
253

    
254
	// Retrieve the table formatted package information and display it in the "Packages" panel
255
	// (Or display an appropriate error message)
256
	var ajaxRequest;
257

    
258
	$.ajax({
259
		url: "/pkg_mgr.php",
260
		type: "post",
261
		data: { ajax: "ajax"},
262
		success: function(data) {
263
			if (data == "error") {
264
				$('#waitmsg').hide();
265
				$('#errmsg').show();
266
			} else {
267
				$('#pkgtbl').html(data);
268
				$('#search-panel').show();
269
			}
270
		},
271
		error: function() {
272
			$('#waitmsg').hide();
273
			$('#errmsg').show();
274
		}
275
	});
276

    
277
});
278
//]]>
279
</script>
280

    
281
<?php include("foot.inc");
282
?>
(96-96/228)