mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
...
This commit is contained in:
@@ -22,7 +22,8 @@ class ImageDownloader
|
||||
|
||||
$this->httpClient = new Client([
|
||||
'timeout' => 30,
|
||||
'headers' => $headers
|
||||
'headers' => $headers,
|
||||
'verify' => false // Disable SSL verification for problematic servers
|
||||
]);
|
||||
$this->basePath = rtrim($basePath, '/');
|
||||
}
|
||||
@@ -37,76 +38,114 @@ class ImageDownloader
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$folderPath = $this->basePath;
|
||||
if (!empty($subfolder)) {
|
||||
$folderPath .= '/' . trim($subfolder, '/');
|
||||
}
|
||||
$maxRetries = 3;
|
||||
$retryDelay = 2; // seconds
|
||||
|
||||
// Create folder if it doesn't exist
|
||||
if (!is_dir($folderPath)) {
|
||||
mkdir($folderPath, 0755, true);
|
||||
}
|
||||
for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
|
||||
try {
|
||||
error_log("Downloading image (attempt {$attempt}/{$maxRetries}): {$url}");
|
||||
|
||||
$filePath = $folderPath . '/' . $filename;
|
||||
$response = $this->httpClient->get($url, [
|
||||
'timeout' => 60, // Longer timeout for large images
|
||||
'connect_timeout' => 30,
|
||||
'headers' => [
|
||||
'User-Agent' => 'MediaCollector/1.0',
|
||||
'Referer' => parse_url($url, PHP_URL_HOST)
|
||||
]
|
||||
]);
|
||||
|
||||
// Check if file already exists
|
||||
if (file_exists($filePath)) {
|
||||
return $filePath;
|
||||
}
|
||||
|
||||
error_log("Downloading image from: {$url} to: {$filePath}");
|
||||
|
||||
$response = $this->httpClient->get($url, [
|
||||
'sink' => $filePath,
|
||||
'headers' => [
|
||||
'User-Agent' => 'MediaCollector/1.0',
|
||||
'Accept' => 'image/*',
|
||||
]
|
||||
]);
|
||||
|
||||
$statusCode = $response->getStatusCode();
|
||||
$contentType = $response->getHeaderLine('content-type');
|
||||
|
||||
error_log("Download response - Status: {$statusCode}, Content-Type: {$contentType}");
|
||||
|
||||
if ($statusCode === 200) {
|
||||
$fileSize = filesize($filePath);
|
||||
error_log("Successfully downloaded image. Size: {$fileSize} bytes");
|
||||
|
||||
// Check if file is actually an image and not empty
|
||||
if ($fileSize > 0) {
|
||||
$imageInfo = getimagesize($filePath);
|
||||
if ($imageInfo !== false) {
|
||||
error_log("Valid image downloaded: {$imageInfo[0]}x{$imageInfo[1]} {$imageInfo['mime']}");
|
||||
return $filePath;
|
||||
} else {
|
||||
error_log("Downloaded file is not a valid image");
|
||||
if (file_exists($filePath)) {
|
||||
unlink($filePath);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error_log("Downloaded file is empty");
|
||||
if (file_exists($filePath)) {
|
||||
unlink($filePath);
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
error_log("HTTP {$response->getStatusCode()} for {$url}");
|
||||
if ($attempt === $maxRetries) {
|
||||
return null;
|
||||
}
|
||||
sleep($retryDelay);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
error_log("Failed to download image. HTTP Status: {$statusCode}");
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (Exception $e) {
|
||||
// Log error but don't throw - images are not critical
|
||||
error_log("Failed to download image {$url}: " . $e->getMessage());
|
||||
return null;
|
||||
$imageData = $response->getBody()->getContents();
|
||||
if (empty($imageData)) {
|
||||
error_log("Empty response for {$url}");
|
||||
if ($attempt === $maxRetries) {
|
||||
return null;
|
||||
}
|
||||
sleep($retryDelay);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validate image data
|
||||
if (!$this->isValidImage($imageData)) {
|
||||
error_log("Invalid image data for {$url}");
|
||||
if ($attempt === $maxRetries) {
|
||||
return null;
|
||||
}
|
||||
sleep($retryDelay);
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->saveImage($imageData, $filename, $subfolder);
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Error downloading {$url} (attempt {$attempt}): " . $e->getMessage());
|
||||
|
||||
if ($attempt === $maxRetries) {
|
||||
error_log("Failed to download {$url} after {$maxRetries} attempts");
|
||||
return null;
|
||||
}
|
||||
|
||||
sleep($retryDelay);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function isValidImage(string $data): bool
|
||||
{
|
||||
// Check for common image signatures
|
||||
$imageTypes = [
|
||||
'image/jpeg' => "\xFF\xD8\xFF",
|
||||
'image/png' => "\x89PNG",
|
||||
'image/gif' => "GIF",
|
||||
'image/webp' => "RIFF"
|
||||
];
|
||||
|
||||
foreach ($imageTypes as $type => $signature) {
|
||||
if (strpos($data, $signature) === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique filename for an image
|
||||
*/
|
||||
public function saveImage(string $imageData, string $filename, string $subfolder = ''): ?string
|
||||
{
|
||||
try {
|
||||
// Create subfolder if it doesn't exist
|
||||
$fullPath = $this->basePath;
|
||||
if (!empty($subfolder)) {
|
||||
$fullPath .= '/' . trim($subfolder, '/');
|
||||
}
|
||||
|
||||
if (!is_dir($fullPath)) {
|
||||
mkdir($fullPath, 0755, true);
|
||||
}
|
||||
|
||||
$filePath = $fullPath . '/' . $filename;
|
||||
|
||||
// Write image data to file
|
||||
$bytesWritten = file_put_contents($filePath, $imageData);
|
||||
if ($bytesWritten === false || $bytesWritten === 0) {
|
||||
error_log("Failed to write image data to {$filePath}");
|
||||
return null;
|
||||
}
|
||||
|
||||
return $filePath;
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Error saving image {$filename}: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public function generateFilename(string $url, string $prefix = ''): string
|
||||
{
|
||||
$extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);
|
||||
|
||||
Reference in New Issue
Block a user