diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 3e4b36f256d96..1416704909f34 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -85,8 +85,6 @@ includes:
- tests/phpstan/baselines/ternary.alwaysTrue.neon
- tests/phpstan/baselines/varTag.noVariable.neon
- tests/phpstan/baselines/variable.undefined.neon
- - tests/phpstan/baselines/while.alwaysFalse.neon
- - tests/phpstan/baselines/while.alwaysTrue.neon
# phpstan:baselines end
parameters:
diff --git a/src/wp-content/themes/twentyfourteen/inc/widgets.php b/src/wp-content/themes/twentyfourteen/inc/widgets.php
index 36846daa84860..b375113b308b5 100644
--- a/src/wp-content/themes/twentyfourteen/inc/widgets.php
+++ b/src/wp-content/themes/twentyfourteen/inc/widgets.php
@@ -137,6 +137,8 @@ public function widget( $args, $instance ) {
if ( $ephemera->have_posts() ) :
$tmp_content_width = $GLOBALS['content_width'];
$GLOBALS['content_width'] = 306;
+ // The global is unset until a loop has run, so this may be reached before it exists.
+ $tmp_more = $GLOBALS['more'] ?? null;
echo $args['before_widget'];
?>
@@ -148,7 +150,6 @@ public function widget( $args, $instance ) {
have_posts() ) :
$ephemera->the_post();
- $tmp_more = $GLOBALS['more'];
$GLOBALS['more'] = 0;
?>
diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php
index 228691d26d12b..906cca0905e1a 100644
--- a/src/wp-includes/class-wp-query.php
+++ b/src/wp-includes/class-wp-query.php
@@ -3839,6 +3839,8 @@ function ( $carry, $post ) {
*
* @since 1.5.0
*
+ * @phpstan-impure
+ *
* @return bool True if posts are available, false if end of the loop.
*/
public function have_posts() {
@@ -3929,6 +3931,8 @@ public function the_comment() {
*
* @since 2.2.0
*
+ * @phpstan-impure
+ *
* @return bool True if comments are available, false if no more comments.
*/
public function have_comments() {
diff --git a/src/wp-includes/query.php b/src/wp-includes/query.php
index 60571c01cb880..42592002c1cab 100644
--- a/src/wp-includes/query.php
+++ b/src/wp-includes/query.php
@@ -956,6 +956,8 @@ function is_main_query() {
*
* @global WP_Query $wp_query WordPress Query object.
*
+ * @phpstan-impure
+ *
* @return bool True if posts are available, false if end of the loop.
*/
function have_posts() {
@@ -1036,6 +1038,8 @@ function the_post() {
*
* @global WP_Query $wp_query WordPress Query object.
*
+ * @phpstan-impure
+ *
* @return bool True if comments are available, false if no more comments.
*/
function have_comments() {
diff --git a/tests/phpstan/baselines/deadCode.unreachable.neon b/tests/phpstan/baselines/deadCode.unreachable.neon
index 0bd31fe524a9a..8a4288bc40c43 100644
--- a/tests/phpstan/baselines/deadCode.unreachable.neon
+++ b/tests/phpstan/baselines/deadCode.unreachable.neon
@@ -38,241 +38,11 @@ parameters:
identifier: deadCode.unreachable
count: 1
path: ../../../src/wp-admin/includes/class-wp-internal-pointers.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 2
- path: ../../../src/wp-admin/includes/dashboard.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 2
path: ../../../src/wp-admin/post.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/author.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/category.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/inc/widgets.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/showcase.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/tag.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfifteen/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfifteen/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfifteen/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/author.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/category.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/inc/widgets.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/tag.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/taxonomy-post_format.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentynineteen/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentynineteen/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentynineteen/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/template-parts/page/content-front-page-panels.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentysixteen/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentysixteen/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentysixteen/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/author.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/category.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/tag.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/taxonomy-post_format.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/author.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/category.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/search.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/tag.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwentyone/archive.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwentyone/index.php
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: ../../../src/wp-content/themes/twentytwentyone/search.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
diff --git a/tests/phpstan/baselines/if.alwaysTrue.neon b/tests/phpstan/baselines/if.alwaysTrue.neon
index f049efde2d19d..6888b9780b5f9 100644
--- a/tests/phpstan/baselines/if.alwaysTrue.neon
+++ b/tests/phpstan/baselines/if.alwaysTrue.neon
@@ -28,11 +28,6 @@ parameters:
identifier: if.alwaysTrue
count: 2
path: ../../../src/wp-admin/upload.php
- -
- message: '#^If condition is always true\.$#'
- identifier: if.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentynineteen/comments.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
diff --git a/tests/phpstan/baselines/while.alwaysFalse.neon b/tests/phpstan/baselines/while.alwaysFalse.neon
deleted file mode 100644
index 3c924003ea783..0000000000000
--- a/tests/phpstan/baselines/while.alwaysFalse.neon
+++ /dev/null
@@ -1,25 +0,0 @@
-# PHPStan baseline for the `while.alwaysFalse` errors in WordPress core.
-#
-# https://phpstan.org/error-identifiers/while.alwaysFalse
-#
-# Each entry is scoped to a single file and carries an exact occurrence count,
-# so that a new instance is reported as a new error rather than being absorbed
-# silently. Fixing an occurrence therefore means decrementing or removing its
-# entry here as part of the same change.
-#
-# The goal is to empty this file and delete it, along with the `includes` entry
-# for it in phpstan.neon.dist.
-#
-# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with
-#
-# composer phpstan:baselines -- --identifier=while.alwaysFalse
-#
-# which reruns the analysis with this file suppressed so the errors surface again.
-
-parameters:
- ignoreErrors:
- -
- message: '#^While loop condition is always false\.$#'
- identifier: while.alwaysFalse
- count: 1
- path: ../../../src/wp-includes/feed-rdf.php
diff --git a/tests/phpstan/baselines/while.alwaysTrue.neon b/tests/phpstan/baselines/while.alwaysTrue.neon
deleted file mode 100644
index 5da6550e89cc0..0000000000000
--- a/tests/phpstan/baselines/while.alwaysTrue.neon
+++ /dev/null
@@ -1,300 +0,0 @@
-# PHPStan baseline for the `while.alwaysTrue` errors in WordPress core.
-#
-# https://phpstan.org/error-identifiers/while.alwaysTrue
-#
-# Each entry is scoped to a single file and carries an exact occurrence count,
-# so that a new instance is reported as a new error rather than being absorbed
-# silently. Fixing an occurrence therefore means decrementing or removing its
-# entry here as part of the same change.
-#
-# The goal is to empty this file and delete it, along with the `includes` entry
-# for it in phpstan.neon.dist.
-#
-# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with
-#
-# composer phpstan:baselines -- --identifier=while.alwaysTrue
-#
-# which reruns the analysis with this file suppressed so the errors surface again.
-
-parameters:
- ignoreErrors:
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-admin/includes/dashboard.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-admin/includes/nav-menu.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/author.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/category.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/inc/widgets.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/showcase.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyeleven/tag.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfifteen/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfifteen/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfifteen/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/author.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/category.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/inc/widgets.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/tag.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyfourteen/taxonomy-post_format.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentynineteen/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentynineteen/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentynineteen/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/front-page.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyseventeen/template-parts/page/content-front-page-panels.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentysixteen/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentysixteen/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentysixteen/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyten/loop-attachment.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyten/loop-page.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentyten/loop-single.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/author.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/category.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/tag.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentythirteen/taxonomy-post_format.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/author.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/category.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwelve/tag.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwenty/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwenty/singular.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwenty/templates/template-cover.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwentyone/archive.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwentyone/index.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-content/themes/twentytwentyone/search.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-includes/block-template.php
- -
- message: '#^While loop condition is always true\.$#'
- identifier: while.alwaysTrue
- count: 1
- path: ../../../src/wp-includes/theme-compat/embed.php
diff --git a/tests/phpunit/tests/theme/twentyFourteenEphemeraWidget.php b/tests/phpunit/tests/theme/twentyFourteenEphemeraWidget.php
new file mode 100644
index 0000000000000..c2442ef18ec7e
--- /dev/null
+++ b/tests/phpunit/tests/theme/twentyFourteenEphemeraWidget.php
@@ -0,0 +1,134 @@
+
+ */
+ private array $original_globals = array();
+
+ public function set_up() {
+ parent::set_up();
+
+ /*
+ * `backupGlobals` is disabled for the suite, so these have to be restored by hand
+ * to keep later tests in the process from inheriting them. Capture them before the
+ * skip below, which still runs `tear_down()`.
+ */
+ foreach ( $this->global_names as $global_name ) {
+ if ( array_key_exists( $global_name, $GLOBALS ) ) {
+ $this->original_globals[ $global_name ] = $GLOBALS[ $global_name ];
+ }
+ }
+
+ $widgets = WP_CONTENT_DIR . '/themes/twentyfourteen/inc/widgets.php';
+ if ( ! file_exists( $widgets ) ) {
+ $this->markTestSkipped( 'The Twenty Fourteen theme is not installed.' );
+ }
+ require_once $widgets;
+ }
+
+ public function tear_down() {
+ foreach ( $this->global_names as $global_name ) {
+ if ( array_key_exists( $global_name, $this->original_globals ) ) {
+ $GLOBALS[ $global_name ] = $this->original_globals[ $global_name ];
+ } else {
+ unset( $GLOBALS[ $global_name ] );
+ }
+ }
+
+ parent::tear_down();
+ }
+
+ /**
+ * The widget must restore the original `$more` global, which `WP_Query::setup_postdata()`
+ * zeroes out for each post the widget's secondary loop renders.
+ */
+ public function test_widget_restores_more_global() {
+ $post_id = self::factory()->post->create(
+ array(
+ 'post_content' => 'I want ice cream!',
+ )
+ );
+ $this->assertIsInt( $post_id );
+ set_post_format( $post_id, 'aside' );
+
+ // Sentinel value for the restore assertion below; it does not affect what the widget renders.
+ $GLOBALS['more'] = 1;
+ $GLOBALS['content_width'] = 474;
+
+ $widget = new Twenty_Fourteen_Ephemera_Widget();
+
+ $output = get_echo(
+ array( $widget, 'widget' ),
+ array(
+ array(
+ 'before_widget' => '',
+ 'after_widget' => '',
+ ),
+ array( 'format' => 'aside' ),
+ )
+ );
+
+ $this->assertNotEmpty( $output, 'The widget content.' );
+ $processor = new WP_HTML_Tag_Processor( $output );
+ $more_link_count = 0;
+ while ( $processor->next_tag( array( 'class_name' => 'more-link' ) ) ) {
+ ++$more_link_count;
+ }
+ $this->assertSame( 1, $more_link_count, 'Expected there to be one more link.' );
+ $this->assertSame( 1, $GLOBALS['more'], 'The $more global was not restored to its original value.' ); // @phpstan-ignore method.alreadyNarrowedType (The global variable is modified by Twenty_Fourteen_Ephemera_Widget::widget().)
+ $this->assertSame( 474, $GLOBALS['content_width'], 'The $content_width global was not restored to its original value.' );
+ }
+
+ /**
+ * The `$more` global is only defined once a loop has run, so the widget must not
+ * assume it exists. It can render before any loop on a 404, an empty search, or an
+ * empty archive, as well as outside the template entirely.
+ */
+ public function test_widget_when_more_global_is_undefined() {
+ $post_id = self::factory()->post->create(
+ array(
+ 'post_content' => 'I want ice cream!',
+ )
+ );
+ $this->assertIsInt( $post_id );
+ set_post_format( $post_id, 'aside' );
+
+ unset( $GLOBALS['more'] );
+ $GLOBALS['content_width'] = 474;
+
+ $widget = new Twenty_Fourteen_Ephemera_Widget();
+
+ $output = get_echo(
+ array( $widget, 'widget' ),
+ array(
+ array(
+ 'before_widget' => '',
+ 'after_widget' => '',
+ ),
+ array( 'format' => 'aside' ),
+ )
+ );
+
+ $this->assertNotEmpty( $output, 'The widget content.' );
+ $this->assertNull( $GLOBALS['more'], 'The $more global was not restored to a falsey value.' ); // @phpstan-ignore offsetAccess.notFound (The global variable is set by Twenty_Fourteen_Ephemera_Widget::widget().)
+ }
+}