Permalink
Browse files

Fixed bug where downloading files generated by something like downloa…

…d.php?foo=bar... would result in each subsequent file overwriting the previous one; additionally, the downloaded files' name is now available in $result->info['downloaded_filename']
  • Loading branch information...
stefangabos committed Nov 28, 2017
1 parent eb6ef47 commit 8275001d0f2fd6cfb25674af7bd5dd9c66cae1be
Showing with 30 additions and 4 deletions.
  1. +30 −4 Zebra_cURL.php
View
@@ -6,7 +6,7 @@
* Read more {@link https://github.com/stefangabos/Zebra_cURL/ here}
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @version 1.3.4 (last revision: May 22, 2017)
* @version 1.3.5 (last revision: November 01, 2017)
* @copyright (c) 2013 - 2017 Stefan Gabos
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LESSER GENERAL PUBLIC LICENSE
* @package Zebra_cURL
@@ -661,8 +661,13 @@ public function delete($urls, $callback = '') {
/**
* Downloads one or more files from one or more URLs specified by the <i>$urls</i> argument, saves the downloaded
* files (with their original name) to the path specified by the <i>$path</i> argument, and executes the callback
* function specified by the <i>$callback</i> argument for each and every request, as soon as a request finishes.
* files to the path specified by the <i>$path</i> argument, and executes the callback function specified by the
* <i>$callback</i> argument for each and every request, as soon as a request finishes.
*
* <samp>If the path you are downloading from refers to a file, then the file's original name will be preserved but,
* if you are downloading a file generated by a script (i.e. http://foo.com/bar.php?w=1200&h=800), the downloaded
* file's name will be random generated. Refer to the downloaded file's name in the result's "info" attribute, in
* the "downloaded_filename" section - see the example below.</samp>
*
* Downloads are streamed (bytes downloaded are directly written to disk) removing the unnecessary strain from your
* server of reading files into memory first, and then writing them to disk.
@@ -709,6 +714,9 @@ public function delete($urls, $callback = '') {
* print_r('<pre>');
* print_r($result);
*
* // get the downloaded file's path
* $result->info['downloaded_filename'];
*
* // show the server's response code
* } else die('Server responded with code ' . $result->info['http_code']);
*
@@ -2532,6 +2540,18 @@ private function _process() {
);
// if downloaded a file
if (isset($request['options'][CURLOPT_BINARYTRANSFER]) && $request['options'][CURLOPT_BINARYTRANSFER]) {
// we make a dummy array with the first first 2 elements (which we also remove from the $arguments[0]->info array)
$tmp_array = array_splice($arguments[0]->info, 0, 2);
// make available the name we saved the file with
// (we need to merge the first 2 elements, our new array and the rest of the elements)
$arguments[0]->info = array_merge($tmp_array, array('downloaded_filename' => $this->_running['fh' . $resource_number]['file_name']), $arguments[0]->info);
}
// feed them as arguments to the callback function
// and save the callback's response, if any
$callback_response = call_user_func_array($request['callback'], $arguments);
@@ -2650,8 +2670,14 @@ private function _queue_requests() {
// we use this so we won't have hashtags and/or query string in the file's name later on
$parsed = parse_url($request['url']);
// the name to save the file by
// if the downloaded path refers to something with a query string (i.e. download.php?foo=bar&w=1000&h=1000)
// the downloaded file's name would be "download.php" and, if you are downloading multiple files, each one
// would overwrite the previous one; therefore we use an md5 of the query string in this case
$request['file_name'] = $request['path'] . (isset($parsed['query']) && $parsed['query'] != '' ? md5($parsed['query']) : basename($parsed['path']));
// open a file and save the file pointer
$request['file_handler'] = fopen($request['path'] . basename($parsed['path']), 'w+');
$request['file_handler'] = fopen($request['file_name'], 'w+');
// tell libcurl to use the file for streaming the download
$this->option(CURLOPT_FILE, $request['file_handler']);

0 comments on commit 8275001

Please sign in to comment.