<?php
/*
Plugin Name: Download Manager
Plugin URI: http://guff.szub.net/download-manager/
Description: Restrict and track downloads through WordPress.
Version: R1.beta2_WP2.1
Author: Kaf Oseo
Author URI: http://szub.net
Copyright (c) 2005, Kaf Oseo (http://szub.net)
Download Manager is released under the GPL license
http://www.gnu.org/licenses/gpl.txt
This is a WordPress plugin (http://wordpress.org).
BASIC INSTRUCTIONS
Place download-mgr.php in the plugins directory, and activate under
Plugins in WordPress. To configure, go to Manage > Downloads.
Link to any file in your download directory using the following URL
query format:
?dl=filename.ext
Examples:
/blog/index.php?dl=test-program.zip
http://www.example.com/?dl=RedSox_2004_stats.sxc
*/
// user-configurable variable >
// Set $tracking_type to have Download Manager use a single table to
// track downloads, multiple tables (one per blog), or do not track.
// Valid value: 'single', 'multiple', 'none'
$tracking_type = 'multiple';
// < user-configurable variable
global $tracking_type;
load_plugin_textdomain('download-mgr'); // plugin localization
if(is_plugin_page()) {
download_Mgr_page();
} else {
function download_Mgr_page() {
global $tracking_type, $user_level, $table_prefix, $wpdb;
if(8 > $user_level) {
_e('You do not have sufficient permissions to access this page.', 'download-mgr');
return;
}
$levels = array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 'public');
$option = get_option('download_mgr');
$test_download_option = $option;
$button_text = __('Update Settings', 'download-mgr');
if(isset($_POST['Submit'])) {
$option = array();
$option['path'] = $_POST['path'];
$option['url'] = $_POST['url'];
$option['allowed_level'] = $_POST['allowed_level'];
$option['show_msgs'] = $_POST['show_msgs'];
$option['wrong_level_msg'] = $_POST['wrong_level_msg'];
$option['no_login_msg'] = $_POST['no_login_msg'];
if(!$test_download_option) {
add_option('download_mgr', $option, 'Settings for Download Manager plugin. To configure, look under Manage > Downloads');
$test_download_option = 1;
} else {
update_option('download_mgr', $option);
}
?>
<div class="updated">
<p><strong><?php _e('Settings have been saved.', 'download-mgr') ?></strong></p>
</div>
<?php
}
if(!$test_download_option) {
$option['path'] = ABSPATH . 'wp-content';
$option['url'] = get_settings('siteurl') . '/wp-content';
$option['allowed_level'] = '0';
$option['show_msgs'] = '1';
$option['wrong_level_msg'] = 'Sorry, you don\'t have the right user level for downloads.';
$option['no_login_msg'] = 'You must be a ' . get_settings('blogname') . ' user and logged on to download.';
$button_text = __('Add Settings', 'download-mgr');
?>
<div class="updated">
<p><strong><?php _e('Set Download Manager options and click Add Settings.', 'download-mgr') ?></strong></p>
</div>
<?php
} else {
$option['path'] = stripslashes(htmlspecialchars($option['path']));
$option['url'] = stripslashes(htmlspecialchars($option['url']));
$option['wrong_level_msg'] = stripslashes(htmlspecialchars($option['wrong_level_msg']));
$option['no_login_msg'] = stripslashes(htmlspecialchars($option['no_login_msg']));
}
?>
<div class="wrap">
<?php if($test_download_option && ('none' != $tracking_type)) {
if(!isset($_GET['tracking'])) { ?>
<div class="download_view"><a href="?page=<?php echo basename(__FILE__); ?>&tracking"><?php _e('Tracking Only', 'download-mgr'); ?></a></div>
<?php } else { ?>
<div class="download_view"><a href="?page=<?php echo basename(__FILE__); ?>"><?php _e('Show Settings', 'download-mgr'); ?></a></div>
<?php }
}
?>
<h2><?php _e('Download Manager', 'download-mgr'); ?></h2>
<?php
if(!isset($_GET['tracking'])) {
?>
<form name="download_options" method="post" action="">
<input type="hidden" name="action" value="update" />
<fieldset class="options">
<legend><?php _e('Settings', 'download-mgr'); ?></legend>
<table cellspacing="2" cellpadding="5" class="editform">
<tr valign="baseline">
<th scope="row"><?php _e('Download path:', 'download-mgr') ?></th>
<td><input type="text" name="path" id="path" size="64" value="<?php echo $option['path']; ?>" /></td>
</tr>
<tr valign="baseline">
<th scope="row"><?php _e('Download URL:', 'download-mgr') ?></th>
<td><input type="text" name="url" id="url" size="64" value="<?php echo $option['url']; ?>" /></td>
</tr>
<tr valign="baseline">
<th scope="row"><?php _e('Access level:', 'download-mgr') ?></th>
<td><select name="allowed_level" id="allowed_level">
<?php
foreach($levels as $level) : ?>
<option value="<?php echo $level; ?>"<?php if($level == $option['allowed_level']) { echo ' selected="selected"'; } ?>><?php echo $level; ?></option>
<?php endforeach; ?>
</select>
<?php _e('(Set lowest allowed user level)', 'download-mgr'); ?>
</td>
</tr>
<tr valign="baseline"<?php if('public' == $option['allowed_level']) echo 'style="display: none;"'; ?>>
<th scope="row"><?php _e('Report errors:', 'download-mgr') ?></th>
<td scope="row">
<label>
<input name="show_msgs" type="checkbox" id="show_msgs" value="1" <?php checked('1', $option['show_msgs'], show_msgs); ?> onclick="toggle('msgs')" />
<?php _e('(Display messages on error)', 'download-mgr') ?>
</label>
</td>
</tr>
</table>
<div id="msgs" <?php if('public' == $option['allowed_level'] || false == $option['show_msgs']) { echo 'style="display:none;"'; } ?>>
<fieldset class="options">
<legend><?php _e('Error Messages', 'download-mgr'); ?></legend>
<table cellspacing="2" cellpadding="5" class="editform">
<th valign="baseline" scope="row"><?php _e('Wrong level:', 'download-mgr') ?>
<td valign="baseline" scope="row"><input type="text" name="wrong_level_msg" id="wrong_level_msg" size="65" value="<?php echo $option['wrong_level_msg']; ?>" /><br/>
</tr>
<tr valign="baseline">
<th scope="row"><?php _e('No login:', 'download-mgr') ?></th>
<td><input type="text" name="no_login_msg" id="no_login_msg" size="65" value="<?php echo $option['no_login_msg']; ?>" /><br/>
</tr>
</table>
</fieldset>
</div>
</fieldset>
<p class="submit">
<input type="submit" name="Submit"
value="<?php echo $button_text; ?> »" />
</p>
</form>
<?php
}
if($test_download_option && ('none' != $tracking_type)) {
download_Mgr_table('create');
if(isset($_GET['tracking']) && $_GET['tracking']) {
$track_file = true;
}
?>
<fieldset class="options">
<legend><?php _e('Download Tracking', 'download-mgr'); ?><?php if($track_file) echo ': ' . $_GET['tracking'] . ' [<a href="?page=' . basename(__FILE__) . '&tracking">«</a>]'; ?></legend>
<table id="downloads">
<?php if($track_file) download_Mgr_table('list_file', $_GET['tracking']); else download_Mgr_table('list', $option['allowed_level']) ?>
</table>
</fieldset>
<?php } ?>
</div>
<?php
}
function download_Mgr_admin() {
if(function_exists('add_management_page')) {
add_management_page(__('Download Manager', 'download-mgr'), __('Downloads', 'download-mgr'), 8, basename(__FILE__), 'download_Mgr_page');
}
}
add_action('admin_head', 'download_Mgr_admin');
function download_Mgr_head(){
if(isset($_GET['page'])) {
echo "<style type=\"text/css\">
<!--
a.list_file {
display: block;
border-bottom: none;
}
a:hover.list_file {
color: #fff;
background-color: #69c;
}
table#downloads {
width: 100%;
border-collapse: collapse;
}
#downloads th, #downloads td {
font-size: 80%;
margin: 0;
padding: 4px;
border: 2px solid #fff;
}
#downloads th {
font-weight: bold;
}
#downloads th#count, #downloads th#login, #downloads th#filename, #downloads th#referer, #downloads th#ip {
width: auto;
}
#downloads th#timestamp {
width: 140px;
}
#downloads td div {
white-space: nowrap;
overflow: hidden;
}
.download_view a {
float: right;
top: 10px;
right: 10px;
font-size: .7em;
text-decoration: none;
display: block;
padding: 1px 4px 1px 4px;
border: none;
}
.download_view a:hover {
color: #fff;
background-color: #69c;
}
//-->
</style>
<script type=\"text/javascript\">
//<![CDATA[
function toggle(id) {
if (document.getElementById) {
var tags = document.getElementById(id);
tags.style.display = (tags.style.display == 'none') ? 'block' : 'none';
}
}
//]]>
</script>\n";
}
}
add_action('admin_head', 'download_Mgr_head');
function download_Mgr_table($do='', $download_param='') {
global $tracking_type, $table_prefix, $wpdb;
$option = get_option('download_mgr');
if('none' != $tracking_type) {
if('multiple' == $tracking_type)
$wpdb->downloads = $table_prefix . 'downloads';
else
$wpdb->downloads = 'downloads';
switch($do) :
case 'create' :
$downloads_table = "CREATE TABLE IF NOT EXISTS $wpdb->downloads(
id INT UNSIGNED NOT NULL auto_increment,
file_name VARCHAR(255) NOT NULL default '',
login VARCHAR(60) default '',
referer TEXT default '',
remote_addr VARCHAR(40) default '',
date DATETIME NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id),
KEY file_name (file_name) )";
$wpdb->query($downloads_table);
break;
case 'insert' :
$result = $wpdb->query(
"INSERT INTO $wpdb->downloads (id, file_name, login, referer, remote_addr, date) VALUES(NULL, '" .
$download_param[0] . "', '" .
$download_param[1] . "', '" .
$download_param[2] . "', '" .
$download_param[3] . "', '" .
$download_param[4] . "')" );
return $result;
break;
case 'list' :
$file_names = @$wpdb->get_col("SELECT DISTINCT file_name FROM $wpdb->downloads ORDER BY file_name ASC");
if($file_names) {
if('public' != $option['allowed_level']) {
$login = "<th id=\"login\">login</th>";
}
$download_list = "<tr>\n<th id=\"filename\">filename</th>$login<th id=\"referer\">referer</th><th id=\"ip\">ip</th><th id=\"timestamp\">timestamp</th><th id=\"count\">count</th>\n</tr>";
foreach($file_names as $file_name) {
$class = ('alternate' == $class) ? '' : 'alternate';
$download = @$wpdb->get_row("SELECT * FROM $wpdb->downloads WHERE file_name = '$file_name' ORDER BY date DESC");
$download_count = count($wpdb->get_col("SELECT id FROM $wpdb->downloads WHERE file_name = '$file_name'"));
if('public' != $option['allowed_level']) {
$td_login = "<td><div>$download->login</div></td>";
}
$download_list .= "<tr align=\"top\" class=\"$class\">\n<td><div><a href=\"?page=" . basename(__FILE__) . "&tracking=$download->file_name\" class=\"list_file\" title=\"$download->file_name ($download_count)\" alt\"$download->file_name ($download_count)\">$download->file_name</div></td>$td_login<td><div>$download->referer</div></td><td><div>$download->remote_addr</div></td><td><div>$download->date</div></td><td align=\"right\"><div>$download_count</div></td>\n</tr>";
}
} else {
$download_list = "<tr>\n<th>" . __('No downloads have been tracked.', 'download-mgr') . "</th>\n</tr>";
}
echo $download_list;
break;
case 'list_file' :
$downloads = @$wpdb->get_results("SELECT login, referer, remote_addr, date FROM $wpdb->downloads WHERE file_name = '$download_param' ORDER BY date DESC");
if($downloads) {
if('public' != $option['allowed_level']) {
$login = "<th id=\"login\">login</th>";
}
$download_list = "<tr>\n$login<th id=\"referer\">referer</th><th id=\"ip\">ip</th><th id=\"timestamp\">timestamp</th>\n</tr>";
foreach($downloads as $download) {
$class = ('alternate' == $class) ? '' : 'alternate';
if('public' != $option['allowed_level']) {
$td_login = "<td><div>$download->login</div></td>";
}
$download_list .= "<tr align=\"top\" class=\"$class\">\n$td_login<td><div>$download->referer</div></td><td><div>$download->remote_addr</div></td><td><div>$download->date</div></td>\n</tr>";
}
} else {
$download_list = "<tr>\n<th>" . __('No downloads have been tracked.', 'download-mgr') . "</th>\n</tr>";
}
echo $download_list;
break;
endswitch;
}
}
if(isset($_GET['dl'])) { // if 'dl' GET query, start downloadin'!
global $wp_version;
$file_name = $_GET['dl'];
$option = get_option('download_mgr');
if (isset($_COOKIE['wordpressuser_' . COOKIEHASH])) {
$user_login = $_COOKIE['wordpressuser_' . COOKIEHASH];
if($wp_version < 2)
$user_level = $wpdb->get_var("SELECT user_level FROM $wpdb->users WHERE user_login = '$user_login'");
else
$user_level = $wpdb->get_var("SELECT meta_value FROM $wpdb->usermeta, $wpdb->users WHERE user_login = '$user_login' AND ID = user_id AND meta_key = '" . $wpdb->prefix . "user_level'");
}
if(('public' == $option['allowed_level']) || ($user_login && ($user_level >= $option['allowed_level']))) { // if proper access level
$file_name = str_replace('../', '', $file_name); // protect from site traversing
if($file_name) { // if filename
// directory crawl process
$path = rtrim(stripslashes($option['path']), '/');
$dir_stack = array($path);
$files = array();
while($dir = array_shift($dir_stack)) {
if($dh = opendir($dir)) {
while(($file = readdir($dh)) !== false) {
if($file != '.' && $file != '..') {
$full_path = "$dir/$file";
$files[] = $full_path;
if(is_dir($full_path)) {
$dir_stack[] = $full_path;
}
}
}
}
closedir($dh);
}
foreach($files as $file) {
if(preg_match("%$file_name$%", $file)) {
$correct_path = str_replace($path, '', $file);
$url = rtrim(stripslashes($option['$url']), '/');
$file_url = $url . $correct_path;
@ignore_user_abort();
@set_time_limit(0);
$mimetype = 'application/octet-stream'; // set mime-type
$handle = fopen($file, "rb"); // now let's get the file!
header("Pragma: "); // Leave blank for issues with IE
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: $mimetype");
header("Content-Disposition: attachment; filename=" . basename($file_name));
header("Content-Length: " . (filesize($file)));
fpassthru($handle);
$referer = $_SERVER['HTTP_REFERER'];
$ip = $_SERVER['REMOTE_ADDR'];
$now = date('Y-m-d H:i:s');
$download_array = array($file_name, $user_login, $referer, $ip, $now);
download_Mgr_table('insert', $download_array); // add record to table
die;
}
}
if(!$correct_path) { // file does not exist; provide 404 error
if(preg_match('/cgi/', php_sapi_name())) {
header('Status: 404 Not Found');
} else {
header('HTTP/1.x 404 Not Found');
}
}
} else {
return; // no file specified, so end gracefully
}
} else {
if(1 == $option['show_msgs']) {
if($user_login && ($user_level < $option['allowed_level'])) { // is user but wrong level
exit(stripslashes($option['wrong_level_msg']));
} else { // is not a user
exit(stripslashes($option['no_login_msg']));
}
} else {
return;
}
}
}
}
?>