protected static function download_test_files(&$test_install_request, $download_location = false, $no_prompts = false)
 {
     // Download needed files for a test
     if ($test_install_request->get_download_object_count() == 0) {
         return true;
     }
     $identifier = $test_install_request->test_profile->get_identifier();
     pts_client::$display->test_install_downloads($test_install_request);
     if ($download_location == false) {
         $download_location = $test_install_request->test_profile->get_install_dir();
     }
     pts_file_io::mkdir($download_location);
     $module_pass = array($identifier, $test_install_request->get_download_objects());
     pts_module_manager::module_process('__pre_test_download', $module_pass);
     foreach ($test_install_request->get_download_objects() as $download_package) {
         $package_filename = $download_package->get_filename();
         $download_destination = $download_location . $package_filename;
         $download_destination_temp = $download_destination . '.pts';
         if ($download_package->get_download_location_type() == null) {
             // Attempt a possible last-minute look-aside copy cache in case a previous test in the install queue downloaded this file already
             $lookaside_copy = pts_test_install_manager::file_lookaside_test_installations($download_package);
             if ($lookaside_copy) {
                 if ($download_package->get_filesize() == 0) {
                     $download_package->set_filesize(filesize($lookaside_copy));
                 }
                 $download_package->set_download_location('LOOKASIDE_DOWNLOAD_CACHE', array($lookaside_copy));
             }
         }
         switch ($download_package->get_download_location_type()) {
             case 'IN_DESTINATION_DIR':
                 pts_client::$display->test_install_download_file('FILE_FOUND', $download_package);
                 continue;
             case 'REMOTE_DOWNLOAD_CACHE':
                 $download_tries = 0;
                 do {
                     foreach ($download_package->get_download_location_path() as $remote_download_cache_file) {
                         pts_client::$display->test_install_download_file('DOWNLOAD_FROM_CACHE', $download_package);
                         pts_network::download_file($remote_download_cache_file, $download_destination_temp);
                         if (!is_file($download_destination_temp) || filesize($download_destination_temp) == 0) {
                             self::test_install_error(null, $test_install_request, 'The file failed to download from the cache.');
                             pts_file_io::unlink($download_destination_temp);
                             break;
                         } else {
                             if ($download_package->check_file_hash($download_destination_temp)) {
                                 rename($download_destination_temp, $download_destination);
                                 break;
                             } else {
                                 self::test_install_error(null, $test_install_request, 'The check-sum of the downloaded file failed.');
                                 pts_file_io::unlink($download_destination_temp);
                             }
                         }
                     }
                     $download_tries++;
                 } while (!is_file($download_destination) && $download_tries < 2);
                 if (is_file($download_destination)) {
                     continue;
                 }
             case 'MAIN_DOWNLOAD_CACHE':
             case 'LOCAL_DOWNLOAD_CACHE':
             case 'LOOKASIDE_DOWNLOAD_CACHE':
                 $download_cache_file = pts_arrays::last_element($download_package->get_download_location_path());
                 if (is_file($download_cache_file)) {
                     if (pts_config::read_bool_config('PhoronixTestSuite/Options/Installation/SymLinkFilesFromCache', 'FALSE') && $download_package->get_download_location_type() != 'LOOKASIDE_DOWNLOAD_CACHE') {
                         // For look-aside copies never symlink (unless a pre-packaged LiveCD) in case the other test ends up being un-installed
                         // SymLinkFilesFromCache is disabled by default
                         pts_client::$display->test_install_download_file('LINK_FROM_CACHE', $download_package);
                         symlink($download_cache_file, $download_destination);
                     } else {
                         // File is to be copied
                         // Try up to two times to copy a file
                         $attempted_copies = 0;
                         do {
                             pts_client::$display->test_install_download_file('COPY_FROM_CACHE', $download_package);
                             // $context = stream_context_create();
                             // stream_context_set_params($context, array('notification' => array('pts_network', 'stream_status_callback')));
                             // TODO: get the context working correctly for this copy()
                             copy($download_cache_file, $download_destination_temp);
                             pts_client::$display->test_install_progress_completed();
                             // Verify that the file was copied fine
                             if ($download_package->check_file_hash($download_destination_temp)) {
                                 rename($download_destination_temp, $download_destination);
                                 break;
                             } else {
                                 self::test_install_error(null, $test_install_request, 'The check-sum of the copied file failed.');
                                 pts_file_io::unlink($download_destination_temp);
                             }
                             $attempted_copies++;
                         } while ($attempted_copies < 2);
                     }
                     if (is_file($download_destination)) {
                         continue;
                     }
                 }
             default:
                 $package_urls = $download_package->get_download_url_array();
                 // Download the file
                 if (!is_file($download_destination) && count($package_urls) > 0 && $package_urls[0] != null) {
                     $fail_count = 0;
                     do {
                         if (pts_network::internet_support_available()) {
                             if (!$no_prompts && pts_config::read_bool_config('PhoronixTestSuite/Options/Installation/PromptForDownloadMirror', 'FALSE') && count($package_urls) > 1) {
                                 // Prompt user to select mirror
                                 do {
                                     echo PHP_EOL . 'Available Download Mirrors:' . PHP_EOL . PHP_EOL;
                                     $url = pts_user_io::prompt_text_menu('Select Preferred Mirror', $package_urls, false);
                                 } while (pts_strings::is_url($url) == false);
                             } else {
                                 // Auto-select mirror
                                 shuffle($package_urls);
                                 do {
                                     $url = array_pop($package_urls);
                                 } while (pts_strings::is_url($url) == false && !empty($package_urls));
                             }
                             pts_client::$display->test_install_download_file('DOWNLOAD', $download_package);
                             $download_start = time();
                             pts_network::download_file($url, $download_destination_temp);
                             $download_end = time();
                         } else {
                             self::test_install_error(null, $test_install_request, 'Internet support is needed and it\'s disabled or not available.');
                             return false;
                         }
                         if ($download_package->check_file_hash($download_destination_temp)) {
                             // Download worked
                             if (is_file($download_destination_temp)) {
                                 rename($download_destination_temp, $download_destination);
                             }
                             if ($download_package->get_filesize() > 0 && $download_end != $download_start) {
                                 pts_download_speed_manager::update_download_speed_average($download_package->get_filesize(), $download_end - $download_start);
                             }
                         } else {
                             // Download failed
                             if (is_file($download_destination_temp) && filesize($download_destination_temp) < 500 && (stripos(file_get_contents($download_destination_temp), 'not found') !== false || strpos(file_get_contents($download_destination_temp), 404) !== false)) {
                                 self::test_install_error(null, $test_install_request, 'File Not Found: ' . $url);
                                 $md5_failed = false;
                             } else {
                                 if (is_file($download_destination_temp) && filesize($download_destination_temp) > 0) {
                                     self::test_install_error(null, $test_install_request, 'Checksum Failed: ' . $url);
                                     $md5_failed = true;
                                 } else {
                                     self::test_install_error(null, $test_install_request, 'Download Failed: ' . $url);
                                     $md5_failed = false;
                                 }
                             }
                             pts_file_io::unlink($download_destination_temp);
                             $fail_count++;
                             if ($fail_count > 3) {
                                 $try_again = false;
                             } else {
                                 if (count($package_urls) > 0 && $package_urls[0] != null) {
                                     self::test_install_error(null, $test_install_request, 'Attempting to download from alternate mirror.');
                                     $try_again = true;
                                 } else {
                                     if ($no_prompts) {
                                         $try_again = false;
                                     } else {
                                         if ($md5_failed) {
                                             $try_again = pts_user_io::prompt_bool_input('Try downloading the file again', true, 'TRY_DOWNLOAD_AGAIN');
                                         } else {
                                             $try_again = false;
                                         }
                                     }
                                     if ($try_again) {
                                         $package_urls[] = $url;
                                     }
                                 }
                             }
                             if (!$try_again) {
                                 //self::test_install_error(null, $test_install_request, 'Download of Needed Test Dependencies Failed!');
                                 return false;
                             }
                         }
                     } while (!is_file($download_destination));
                 }
                 pts_module_manager::module_process('__interim_test_download', $module_pass);
         }
     }
     pts_module_manager::module_process('__post_test_download', $identifier);
     return true;
 }
 public function scan_download_caches($local_download_caches, $remote_download_caches, $remote_files, $phoromatic_server_caches, $skip_hash_checks = false)
 {
     $download_location = $this->test_profile->get_install_dir();
     $main_download_cache = pts_strings::add_trailing_slash(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
     foreach ($this->test_files as &$download_package) {
         $package_filename = $download_package->get_filename();
         if (is_file($download_location . $package_filename)) {
             // File is already there in the test/destination directory, must have been previously downloaded
             // Could add an MD5 check here to ensure validity, but if it made it here it was already valid unless user modified it
             if ($download_package->get_filesize() == 0) {
                 $download_package->set_filesize(filesize($download_location . $package_filename));
             }
             $download_package->set_download_location('IN_DESTINATION_DIR');
         } else {
             if (is_file($main_download_cache . $package_filename)) {
                 // In main download cache
                 if ($download_package->get_filesize() == 0) {
                     $download_package->set_filesize(filesize($main_download_cache . $package_filename));
                 }
                 $download_package->set_download_location('MAIN_DOWNLOAD_CACHE', array($main_download_cache . $package_filename));
             } else {
                 if (is_file(PTS_SHARE_PATH . 'download-cache/' . $package_filename)) {
                     // In system's /usr/share download cache
                     if ($download_package->get_filesize() == 0) {
                         $download_package->set_filesize(filesize(PTS_SHARE_PATH . 'download-cache/' . $package_filename));
                     }
                     $download_package->set_download_location('MAIN_DOWNLOAD_CACHE', array(PTS_SHARE_PATH . 'download-cache/' . $package_filename));
                 } else {
                     // Scan the local download caches
                     foreach ($local_download_caches as &$cache_directory) {
                         if (is_file($cache_directory . $package_filename) && ($skip_hash_checks || $download_package->check_file_hash($cache_directory . $package_filename))) {
                             if ($download_package->get_filesize() == 0) {
                                 $download_package->set_filesize(filesize($cache_directory . $package_filename));
                             }
                             $download_package->set_download_location('LOCAL_DOWNLOAD_CACHE', array($cache_directory . $package_filename));
                             break;
                         }
                     }
                     // Look-aside download cache copy
                     // Check to see if the same package name with the same package check-sum is already present in another test installation
                     $lookaside_copy = pts_test_install_manager::file_lookaside_test_installations($download_package);
                     if ($lookaside_copy) {
                         if ($download_package->get_filesize() == 0) {
                             $download_package->set_filesize(filesize($lookaside_copy));
                         }
                         $download_package->set_download_location('LOOKASIDE_DOWNLOAD_CACHE', array($lookaside_copy));
                     }
                     // Check Phoromatic server caches
                     if ($download_package->get_download_location_type() == null && $phoromatic_server_caches) {
                         foreach ($phoromatic_server_caches as $server_url => $repo) {
                             if (isset($repo[$package_filename]) && ($skip_hash_checks || $repo[$package_filename]['md5'] == $download_package->get_md5() || $repo[$package_filename]['sha256'] == $download_package->get_sha256() || $download_package->get_sha256() == null && $download_package->get_md5() == null)) {
                                 $download_package->set_download_location('REMOTE_DOWNLOAD_CACHE', array($server_url . '/download-cache.php?download=' . $package_filename));
                                 break;
                             }
                         }
                     }
                     // If still not found, check remote download caches
                     if ($download_package->get_download_location_type() == null) {
                         if (isset($remote_files[$package_filename])) {
                             $download_package->set_download_location('REMOTE_DOWNLOAD_CACHE', $remote_files[$package_filename]);
                         } else {
                             if (!empty($remote_download_caches)) {
                                 // Check for files manually
                                 foreach ($remote_download_caches as $remote_dir) {
                                     $remote_file = $remote_dir . $package_filename;
                                     $stream_context = pts_network::stream_context_create();
                                     $file_pointer = fopen($remote_file, 'r', false, $stream_context);
                                     if ($file_pointer !== false) {
                                         $download_package->set_download_location('REMOTE_DOWNLOAD_CACHE', $remote_file);
                                         break;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }