Version Description
Fixed incorrect header for file size. That should fix incompatibility with some plugins and downloaders.
Support for resumed transfers.
Download this release
Release Info
Developer | pepak.net |
Plugin | Simple Download Monitor |
Version | 0.09 |
Comparing to | |
See all releases |
Code changes from version 0.08 to 0.09
- readme.txt +9 -2
- sdmon.css +10 -0
- simple-download-monitor.php +150 -8
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: Pepak
|
|
3 |
Donate link:
|
4 |
Tags: files, counter, count, tracking, download monitor, monitor, downloads, download
|
5 |
Requires at least: 2.8.0
|
6 |
-
Tested up to: 2.
|
7 |
-
Stable tag: 0.
|
8 |
|
9 |
Count the number of downloads without having to maintain a comprehensive download page.
|
10 |
|
@@ -84,6 +84,13 @@ webhosting.
|
|
84 |
|
85 |
== Changelog ==
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
= 0.08 =
|
88 |
* Administrators can now delete download statistics from the Tools panel:
|
89 |
A checkbox is shown next to each record, and a button for deleting checked
|
3 |
Donate link:
|
4 |
Tags: files, counter, count, tracking, download monitor, monitor, downloads, download
|
5 |
Requires at least: 2.8.0
|
6 |
+
Tested up to: 2.9.1
|
7 |
+
Stable tag: 0.09
|
8 |
|
9 |
Count the number of downloads without having to maintain a comprehensive download page.
|
10 |
|
84 |
|
85 |
== Changelog ==
|
86 |
|
87 |
+
= 0.09 =
|
88 |
+
|
89 |
+
* Fixed incorrect header for file size. That should fix incompatibility
|
90 |
+
with some plugins and downloaders.
|
91 |
+
|
92 |
+
* Support for resumed transfers.
|
93 |
+
|
94 |
= 0.08 =
|
95 |
* Administrators can now delete download statistics from the Tools panel:
|
96 |
A checkbox is shown next to each record, and a button for deleting checked
|
sdmon.css
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#sdmon .sdmon-rownum { width: 3ex; text-align: right; }
|
2 |
+
#sdmon .sdmon-filename { }
|
3 |
+
#sdmon .sdmon-count { text-align: right; }
|
4 |
+
#sdmon .sdmon-date { width: 24ex; text-align: center; }
|
5 |
+
#sdmon .sdmon-nonex { width: 5ex; text-align: center; }
|
6 |
+
#sdmon .sdmon-ipaddr { }
|
7 |
+
#sdmon .sdmon-referer { }
|
8 |
+
#sdmon .sdmon-username { }
|
9 |
+
#sdmon th {text-align: center; }
|
10 |
+
#sdmon th, #sdmon td { padding-left: 1ex; padding-right: 1ex; }
|
simple-download-monitor.php
CHANGED
@@ -4,12 +4,12 @@
|
|
4 |
Plugin Name: Simple Download Monitor
|
5 |
Plugin URI: http://www.pepak.net/wordpress/simple-download-monitor-plugin
|
6 |
Description: Count the number of downloads without having to maintain a comprehensive download page.
|
7 |
-
Version: 0.
|
8 |
Author: Pepak
|
9 |
Author URI: http://www.pepak.net
|
10 |
*/
|
11 |
|
12 |
-
/* Copyright 2009 Pepak (email: wordpress@pepak.net)
|
13 |
|
14 |
This program is free software; you can redistribute it and/or modify
|
15 |
it under the terms of the GNU General Public License as published by
|
@@ -110,6 +110,152 @@ if (!class_exists('SimpleDownloadMonitor'))
|
|
110 |
return $table;
|
111 |
}
|
112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
public function Download($filename)
|
114 |
{
|
115 |
global $wpdb, $user_login, $user_ID;
|
@@ -169,12 +315,8 @@ if (!class_exists('SimpleDownloadMonitor'))
|
|
169 |
$inlineregexp = self::PREG_DELIMITER . get_option(self::PREFIX . 'inline') . self::PREG_DELIMITER;
|
170 |
if ($inlineregexp && preg_match($inlineregexp, $relfilename))
|
171 |
$disposition = 'inline';
|
172 |
-
|
173 |
-
|
174 |
-
header('Content-size: ' . filesize($fullfilename));
|
175 |
-
// Send the file to user.
|
176 |
-
$fp = fopen($fullfilename, 'rb');
|
177 |
-
fpassthru($fp);
|
178 |
// Successful end
|
179 |
return TRUE;
|
180 |
}
|
4 |
Plugin Name: Simple Download Monitor
|
5 |
Plugin URI: http://www.pepak.net/wordpress/simple-download-monitor-plugin
|
6 |
Description: Count the number of downloads without having to maintain a comprehensive download page.
|
7 |
+
Version: 0.09
|
8 |
Author: Pepak
|
9 |
Author URI: http://www.pepak.net
|
10 |
*/
|
11 |
|
12 |
+
/* Copyright 2009, 2010 Pepak (email: wordpress@pepak.net)
|
13 |
|
14 |
This program is free software; you can redistribute it and/or modify
|
15 |
it under the terms of the GNU General Public License as published by
|
110 |
return $table;
|
111 |
}
|
112 |
|
113 |
+
//-----------------------------------------------------------------------------------
|
114 |
+
// Methods set_range, buffered_read, byteserve adapted from
|
115 |
+
// http://www.coneural.org/florian/papers/04_byteserving.php
|
116 |
+
|
117 |
+
function set_range($range, $filesize, &$first, &$last){
|
118 |
+
/*
|
119 |
+
Sets the first and last bytes of a range, given a range expressed as a string
|
120 |
+
and the size of the file.
|
121 |
+
|
122 |
+
If the end of the range is not specified, or the end of the range is greater
|
123 |
+
than the length of the file, $last is set as the end of the file.
|
124 |
+
|
125 |
+
If the begining of the range is not specified, the meaning of the value after
|
126 |
+
the dash is "get the last n bytes of the file".
|
127 |
+
|
128 |
+
If $first is greater than $last, the range is not satisfiable, and we should
|
129 |
+
return a response with a status of 416 (Requested range not satisfiable).
|
130 |
+
|
131 |
+
Examples:
|
132 |
+
$range='0-499', $filesize=1000 => $first=0, $last=499 .
|
133 |
+
$range='500-', $filesize=1000 => $first=500, $last=999 .
|
134 |
+
$range='500-1200', $filesize=1000 => $first=500, $last=999 .
|
135 |
+
$range='-200', $filesize=1000 => $first=800, $last=999 .
|
136 |
+
|
137 |
+
*/
|
138 |
+
$dash=strpos($range,'-');
|
139 |
+
$first=trim(substr($range,0,$dash));
|
140 |
+
$last=trim(substr($range,$dash+1));
|
141 |
+
if ($first=='') {
|
142 |
+
//suffix byte range: gets last n bytes
|
143 |
+
$suffix=$last;
|
144 |
+
$last=$filesize-1;
|
145 |
+
$first=$filesize-$suffix;
|
146 |
+
if($first<0) $first=0;
|
147 |
+
} else {
|
148 |
+
if ($last=='' || $last>$filesize-1) $last=$filesize-1;
|
149 |
+
}
|
150 |
+
if($first>$last){
|
151 |
+
//unsatisfiable range
|
152 |
+
header("Status: 416 Requested range not satisfiable");
|
153 |
+
header("Content-Range: */$filesize");
|
154 |
+
exit;
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
function buffered_read($file, $bytes, $buffer_size=1024){
|
159 |
+
/*
|
160 |
+
Outputs up to $bytes from the file $file to standard output, $buffer_size bytes at a time.
|
161 |
+
*/
|
162 |
+
$bytes_left=$bytes;
|
163 |
+
while($bytes_left>0 && !feof($file)){
|
164 |
+
if($bytes_left>$buffer_size)
|
165 |
+
$bytes_to_read=$buffer_size;
|
166 |
+
else
|
167 |
+
$bytes_to_read=$bytes_left;
|
168 |
+
$bytes_left-=$bytes_to_read;
|
169 |
+
$contents=fread($file, $bytes_to_read);
|
170 |
+
echo $contents;
|
171 |
+
flush();
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
function byteserve($filename, $mimetype, $disposition = ''){
|
176 |
+
/*
|
177 |
+
Byteserves the file $filename.
|
178 |
+
|
179 |
+
When there is a request for a single range, the content is transmitted
|
180 |
+
with a Content-Range header, and a Content-Length header showing the number
|
181 |
+
of bytes actually transferred.
|
182 |
+
|
183 |
+
When there is a request for multiple ranges, these are transmitted as a
|
184 |
+
multipart message. The multipart media type used for this purpose is
|
185 |
+
"multipart/byteranges".
|
186 |
+
*/
|
187 |
+
|
188 |
+
$filesize=filesize($filename);
|
189 |
+
$file=fopen($filename,"rb");
|
190 |
+
|
191 |
+
$ranges=NULL;
|
192 |
+
if ($_SERVER['REQUEST_METHOD']=='GET' && isset($_SERVER['HTTP_RANGE']) && $range=stristr(trim($_SERVER['HTTP_RANGE']),'bytes=')){
|
193 |
+
$range=substr($range,6);
|
194 |
+
$boundary=sha1(uniqid());//set a random boundary
|
195 |
+
$ranges=explode(',',$range);
|
196 |
+
}
|
197 |
+
|
198 |
+
if($ranges && count($ranges)){
|
199 |
+
header("HTTP/1.1 206 Partial content");
|
200 |
+
header("Accept-Ranges: bytes");
|
201 |
+
if(count($ranges)>1){
|
202 |
+
/*
|
203 |
+
More than one range is requested.
|
204 |
+
*/
|
205 |
+
|
206 |
+
//compute content length
|
207 |
+
$content_length=0;
|
208 |
+
foreach ($ranges as $range){
|
209 |
+
$this->set_range($range, $filesize, $first, $last);
|
210 |
+
$content_length+=strlen("\r\n--$boundary\r\n");
|
211 |
+
$content_length+=strlen("Content-type: $mimetype\r\n");
|
212 |
+
$content_length+=strlen("Content-range: bytes $first-$last/$filesize\r\n\r\n");
|
213 |
+
$content_length+=$last-$first+1;
|
214 |
+
}
|
215 |
+
$content_length+=strlen("\r\n--$boundary--\r\n");
|
216 |
+
|
217 |
+
//output headers
|
218 |
+
header("Content-Length: $content_length");
|
219 |
+
//see http://httpd.apache.org/docs/misc/known_client_problems.html for an discussion of x-byteranges vs. byteranges
|
220 |
+
header("Content-Type: multipart/x-byteranges; boundary=$boundary");
|
221 |
+
|
222 |
+
//output the content
|
223 |
+
foreach ($ranges as $range){
|
224 |
+
$this->set_range($range, $filesize, $first, $last);
|
225 |
+
echo "\r\n--$boundary\r\n";
|
226 |
+
echo "Content-type: $mimetype\r\n";
|
227 |
+
echo "Content-range: bytes $first-$last/$filesize\r\n\r\n";
|
228 |
+
fseek($file,$first);
|
229 |
+
$this->buffered_read ($file, $last-$first+1);
|
230 |
+
}
|
231 |
+
echo "\r\n--$boundary--\r\n";
|
232 |
+
} else {
|
233 |
+
/*
|
234 |
+
A single range is requested.
|
235 |
+
*/
|
236 |
+
$range=$ranges[0];
|
237 |
+
$this->set_range($range, $filesize, $first, $last);
|
238 |
+
header("Content-Length: ".($last-$first+1) );
|
239 |
+
header("Content-Range: bytes $first-$last/$filesize");
|
240 |
+
header("Content-Type: $mimetype");
|
241 |
+
if ($disposition)
|
242 |
+
header("Content-Disposition: $disposition");
|
243 |
+
fseek($file,$first);
|
244 |
+
$this->buffered_read($file, $last-$first+1);
|
245 |
+
}
|
246 |
+
} else{
|
247 |
+
//no byteserving
|
248 |
+
header("Accept-Ranges: bytes");
|
249 |
+
header("Content-Length: $filesize");
|
250 |
+
header("Content-Type: $mimetype");
|
251 |
+
if ($disposition)
|
252 |
+
header("Content-Disposition: $disposition");
|
253 |
+
readfile($filename);
|
254 |
+
}
|
255 |
+
fclose($file);
|
256 |
+
}
|
257 |
+
//-----------------------------------------------------------------------------------
|
258 |
+
|
259 |
public function Download($filename)
|
260 |
{
|
261 |
global $wpdb, $user_login, $user_ID;
|
315 |
$inlineregexp = self::PREG_DELIMITER . get_option(self::PREFIX . 'inline') . self::PREG_DELIMITER;
|
316 |
if ($inlineregexp && preg_match($inlineregexp, $relfilename))
|
317 |
$disposition = 'inline';
|
318 |
+
$disposition = $disposition . '; filename=' . basename($fullfilename);
|
319 |
+
$this->byteserve($fullfilename, $mimetype, $disposition);
|
|
|
|
|
|
|
|
|
320 |
// Successful end
|
321 |
return TRUE;
|
322 |
}
|