268 lines
7.2 KiB
PHP
268 lines
7.2 KiB
PHP
<?php
|
|
|
|
class Downloader
|
|
{
|
|
private $method;
|
|
|
|
private $curlHeaders = [];
|
|
|
|
public function importProductImage($url, $checkExisting = false)
|
|
{
|
|
global $cfg;
|
|
|
|
static $downloaded = [];
|
|
|
|
if (isset($downloaded[$url])) {
|
|
return $downloaded[$url];
|
|
}
|
|
|
|
$path_parts = pathinfo($url);
|
|
if (empty($path_parts['extension'])) {
|
|
$path_parts['basename'] .= '.jpg';
|
|
$path_parts['extension'] = 'jpg';
|
|
}
|
|
|
|
$sync_id = $path_parts['basename'] ?? '';
|
|
|
|
if ($checkExisting == 'full') {
|
|
$sync_id = $url;
|
|
}
|
|
|
|
if ($checkExisting && $sync_id) {
|
|
$id = returnSQLResult('SELECT id
|
|
FROM photos
|
|
WHERE sync_id=:sync_id', ['sync_id' => $sync_id]);
|
|
|
|
if ($id > 0) {
|
|
return $downloaded[$url] = $id;
|
|
}
|
|
}
|
|
|
|
$filename = tempnam($cfg['Path']['photos'], 'import_image');
|
|
|
|
if (empty($filename)) {
|
|
$filename = $cfg['Path']['photos'].'import.jpg';
|
|
}
|
|
|
|
if (!$this->copyRemoteFile($url, $filename)) {
|
|
@unlink($filename);
|
|
|
|
return false;
|
|
}
|
|
|
|
$picture = [
|
|
'name' => $path_parts['basename'],
|
|
'type' => strtolower($path_parts['extension']),
|
|
'tmp_name' => $filename,
|
|
];
|
|
|
|
$img = new Photos('product');
|
|
$img->newImage();
|
|
if (!$img->uploadImage($picture, false)) {
|
|
@unlink($filename);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Save to DB
|
|
$img->insertImageIntoDB('', '', '', $sync_id);
|
|
|
|
@unlink($filename);
|
|
|
|
return $downloaded[$url] = $img->getID();
|
|
}
|
|
|
|
public function downloadImage($url)
|
|
{
|
|
global $cfg;
|
|
|
|
$filename = tempnam(sys_get_temp_dir(), 'downl');
|
|
|
|
if (empty($filename)) {
|
|
$filename = $cfg['Path']['photos'].'import.jpg';
|
|
}
|
|
|
|
$path_parts = pathinfo($url);
|
|
if (empty($path_parts['extension'])) {
|
|
$path_parts['basename'] .= '.jpg';
|
|
$path_parts['extension'] = 'jpg';
|
|
}
|
|
|
|
if (!$this->copyRemoteFile($url, $filename)) {
|
|
return false;
|
|
}
|
|
|
|
return [
|
|
'url' => $url,
|
|
'name' => $path_parts['basename'],
|
|
'type' => strtolower($path_parts['extension']),
|
|
'tmp_name' => $filename,
|
|
];
|
|
}
|
|
|
|
public function cleanUpFile($file)
|
|
{
|
|
@unlink($file['tmp_name']);
|
|
}
|
|
|
|
public function copyRemoteFile($src, $dest)
|
|
{
|
|
if (file_exists($dest)) {
|
|
unlink($dest);
|
|
}
|
|
|
|
// Normalize URL
|
|
if (in_array(parse_url($src, PHP_URL_SCHEME), ['http', 'https'])) {
|
|
$src = str_replace(' ', '%20', $src);
|
|
}
|
|
|
|
if (!file_exists(dirname($dest))) {
|
|
mkdir(dirname($dest), 0755, true);
|
|
}
|
|
|
|
// Download file
|
|
if ($this->method == 'ftp') {
|
|
// set up basic connection
|
|
$src = urldecode($src);
|
|
$url_parts = parse_url($src);
|
|
|
|
$conn_id = ftp_connect($url_parts['host']);
|
|
|
|
ftp_set_option($conn_id, FTP_TIMEOUT_SEC, 600);
|
|
|
|
if (!$conn_id) {
|
|
throw new Exception('Error: ftp_connect failed');
|
|
}
|
|
|
|
if (!ftp_login($conn_id, $url_parts['user'], $url_parts['pass'])) {
|
|
throw new Exception('Error: ftp_login failed');
|
|
}
|
|
|
|
if (!ftp_pasv($conn_id, true)) {
|
|
throw new Exception('Error: ftp_pasv failed');
|
|
}
|
|
|
|
if (!ftp_raw($conn_id, 'OPTS UTF8 ON')) {
|
|
throw new Exception('Error: ftp_raw failed');
|
|
}
|
|
|
|
if (!ftp_get($conn_id, $dest, $url_parts['path'], FTP_ASCII)) {
|
|
throw new Exception('Error: ftp_get failed');
|
|
}
|
|
|
|
$len = filesize($dest);
|
|
|
|
ftp_close($conn_id);
|
|
} elseif (str_starts_with($this->method ?? '', 'sftp')) {
|
|
$src = urldecode($src);
|
|
$url_parts = parse_url($src);
|
|
|
|
$sftp = new phpseclib3\Net\SFTP($url_parts['host'], 22, 600);
|
|
|
|
if (!$sftp->login($url_parts['user'], $url_parts['pass'])) {
|
|
throw new Exception('Error: SFTP login failed');
|
|
}
|
|
|
|
if (!$sftp->get($url_parts['path'], $dest)) {
|
|
throw new Exception('Error: SFTP get() failed');
|
|
}
|
|
|
|
if ($this->method === 'sftp_convert_ISO-8859-15') {
|
|
file_put_contents($dest, mb_convert_encoding(file_get_contents($dest), 'UTF-8', 'ISO-8859-15'));
|
|
}
|
|
|
|
$len = filesize($dest);
|
|
|
|
$sftp->disconnect();
|
|
} elseif ($this->method == 'curl') {
|
|
$curl = curl_init();
|
|
|
|
$file = fopen($dest, 'w+');
|
|
curl_setopt($curl, CURLOPT_URL, $src); // input
|
|
if (!empty($this->curlHeaders)) {
|
|
curl_setopt($curl, CURLOPT_HTTPHEADER, $this->curlHeaders);
|
|
}
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
|
curl_setopt($curl, CURLOPT_FILE, $file);
|
|
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
|
curl_setopt($curl, CURLOPT_FTP_USE_EPSV, true);
|
|
curl_setopt($curl, CURLOPT_QUOTE, ['OPTS UTF8 ON']);
|
|
|
|
$ret = curl_exec($curl);
|
|
|
|
fclose($file);
|
|
|
|
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
|
if ($httpCode == 404) {
|
|
return false;
|
|
}
|
|
|
|
if (!$ret) {
|
|
echo "Error: curl_exec of {$src} failed: ".curl_error($curl);
|
|
logError(__FILE__, __LINE__, "Error: curl_exec of {$src} failed:".curl_error($curl));
|
|
|
|
$size = filesize($src);
|
|
$sizeDest = filesize($dest);
|
|
if ($sizeDest <= 0) {
|
|
logError(__FILE__, __LINE__, 'Downloaded empty file');
|
|
echo 'Downloaded empty file';
|
|
|
|
return false;
|
|
}
|
|
if ($size != $sizeDest) {
|
|
throw new Exception('Filesize mismatch. '.$size.' != '.$sizeDest);
|
|
} else {
|
|
throw new Exception('Filesize '.$size.' == '.$sizeDest.' => OK, ignoring error');
|
|
}
|
|
}
|
|
|
|
curl_close($curl);
|
|
|
|
$len = filesize($dest);
|
|
} else {
|
|
if (parse_url($src, PHP_URL_SCHEME) == 'ftp') {
|
|
$src = iconv('utf-8', 'cp1250', $src);
|
|
}
|
|
|
|
ini_set('default_socket_timeout', 600);
|
|
|
|
$stream_context = stream_context_create(['ssl' => [
|
|
'verify_peer' => false,
|
|
]]);
|
|
|
|
$fsrc = fopen($src, 'r', false, $stream_context);
|
|
|
|
if ($fsrc == false) {
|
|
return false;
|
|
}
|
|
|
|
$fdest = fopen($dest, 'w+');
|
|
$len = stream_copy_to_stream($fsrc, $fdest);
|
|
|
|
fclose($fsrc);
|
|
fclose($fdest);
|
|
}
|
|
|
|
return $len;
|
|
}
|
|
|
|
/**
|
|
* @param string $method
|
|
*
|
|
* @return Downloader
|
|
*/
|
|
public function setMethod($method)
|
|
{
|
|
$this->method = $method;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setCurlHeader(string $value): self
|
|
{
|
|
$this->curlHeaders[] = $value;
|
|
|
|
return $this;
|
|
}
|
|
}
|