mirror of
https://gh.wpcy.net/https://github.com/aspirepress/AspireCloud.git
synced 2026-07-16 11:26:56 +08:00
133 lines
5.1 KiB
PHP
133 lines
5.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Utils\Regex;
|
|
use App\Values\WpOrg\Plugins\PluginResponse;
|
|
use App\Values\WpOrg\Themes\ThemeResponse;
|
|
use App\Values\WpOrg\Themes\ThemeUpdateCheckResponse;
|
|
use App\Values\WpOrg\Themes\ThemeUpdateData;
|
|
use Bag\Collection;
|
|
use Bag\Values\Optional;
|
|
|
|
class UrlRewriteService
|
|
{
|
|
public function rewritePluginResponse(PluginResponse $response): PluginResponse
|
|
{
|
|
$out = $response->with([
|
|
'download_link' => $this->rewriteDotOrgUrl($response->download_link),
|
|
'banners' => array_map($this->rewriteDotOrgUrl(...), $response->banners),
|
|
'icons' => array_map($this->rewriteDotOrgUrl(...), $response->icons),
|
|
'screenshots' => $this->rewriteScreenshots($response->screenshots),
|
|
'versions' => array_map($this->rewriteDotOrgUrl(...), $response->versions),
|
|
// TODO: sections -- rewrite urls in description
|
|
]);
|
|
|
|
return $this->fixupDownloadLink($out, $response->download_link);
|
|
}
|
|
|
|
public function rewriteThemeResponse(ThemeResponse $response): ThemeResponse
|
|
{
|
|
$out = $response->with([
|
|
'download_link' => $this->rewriteDotOrgUrl($response->download_link),
|
|
'screenshot_url' => $this->rewriteThemeScreenshotUrl($response->screenshot_url),
|
|
'versions' => $this->rewriteThemeVersions($response->versions),
|
|
// TODO: sections -- rewrite urls in description
|
|
]);
|
|
|
|
return $this->fixupDownloadLink($out, $response->download_link);
|
|
}
|
|
|
|
public function rewriteThemeUpdateData(ThemeUpdateData $update): ThemeUpdateData
|
|
{
|
|
return $update->with([
|
|
'url' => $this->rewriteDotOrgUrl($update->url),
|
|
'package' => $this->rewriteDotOrgUrl($update->package),
|
|
]);
|
|
}
|
|
|
|
public function rewriteThemeUpdateCheckResponse(ThemeUpdateCheckResponse $response): ThemeUpdateCheckResponse
|
|
{
|
|
return $response->with([
|
|
'themes' => $response->themes->map($this->rewriteThemeUpdateData(...)),
|
|
'no_update' => $response->no_update->map($this->rewriteThemeUpdateData(...)),
|
|
]);
|
|
}
|
|
|
|
public function rewriteDotOrgUrl(string $url): string
|
|
{
|
|
$base = config('app.aspirecloud.download.base');
|
|
|
|
// https://downloads.wordpress.org/plugin/elementor.3.26.5.zip
|
|
// => /download/plugin/elementor.3.26.5.zip
|
|
if (str_contains($url, '//downloads.')) {
|
|
return \Safe\preg_replace('#https?://.*?/#i', $base, $url);
|
|
}
|
|
|
|
// https://ps.w.org/elementor/assets/screenshot-1.gif?rev=3005087
|
|
// => /download/assets/plugin/elementor/3005087/screenshot-1.gif
|
|
if ($matches = Regex::match('#//ps\.w\.org/(.*?)/assets/(.*?)(?:\?rev=(.*))?$#i', $url)) {
|
|
$slug = $matches[1];
|
|
$file = $matches[2];
|
|
$revision = $matches[3] ?? 'head';
|
|
return $base . "assets/plugin/$slug/$revision/$file";
|
|
}
|
|
|
|
// https://s.w.org/plugins/geopattern-icon/addi-simple-slider_c8bcb2.svg
|
|
// => /download/gp-icon/plugin/addi-simple-slider/head/addi-simple-slider_c8bcb2.svg
|
|
if ($matches = Regex::match(
|
|
'#//s\.w\.org/plugins/geopattern-icon/((.*?)(?:_[^.]+)?\.svg)(?:\?rev=(.*))?$#i',
|
|
$url,
|
|
)) {
|
|
$file = $matches[1];
|
|
$slug = $matches[2];
|
|
$revision = $matches[3] ?? 'head';
|
|
return $base . "gp-icon/plugin/$slug/$revision/$file";
|
|
}
|
|
|
|
return $url;
|
|
}
|
|
|
|
public function rewriteScreenshots(array $screenshots): array
|
|
{
|
|
return array_map(
|
|
fn(array $screenshot) => [...$screenshot, 'src' => self::rewriteDotOrgUrl($screenshot['src'] ?? '')],
|
|
$screenshots,
|
|
);
|
|
}
|
|
|
|
// IN: //ts.w.org/wp-content/themes/abhokta/screenshot.png?ver=1.0.0
|
|
// OUT: /download/assets/theme/abhokta/1.0.0/screenshot.png
|
|
public function rewriteThemeScreenshotUrl(string $url): ?string
|
|
{
|
|
$base = config('app.aspirecloud.download.base');
|
|
$matches = Regex::match('#^.*?/themes/(.*?)/(.*?)(?:\?ver=(.*))?$#i', $url);
|
|
if (!$matches) {
|
|
return $url;
|
|
}
|
|
$slug = $matches[1];
|
|
$file = $matches[2];
|
|
$revision = $matches[3] ?? 'head';
|
|
return $base . "assets/theme/$slug/$revision/$file";
|
|
}
|
|
|
|
public function fixupDownloadLink(PluginResponse|ThemeResponse $out, string $fallback): PluginResponse|ThemeResponse
|
|
{
|
|
if (Regex::match('#/(?:plugin|theme)/([^/.]+)\.zip$#i', $out->download_link)) {
|
|
// no dots in the filename before the extension, which means this link isn't useful for caching.
|
|
// replace it with the url for the current version instead, or the unrewritten link if that doesn't exist.
|
|
return $out->with(['download_link' => $out->versions[$out->version] ?? $fallback]);
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
public function rewriteThemeVersions(Optional|array $versions): Optional|array
|
|
{
|
|
if ($versions instanceof Optional) {
|
|
return $versions;
|
|
}
|
|
return array_map($this->rewriteDotOrgUrl(...), $versions);
|
|
}
|
|
}
|