-
Notifications
You must be signed in to change notification settings - Fork 3
Feature/ghf35 resolve issue with non published events in pagination #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
gin0115
merged 4 commits into
trunk
from
feature/ghf35-resolve-issue-with-non-published-events-in-pagination
Aug 13, 2025
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
7e0ffd7
Ensure that all event dates from non published events do not get used…
gin0115 a3d2dd6
Ensure that all event dates from non published events do not get used…
gin0115 1734ea2
Fix simple liniting issues
gin0115 16bd4ff
ensuee that only unique posts are ignored
gin0115 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Potential gap: private parent events may still leak without sufficient capabilities; consider a capability-agnostic approach
The current helper relies on
get_posts()for parent events withpost_status!= 'publish'. Depending on the current user's capabilities, queries forpost_status = 'private'can return no results, which would miss those parents and allow their published date children to slip into pagination.Proposed robust approach (avoids capability checks and is a single, efficient JOIN):
function se_get_date_ids_for_non_published_events() { - static $dates = null; - if ( is_array( $dates ) ) { - return $dates; - } - - // Get all events that not published (draft or pending or private). - $args = array( - 'post_type' => SE_Event_Post_Type::$post_type, - 'post_status' => array_diff( get_post_stati(), array( 'publish' ) ), - 'posts_per_page' => -1, - 'fields' => 'ids', - ); - $draft_dates = get_posts( $args ); - - $dates = array(); - - foreach ( $draft_dates as $draft_date ) { - // Get all dates for this event. - $event_dates = se_event_get_event_dates( $draft_date ); - if ( ! empty( $event_dates ) ) { - foreach ( $event_dates as $date ) { - $dates[] = $date['id']; - } - } - } - return $dates; + static $dates = null; + if ( is_array( $dates ) ) { + return $dates; + } + + global $wpdb; + $event_pt = SE_Event_Post_Type::$post_type; + $date_pt = SE_Event_Post_Type::$event_date_post_type; + + // Fetch IDs of published event-date posts whose parent events are not published. + $sql = " + SELECT d.ID + FROM {$wpdb->posts} AS d + INNER JOIN {$wpdb->posts} AS e ON e.ID = d.post_parent + WHERE d.post_type = %s + AND d.post_status = 'publish' + AND e.post_type = %s + AND e.post_status <> %s + "; + // Capability-agnostic: direct SQL ignores current user's read_private_* caps. + $prepared = $wpdb->prepare( $sql, $date_pt, $event_pt, 'publish' ); + $dates = array_map( 'intval', $wpdb->get_col( $prepared ) ); + + return $dates; }Follow-up: If you prefer to avoid SQL, an alternative is to query all published
se-event-dateIDs and filter by parent status withget_post_status( $parent_id ) !== 'publish'. This is simpler but can be heavier on large datasets.To verify the private-event case in a non-admin session:
🌐 Web query:
💡 Result:
If a user does not have the
read_private_postscapability, WP_Query will exclude posts with theprivatepost_status from query results for that user. Only users with the correct capability (such as Administrators and Editors by default) will see private posts; other users and guests cannot see them at all[1][2][8].Key Behavior:
read_private_postsfor the queried post type[2][8].anyfor post types, older versions of WordPress (pre-5.9) had issues where private posts were excluded indiscriminately; the correct behavior is to check the user’s capability per post type and only include private posts for types where the user has permission[3].Technical Details:
post_statusis set toprivate, it confirms the user canread_private_posts; if not, those posts are excluded from results[8][3].pre_get_postsfilter can be used to customize which users see private posts, but you must check the user capability first—usually withcurrent_user_can('read_private_posts')for the relevant post type[4].Summary Table:
privatestatus)So, WP_Query enforces the visibility of private posts strictly based on user capabilities. Users without
read_private_postswill never see private posts in query results, regardless of query arguments, unless custom query manipulation circumvents the check (which is not standard practice)[1][2][8][4].Citations:
Ensure Private Events’ Dates Are Always Excluded, Regardless of User Capabilities
WP_Query (and thus get_posts()) will automatically omit
privateposts for users without theread_private_postscapability. As a result, private parent events may be skipped by your draft query, yet their published date children will still be returned—leaking those dates into pagination.What to do:
Suggested SQL-based refactor in src/template-functions.php:
function se_get_date_ids_for_non_published_events() { - static $dates = null; - if ( is_array( $dates ) ) { - return $dates; - } - - // Get all events that not published (draft or pending or private). - $args = array( - 'post_type' => SE_Event_Post_Type::$post_type, - 'post_status' => array_diff( get_post_stati(), array( 'publish' ) ), - 'posts_per_page' => -1, - 'fields' => 'ids', - ); - $draft_dates = get_posts( $args ); - - $dates = array(); - - foreach ( $draft_dates as $draft_date ) { - // Get all dates for this event. - $event_dates = se_event_get_event_dates( $draft_date ); - if ( ! empty( $event_dates ) ) { - foreach ( $event_dates as $date ) { - $dates[] = $date['id']; - } - } - } - return $dates; + static $dates = null; + if ( is_array( $dates ) ) { + return $dates; + } + + global $wpdb; + $event_pt = SE_Event_Post_Type::$post_type; + $date_pt = SE_Event_Post_Type::$event_date_post_type; + + // Get published dates whose parent events are not published—ignores WP_Query caps. + $sql = " + SELECT d.ID + FROM {$wpdb->posts} AS d + INNER JOIN {$wpdb->posts} AS e ON e.ID = d.post_parent + WHERE d.post_type = %s + AND d.post_status = 'publish' + AND e.post_type = %s + AND e.post_status <> 'publish' + "; + $prepared = $wpdb->prepare( $sql, $date_pt, $event_pt ); + $dates = array_map( 'intval', $wpdb->get_col( $prepared ) ); + + return $dates; }Alternative PHP-only approach (may be heavier on large data sets):
Please update the code in src/template-functions.php (around lines 539–566) to one of these implementations to prevent private or draft parent events from leaking their published dates.
🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wont leak into pagination as we only get the parent posts, so its not an issue. This is unlikely to be an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gin0115 Understood! You know your system's usage patterns best. If private parent events aren't a common scenario in your implementation and the current approach serves your needs effectively, then the existing logic is fine.
Thanks for clarifying - I'll keep this context in mind for future reviews of this codebase.
✏️ Learnings added