JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Fix db_get_value after mysql->mysqli upgrade
[wfpl.git] / uploader.php
1 <?php
2
3 # This program is in the public domain within the United States. Additionally,
4 # we waive copyright and related rights in the work worldwide through the CC0
5 # 1.0 Universal public domain dedication, which can be found at
6 # http://creativecommons.org/publicdomain/zero/1.0/
7
8
9 require_once(__DIR__.'/'.'template.php');
10 require_once(__DIR__.'/'.'encode.php');
11 require_once(__DIR__.'/'.'session.php');
12 require_once(__DIR__.'/'.'upload.php'); # FIXME for path_to() which should be somewhere else
13
14 # This function is for making an uploader with a progress bar.
15 #
16 # Parameter: (optional)
17 #     progress_url: URL javascript should use to get progress updates (defaults to this_url() with the query string replaced with ?wfpl_upload_progress=FILENAME (where FILENAME is the first parameter.))
18 #
19 # You must also set $GLOBALS['wfpl_uploader_port'] to an available port for the upload receiver to run on.
20 #
21 # Returns: (an array containing)
22 #     html
23 #     css
24 #     javascript
25 #     filename
26
27 function uploader($progress_url = '') {
28         if(!$filename) {
29                 $filename = strtolower(session_generate_key());
30         }
31         if(!$progress_url) {
32                 $progress_url = this_url();
33                 $q = strpos($progress_url, '?');
34                 if($q) {
35                         $progress_url = substr($progress_url, 0, $q);
36                 }
37                 $progress_url .= '?wfpl_upload_progress=' . enc_url_val($filename);
38         }
39         if(!$GLOBALS['wfpl_uploader_host']) {
40                 $GLOBALS['wfpl_uploader_host'] = this_host();
41         }
42
43         $html = new tem();
44         $html->load(__DIR__.'/'.'uploader/uploader.html');
45         $html->set('filename', $filename);
46         $html->set('host', $GLOBALS['wfpl_uploader_host']);
47         $html->set('port', $GLOBALS['wfpl_uploader_port']);
48         $html->show('main');
49         $html = $html->get('main');
50
51         $css = read_whole_file(__DIR__.'/'.'uploader/uploader.css');
52
53         $javascript = new tem();
54         $javascript->load(__DIR__.'/'.'uploader/progress.js');
55         $javascript->set('url', $progress_url);
56         $javascript = $javascript->run();
57
58         uploader_daemon_start($GLOBALS['wfpl_uploader_port']);
59
60         return array($html, $css, $javascript, $filename);
61 }
62
63 function uploader_move($tmp_filename, $filename) {
64         $tmp_path = $GLOBALS['wfpl_uploader_path'] . '/partial/' . $tmp_filename;
65         $out_path = $GLOBALS['wfpl_uploader_path'] . '/' . $filename;
66         unlink($GLOBALS['wfpl_uploader_path'] . '/progress/' . $tmp_filename);
67         rename($tmp_path, $out_path);
68 }
69
70 # start a daemon to accept file uploads and give progress indicators
71 # if the port is used (eg if the daemon is already running) this will do nothing.
72 function uploader_daemon_start($port) {
73         exec(path_to('tcpserver') . " -q -R -H -llocalhost 0 $port " . path_to('perl') . ' lib/wfpl/uploader/daemon.pl ' . $GLOBALS['wfpl_uploader_path'] . ' >/dev/null 2>/dev/null < /dev/null &');
74 }
75
76 /* call this to respond to the javascript async request for progress on the upload */
77 function wfpl_uploader_progress() {
78         if(!isset($_REQUEST['wfpl_upload_progress'])) {
79                 return;
80         }
81
82         # allow this script to run for 8 hours
83         set_time_limit(28800);
84
85         $file = $_REQUEST['wfpl_upload_progress'];
86         $file = strtolower($file);
87         $file = preg_replace('|[^a-z0-9.-]|', '_', $file);
88         $file = preg_replace('|^[.-]|', '_', $file);
89         $file = $GLOBALS['wfpl_uploader_path'] . "/progress/$file";
90         
91         $waited = 0;
92         while(!file_exists($file)) {
93                 usleep(500000);
94                 ++$waited;
95                 if($waited > 100) {
96                         return;
97                 }
98         }
99
100         $progress_sent = 0;
101         while(true) {
102                 clearstatcache();
103                 $stats = stat($file);
104                 if($stats !== false) {
105                         $progress = $stats['size'];
106                         if($progress > $progress_sent) {
107                                 print(substr('............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................', 0, $progress - $progress_sent));
108                                 flush();
109                                 $progress_sent = $progress;
110                                 if($progress == 1000) {
111                                         return;
112                                 }
113                         }
114                 }
115                 usleep(500000); # wait half a second
116         }
117 }