fix: empty status filter, hidden-field probing, own private posts

Review fix round 2: content-query no longer lets get_posts() fall back
to 'publish' when every requested status is capability-gated out (now
short-circuits to an empty page). Its field filter shares PostPresenter's
hidden-field rule (Pods password type, protected meta) so a hidden key
is rejected like an unknown one instead of reaching the query. Password
fields are now type-checked as strings on write. A user without
edit_private_posts can still query their own private posts when the
query is already author-restricted, matching WordPress core.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
2026-09-25 22:53:58 +02:00
co-authored by Claude Opus 5.5
parent 0890e6f165
commit b9d46f3cec
5 changed files with 123 additions and 15 deletions
@@ -144,7 +144,7 @@ class PostPresenter
{
$result = [];
foreach ($this->schema->fields((string) $post->post_type) as $key => $field) {
if ($this->isHidden($field)) {
if (self::isHiddenField($field)) {
continue;
}
@@ -158,9 +158,11 @@ class PostPresenter
* Pods password fields and readonly protected meta (WordPress' own "_"-prefixed
* internal keys) are never read out via lit-content-get/-query: neither belongs in
* front of the model, and both are one plugin registration away from leaking secrets
* or internal engine state.
* or internal engine state. Public and static so ContentQueryAbility can apply the
* same rule to its `field` filter – a hidden field must be as unreachable through the
* query filter as it is through the fields map, or the filter becomes a probe.
*/
private function isHidden(FieldDefinition $field): bool
public static function isHiddenField(FieldDefinition $field): bool
{
if ($field->type === 'password') {
return true;