/** * Function to download a file to the user. * @param String $RealFile * @param String $OutputFile * @return boolean */ public static function download($RealFile, $OutputFile = null) { $File = realpath($RealFile); //get the file path of the real file. if (!$File) { //If the real file does not exists, then just return. return false; } if (!DownloadManager::IsModifiedSince($File)) { //If the file has not modifed since last visit, no need to send data. return true; } $FileSize = filesize($File); if ($OutputFile === null) { //If no outfile has not been mentioned, use the real file name by default. $OutputFile = basename($RealFile); } if (strpos($OutputFile, " ") !== false) { //to handle situtations where the file contains space in its name. $OutputFile = "'{$OutputFile}'"; } header("Content-Type: " . DownloadManager::MIME($OutputFile)); //specify the header for the file type. header("Content-disposition: filename={$OutputFile}"); //specify the header for the file name. $extremes = DownloadManager::calculateHttpRange(); //calculate the range, if present, till the file needs to be read. //check for the present of ranges that has to be read. if (isset($extremes[0])) { $seek_start = $extremes[0]; } if (isset($extremes[1])) { $seek_end = $extremes[1]; } //set start and end based on range (if set), else set defaults //also check for invalid ranges. $seek_end = empty($seek_end) ? $FileSize - 1 : min(abs(intval($seek_end)), $FileSize - 1); $seek_start = empty($seek_start) || $seek_end < abs(intval($seek_start)) ? 0 : max(abs(intval($seek_start)), 0); //add headers if resumable $Resumable = false; if ($seek_start > 0 || $seek_end < $FileSize - 1) { $Resumable = true; header('HTTP/1.1 206 Partial Content'); //specify header that the data you are getting is partial data. } //specify headers for common information. header('Accept-Ranges: bytes'); header('Content-Range: bytes ' . $seek_start . '-' . $seek_end . '/' . $FileSize); header('Content-Length: ' . ($seek_end - $seek_start + 1)); return DownloadManager::downloadSpeed($File, $seek_start, $seek_end, $Resumable); }