diff --git a/app/Services/Social/LinkedInPagePublisher.php b/app/Services/Social/LinkedInPagePublisher.php index 5d443505..f2fc484b 100644 --- a/app/Services/Social/LinkedInPagePublisher.php +++ b/app/Services/Social/LinkedInPagePublisher.php @@ -274,15 +274,19 @@ private function uploadImage($mediaItem, string $ownerUrn): ?string $tempFile = $optimizedPath; } - $imageContent = file_get_contents($tempFile); + $stream = fopen($tempFile, 'r'); $uploadResponse = Http::withToken($this->accessToken) ->withHeaders([ 'Content-Type' => 'application/octet-stream', ]) - ->withBody($imageContent, 'application/octet-stream') + ->withBody($stream, 'application/octet-stream') ->put($uploadUrl); + if (is_resource($stream)) { + fclose($stream); + } + if ($uploadResponse->failed()) { Log::error('LinkedIn Page image upload failed', ['body' => $uploadResponse->body()]); $this->handleApiError($uploadResponse); diff --git a/app/Services/Social/LinkedInPublisher.php b/app/Services/Social/LinkedInPublisher.php index 37d81c89..5d9605e3 100644 --- a/app/Services/Social/LinkedInPublisher.php +++ b/app/Services/Social/LinkedInPublisher.php @@ -255,15 +255,19 @@ private function uploadImage($mediaItem, string $ownerUrn): ?string $tempFile = $optimizedPath; } - $imageContent = file_get_contents($tempFile); + $stream = fopen($tempFile, 'r'); $uploadResponse = Http::withToken($this->accessToken) ->withHeaders([ 'Content-Type' => 'application/octet-stream', ]) - ->withBody($imageContent, 'application/octet-stream') + ->withBody($stream, 'application/octet-stream') ->put($uploadUrl); + if (is_resource($stream)) { + fclose($stream); + } + if ($uploadResponse->failed()) { Log::error('LinkedIn image upload failed', ['body' => $uploadResponse->body()]); $this->handleApiError($uploadResponse); diff --git a/app/Services/Social/MastodonPublisher.php b/app/Services/Social/MastodonPublisher.php index 073a3e4f..fa962cd1 100644 --- a/app/Services/Social/MastodonPublisher.php +++ b/app/Services/Social/MastodonPublisher.php @@ -87,10 +87,16 @@ private function uploadMedia(SocialAccount $account, string $instance, string $u $name = 'media'; } + $stream = fopen($tempFile, 'r'); + $response = Http::withToken($account->access_token) - ->attach('file', fopen($tempFile, 'r'), $name) + ->attach('file', $stream, $name) ->post("{$instance}/api/v1/media"); + if (is_resource($stream)) { + fclose($stream); + } + if ($response->failed()) { Log::error('Mastodon media upload failed', [ 'status' => $response->status(), diff --git a/app/Services/Social/PinterestPublisher.php b/app/Services/Social/PinterestPublisher.php index 28f7e97c..b67f2fcd 100644 --- a/app/Services/Social/PinterestPublisher.php +++ b/app/Services/Social/PinterestPublisher.php @@ -161,36 +161,35 @@ private function publishVideoPin(PostPlatform $postPlatform): array // Download video to temp file (memory-safe) $tempFile = tempnam(sys_get_temp_dir(), 'pin_video_'); - Http::withOptions(['sink' => $tempFile])->timeout(600)->get($media->url); + $videoStream = null; - $videoContent = fopen($tempFile, 'r'); + try { + Http::withOptions(['sink' => $tempFile])->timeout(600)->get($media->url); - if ($videoContent === false) { + $videoStream = fopen($tempFile, 'r'); + + if ($videoStream === false) { + throw new \Exception('Failed to read video file'); + } + + $multipart[] = [ + 'name' => 'file', + 'contents' => $videoStream, + 'filename' => basename($media->url), + ]; + + $uploadResponse = Http::asMultipart() + ->timeout(600) + ->post($uploadUrl, $multipart); + + if ($uploadResponse->failed()) { + $this->handleApiError($uploadResponse); + } + } finally { + if ($videoStream !== null && is_resource($videoStream)) { + fclose($videoStream); + } @unlink($tempFile); - throw new \Exception('Failed to read video file'); - } - - $multipart[] = [ - 'name' => 'file', - 'contents' => $videoContent, - 'filename' => basename($media->url), - ]; - - $uploadResponse = Http::asMultipart() - ->timeout(600) - ->post($uploadUrl, $multipart); - - if (is_resource($videoContent)) { - fclose($videoContent); - } - @unlink($tempFile); - - if ($uploadResponse->failed()) { - Log::error('Pinterest video upload failed', [ - 'status' => $uploadResponse->status(), - 'body' => $uploadResponse->body(), - ]); - throw new \Exception('Pinterest video upload failed'); } // Step 3: Wait for processing