148 lines
4.0 KiB
PHP
148 lines
4.0 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Modules\Core\Stoic;
|
||
|
|
|
||
|
|
use Illuminate\Support\Facades\Storage;
|
||
|
|
use Symfony\Component\Yaml\Yaml;
|
||
|
|
|
||
|
|
class Stoic
|
||
|
|
{
|
||
|
|
public static array $config = [];
|
||
|
|
public static array $presets = [];
|
||
|
|
public static string $thumbs_path;
|
||
|
|
|
||
|
|
private static function loadConfig(): void
|
||
|
|
{
|
||
|
|
if (!empty(static::$config)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
$config = Yaml::parseFile(resource_path("stoic/stoic_config.yml"));
|
||
|
|
static::$config = $config;
|
||
|
|
static::$thumbs_path = $config["thumbs_path"];
|
||
|
|
static::$presets = $config["presets"];
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function presets(): array
|
||
|
|
{
|
||
|
|
static::loadConfig();
|
||
|
|
return static::$presets;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Returns the public URL for a stoic image at a given preset.
|
||
|
|
public static function image(string $filename, string $preset): string
|
||
|
|
{
|
||
|
|
static::loadConfig();
|
||
|
|
|
||
|
|
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||
|
|
|
||
|
|
if ($ext === "svg") {
|
||
|
|
$rel = static::thumbsRelPath() . "images/" . $filename;
|
||
|
|
return Storage::disk("public")->url($rel);
|
||
|
|
}
|
||
|
|
|
||
|
|
$webp = substr($filename, 0, -strlen($ext)) . "webp";
|
||
|
|
$rel = static::thumbsRelPath() . "presets/" . $preset . "/" . $webp;
|
||
|
|
|
||
|
|
return Storage::disk("public")->url($rel);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Generates the full srcset string for all configured presets.
|
||
|
|
public static function srcset(string $filename): string
|
||
|
|
{
|
||
|
|
static::loadConfig();
|
||
|
|
|
||
|
|
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||
|
|
if ($ext === "svg") {
|
||
|
|
return "";
|
||
|
|
}
|
||
|
|
|
||
|
|
return collect(static::$presets)
|
||
|
|
->map(
|
||
|
|
fn($p) => static::image($filename, $p["code"]) .
|
||
|
|
" " .
|
||
|
|
$p["width"] .
|
||
|
|
"w",
|
||
|
|
)
|
||
|
|
->implode(", ");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Returns [width, height] for a given preset from the sidecar JSON.
|
||
|
|
public static function dimensions(string $filename, string $preset): array
|
||
|
|
{
|
||
|
|
static::loadConfig();
|
||
|
|
|
||
|
|
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||
|
|
if ($ext === "svg") {
|
||
|
|
return [null, null];
|
||
|
|
}
|
||
|
|
|
||
|
|
$rel = static::thumbsRelPath() . "images/" . $filename . ".json";
|
||
|
|
$path = Storage::disk("public")->path($rel);
|
||
|
|
$meta = json_decode(@file_get_contents($path), true);
|
||
|
|
|
||
|
|
$p = $meta["presets"][$preset] ?? null;
|
||
|
|
if (!$p) {
|
||
|
|
return [null, null];
|
||
|
|
}
|
||
|
|
|
||
|
|
return [(int) $p["w"], (int) $p["h"]];
|
||
|
|
}
|
||
|
|
|
||
|
|
// Path of the thumbs directory relative to the public storage disk root.
|
||
|
|
// Uses a fixed marker so it works regardless of the app's base path (local vs Docker).
|
||
|
|
private static function thumbsRelPath(): string
|
||
|
|
{
|
||
|
|
$marker = "/storage/app/public/";
|
||
|
|
$pos = strpos(static::$thumbs_path, $marker);
|
||
|
|
|
||
|
|
if ($pos !== false) {
|
||
|
|
return substr(static::$thumbs_path, $pos + strlen($marker));
|
||
|
|
}
|
||
|
|
|
||
|
|
return ltrim(static::$thumbs_path, "/");
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function token(string $email): string
|
||
|
|
{
|
||
|
|
$ttl = 60;
|
||
|
|
$payload = base64_encode(
|
||
|
|
json_encode([
|
||
|
|
"email" => $email,
|
||
|
|
"exp" => time() + $ttl,
|
||
|
|
]),
|
||
|
|
);
|
||
|
|
|
||
|
|
$sig = hash_hmac(
|
||
|
|
"sha256",
|
||
|
|
$payload,
|
||
|
|
config("services.stoic.sso_secret"),
|
||
|
|
);
|
||
|
|
|
||
|
|
$token = "t=" . urlencode($payload) . "&s=" . $sig;
|
||
|
|
|
||
|
|
return $token;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function hasMany(
|
||
|
|
string $relation,
|
||
|
|
array $slugs,
|
||
|
|
string $prefix,
|
||
|
|
) {
|
||
|
|
$slugs = array_map(
|
||
|
|
fn($i) => str_replace($prefix . "/", "", $i),
|
||
|
|
$slugs,
|
||
|
|
);
|
||
|
|
|
||
|
|
return $relation::whereIn("slug", $slugs)->get();
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function hasOne(
|
||
|
|
string $relation,
|
||
|
|
string $slug,
|
||
|
|
string $prefix,
|
||
|
|
) {
|
||
|
|
$slug = str_replace($prefix . "/", "", $slug);
|
||
|
|
return $relation::firstWhere("slug", $slug);
|
||
|
|
}
|
||
|
|
}
|