Files
lgp-admin-plus-api/app/Service/common/MediaUrlService.php

101 lines
2.8 KiB
PHP
Raw Normal View History

<?php
namespace App\Service\common;
/**
* 媒体地址规整
*
* 老后台的约定是:入库存相对路径(/storage/xxx.jpg出库用 asset() 拼成绝对地址;
* OSS 上传拿到的本来就是绝对地址。两种值混在同一列里,读写都得判断一次。
* 这里把判断收在一处,业务 Service 只调 toPublic / toStorage。
*/
class MediaUrlService
{
private static mixed $_instance;
public static function getInstance(): null|static
{
$name = get_called_class();
if (!isset(self::$_instance[$name])) {
self::$_instance[$name] = new static();
}
return self::$_instance[$name];
}
/**
* 出库:相对路径补上站点域名,绝对地址原样返回
*/
public function toPublic(?string $path): string
{
$path = trim((string) $path);
if ($path === '') {
return '';
}
if ($this->isAbsolute($path)) {
return $path;
}
return rtrim((string) config('app.url'), '/') . '/' . ltrim($path, '/');
}
/**
* 入库:本站域名下的地址存成相对路径,避免换域名后历史数据全指向旧域名;
* 第三方 OSS 地址保持原样
*/
public function toStorage(?string $url): string
{
$url = trim((string) $url);
if ($url === '') {
return '';
}
$appUrl = rtrim((string) config('app.url'), '/');
if ($appUrl !== '' && str_starts_with($url, $appUrl)) {
return substr($url, strlen($appUrl)) ?: '';
}
return $url;
}
/**
* 批量出库,给 list
*/
public function publicEach(array &$rows, array $fields): void
{
foreach ($rows as &$row) {
foreach ($fields as $field) {
if (array_key_exists($field, $row)) {
$row[$field] = $this->toPublic($row[$field]);
}
}
}
unset($row);
}
/**
* 前端图片上传组件回传的是数组,取第一个;已是字符串则原样
*/
public function firstOf(mixed $value): string
{
if (is_array($value)) {
$value = $value[0] ?? '';
}
return $this->toStorage(is_string($value) ? $value : '');
}
/**
* 去掉 OSS 处理参数(?imageView2/... ?watermark/...),用于素材库按 path 做引用匹配
*/
public function stripProcessParams(?string $url): string
{
$url = trim((string) $url);
if ($url === '') {
return '';
}
$pos = strpos($url, '?');
return $pos === false ? $url : substr($url, 0, $pos);
}
private function isAbsolute(string $path): bool
{
return (bool) preg_match('#^(https?:)?//#i', $path);
}
}