<?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(
$user_level) {
            
_e('You do not have sufficient permissions to access this page.''download-mgr');
            return;
        }

        
$levels = array(109876543210'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')" />&nbsp;
        <?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?> &raquo;" />
</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">&laquo;</a>]';   ?></legend>
    <table id="downloads">
        <?php if($track_filedownload_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'), 8basename(__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(
== $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;
            }
        }
    }
}
?>