Skip to content

Commit

Permalink
Merge pull request #794 from helsingborg-stad/feat/sticky-posts-in-po…
Browse files Browse the repository at this point in the history
…st-module

feat: sticky posts in post module
  • Loading branch information
NiclasNorin authored Jan 27, 2025
2 parents 5b832de + c630291 commit 847c92a
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 33 deletions.
139 changes: 120 additions & 19 deletions source/php/Module/Posts/Helper/GetPosts.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
class GetPosts
{
public function __construct(
private \Municipio\StickyPost\Helper\GetStickyOption|null $getStickyOption = null,
private IsUserLoggedIn&SwitchToBlog&RestoreCurrentBlog&GetPermalink&GetPostType&IsArchive&GetTheID $wpService,
private WpQueryFactoryInterface $wpQueryFactory
)
Expand All @@ -37,27 +38,40 @@ public function getPostsAndPaginationData(array $fields, int $page = 1) :array
private function getPostsFromSelectedSites(array $fields, int $page):array {

if(!empty($fields['posts_data_network_sources'])) {
$posts = [];
$posts = [];
$maxNumPages = 0;
$stickyPosts = [];

foreach($fields['posts_data_network_sources'] as $site) {
$this->wpService->switchToBlog($site['value']);
$wpQuery = new \WP_Query($this->getPostArgs($fields, $page));
$postsFromSite = $wpQuery->get_posts();

$stickyPostIds = $this->getStickyPostIds($fields, $page);
$stickyPostsFromSite = $this->getStickyPostsForSite($fields, $page, $stickyPostIds);
$wpQuery = $this->wpQueryFactory->create($this->getPostArgs($fields, $page, $stickyPostIds, count($stickyPostsFromSite)));
$postsFromSite = $wpQuery->get_posts();

$stickyPostsFromSite = $this->addSiteDataToPosts($stickyPostsFromSite, $site);
$postsFromSite = $this->addSiteDataToPosts($postsFromSite, $site);

array_walk($postsFromSite, function($post) use ($site) {
// Add the original permalink to the post object for reference in network sources.
$post->originalSite = $site['label'];
$post->originalBlogId = (int)$site['value'];
});

$posts = array_merge($posts, $postsFromSite);
$stickyPosts = array_merge($stickyPosts, $stickyPostsFromSite);
$posts = array_merge($posts, $postsFromSite);
$maxNumPages = max($maxNumPages, $wpQuery->max_num_pages);

$this->wpService->restoreCurrentBlog();
}

// Limit the number of posts to the desired count to avoid exceeding the limit.
$stickyPostsFromSite = $this->sortPosts($stickyPosts, $fields['posts_sort_by'] ?? 'date', $fields['posts_sort_order'] ?? 'desc');

$posts = $this->sortPosts($posts, $fields['posts_sort_by'] ?? 'date', $fields['posts_sort_order'] ?? 'desc');

$posts = array_merge($stickyPostsFromSite, $posts);
$posts = array_slice($posts, 0, $this->getPostsPerPage($fields));

return [
Expand All @@ -66,26 +80,90 @@ private function getPostsFromSelectedSites(array $fields, int $page):array {
];
}

$wpQuery = $this->wpQueryFactory->create($this->getPostArgs($fields, $page));
$stickyPostIds = $this->getStickyPostIds($fields, $page);
$stickyPostsFromSite = $this->getStickyPostsForSite($fields, $page, $stickyPostIds);

$wpQuery = $this->wpQueryFactory->create($this->getPostArgs($fields, $page, $stickyPostIds, count($stickyPostsFromSite)));

$stickyPostsFromSite = $this->sortPosts($stickyPostsFromSite, $fields['posts_sort_by'] ?? 'date', $fields['posts_sort_order'] ?? 'desc');

$posts = array_merge($stickyPostsFromSite, $wpQuery->get_posts());

return [
'posts' => $wpQuery->get_posts(),
'posts' => $posts,
'maxNumPages' => $wpQuery->max_num_pages
];
}

private function getPostArgs(array $fields, int $page)
/**
* Add site data to posts
*/
private function addSiteDataToPosts(array $posts, array $site): array
{
array_walk($posts, function(&$post) use ($site) {
// Add the original permalink to the post object for reference in network sources.
$post->originalSite = $site['label'];
$post->originalBlogId = (int)$site['value'];
});

return $posts;
}

/**
* Get sticky posts for site
*/
private function getStickyPostsForSite(array $fields, int $page, array $stickyPostIds): array
{
if (
empty($stickyPostIds) ||
empty($fields['posts_data_source']) ||
$fields['posts_data_source'] !== 'posttype' ||
empty($fields['posts_data_post_type']) ||
$page !== 1
) {
return [];
}

if (array_key_exists($currentPostID = $this->getCurrentPostID(), $stickyPostIds)) {
unset($stickyPostIds[$currentPostID]);
}

$args = $this->getDefaultQueryArgs();
$args['post_type'] = $fields['posts_data_post_type'];
$args['post__in'] = array_values($stickyPostIds);
$args['orderby'] = 'date';
$args['order'] = 'DESC';
$args['posts_per_page'] = $this->getPostsPerPage($fields);

$wpQuery = $this->wpQueryFactory->create($args);

return $wpQuery->get_posts();
}

/**
* Get sticky post IDs
*/
private function getStickyPostIds(array $fields, int $page): array
{
$stickyPosts = [];
if (is_null($this->getStickyOption) || !empty($fields['posts_data_post_type'])) {
$stickyPosts = $this->getStickyOption->getOption($fields['posts_data_post_type']);
}

return $stickyPosts;
}

/**
* Get post args
*/
private function getPostArgs(array $fields, int $page, array $stickyPostIds = [], int $stickyCount = 0)
{
$metaQuery = false;
$orderby = !empty($fields['posts_sort_by']) ? $fields['posts_sort_by'] : 'date';
$order = !empty($fields['posts_sort_order']) ? $fields['posts_sort_order'] : 'desc';
$metaQuery = false;
$orderby = !empty($fields['posts_sort_by']) ? $fields['posts_sort_by'] : 'date';
$order = !empty($fields['posts_sort_order']) ? $fields['posts_sort_order'] : 'desc';

// Get post args
$getPostsArgs = [
'post_type' => 'any',
'post_password' => false,
'suppress_filters' => false
];
$getPostsArgs = $this->getDefaultQueryArgs();

// Sort by meta key
if (strpos($orderby, '_metakey_') === 0) {
Expand Down Expand Up @@ -148,11 +226,14 @@ private function getPostArgs(array $fields, int $page)
switch ($fields['posts_data_source'] ?? []) {
case 'posttype':
$getPostsArgs['post_type'] = $fields['posts_data_post_type'];
$postsNotIn = [];
if ($currentPostID = $this->getCurrentPostID()) {
$getPostsArgs['post__not_in'] = [
$currentPostID
];
$postsNotIn[] = $currentPostID;
}

$postsNotIn = array_merge($postsNotIn, $stickyPostIds);
$getPostsArgs['post__not_in'] = $postsNotIn;

break;

case 'children':
Expand Down Expand Up @@ -181,14 +262,31 @@ private function getPostArgs(array $fields, int $page)
}

// Number of posts
$getPostsArgs['posts_per_page'] = $this->getPostsPerPage($fields);
$postsPerPage = $this->getPostsPerPage($fields) - $stickyCount;
$getPostsArgs['posts_per_page'] = $postsPerPage < 0 ? 0 : $postsPerPage;

// Apply pagination
$getPostsArgs['paged'] = $page;

return $getPostsArgs;
}

/**
* Get default query args
*/
private function getDefaultQueryArgs()
{
return [
'post_type' => 'any',
'post_password' => false,
'suppress_filters' => false,
'ignore_sticky_posts' => true,
];
}

/**
* Get posts per page
*/
private function getPostsPerPage(array $fields): int {
if (isset($fields['posts_count']) && is_numeric($fields['posts_count'])) {
return ($fields['posts_count'] == -1 || $fields['posts_count'] > 100) ? 100 : $fields['posts_count'];
Expand All @@ -197,6 +295,9 @@ private function getPostsPerPage(array $fields): int {
return 10;
}

/**
* Get post types from schema type
*/
private function getPostTypesFromSchemaType(string $schemaType):array {

$class = '\Municipio\SchemaData\Helper\GetSchemaType';
Expand Down
26 changes: 13 additions & 13 deletions source/php/Module/Posts/Helper/GetPostsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function testGetCurrentPostIDReturnsTheCurrentPostID() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$this->assertEquals(1, $getPosts->getCurrentPostID());
}
Expand All @@ -27,7 +27,7 @@ public function testGetCurrentPostIDReturnsFalseWhenPostIsNotSet() {
$wpService = new FakeWpService(['getTheID' => false, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$this->assertFalse($getPosts->getCurrentPostID());
}
Expand All @@ -37,7 +37,7 @@ public function testGetCurrentPostIDReturnsFalseWhenInArchiveContext() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => true]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$this->assertFalse($getPosts->getCurrentPostID());
}
Expand All @@ -53,7 +53,7 @@ public function testSortPostsSortsPostsByDate() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'date', 'desc');

Expand All @@ -73,7 +73,7 @@ public function testSortPostsSortsPostsByDateAscending() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'date', 'asc');

Expand All @@ -93,7 +93,7 @@ public function testSortPostsSortsPostsByTitleDescending() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'title', 'desc');

Expand All @@ -113,7 +113,7 @@ public function testSortPostsSortsPostsByTitleAscending() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'title', 'asc');

Expand All @@ -133,7 +133,7 @@ public function testSortPostsSortsPostsByModifiedDateDescending() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'modified', 'desc');

Expand All @@ -153,7 +153,7 @@ public function testSortPostsSortsPostsByModifiedDateAscending() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'modified', 'asc');

Expand All @@ -173,7 +173,7 @@ public function testGetPostsSortsPostsByMenuOrderDescending() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'menu_order', 'desc');

Expand All @@ -193,7 +193,7 @@ public function testGetPostsSortsPostsByMenuOrderAscending() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'menu_order', 'asc');

Expand All @@ -213,7 +213,7 @@ public function testSortPostsSortsPostsRandomly() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$firstSort = $getPosts->sortPosts($posts, 'rand', 'asc');
$secondSort = $getPosts->sortPosts($posts, 'rand', 'asc');
Expand All @@ -237,7 +237,7 @@ public function testSortPostsDoesNotSortIfInvalidSortOrderIsProvided() {
$wpService = new FakeWpService(['getTheID' => 1, 'isArchive' => false]);
$wpQueryFactory = $this->createStub(WpQueryFactoryInterface::class);

$getPosts = new GetPosts($wpService, $wpQueryFactory);
$getPosts = new GetPosts(null, $wpService, $wpQueryFactory);

$sortedPosts = $getPosts->sortPosts($posts, 'foo');

Expand Down
6 changes: 5 additions & 1 deletion source/php/Module/Posts/Posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ public function init()
);

// Helpers
$this->getPostsHelper = new GetPosts(WpService::get(), new WpQueryFactory());
$stickyPostHelper = new \Municipio\StickyPost\Helper\GetStickyOption(
new \Municipio\StickyPost\Config\StickyPostConfig(),
WpService::get()
);
$this->getPostsHelper = new GetPosts($stickyPostHelper, WpService::get(), new WpQueryFactory());
$this->archiveUrlHelper = new GetArchiveUrl();
new PostsAjax($this);
}
Expand Down

0 comments on commit 847c92a

Please sign in to comment.