Project

General

Profile

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

    
55
##|+PRIV
56
##|*IDENT=page-system-packagemanager
57
##|*NAME=System: Package Manager
58
##|*DESCR=Allow access to the 'System: Package Manager' page.
59
##|*MATCH=pkg_mgr.php*
60
##|-PRIV
61

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

    
64
require_once("globals.inc");
65
require_once("guiconfig.inc");
66
require_once("pkg-utils.inc");
67

    
68
// if upgrade in progress, alert user
69
if (is_subsystem_dirty('packagelock')) {
70
	$pgtitle = array(gettext("System"), gettext("Package Manager"));
71
	include("head.inc");
72
	print_info_box("Please wait while packages are reinstalled in the background.");
73
	include("foot.inc");
74
	exit;
75
}
76

    
77
// We are being called only to get the pacakge data, not to display anything
78
if (($_REQUEST) && ($_REQUEST['ajax'])) {
79
	print(get_pkg_table());
80
	exit;
81
}
82

    
83
// THe content for the table of packages is created here and fetched by Ajax. This allows us to draw the page and dispay
84
// any required messages while the table it being downloaded/populated. On very small/slow systems, that can take a while
85
function get_pkg_table() {
86

    
87
	$pkg_info = get_pkg_info();
88

    
89
	if (!$pkg_info) {
90
		print("error");
91
		exit;
92
	}
93

    
94
	$pkgtbl = 	'<table id="pkgtable" class="table table-striped table-hover">' . "\n";
95
	$pkgtbl .= 		'<thead>' . "\n";
96
	$pkgtbl .= 			'<tr>' . "\n";
97
	$pkgtbl .= 				'<th>' . gettext("Name") . "</th>\n";
98
	$pkgtbl .= 				'<th>' . gettext("Version") . "</th>\n";
99
	$pkgtbl .= 				'<th>' . gettext("Description") . "</th>\n";
100
	$pkgtbl .= 				'<th></th>' . "\n";
101
	$pkgtbl .= 			'</tr>' . "\n";
102
	$pkgtbl .= 		'</thead>' . "\n";
103
	$pkgtbl .= 		'<tbody>' . "\n";
104

    
105
	foreach ($pkg_info as $index) {
106
		if (isset($index['installed'])) {
107
			continue;
108
		}
109

    
110
		$pkgtbl .= 	'<tr>' . "\n";
111
		$pkgtbl .= 	'<td>' . "\n";
112

    
113
		if (($index['www']) && ($index['www'] != "UNKNOWN")) {
114
			$pkgtbl .= 	'<a title="' . gettext("Visit official website") . '" target="_blank" href="' . htmlspecialchars($index['www']) . '">' . "\n";
115
			$pkgtbl .= htmlspecialchars($index['shortname']) . '</a>' . "\n";
116
		} else {
117
			$pkgtbl .= htmlspecialchars($index['shortname']);
118
		}
119
		$pkgtbl .= 	'</td>' . "\n";
120
		$pkgtbl .= 	'<td>' . "\n";
121

    
122
		if (!$g['disablepackagehistory']) {
123
			$pkgtbl .= '<a target="_blank" title="' . gettext("View changelog") . '" href="' . htmlspecialchars($index['changeloglink']) . '">' . "\n";
124
			$pkgtbl .= htmlspecialchars($index['version']) . '</a>' . "\n";
125
		} else {
126
			$pkgtbl .= htmlspecialchars($index['version']);
127
		}
128

    
129
		$pkgtbl .= 	'</td>' . "\n";
130
		$pkgtbl .= 	'<td>' . "\n";
131
		$pkgtbl .= 		$index['desc'];
132

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

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

    
140
			$pkgtbl .= "\n";
141
		}
142

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

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

    
151
		$pkgtbl .= 	'</td>' . "\n";
152
		$pkgtbl .= 	'</tr>' . "\n";
153
	}
154

    
155
	$pkgtbl .= 	'</tbody>' . "\n";
156
	$pkgtbl .= '</table>' . "\n";
157

    
158
	return ($pkgtbl);
159
}
160

    
161
$pgtitle = array(gettext("System"), gettext("Package Manager"), gettext("Available Packages"));
162
include("head.inc");
163

    
164
$tab_array = array();
165
$tab_array[] = array(gettext("Installed Packages"), false, "pkg_mgr_installed.php");
166
$tab_array[] = array(gettext("Available Packages"), true, "pkg_mgr.php");
167
display_top_tabs($tab_array);
168
?>
169
<div class="panel panel-default" id="search-panel" style="display: none;">
170
	<div class="panel-heading">
171
		<h2 class="panel-title">
172
			<?=gettext('Search')?>
173
			<span class="widget-heading-icon pull-right">
174
				<a data-toggle="collapse" href="#search-panel_panel-body">
175
					<i class="fa fa-plus-circle"></i>
176
				</a>
177
			</span>
178
		</h2>
179
	</div>
180
	<div id="search-panel_panel-body" class="panel-body collapse in">
181
		<div class="form-group">
182
			<label class="col-sm-2 control-label">
183
				<?=gettext("Search term")?>
184
			</label>
185
			<div class="col-sm-5"><input class="form-control" name="searchstr" id="searchstr" type="text"/></div>
186
			<div class="col-sm-2">
187
				<select id="where" class="form-control">
188
					<option value="0"><?=gettext("Name")?></option>
189
					<option value="1"><?=gettext("Description")?></option>
190
					<option value="2" selected><?=gettext("Both")?></option>
191
				</select>
192
			</div>
193
			<div class="col-sm-3">
194
				<a id="btnsearch" title="<?=gettext("Search")?>" class="btn btn-primary btn-sm"><i class="fa fa-search icon-embed-btn"></i><?=gettext("Search")?></a>
195
				<a id="btnclear" title="<?=gettext("Clear")?>" class="btn btn-info btn-sm"><i class="fa fa-undo icon-embed-btn"></i><?=gettext("Clear")?></a>
196
			</div>
197
			<div class="col-sm-10 col-sm-offset-2">
198
				<span class="help-block"><?=gettext('Enter a search string or *nix regular expression to search package names and descriptions.')?></span>
199
			</div>
200
		</div>
201
	</div>
202
</div>
203

    
204
<div class="panel panel-default">
205
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Packages')?></h2></div>
206
	<div id="pkgtbl" class="panel-body table-responsive">
207
		<div id="waitmsg">
208
			<?php print_info_box(gettext("Please wait while the list of packages is retrieved and formatted.") . '&nbsp;<i class="fa fa-cog fa-spin"></i>'); ?>
209
		</div>
210

    
211
		<div id="errmsg" style="display: none;">
212
			<?php print_info_box("<ul><li>" . gettext("Unable to retrieve package information.") . "</li></ul>", 'danger'); ?>
213
		</div>
214
	</div>
215
</div>
216

    
217
<script type="text/javascript">
218
//<![CDATA[
219

    
220
events.push(function() {
221

    
222
	// Initial state & toggle icons of collapsed panel
223
	$('.panel-heading a[data-toggle="collapse"]').each(function (idx, el) {
224
		var body = $(el).parents('.panel').children('.panel-body')
225
		var isOpen = body.hasClass('in');
226

    
227
		$(el).children('i').toggleClass('fa-plus-circle', !isOpen);
228
		$(el).children('i').toggleClass('fa-minus-circle', isOpen);
229

    
230
		body.on('shown.bs.collapse', function() {
231
			$(el).children('i').toggleClass('fa-minus-circle', true);
232
			$(el).children('i').toggleClass('fa-plus-circle', false);
233
		});
234
	});
235

    
236
	// Make these controls plain buttons
237
	$("#btnsearch").prop('type', 'button');
238
	$("#btnclear").prop('type', 'button');
239

    
240
	// Search for a term in the package name and/or description
241
	$("#btnsearch").click(function() {
242
		var searchstr = $('#searchstr').val().toLowerCase();
243
		var table = $("table tbody");
244
		var where = $('#where').val();
245

    
246
		table.find('tr').each(function (i) {
247
			var $tds = $(this).find('td'),
248
				shortname = $tds.eq(0).text().trim().toLowerCase(),
249
				descr = $tds.eq(2).text().trim().toLowerCase();
250

    
251
			regexp = new RegExp(searchstr);
252
			if (searchstr.length > 0) {
253
				if (!(regexp.test(shortname) && (where != 1)) && !(regexp.test(descr) && (where != 0))) {
254
					$(this).hide();
255
				} else {
256
					$(this).show();
257
				}
258
			} else {
259
				$(this).show();	// A blank search string shows all
260
			}
261
		});
262
	});
263

    
264
	// Clear the search term and unhide all rows (that were hidden during a previous search)
265
	$("#btnclear").click(function() {
266
		var table = $("table tbody");
267

    
268
		$('#searchstr').val("");
269

    
270
		table.find('tr').each(function (i) {
271
			$(this).show();
272
		});
273
	});
274

    
275
	// Hitting the enter key will do the same as clicking the search button
276
	$("#searchstr").on("keyup", function (event) {
277
	    if (event.keyCode == 13) {
278
	        $("#btnsearch").get(0).click();
279
	    }
280
	});
281

    
282
	// Retrieve the table formatted pacakge information and display it in the "Packages" panel
283
	// (Or display an appropriate error message)
284
	var ajaxRequest;
285

    
286
	$.ajax({
287
		url: "/pkg_mgr.php",
288
		type: "post",
289
		data: { ajax: "ajax"},
290
		success: function(data) {
291
			if (data == "error") {
292
				$('#waitmsg').hide();
293
				$('#errmsg').show();
294
			} else {
295
				$('#pkgtbl').html(data);
296
				$('#search-panel').show();
297
			}
298
		},
299
		error: function() {
300
			$('#waitmsg').hide();
301
			$('#errmsg').show();
302
		}
303
	});
304

    
305
});
306
//]]>
307
</script>
308

    
309
<?php include("foot.inc");
310
?>
(101-101/227)