The documented return type is `WP_Term|WP_Post_Type|WP_Post|WP_User|null`, but `get_queried_object()` could return `false` from author queries because `get_userdata()` yields `false` when the resolved author ID is `null` or matches no user. Guard the `get_userdata()` call and its result so `$this->queried_object` stays `null` in those cases. The adjacent posts page branch is hardened the same way, since `get_post()` can return `null` for a missing or deleted page, which previously caused a property access on `null`.
Developed in https://github.com/WordPress/wordpress-develop/pull/12069.
Follow-up to r52822, r3290.
Props tusharbharti, tommusrhodus, yusufmudagal, westonruter.
Fixes#65400.
Built from https://develop.svn.wordpress.org/trunk@62476
git-svn-id: http://core.svn.wordpress.org/trunk@61757 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This prevents a fatal error from `urldecode()` in `wp_basename()` if an array is passed instead.
Follow-up to [15732], [15824], [15825], [15923], [16155], [50565], [60927].
Props patricedefago, alexodiy, SergeyBiryukov.
Fixes#64870.
Built from https://develop.svn.wordpress.org/trunk@62047
git-svn-id: http://core.svn.wordpress.org/trunk@61329 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This updates various `@var` tags on class properties to correctly indicate that the props may be `null` or unset:
* `WP_Dependencies::$all_queued_deps` is nullable by both `::enqueue()` and `::dequeue`. Also, the types of the keys and values are specified.
* `WP_Duotone::$global_styles_presets` and `::$global_styles_block_names` start off unset and are only initialized by static classes.
* `WP_Query::init()` and `WP_Rewrite::init()` are public methods that `unset()`s many class props.
* `WP_Theme::cache_delete()` sets many props to `null`.
Developed in https://github.com/WordPress/wordpress-develop/pull/8953
Props justlevine, westonruter.
See #64238, #64224.
Built from https://develop.svn.wordpress.org/trunk@61299
git-svn-id: http://core.svn.wordpress.org/trunk@60611 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The `generate_cache_key()` method in `WP_Query` referenced an undefined variable `$q`. The method only has two parameters: `$args` and `$sql`. The variable `$q` is not defined anywhere in this method scope. This patch replaces the undefined `$q` variable with the correct `$args` parameter.
Follow-up to [59442]
Props ramonopoly, westonruter
Fixes #64135.
Built from https://develop.svn.wordpress.org/trunk@61043
git-svn-id: http://core.svn.wordpress.org/trunk@60379 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Query-based caches are now improved by reusing cache keys. Previously, cache keys for query caches were generated using the `last_changed` value as part of the key. This meant that whenever `last_changed` was updated, all the previously cached values for the group became unreachable.
The new approach allows WordPress to replace previously cached results that are known to be stale. The previous approach relied on the object cache backend evicting stale keys which is done at various levels of efficiency.
To address this, the following new helper functions have been introduced:
* wp_cache_get_salted
* wp_cache_set_salted
* wp_cache_get_multiple_salted
* wp_cache_set_multiple_salted
These functions provide a consistent way to get/set query caches. Instead of using the last_changed value as part of the cache key, it is now stored inside the cache value as a "salt". This allows cache keys to be reused, with values updated in place rather than relying on eviction of outdated entries.
Props spacedmonkey, peterwilsoncc, flixos90, sanchothefat, tillkruess, rmccue, mukesh27, adamsilverstein, owi, nickchomey.
Built from https://develop.svn.wordpress.org/trunk@60697
git-svn-id: http://core.svn.wordpress.org/trunk@60033 1a063a9b-81f0-0310-95a4-ce76da25c4cd
While the 2022 and 2024 Mariano Rivera AL Reliever of the Year is named Clase, that's not relevant to the generation of cache keys and has nothing to do with orderby.
Introduced in [59766].
Props marian1, abcd95, sabernhardt.
Fixes#63679.
Built from https://develop.svn.wordpress.org/trunk@60444
git-svn-id: http://core.svn.wordpress.org/trunk@59780 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Fixes a performance regression starting the loop after calling `WP_Query( [ 'fields' => 'all' ] )`. This changes how `WP_Query::the_post()` determines whether there is a need to traverse the posts for cache warming.
If IDs are queried, `WP_Query::$posts` is assumed to be an array of post IDs. If all fields are queried, `WP_Query::$posts` is assumed to be an array of fully populated post objects.
Follow up to [59919], [59937].
Props joemcgill, peterwilsoncc, SirLouen.
Fixes#56992.
Built from https://develop.svn.wordpress.org/trunk@59993
git-svn-id: http://core.svn.wordpress.org/trunk@59335 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Ensures that the global post object is populated with the autosave post when a preview link is used for a published post. This allows post authors to preview the changes to a post prior to publication.
This modifies `WP_Query::the_post()` to only call `get_post()` if `WP_Query::$posts` does not contain `WP_Post` objects. Other data types (`stdClass` or numeric) indicates partial data was queried, a `WP_Post` object indicates the full data was queried and populated.
Props peterwilsoncc, mamaduka, wildworks, audrasjb.
Fixes#56992.
Built from https://develop.svn.wordpress.org/trunk@59937
git-svn-id: http://core.svn.wordpress.org/trunk@59279 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Modifies `WP_Query::the_post()` to ensure the entire global post object is populated regardless of the `fields` parameter initially set by the developer.
In secondary loops, this ensures that `get_the_content()` and other getter functions operate as documented when called without a post ID and return the appropriate data for the global post object.
This introduces consistency when starting the loop and the `fields` parameter is set to `id=>parent` to the behaviour when set to either `all` or `ids`.
There is no change to the `WP_Query::$posts` parameter nor when a query is made without starting the secondary loop, ie without calling `WP_Query::the_post()`.
Props juzar, mukesh27, oglekler, peterwilsoncc, sirlouen, joemcgill.
Fixes#56992.
Built from https://develop.svn.wordpress.org/trunk@59919
git-svn-id: http://core.svn.wordpress.org/trunk@59261 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Introduces normalization a number of arguments passed to `WP_Query` to increase cache hits for equivalent requests. For example `author__in => [ 1, 2 ]` and `author__in => [ 2, 1 ]` will now hit the same cache.
Prior to generating the SQL request and cache key, the following are sorted, made unique and type cast as appropriate.
* `post_type` when passed as an array
* `post_status` when passed as an array
* `term_query`s containing `terms`
* `cat`
* `category__in`
* `category__not_in`
* `category__and`
* `tag_slug__in`
* `tag__in`
* `tag__not_in`
* `tag__and`
* `tag_slug__in`
* `tag_slug__and`
* `post_parent__not_in`
* `author`
* `author__not_in`
* `author__in`
The following are sorted for the purposes of generating the cache key and SQL `WHERE` clause but unmodified for use in the `ORDER BY` SQL clause:
* `post_name__in`
* `post__in`
* `post_parent__in`
This commit includes changes to unrelated tests, assertions in `Tests_Query_ParseQuery::test_parse_query_cat_array_mixed()` and `WP_Test_REST_Posts_Controller::test_get_items_not_sticky_with_exclude()` have been modified to account for the sorting of the items above.
Props thekt12, peterwilsoncc, spacedmonkey, joemcgill, flixos90, mukesh27, pbearne, swissspidy.
Fixes#59516.
Built from https://develop.svn.wordpress.org/trunk@59766
git-svn-id: http://core.svn.wordpress.org/trunk@59108 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit fixes an issue where some magic `__isset()` methods were potentially returning `void` (if the prop is not in an allow-listed array of fields) instead of an explicit boolean `false`.
Addressed methods:
* `WP_Comment::__isset()`
* `WP_Query::__isset()`
Follow-up to [28523], [31151], [34583], [34599].
Props justlevine.
See #52217.
Built from https://develop.svn.wordpress.org/trunk@59337
git-svn-id: http://core.svn.wordpress.org/trunk@58723 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Add more context to the `split_the_query` filter by adding two new parameters: '$old_request' and '$clauses'. This enriches the filter with additional information about the SQL query before the query is run, enabling developers to have more context to help decide if a query should be split.
Props spacedmonkey, shailu25, rcorrales, tillkruess.
Fixes#59514.
Built from https://develop.svn.wordpress.org/trunk@58180
git-svn-id: http://core.svn.wordpress.org/trunk@57643 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Query caching in `WP_Query` was added in [53941]. When this functionality was added to the `WP_Query` class, a number of edge cases were missed that would result in redundant duplicate queries. It was possible to pass parameters to `WP_Query` that would be different but would result in the same database query being generated. As the cache key is generated from a mixture of query arguments and the SQL query, this resulted in different cache keys for the same database query, resulting in unnecessary duplicate queries. In this change, the logic in the `generate_cache_key` method has been improved to ensure reuse of existing caches. The following edge cases have been considered:
- Passing `post_type` as an empty string.
- Passing `post_type` as the string `any`.
- Passing `post_type` as array vs. string.
- Passing `post_type` as an array in a different order.
- Not passing `orderby`.
- Passing `post_status` as an array vs. string.
- Passing `post_status` as an array in a different order.
This change also fixes an issue where the old SQL query would not match, as the queries had different whitespaces.
Props spacedmonkey, joemcgill, pbearne, peterwilsoncc, rajinsharwar, mukesh27, thekt12, huzaifaalmesbah, rodionov201.
Fixes#59442.
Built from https://develop.svn.wordpress.org/trunk@58122
git-svn-id: http://core.svn.wordpress.org/trunk@57587 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Unintended leading whitespace at the beginning of a raw MySQL query led to unexpected behavior such as broken pagination. Eliminating said whitespace avoids that.
Adds unit tests to prevent regressions.
Props wpfed, swissspidy, ironprogrammer, tadamarketing, afercia.
Fixes#56841.
Built from https://develop.svn.wordpress.org/trunk@57750
git-svn-id: http://core.svn.wordpress.org/trunk@57251 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This changeset introduces two functions:
* `wp_is_serving_rest_request()` returns a boolean for whether WordPress is serving an actual REST API request.
* `wp_is_rest_endpoint()` returns a boolean for whether a WordPress REST API endpoint is currently being used. While this is always the case if `wp_is_serving_rest_request()` returns `true`, the function additionally covers the scenario of internal REST API requests, i.e. where WordPress calls a REST API endpoint within the same request.
Both functions should only be used after the `parse_request` action.
All relevant manual checks have been adjusted to use one of the new functions, depending on the use-case. They were all using the same constant check so far, while in fact some of them were intending to check for an actual REST API request while others were intending to check for REST endpoint usage.
A new filter `wp_is_rest_endpoint` can be used to alter the return value of the `wp_is_rest_endpoint()` function.
Props lots.0.logs, TimothyBlynJacobs, flixos90, joehoyle, peterwilsoncc, swissspidy, SergeyBiryukov, pento, mikejolley, iandunn, hellofromTonya, Cybr, petitphp.
Fixes#42061.
Built from https://develop.svn.wordpress.org/trunk@57312
git-svn-id: http://core.svn.wordpress.org/trunk@56818 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Move the cache of post parent IDs from the dedicated group `post_parents` to `posts`. This maintains backward compatibility for clearing all post object related data by calling `wp_cache_flush_group( 'posts' )`.
Post parent IDs are now cached with with the prefix `post_parent:` in the `posts` group.
Follow up to [56763].
Props spacedmonkey, joemcgill, peterwilsoncc.
See #59188.
Built from https://develop.svn.wordpress.org/trunk@56925
git-svn-id: http://core.svn.wordpress.org/trunk@56436 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The `page` query var only accepts a scalar value and passes the value through functions that assume a scalar value.
Adding an extra guard condition does not affect its functionality but does avoid a PHP fatal error for `trim()` when a non-scalar value such as an array is passed.
Follow-up to [2535], [53891].
Props brookedot, rlmc, mukesh27, SergeyBiryukov.
Fixes#56558.
Built from https://develop.svn.wordpress.org/trunk@56815
git-svn-id: http://core.svn.wordpress.org/trunk@56327 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Change the name of `_prime_post_parents_caches()` to `_prime_post_parent_id_caches()` to make it clearer only the parent post ID is cached rather than the entire post parent object.
Follow up to [56763].
Props spacedmonkey, joemcgill, peterwilsoncc.
See #59188.
Built from https://develop.svn.wordpress.org/trunk@56811
git-svn-id: http://core.svn.wordpress.org/trunk@56323 1a063a9b-81f0-0310-95a4-ce76da25c4cd
In [53941], the addition of query caching to `WP_Query` brought about an unintended issue when querying for fields equal to id=>parent. Specifically, on websites with object caching enabled and a substantial number of pages, the second run of this query triggered the `_prime_post_caches` function for id=>parent. This led to the unnecessary priming of post, meta, and term caches, even when only id and parent information were requested.
This commit addresses this issue by introducing a new function, `_prime_post_parents_caches`, which primes a dedicated cache for post parents. This cache is primed during the initial query execution. Subsequently, the `wp_cache_get_multiple` function is employed to retrieve all post parent data in a single object cache request, optimizing performance.
Additionally, this commit extends the coverage of existing unit tests to ensure the reliability of the changes.
Props kevinfodness, joemcgill, peterwilsoncc, LinSoftware, thekt12, spacedmonkey.
Fixes#59188
Built from https://develop.svn.wordpress.org/trunk@56763
git-svn-id: http://core.svn.wordpress.org/trunk@56275 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The `WP_Query` class enables developers to customize queries using filters like `posts_fields_request`, `posts_request`, and `the_posts`, which can modify both the queried fields and retrieved post objects. In some cases with these filters, incomplete or invalid post objects lacking essential data may arise. To address this, if any of these filters are active during a query, the `get_posts` method now avoids caching post objects with the usual `update_post_caches` function call, opting for a call to `_prime_post_caches` instead. This may occasionally trigger new database queries to prime the post data cache. While this enhancement may result in rare additional database queries, it ensures that invalid post objects aren't cached, prioritizing data consistency and integrity in filtered query scenarios.
Props saulirajala, spacedmonkey, flixos90, mukesh27, peterwilsoncc.
Fixes#58599.
Built from https://develop.svn.wordpress.org/trunk@56656
git-svn-id: http://core.svn.wordpress.org/trunk@56168 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Prior to this commit, the `WP_Query` class split the query for posts into two database queries. First, it initiated an ID-based query to retrieve post IDs, followed by a call to _prime_post_caches to fetch post objects if they weren't already in memory. This splitting of queries was limited to cases where fewer than 500 posts were being requested, to prevent a potentially large database query within the IN statement in _prime_post_caches.
However, this limitation becomes unnecessary when a persistent object cache is enabled, as the post objects can be efficiently retrieved from the fast object cache. This commit transfers the responsibility of fetching posts to the object cache, which not only speeds up the process but also reduces the strain on the database server.
Props peterwilsoncc, spacedmonkey, SergeyBiryukov.
Fixes#57296.
Built from https://develop.svn.wordpress.org/trunk@56513
git-svn-id: http://core.svn.wordpress.org/trunk@56025 1a063a9b-81f0-0310-95a4-ce76da25c4cd
`str_starts_with()` and `str_ends_with()` were introduced in PHP 8.0 to perform a case-sensitive check indicating if the string to search in (haystack) begins or ends with the given substring (needle).
WordPress core includes a polyfill for these functions on PHP < 8.0 as of WordPress 5.9.
Follow-up to [55990], [56014].
See #58220.
Built from https://develop.svn.wordpress.org/trunk@56019
git-svn-id: http://core.svn.wordpress.org/trunk@55531 1a063a9b-81f0-0310-95a4-ce76da25c4cd
`str_contains()` was introduced in PHP 8.0 to perform a case-sensitive check indicating if the string to search in (haystack) contains the given substring (needle).
WordPress core includes a polyfill for `str_contains()` on PHP < 8.0 as of WordPress 5.9.
This commit replaces `false !== strpos( ... )` with `str_contains()` in core files, making the code more readable and consistent, as well as better aligned with modern development practices.
Follow-up to [52039], [52040], [52326], [55703], [55710], [55987].
Props Soean, spacedmonkey, costdev, dingo_d, azaozz, mikeschroder, flixos90, peterwilsoncc, SergeyBiryukov.
Fixes#58206.
Built from https://develop.svn.wordpress.org/trunk@55988
git-svn-id: http://core.svn.wordpress.org/trunk@55500 1a063a9b-81f0-0310-95a4-ce76da25c4cd
As of [55749] wp_queue_comments_for_comment_meta_lazyload is no longer used in core. This commit, deprecates this function. Update docs and tests accordingly.
Props sh4lin, spacedmonkey, costdev, peterwilsoncc.
Fixes#58301.
Built from https://develop.svn.wordpress.org/trunk@55855
git-svn-id: http://core.svn.wordpress.org/trunk@55367 1a063a9b-81f0-0310-95a4-ce76da25c4cd
When the logic to exclude images that likely appear above the fold from being lazy-loaded was introduced in WordPress 5.9, initially only images that appear within the main query loop were being considered. However, there is a good chance that images above the fold are rendered before the loop starts, for example in the header template part.
It is particularly common for a theme to display the featured image for a single post in the header. Based on HTTP Archive data from February 2023, the majority of LCP images that are still being lazy-loaded on WordPress sites use the `wp-post-image` class, i.e. are featured images.
This changeset enhances the logic in `wp_get_loading_attr_default()` to not lazy-load images that appear within or after the header template part and before the query loop, using a new `WP_Query::$before_loop` property.
For block themes, this was for the most part already addressed in [55318], however this enhancement implements the solution in a more generally applicable way that brings the improvement to classic themes as well.
Props thekt12, flixos90, spacedmonkey, costdev, zunaid321, mukesh27.
Fixes#58211.
See #53675, #56930.
Built from https://develop.svn.wordpress.org/trunk@55847
git-svn-id: http://core.svn.wordpress.org/trunk@55359 1a063a9b-81f0-0310-95a4-ce76da25c4cd