184 lines
5.3 KiB
PHP
184 lines
5.3 KiB
PHP
|
<?php
|
||
|
namespace ShortPixel\Helper;
|
||
|
|
||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||
|
exit; // Exit if accessed directly.
|
||
|
}
|
||
|
|
||
|
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
||
|
use ShortPixel\Controller\ResponseController as ResponseController;
|
||
|
|
||
|
class DownloadHelper
|
||
|
{
|
||
|
private static $instance;
|
||
|
|
||
|
public function __construct()
|
||
|
{
|
||
|
$this->checkEnv();
|
||
|
}
|
||
|
|
||
|
public static function getInstance()
|
||
|
{
|
||
|
if (is_null(self::$instance))
|
||
|
{
|
||
|
self::$instance = new DownloadHelper();
|
||
|
}
|
||
|
|
||
|
return self::$instance;
|
||
|
}
|
||
|
|
||
|
protected function checkEnv()
|
||
|
{
|
||
|
if ( ! function_exists( 'download_url' ) ) {
|
||
|
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function downloadFile($url, $args = array())
|
||
|
{
|
||
|
$defaults = array(
|
||
|
'expectedSize' => null,
|
||
|
'destinationPath' => null,
|
||
|
);
|
||
|
|
||
|
$args = wp_parse_args($args, $defaults);
|
||
|
$success = false;
|
||
|
|
||
|
Log::addDebug('Downloading file :' . $url, $args);
|
||
|
|
||
|
$methods = array(
|
||
|
"download_url" => array(array($this, 'downloadURLMethod'), $url, false),
|
||
|
"download_url_force" => array(array($this, 'downloadURLMethod'), true),
|
||
|
"remote_get" => array(array($this, 'remoteGetMethod'), $url)
|
||
|
);
|
||
|
|
||
|
foreach($methods as $name => $data)
|
||
|
{
|
||
|
$function = $data[0];
|
||
|
if (is_callable($function))
|
||
|
{
|
||
|
$result = call_user_func_array($function, array_slice($data, 1) );
|
||
|
|
||
|
if (false !== $result)
|
||
|
{
|
||
|
$tempFile = $result;
|
||
|
$success = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (false === $success)
|
||
|
{
|
||
|
Log::addError('Failed to download File', $result);
|
||
|
ResponseController::addData('is_error', true);
|
||
|
//Responsecontroller::addData('message', $tempFile->get_error_message());
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$fs = \wpSPIO()->filesystem();
|
||
|
$file = $fs->getFile($tempFile);
|
||
|
|
||
|
if (! is_null($args['destinationPath']))
|
||
|
{
|
||
|
$result = $this->moveDownload($file, $args['destinationPath']);
|
||
|
if (false === $result)
|
||
|
{
|
||
|
Log::addError('Failed to move Download', $args);
|
||
|
ResponseController::addData('is_error', true);
|
||
|
Responsecontroller::addData('message', __('Failed to move download to destination!', 'shortpixel-image-optimiser'));
|
||
|
return false;
|
||
|
}
|
||
|
else {
|
||
|
$file = $result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $file;
|
||
|
}
|
||
|
|
||
|
protected function moveDownload($fileObj, $destinationPath)
|
||
|
{
|
||
|
$fs = \wpSPIO()->filesystem();
|
||
|
|
||
|
$destinationFile = $fs->getFile($destinationPath);
|
||
|
// If file is non-existing, check directory and write-permissions.
|
||
|
if (false == $destinationFile->exists())
|
||
|
{
|
||
|
$dirObj = $destinationFile->getFileDir();
|
||
|
$dirObj->check(true);
|
||
|
}
|
||
|
|
||
|
$result = $fileObj->copy($destinationFile);
|
||
|
|
||
|
if ($result === false)
|
||
|
return false;
|
||
|
|
||
|
return $destinationFile;
|
||
|
|
||
|
}
|
||
|
|
||
|
private function downloadURLMethod($url, $force = false)
|
||
|
{
|
||
|
$executionTime = ini_get('max_execution_time');
|
||
|
if (! is_numeric($executionTime)) // edge case
|
||
|
{
|
||
|
$executionTime = 0;
|
||
|
}
|
||
|
$downloadTimeout = max($executionTime - 10, 15);
|
||
|
|
||
|
$url = $this->setPreferredProtocol(urldecode($url), $force);
|
||
|
$tempFile = \download_url($url, $downloadTimeout);
|
||
|
|
||
|
if (is_wp_error($tempFile))
|
||
|
{
|
||
|
Log::addError('Failed to Download File ', $tempFile);
|
||
|
Responsecontroller::addData('message', $tempFile->get_error_message());
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return $tempFile;
|
||
|
}
|
||
|
|
||
|
private function remoteGetMethod($url)
|
||
|
{
|
||
|
//get_temp_dir
|
||
|
$tmpfname = tempnam(get_temp_dir(), 'spiotmp');
|
||
|
$downloadTimeout = max(ini_get('max_execution_time') - 10, 15);
|
||
|
|
||
|
$args_for_get = array(
|
||
|
'stream' => true,
|
||
|
'filename' => $tmpfname,
|
||
|
'timeout' => $downloadTimeout,
|
||
|
);
|
||
|
|
||
|
$response = wp_remote_get( $url, $args_for_get );
|
||
|
|
||
|
if (wp_remote_retrieve_response_code($response) == 200 && isset($response['filename']))
|
||
|
{
|
||
|
$filepath = $response['filename'];
|
||
|
return $filepath; // body is the full image is all went well.
|
||
|
}
|
||
|
else {
|
||
|
Log::addError('Wp Remote Get failed', $response);
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private function setPreferredProtocol($url, $reset = false) {
|
||
|
//switch protocol based on the formerly detected working protocol
|
||
|
$settings = \wpSPIO()->settings();
|
||
|
|
||
|
if($settings->downloadProto == '' || $reset) {
|
||
|
//make a test to see if the http is working
|
||
|
$testURL = 'http://' . SHORTPIXEL_API . '/img/connection-test-image.png';
|
||
|
$result = download_url($testURL, 10);
|
||
|
$settings->downloadProto = is_wp_error( $result ) ? 'https' : 'http';
|
||
|
}
|
||
|
return $settings->downloadProto == 'http' ?
|
||
|
str_replace('https://', 'http://', $url) :
|
||
|
str_replace('http://', 'https://', $url);
|
||
|
}
|
||
|
}
|