UploadHelper.php 5.31 KB
<?php

namespace App\Helpers;

use AlibabaCloud\SDK\Mts\V20140618\Mts;
use AlibabaCloud\SDK\Sts\V20150401\Models\AssumeRoleRequest;
use AlibabaCloud\SDK\Sts\V20150401\Models\AssumeRoleResponseBody\credentials;
use AlibabaCloud\SDK\Sts\V20150401\Sts;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
use Darabonba\OpenApi\Models\Config;
use Illuminate\Support\Str;
use Illuminate\Support\Stringable;
use OSS\OssClient;

class UploadHelper
{
    /**
     * @return bool
     */
    public static function isInternalServer(): bool
    {
        return config('services.oss.internal_server', false);
    }

    /**
     * @param array<string,string> $options
     * @return \Darabonba\OpenApi\Models\Config
     */
    protected static function getConfig(array $options = []): Config
    {
        return new Config(['accessKeyId' => config('services.oss.sts.key'), 'accessKeySecret' => config('services.oss.sts.secret'), ...$options]);
    }

    /**
     * @return \AlibabaCloud\SDK\Sts\V20150401\Sts
     */
    public static function getStsClient(): Sts
    {
        return new Sts(self::getConfig(['regionId' => config('services.oss.sts.endpoint')]));
    }

    /**
     * @param int $second
     * @return \AlibabaCloud\SDK\Sts\V20150401\Models\AssumeRoleResponseBody\credentials
     */
    public static function getStsToken(int $second = 3000): credentials
    {
        $assumeRoleRequest = new AssumeRoleRequest([
            "roleArn"         => config('services.oss.sts.role'),
            "roleSessionName" => Str::uuid()->toString(),
            "durationSeconds" => $second,
        ]);

        return self::getStsClient()->assumeRoleWithOptions($assumeRoleRequest, new RuntimeOptions([]))->body->credentials;
    }

    /**
     * @return \AlibabaCloud\SDK\Mts\V20140618\Mts
     */
    public static function getMtsClient(): Mts
    {
        return new Mts(self::getConfig(['regionId' => config('services.oss.mts.endpoint'), 'protocol' => 'HTTPS']));
    }

    /**
     * @return \OSS\OssClient
     */
    public static function getOssClient(bool $internal = false): OssClient
    {
        $token = self::getStsToken();
        return new OssClient($token->accessKeyId, $token->accessKeySecret, $internal ? self::getOssInternal() : self::getOssEndpoint(), false, $token->securityToken);
    }

    /**
     * @param string              $object
     * @param array<string,mixed> $options
     * @param int                 $second
     * @return string
     * @throws \OSS\Core\OssException
     */
    public static function getOssSignUrl(string $object, array $options = [], int $second = 3000): string
    {
        return self::getOssClient()->signUrl(self::getOssBucket(), $object, $second, "PUT", [
            OssClient::OSS_OBJECT_ACL => OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE, ...$options
        ]);
    }

    /**
     * @return string
     */
    public static function getOssBucket(): string
    {
        return config('services.oss.bucket');
    }

    public static function getOssSSL(): string
    {
        return config('services.oss.ssl') ? 'https://' : 'http://';
    }

    /**
     * @return string
     */
    public static function getOssDomain(bool $host = true): string
    {
        return Str::of(config('services.oss.domain'))->when($host, fn(Stringable $str) => $str->prepend(self::getOssSSL()))->toString();
    }

    /**
     * @param bool $useSuper
     * @param bool $host
     * @return string
     */
    public static function getOssEndpoint(bool $useSuper = false, bool $host = false): string
    {
        return Str::of($useSuper ? config('services.oss.super_endpoint') : config('services.oss.endpoint'))
            ->when($host, fn(Stringable $str) => $str->prepend(self::getOssSSL() . self::getOssBucket() . '.'))->toString();
    }

    public static function getOssInternal(bool $host = false): string
    {
        return Str::of(config('services.oss.internal'))
            ->when($host, fn(Stringable $str) => $str->prepend(self::getOssSSL() . self::getOssBucket() . '.'))->toString();
    }

    /**
     * @param string $prefix
     * @return string
     */
    public static function getFileName(string $prefix = ''): string
    {
        return implode('/', array_filter([$prefix, now()->format('Ymd'), Str::ulid()->toBase32()]));
    }

    /**
     * @param string $url
     * @return string
     */
    public static function urlToPath(string $url): string
    {
        return ltrim(parse_url($url, PHP_URL_PATH), '/');
    }

    /**
     * @param string              $object
     * @param string              $file
     * @param array<string,mixed> $options
     * @return string
     * @throws \OSS\Core\OssException
     */
    public static function put(string $object, string $file, array $options = []): string
    {
        self::getOssClient(self::isInternalServer())->uploadFile(self::getOssBucket(), $object, $file, [
            OssClient::OSS_OBJECT_ACL => OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE, ...$options
        ]);

        return self::getOssDomain() . '/' . $object;
    }

    /**
     * CDN域名转 OSS域名
     * @param string $url
     * @param bool   $internal
     * @return string
     */
    public static function toEndpointUrl(string $url, bool $internal = false): string
    {
        return Str::replace(self::getOssDomain(), $internal ? self::getOssInternal(true) : self::getOssEndpoint(false, true), $url);
    }
}