Files
2026-09-15 10:35:56 +08:00

125 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\Homepage\Block;
use Mageplaza\Blog\Block\Post\View;
use Mageplaza\Blog\Model\Post;
/**
* Provides chronological navigation for the current news post.
*/
class NewsPostNavigation extends View
{
/** @var bool */
private bool $navigationLoaded = false;
/** @var Post|null */
private ?Post $previousPost = null;
/** @var Post|null */
private ?Post $nextPost = null;
/**
* Get the news post immediately before the current post.
*
* @return Post|null
*/
public function getPreviousPost(): ?Post
{
$this->loadNavigation();
return $this->previousPost;
}
/**
* Get the news post immediately after the current post.
*
* @return Post|null
*/
public function getNextPost(): ?Post
{
$this->loadNavigation();
return $this->nextPost;
}
/**
* Get the active storefront ID.
*
* @return int
*/
public function getCurrentStoreId(): int
{
return (int) $this->store->getStore()->getId();
}
/**
* Resolve both navigation directions once per request.
*
* @return void
*/
private function loadNavigation(): void
{
if ($this->navigationLoaded) {
return;
}
$this->navigationLoaded = true;
$currentPost = $this->getPost();
$currentPostId = (int) $currentPost->getId();
$publishDate = (string) $currentPost->getData('publish_date');
if ($currentPostId <= 0 || $publishDate === '') {
return;
}
$this->previousPost = $this->findPost([
'publish_date' => ['eq' => $publishDate],
'post_id' => ['lt' => $currentPostId],
], 'DESC');
if ($this->previousPost === null) {
$this->previousPost = $this->findPost([
'publish_date' => ['lt' => $publishDate],
], 'DESC');
}
$this->nextPost = $this->findPost([
'publish_date' => ['eq' => $publishDate],
'post_id' => ['gt' => $currentPostId],
], 'ASC');
if ($this->nextPost === null) {
$this->nextPost = $this->findPost([
'publish_date' => ['gt' => $publishDate],
], 'ASC');
}
}
/**
* Get the closest published post matching the supplied filters.
*
* @param array $filters
* @param string $direction
* @return Post|null
*/
private function findPost(array $filters, string $direction): ?Post
{
$collection = $this->helperData->getPostList($this->getCurrentStoreId());
foreach ($filters as $field => $condition) {
$collection->addFieldToFilter($field, $condition);
}
$collection->setOrder('publish_date', $direction)
->setOrder('post_id', $direction)
->setPageSize(1)
->setCurPage(1);
$post = $collection->getFirstItem();
return $post instanceof Post && $post->getId() ? $post : null;
}
}