FOF30\Download\Download::importFromURL PHP Method

importFromURL() public method

Performs the staggered download of file.
public importFromURL ( array $params ) : array
$params array A parameters array, as sent by the user interface
return array A return status array
    public function importFromURL($params)
    {
        $this->params = $params;
        // Fetch data
        $url = $this->getParam('url');
        $localFilename = $this->getParam('localFilename');
        $frag = $this->getParam('frag', -1);
        $totalSize = $this->getParam('totalSize', -1);
        $doneSize = $this->getParam('doneSize', -1);
        $maxExecTime = $this->getParam('maxExecTime', 5);
        $runTimeBias = $this->getParam('runTimeBias', 75);
        $length = $this->getParam('length', 1048576);
        if (empty($localFilename)) {
            $localFilename = basename($url);
            if (strpos($localFilename, '?') !== false) {
                $paramsPos = strpos($localFilename, '?');
                $localFilename = substr($localFilename, 0, $paramsPos - 1);
                $platformBaseDirectories = $this->container->platform->getPlatformBaseDirs();
                $tmpDir = $platformBaseDirectories['tmp'];
                $tmpDir = rtrim($tmpDir, '/\\');
                $localFilename = $tmpDir . '/' . $localFilename;
            }
        }
        // Init retArray
        $retArray = array("status" => true, "error" => '', "frag" => $frag, "totalSize" => $totalSize, "doneSize" => $doneSize, "percent" => 0, "localfile" => $localFilename);
        try {
            $timer = new Timer($maxExecTime, $runTimeBias);
            $start = $timer->getRunningTime();
            // Mark the start of this download
            $break = false;
            // Don't break the step
            do {
                // Do we have to initialize the file?
                if ($frag == -1) {
                    // Currently downloaded size
                    $doneSize = 0;
                    if (@file_exists($localFilename)) {
                        @unlink($localFilename);
                    }
                    // Delete and touch the output file
                    $fp = @fopen($localFilename, 'wb');
                    if ($fp !== false) {
                        @fclose($fp);
                    }
                    // Init
                    $frag = 0;
                    $retArray['totalSize'] = $this->adapter->getFileSize($url);
                    if ($retArray['totalSize'] <= 0) {
                        $retArray['totalSize'] = 0;
                    }
                    $totalSize = $retArray['totalSize'];
                }
                // Calculate from and length
                $from = $frag * $length;
                $to = $length + $from - 1;
                // Try to download the first frag
                $required_time = 1.0;
                $error = '';
                try {
                    $result = $this->adapter->downloadAndReturn($url, $from, $to, $this->adapterOptions);
                } catch (DownloadError $e) {
                    $result = false;
                    $error = $e->getMessage();
                }
                if ($result === false) {
                    // Failed download
                    if ($frag == 0) {
                        // Failure to download first frag = failure to download. Period.
                        $retArray['status'] = false;
                        $retArray['error'] = $error;
                        return $retArray;
                    } else {
                        // Since this is a staggered download, consider this normal and finish
                        $frag = -1;
                        $totalSize = $doneSize;
                        $break = true;
                    }
                }
                // Add the currently downloaded frag to the total size of downloaded files
                if ($result !== false) {
                    $fileSize = strlen($result);
                    $doneSize += $fileSize;
                    // Append the file
                    $fp = @fopen($localFilename, 'ab');
                    if ($fp === false) {
                        // Can't open the file for writing
                        $retArray['status'] = false;
                        $retArray['error'] = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_COULDNOTWRITELOCALFILE', $localFilename);
                        return $retArray;
                    }
                    fwrite($fp, $result);
                    fclose($fp);
                    $frag++;
                    if ($fileSize < $length || $fileSize > $length || $totalSize == $doneSize && $totalSize > 0) {
                        // A partial download or a download larger than the frag size means we are done
                        $frag = -1;
                        //debugMsg("-- Import complete (partial download of last frag)");
                        $totalSize = $doneSize;
                        $break = true;
                    }
                }
                // Advance the frag pointer and mark the end
                $end = $timer->getRunningTime();
                // Do we predict that we have enough time?
                $required_time = max(1.1 * ($end - $start), $required_time);
                if ($required_time > 10 - $end + $start) {
                    $break = true;
                }
                $start = $end;
            } while ($timer->getTimeLeft() > 0 && !$break);
            if ($frag == -1) {
                $percent = 100;
            } elseif ($doneSize <= 0) {
                $percent = 0;
            } else {
                if ($totalSize > 0) {
                    $percent = 100 * ($doneSize / $totalSize);
                } else {
                    $percent = 0;
                }
            }
            // Update $retArray
            $retArray = array("status" => true, "error" => '', "frag" => $frag, "totalSize" => $totalSize, "doneSize" => $doneSize, "percent" => $percent);
        } catch (DownloadError $e) {
            $retArray['status'] = false;
            $retArray['error'] = $e->getMessage();
        }
        return $retArray;
    }

Usage Example

Beispiel #1
0
 /**
  * @covers  FOF30\Download\Download::importFromUrl
  *
  * @dataProvider    FOF30\Tests\Download\DownloadDataprovider::getTestImportFromUrl
  *
  * @param array $config
  * @param array $params
  * @param array $test
  */
 public function testImportFromUrl(array $config, array $params, array $test)
 {
     // Set up the FakeCurl simulator
     FakeCurl::setUp($config);
     // Get the download class
     $download = new Download(static::$container);
     $download->setAdapter('curl');
     // Initialise
     $loopAllowed = $test['loop'];
     // Get the output file name
     $platformDirs = static::$container->platform->getPlatformBaseDirs();
     $tmpDir = $platformDirs['tmp'];
     $localFilename = $tmpDir . '/test.dat';
     // Set up the download parameters
     $params['localFilename'] = $localFilename;
     #$params['maxExecTime'] = $test['loop'] ? 10000 : 0;
     $params['maxExecTime'] = 0;
     if (isset($test['localfile'])) {
         if (empty($test['localfile'])) {
             unset($params['localFilename']);
         } else {
             $params['localFilename'] = $test['localfile'];
         }
     }
     // Remove the local filename if it's still there
     @unlink($localFilename);
     do {
         $ret = $download->importFromURL($params);
         if ($loopAllowed) {
             $loopAllowed = !($ret['frag'] == -1 || $ret['error']);
         }
         $params = array_merge($params, $ret);
         if (isset($params['localFilename']) && !empty($params['localFilename'])) {
             $localFilename = $params['localFilename'];
         }
     } while ($loopAllowed);
     foreach ($test['expect'] as $k => $v) {
         // Validate expected parameters
         $this->assertEquals($v, $ret[$k], $test['message'] . " (returned {$k} does not match)");
     }
     // Check the return size
     if (!$test['expect']['error']) {
         $fileSize = @filesize($localFilename);
         $this->assertEquals($test['retSize'], $fileSize, $test['message'] . " (size doesn't match {$test['retSize']})");
     }
     // Remove the local filename if it's still there
     @unlink($localFilename);
 }