1 <?php
2
3 namespace Alo\CLI;
4
5 use Alo\cURL;
6 use Alo\File;
7
8 if(!defined('GEN_START')) {
9 http_response_code(404);
10 die();
11 }
12
13 /**
14 * Downloads an external resource to disk, echoing the progress
15 *
16 * @author Art <a.molcanovas@gmail.com>
17 */
18 class Downloader {
19
20 /**
21 * cURL handler
22 *
23 * @var cURL
24 */
25 protected $curl;
26
27 /**
28 * Download destination
29 *
30 * @var string
31 */
32 protected $dest;
33
34 /**
35 * Timestamp when we last reported the status
36 *
37 * @var int
38 */
39 protected $last_report_time;
40
41 /**
42 * The last reported status
43 *
44 * @var string
45 */
46 protected $last_report_status;
47
48 /**
49 * Output
50 *
51 * @var resource
52 */
53 protected $fp;
54
55 /**
56 * Number of times the status has been reported
57 *
58 * @var int
59 */
60 protected $report_count;
61
62 /**
63 * Instantiates the class
64 *
65 * @author Art <a.molcanovas@gmail.com>
66 *
67 * @param string $source Download source
68 * @param string $destination Download destination
69 */
70 function __construct($source, $destination) {
71 $this->dest = $destination;
72 $this->report_count = 0;
73
74 $this->curl = new cURL($source);
75 $this->curl->setProgressFunction([$this, 'progressFunction']);
76 }
77
78 /**
79 * The progress function
80 *
81 * @author Art <a.molcanovas@gmail.com>
82 *
83 * @param resource $resource Coulsn't find documentation on this one, most likely the curl resource
84 * @param int $download_size How much we are downloading
85 * @param int $downloaded How much we have downloaded
86 * @param int $upload_size How much we are uploading
87 * @param int $uploaded How much we have uploaded
88 */
89 function progressFunction($resource, $download_size, $downloaded, $upload_size, $uploaded) {
90 $ed = $size = 0;
91
92 if($download_size > 0 && $downloaded > 0) {
93 $ed = $downloaded;
94 $size = $download_size;
95 } elseif($upload_size > 0 && $uploaded > 0) {
96 $ed = $uploaded;
97 $size = $upload_size;
98 }
99
100 if($ed && $size && $this->report_count++ != 0) {
101 $status = File::convert_size($ed) . '/' . File::convert_size($size) . ' downloaded ['
102 . round(($ed / $size) * 100, 3) . ' %]';
103
104 $time = time();
105 if($status != $this->last_report_status && ($time != $this->last_report_time || $ed == $size)) {
106 $this->last_report_time = $time;
107 $this->last_report_status = $status;
108 echo $status . PHP_EOL;
109 }
110
111 $this->report_count++;
112 }
113
114 //Unnecessary, but stops the IDE from thinking the variable is unused
115 unset($resource);
116 }
117
118 /**
119 * Starts the download
120 *
121 * @author Art <a.molcanovas@gmail.com>
122 * @return bool Whther the download was successful (on the cURL side)
123 */
124 function download() {
125 if(file_exists($this->dest)) {
126 unlink($this->dest);
127 }
128
129 $this->fp = fopen($this->dest, 'w');
130 $this->curl->setopt(CURLOPT_FILE, $this->fp);
131 $this->curl->exec();
132 fclose($this->fp);
133
134 $errno = $this->curl->errno();
135
136 if($errno === CURLE_OK) {
137 return true;
138 } else {
139 echo $this->curl->error() . PHP_EOL;
140
141 return false;
142 }
143 }
144 }