150 lines
4.8 KiB
PHP
150 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
use App\Models\Blog;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Support\Str;
|
|
|
|
class BlogStructuredData extends StructuredData
|
|
{
|
|
public static function forIndex(LengthAwarePaginator $posts, string $pageUrl): array
|
|
{
|
|
$pageName = __('blog.meta-index-title');
|
|
$pageDescription = __('blog.meta-index-description');
|
|
|
|
$itemListElements = [];
|
|
$offset = ($posts->currentPage() - 1) * $posts->perPage();
|
|
|
|
foreach ($posts as $index => $post) {
|
|
$itemListElements[] = self::listItem(
|
|
$offset + $index + 1,
|
|
self::postSummarySchema($post),
|
|
);
|
|
}
|
|
|
|
return self::wrap([
|
|
self::websiteNode(),
|
|
self::organizationNode(),
|
|
self::webPageNode($pageUrl, $pageName, $pageDescription, [
|
|
'@type' => 'CollectionPage',
|
|
'mainEntity' => ['@id' => $pageUrl . '#itemlist'],
|
|
]),
|
|
self::breadcrumbNode($pageUrl, [
|
|
['name' => __('blog.breadcrumb_home'), 'item' => self::siteUrl()],
|
|
['name' => $pageName, 'item' => $pageUrl],
|
|
]),
|
|
[
|
|
'@type' => 'ItemList',
|
|
'@id' => $pageUrl . '#itemlist',
|
|
'name' => $pageName,
|
|
'numberOfItems' => $posts->total(),
|
|
'itemListElement' => $itemListElements,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public static function forShow(Blog $post, string $pageUrl): array
|
|
{
|
|
$title = $post->translate('title');
|
|
$description = Str::limit(strip_tags((string) $post->translate('excerpt')), 160);
|
|
$imageUrl = $post->featured_image_url ?: self::defaultImageUrl();
|
|
$publishedAt = $post->published_at ?? $post->created_at;
|
|
|
|
$blogPosting = [
|
|
'@type' => 'BlogPosting',
|
|
'@id' => $pageUrl . '#article',
|
|
'mainEntityOfPage' => ['@id' => $pageUrl . '#webpage'],
|
|
'headline' => $title,
|
|
'description' => $description,
|
|
'image' => [$imageUrl],
|
|
'inLanguage' => app()->getLocale(),
|
|
'author' => [
|
|
'@type' => 'Person',
|
|
'name' => $post->author->name ?? __('blog.default_author'),
|
|
],
|
|
'publisher' => self::publisherNode(),
|
|
'datePublished' => $publishedAt->toIso8601String(),
|
|
'dateModified' => $post->updated_at->toIso8601String(),
|
|
'url' => $pageUrl,
|
|
];
|
|
|
|
$content = strip_tags((string) $post->translate('content'));
|
|
if ($content !== '') {
|
|
$blogPosting['articleBody'] = Str::limit($content, 5000);
|
|
}
|
|
|
|
return self::wrap([
|
|
self::websiteNode(),
|
|
self::organizationNode(),
|
|
self::webPageNode($pageUrl, $title, $description, [
|
|
'mainEntity' => ['@id' => $pageUrl . '#article'],
|
|
'dateModified' => $post->updated_at->toIso8601String(),
|
|
]),
|
|
self::breadcrumbNode($pageUrl, [
|
|
['name' => __('blog.breadcrumb_home'), 'item' => self::siteUrl()],
|
|
['name' => __('blog.meta-index-title'), 'item' => route('blog.index')],
|
|
['name' => $title, 'item' => $pageUrl],
|
|
]),
|
|
$blogPosting,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
protected static function postSummarySchema(Blog $post): array
|
|
{
|
|
$schema = [
|
|
'@type' => 'BlogPosting',
|
|
'headline' => $post->translate('title'),
|
|
'url' => route('blog.show', $post->slug),
|
|
];
|
|
|
|
if ($post->featured_image_url) {
|
|
$schema['image'] = [$post->featured_image_url];
|
|
}
|
|
|
|
$publishedAt = $post->published_at ?? $post->created_at;
|
|
if ($publishedAt) {
|
|
$schema['datePublished'] = $publishedAt->toIso8601String();
|
|
}
|
|
|
|
return $schema;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
protected static function publisherNode(): array
|
|
{
|
|
$publisher = [
|
|
'@type' => 'Organization',
|
|
'@id' => self::siteUrl() . '#organization',
|
|
'name' => self::siteName(),
|
|
];
|
|
|
|
$logo = setting('site_logo');
|
|
if ($logo) {
|
|
$logoUrl = str_starts_with($logo, 'http') ? $logo : asset('storage/' . ltrim($logo, '/'));
|
|
$publisher['logo'] = [
|
|
'@type' => 'ImageObject',
|
|
'url' => $logoUrl,
|
|
];
|
|
}
|
|
|
|
return $publisher;
|
|
}
|
|
|
|
protected static function defaultImageUrl(): string
|
|
{
|
|
$defaultImage = setting('default_meta_image');
|
|
|
|
if ($defaultImage) {
|
|
return str_starts_with($defaultImage, 'http') ? $defaultImage : asset($defaultImage);
|
|
}
|
|
|
|
return asset('assets/img/logo.png');
|
|
}
|
|
}
|