Implement creator studio and upload updates
This commit is contained in:
103
app/Support/Seo/BreadcrumbTrail.php
Normal file
103
app/Support/Seo/BreadcrumbTrail.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Support\Seo;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
final class BreadcrumbTrail
|
||||
{
|
||||
/**
|
||||
* @param iterable<mixed>|Collection<int, mixed>|null $breadcrumbs
|
||||
* @return list<array{name: string, url: string}>
|
||||
*/
|
||||
public static function normalize(iterable|Collection|null $breadcrumbs): array
|
||||
{
|
||||
$items = collect($breadcrumbs instanceof Collection ? $breadcrumbs->all() : ($breadcrumbs ?? []))
|
||||
->map(fn (mixed $crumb): ?array => self::mapCrumb($crumb))
|
||||
->filter(fn (?array $crumb): bool => is_array($crumb) && $crumb['name'] !== '' && $crumb['url'] !== '')
|
||||
->values();
|
||||
|
||||
$home = [
|
||||
'name' => 'Home',
|
||||
'url' => self::absoluteUrl('/'),
|
||||
];
|
||||
|
||||
$normalized = [];
|
||||
$seen = [];
|
||||
|
||||
foreach ($items as $crumb) {
|
||||
$name = trim((string) ($crumb['name'] ?? ''));
|
||||
$url = self::absoluteUrl((string) ($crumb['url'] ?? ''));
|
||||
|
||||
if ($name === '' || $url === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::isHome($name, $url)) {
|
||||
$name = $home['name'];
|
||||
$url = $home['url'];
|
||||
}
|
||||
|
||||
$key = strtolower($name) . '|' . rtrim(strtolower($url), '/');
|
||||
if (isset($seen[$key])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$seen[$key] = true;
|
||||
$normalized[] = ['name' => $name, 'url' => $url];
|
||||
}
|
||||
|
||||
if ($normalized === [] || ! self::isHome($normalized[0]['name'], $normalized[0]['url'])) {
|
||||
array_unshift($normalized, $home);
|
||||
}
|
||||
|
||||
return array_values($normalized);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $crumb
|
||||
* @return array{name: string, url: string}|null
|
||||
*/
|
||||
private static function mapCrumb(mixed $crumb): ?array
|
||||
{
|
||||
if (is_array($crumb)) {
|
||||
return [
|
||||
'name' => trim((string) ($crumb['name'] ?? '')),
|
||||
'url' => trim((string) ($crumb['url'] ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
if (is_object($crumb)) {
|
||||
return [
|
||||
'name' => trim((string) ($crumb->name ?? '')),
|
||||
'url' => trim((string) ($crumb->url ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function isHome(string $name, string $url): bool
|
||||
{
|
||||
$normalizedUrl = rtrim(strtolower($url), '/');
|
||||
$homeUrl = rtrim(strtolower(self::absoluteUrl('/')), '/');
|
||||
|
||||
return strtolower($name) === 'home' || $normalizedUrl === $homeUrl;
|
||||
}
|
||||
|
||||
private static function absoluteUrl(string $url): string
|
||||
{
|
||||
$trimmed = trim($url);
|
||||
if ($trimmed === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('/^https?:\/\//i', $trimmed) === 1) {
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
return url($trimmed);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user