Example #1
0
 /**
  * Performs the staggered download of file. The downloaded file will be stored in Joomla!'s temp-path using the
  * basename of the URL as a filename
  *
  * The $params array can have any of the following keys
  * url			The file being downloaded
  * frag			Rolling counter of the file fragment being downloaded
  * totalSize	The total size of the file being downloaded, in bytes
  * doneSize		How many bytes we have already downloaded
  * maxExecTime	Maximum execution time downloading file fragments, in seconds
  * length		How many bytes to download at once
  *
  * The array returned is in the following format:
  *
  * status		True if there are no errors, false if there are errors
  * error		A string with the error message if there are errors
  * frag			The next file fragment to download
  * totalSize	The total size of the downloaded file in bytes, if the server supports HEAD requests
  * doneSize		How many bytes have already been downloaded
  * percent		% of the file already downloaded (if totalSize could be determined)
  * localfile	The name of the local file, without the path
  *
  * @param   array $params 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);
         }
     }
     $tmpDir = JFactory::getConfig()->get('tmp_path', JPATH_ROOT . '/tmp');
     $tmpDir = rtrim($tmpDir, '/\\');
     // Init retArray
     $retArray = array("status" => true, "error" => '', "frag" => $frag, "totalSize" => $totalSize, "doneSize" => $doneSize, "percent" => 0, "localfile" => $localFilename);
     try {
         $timer = new F0FUtilsTimer($maxExecTime, $runTimeBias);
         $start = $timer->getRunningTime();
         // Mark the start of this download
         $break = false;
         // Don't break the step
         // Figure out where on Earth to put that file
         $local_file = $tmpDir . '/' . $localFilename;
         while ($timer->getTimeLeft() > 0 && !$break) {
             // Do we have to initialize the file?
             if ($frag == -1) {
                 // Currently downloaded size
                 $doneSize = 0;
                 if (@file_exists($local_file)) {
                     @unlink($local_file);
                 }
                 // Delete and touch the output file
                 $fp = @fopen($local_file, 'wb');
                 if ($fp !== false) {
                     @fclose($fp);
                 }
                 // Init
                 $frag = 0;
                 //debugMsg("-- First frag, getting the file size");
                 $retArray['totalSize'] = $this->adapter->getFileSize($url);
                 $totalSize = $retArray['totalSize'];
             }
             // Calculate from and length
             $from = $frag * $length;
             $to = $length + $from - 1;
             // Try to download the first frag
             $required_time = 1.0;
             try {
                 $result = $this->adapter->downloadAndReturn($url, $from, $to, $this->adapterOptions);
                 if ($result === false) {
                     throw new Exception(JText::sprintf('LIB_FOF_DOWNLOAD_ERR_COULDNOTDOWNLOADFROMURL', $url), 500);
                 }
             } catch (Exception $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;
                     //debugMsg("-- Download FAILED");
                     return $retArray;
                 } else {
                     // Since this is a staggered download, consider this normal and finish
                     $frag = -1;
                     //debugMsg("-- Import complete");
                     $totalSize = $doneSize;
                     $break = true;
                 }
             }
             // Add the currently downloaded frag to the total size of downloaded files
             if ($result) {
                 $filesize = strlen($result);
                 //debugMsg("-- Successful download of $filesize bytes");
                 $doneSize += $filesize;
                 // Append the file
                 $fp = @fopen($local_file, 'ab');
                 if ($fp === false) {
                     //debugMsg("-- Can't open local file $local_file for writing");
                     // Can't open the file for writing
                     $retArray['status'] = false;
                     $retArray['error'] = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_COULDNOTWRITELOCALFILE', $local_file);
                     return $retArray;
                 }
                 fwrite($fp, $result);
                 fclose($fp);
                 //debugMsg("-- Appended data to local file $local_file");
                 $frag++;
                 //debugMsg("-- Proceeding to next fragment, frag $frag");
                 if ($filesize < $length || $filesize > $length) {
                     // 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;
         }
         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 (Exception $e) {
         //debugMsg("EXCEPTION RAISED:");
         //debugMsg($e->getMessage());
         $retArray['status'] = false;
         $retArray['error'] = $e->getMessage();
     }
     return $retArray;
 }
 /**
  * Performs a slow, thorough check of all files and folders (including MD5/SHA1 sum checks)
  *
  * @param int $idx The index from where to start
  *
  * @return array Progress report
  */
 public function slowCheck($idx = 0)
 {
     $ret = array('done' => false, 'files' => array(), 'folders' => array(), 'idx' => $idx);
     $totalFiles = count($this->fileList);
     $totalFolders = count($this->dirList);
     $fileKeys = array_keys($this->fileList);
     $timer = new F0FUtilsTimer(3.0, 75.0);
     while ($timer->getTimeLeft() && ($idx < $totalFiles || $idx < $totalFolders)) {
         if ($idx < $totalFolders) {
             $directory = JPATH_ROOT . '/' . $this->dirList[$idx];
             if (!@is_dir($directory)) {
                 $ret['folders'][] = $directory;
             }
         }
         if ($idx < $totalFiles) {
             $fileKey = $fileKeys[$idx];
             $filePath = JPATH_ROOT . '/' . $fileKey;
             $fileData = $this->fileList[$fileKey];
             if (!@file_exists($filePath)) {
                 $ret['files'][] = $fileKey . ' (missing)';
             } elseif (@filesize($filePath) != $fileData[0]) {
                 $ret['files'][] = $fileKey . ' (size ' . @filesize($filePath) . ' ≠ ' . $fileData[0] . ')';
             } else {
                 if (function_exists('sha1_file')) {
                     $fileSha1 = @sha1_file($filePath);
                     if ($fileSha1 != $fileData[2]) {
                         $ret['files'][] = $fileKey . ' (SHA1 ' . $fileSha1 . ' ≠ ' . $fileData[2] . ')';
                     }
                 } elseif (function_exists('md5_file')) {
                     $fileMd5 = @md5_file($filePath);
                     if ($fileMd5 != $fileData[1]) {
                         $ret['files'][] = $fileKey . ' (MD5 ' . $fileMd5 . ' ≠ ' . $fileData[1] . ')';
                     }
                 }
             }
         }
         $idx++;
     }
     if ($idx >= $totalFiles && $idx >= $totalFolders) {
         $ret['done'] = true;
     }
     $ret['idx'] = $idx;
     return $ret;
 }