Source path: app/Services/Publishers/BasePublisher.php
Extracted from supplied specification. Review before copying into application.

<?php
namespace App\Services\Publishers;

use App\Models\Media;
use App\Models\PostTarget;
use App\Models\SocialAccount;
use Illuminate\Support\Facades\Storage;

abstract class BasePublisher implements Publisher
{
    protected function token(SocialAccount $a): string
    {
        if ($a->token_expires_at && $a->token_expires_at->lt(now()->addMinutes(5))) {
            $this->refreshToken($a);
            $a->refresh();
        }
        return $a->access_token;
    }

    /** @return \Illuminate\Support\Collection<Media> */
    protected function media(PostTarget $t)
    {
        return $t->post->media()->where('status', 'ready')->orderBy('id')->get();
    }

    /** Copy any-disk file to a local temp path. Caller unlinks. */
    protected function tmp(Media $m): string
    {
        $path = tempnam(sys_get_temp_dir(), 'pub') . '.' . pathinfo($m->path, PATHINFO_EXTENSION);
        $src = Storage::disk(config('filesystems.default'))->readStream($m->path);
        $dst = fopen($path, 'w');
        stream_copy_to_stream($src, $dst);
        fclose($dst);
        return $path;
    }

    protected function saveTokens(SocialAccount $a, array $t): void
    {
        $a->update([
            'access_token' => $t['access_token'],
            'refresh_token' => $t['refresh_token'] ?? $a->refresh_token,
            'token_expires_at' => isset($t['expires_in']) ? now()->addSeconds((int) $t['expires_in']) : $a->token_expires_at,
        ]);
    }
}
X
