Skip to content
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
382ce6c
Bump minimum PHP version to 7.4 in composer.json
westonruter May 8, 2026
e9ce2ca
Bump PHPCS testVersion to 7.4-
westonruter May 8, 2026
2a5cc3f
Bump plugin header Requires PHP from 7.2 to 7.4
westonruter May 8, 2026
872f9c5
Drop PHP 7.2 and 7.3 from the unit-test matrix
westonruter May 8, 2026
0e0671f
Update CONTRIBUTING.md and AGENTS.md to reference PHP 7.4
westonruter May 8, 2026
619d91b
Update phpstan.neon.dist comment to reference PHP 7.4
westonruter May 8, 2026
cd44261
Drop PHP 7.2/7.3 array_merge empty-input guard
westonruter May 8, 2026
04e1f38
Reindent speculation-rules heredoc closer using PHP 7.3+ flexible her…
westonruter May 8, 2026
6017bd9
Allow @var docblocks alongside native property type hints
westonruter May 8, 2026
6d94c56
Add native typed properties to OD_HTML_Tag_Processor
westonruter May 8, 2026
2eb0730
Add native typed properties to OD_URL_Metric_Group
westonruter May 8, 2026
3dee81d
Add native typed properties to OD_URL_Metric_Group_Collection
westonruter May 8, 2026
2565e27
Add native typed properties to OD_Tag_Visitor_Context
westonruter May 8, 2026
500ece2
Add native typed properties to OD_Template_Optimization_Context
westonruter May 8, 2026
0c35e17
Add native typed properties to OD_URL_Metric_Store_Request_Context
westonruter May 8, 2026
65cb28c
Add native typed properties to OD_URL_Metric
westonruter May 8, 2026
7f02300
Add native typed properties to OD_Element
westonruter May 8, 2026
d7dc8e0
Add native typed properties to small OD classes
westonruter May 8, 2026
1b6b942
Add native typed properties to image-prioritizer tag visitors
westonruter May 8, 2026
2f0fc6d
Add native typed property to Embed_Optimizer_Tag_Visitor
westonruter May 8, 2026
a8b58ae
Add native typed property to PLSR_URL_Pattern_Prefixer
westonruter May 8, 2026
5260154
Add native typed properties to performance-lab server-timing classes
westonruter May 8, 2026
2aea571
Add native typed properties to view-transitions classes
westonruter May 8, 2026
6a0ce79
Require native property type hints across plugin source
westonruter May 8, 2026
8f3b90a
Convert single-expression closures to arrow functions in optimization…
westonruter May 8, 2026
884f24f
Convert single-expression closures to arrow functions in performance-lab
westonruter May 8, 2026
74a704e
Convert single-expression closures to arrow functions in image-priori…
westonruter May 8, 2026
1ae6374
Convert single-expression closure to arrow function in speculation-rules
westonruter May 8, 2026
f6cb8a2
Convert single-expression closures to arrow functions in web-worker-o…
westonruter May 8, 2026
200b0cc
Convert single-expression closure to arrow function in view-transitions
westonruter May 8, 2026
71430b3
Simplify boolean logic in plvt_register_view_transition_animations()
westonruter May 8, 2026
ea9906a
Remove redundant type hint
westonruter May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/php-test-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ['8.1', '8.0', '7.4', '7.3', '7.2']
php: ['8.1', '8.0', '7.4']
wp: ['latest']
coverage: [false]
include:
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Every file, function, class, method constant, and global variable must have an a

Follow coding conventions in WordPress core. Namespaces are generally not used, as they are not normally used in WordPress core code. Procedural programming patterns are favored where classes play a supporting role, rather than everything being written in OOP.

Whenever possible, the most specific PHP type hints should be used, when backward compatible with PHP 7.2, the minimum version of PHP supported by WordPress and this repository. When native PHP type cannot be used, PHPStan's [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types) should be used, including not only the basic types but also subtypes like `non-empty-string`, [integer ranges](https://phpstan.org/writing-php-code/phpdoc-types#integer-ranges), [general arrays](https://phpstan.org/writing-php-code/phpdoc-types#general-arrays), and especially [array shapes](https://phpstan.org/writing-php-code/phpdoc-types#array-shapes). The types should comply with PHPStan's level 10. The one exception for using PHP types is whenever a function is used as a filter. Since plugins can supply any value at all when filtering, use the expected type with a union to `mixed`. The first statement in the function in this case must always check the type, and if it is not the expected type, override it to be so.
Whenever possible, the most specific PHP type hints should be used, when backward compatible with PHP 7.4, the minimum version of PHP supported by WordPress and this repository. When native PHP type cannot be used, PHPStan's [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types) should be used, including not only the basic types but also subtypes like `non-empty-string`, [integer ranges](https://phpstan.org/writing-php-code/phpdoc-types#integer-ranges), [general arrays](https://phpstan.org/writing-php-code/phpdoc-types#general-arrays), and especially [array shapes](https://phpstan.org/writing-php-code/phpdoc-types#array-shapes). The types should comply with PHPStan's level 10. The one exception for using PHP types is whenever a function is used as a filter. Since plugins can supply any value at all when filtering, use the expected type with a union to `mixed`. The first statement in the function in this case must always check the type, and if it is not the expected type, override it to be so.

Never render HTML `SCRIPT` tags directly in HTML. Always use the relevant APIs in WordPress for adding scripts, including `wp_enqueue_script()`, `wp_add_inline_script()`, `wp_localize_script()`, `wp_print_script_tag()`, `wp_print_inline_script_tag()`, `wp_enqueue_script_module()` among others. Favor modules over classic scripts.

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Thank you for your interest in contributing to the Performance Lab plugin! Compl
In general, all code must follow the [WordPress Coding Standards and best practices](https://developer.wordpress.org/coding-standards/). All code in the Performance Lab plugin must follow these requirements:

- **WordPress**: As of Performance Lab v3.3.0, released July 15, 2024, the plugin's minimum WordPress version requirement is 6.5.
- **PHP**: Always match the latest WordPress version. The minimum required version right now is 7.2.
- **PHP**: Always match the latest WordPress version. The minimum required version right now is 7.4.

## Guidelines

Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"issues": "https://github.com/WordPress/performance/issues"
},
"require": {
"php": "^7.2 || ^8.0",
"php": "^7.4 || ^8.0",
"ext-json": "*"
},
"suggest": {
Expand Down Expand Up @@ -43,7 +43,7 @@
"composer/installers": true
},
"platform": {
"php": "7.2"
"php": "7.4"
}
},
"scripts": {
Expand Down
6 changes: 3 additions & 3 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ parameters:
scanDirectories:
- vendor/wp-phpunit/wp-phpunit/
scanFiles:
# These are needed due config.platform.php being 7.2 in composer.json and wordpress-stubs not including polyfills.
# These are needed due config.platform.php being 7.4 in composer.json and wordpress-stubs not including polyfills.
# See <https://github.com/php-stubs/wordpress-stubs/issues/100>.
- vendor/phpstan/php-8-stubs/stubs/ext/standard/str_contains.php
- vendor/phpstan/php-8-stubs/stubs/ext/standard/str_starts_with.php
Expand Down
2 changes: 1 addition & 1 deletion plugins/auto-sizes/auto-sizes.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Plugin URI: https://github.com/WordPress/performance/tree/trunk/plugins/auto-sizes
* Description: Improves responsive images with better sizes calculations and auto-sizes for lazy-loaded images.
* Requires at least: 6.8
* Requires PHP: 7.2
* Requires PHP: 7.4
* Version: 1.7.0
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
Expand Down
2 changes: 1 addition & 1 deletion plugins/dominant-color-images/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Plugin URI: https://github.com/WordPress/performance/tree/trunk/plugins/dominant-color-images
* Description: Displays placeholders based on an image's dominant color while the image is loading.
* Requires at least: 6.6
* Requires PHP: 7.2
* Requires PHP: 7.4
* Version: 1.2.1
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ final class Embed_Optimizer_Tag_Visitor {
*
* @var bool
*/
private $added_lazy_script = false;
private bool $added_lazy_script = false;

/**
* Determines whether the processor is currently at a figure.wp-block-embed tag.
Expand Down
2 changes: 1 addition & 1 deletion plugins/embed-optimizer/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Plugin URI: https://github.com/WordPress/performance/tree/trunk/plugins/embed-optimizer
* Description: Optimizes the performance of embeds through lazy-loading, adding dns-prefetch links, and reserving space to reduce layout shifts.
* Requires at least: 6.6
* Requires PHP: 7.2
* Requires PHP: 7.4
* Version: 1.0.0-beta5
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,17 @@ final class Image_Prioritizer_Background_Image_Styled_Tag_Visitor extends Image_
* @since 0.3.0
* @var bool
*/
private $added_lazy_assets = false;
private bool $added_lazy_assets = false;

/**
* Tuples of URL Metric group and the common LCP element external background image.
*
* Lazily populated in {@see self::maybe_preload_external_lcp_background_image()}.
*
* @since 0.3.0
* @var array<array{OD_URL_Metric_Group, LcpElementExternalBackgroundImage}>
* @var array<array{OD_URL_Metric_Group, LcpElementExternalBackgroundImage}>|null
*/
private $group_common_lcp_element_external_background_images;
private ?array $group_common_lcp_element_external_background_images = null;

/**
* Visits a tag.
Expand Down Expand Up @@ -146,7 +148,7 @@ private function maybe_preload_external_lcp_background_image( OD_Tag_Visitor_Con
// Gather the tuples of URL Metric group and the common LCP element external background image.
// Note the groups of URL Metrics do not change across invocations, we just need to compute this once for all.
// TODO: Instead of populating this here, it could be done once per invocation during the od_start_template_optimization action since the page's OD_URL_Metric_Group_Collection is available there.
if ( ! is_array( $this->group_common_lcp_element_external_background_images ) ) {
if ( null === $this->group_common_lcp_element_external_background_images ) {
$this->group_common_lcp_element_external_background_images = array();
foreach ( $context->url_metric_group_collection as $group ) {
$common = $this->get_common_lcp_element_external_background_image( $group );
Expand All @@ -156,15 +158,17 @@ private function maybe_preload_external_lcp_background_image( OD_Tag_Visitor_Con
}
}

$tuples = $this->group_common_lcp_element_external_background_images;

// There are no common LCP background images, so abort.
if ( count( $this->group_common_lcp_element_external_background_images ) === 0 ) {
if ( count( $tuples ) === 0 ) {
return;
}

$processor = $context->processor;
$tag_name = strtoupper( (string) $processor->get_tag() );
foreach ( array_keys( $this->group_common_lcp_element_external_background_images ) as $i ) {
list( $group, $common ) = $this->group_common_lcp_element_external_background_images[ $i ];
foreach ( array_keys( $tuples ) as $i ) {
list( $group, $common ) = $tuples[ $i ];
if (
// Note that the browser may send a lower-case tag name in the case of XHTML or embedded SVG/MathML, but
// the HTML Tag Processor is currently normalizing to all upper-case. The HTML Processor on the other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,7 @@ private function get_valid_src( OD_HTML_Tag_Processor $processor, string $attrib
private function add_image_preload_link_for_lcp_element_groups( OD_Tag_Visitor_Context $context, string $xpath, array $attributes ): void {
$attributes = array_filter(
$attributes,
static function ( $attribute_value ) {
return is_string( $attribute_value ) && '' !== $attribute_value;
}
static fn ( $attribute_value ) => is_string( $attribute_value ) && '' !== $attribute_value
);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ final class Image_Prioritizer_Video_Tag_Visitor extends Image_Prioritizer_Tag_Vi
* @since 0.2.0
* @var bool
*/
protected $added_lazy_script = false;
protected bool $added_lazy_script = false;

/**
* Visits a tag.
Expand Down
4 changes: 1 addition & 3 deletions plugins/image-prioritizer/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,7 @@ function image_prioritizer_validate_background_image_url( string $url ) {
}

$allowed_hosts = array_map(
static function ( $host ) {
return wp_parse_url( $host, PHP_URL_HOST );
},
static fn ( $host ) => wp_parse_url( $host, PHP_URL_HOST ),
get_allowed_http_origins()
);

Expand Down
2 changes: 1 addition & 1 deletion plugins/image-prioritizer/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Plugin URI: https://github.com/WordPress/performance/tree/trunk/plugins/image-prioritizer
* Description: Prioritizes the loading of images and videos based on how visible they are to actual visitors; adds <code>fetchpriority</code> and applies lazy-loading.
* Requires at least: 6.6
* Requires PHP: 7.2
* Requires PHP: 7.4
* Requires Plugins: optimization-detective
* Version: 1.0.0-beta3
* Author: WordPress Performance Team
Expand Down
4 changes: 2 additions & 2 deletions plugins/optimization-detective/class-od-element.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ class OD_Element implements ArrayAccess, JsonSerializable {
* @since 0.7.0
* @var ElementData
*/
protected $data;
protected array $data;

/**
* URL Metric that this element belongs to.
*
* @since 0.7.0
* @var OD_URL_Metric
*/
protected $url_metric;
protected OD_URL_Metric $url_metric;

/**
* Constructor.
Expand Down
18 changes: 9 additions & 9 deletions plugins/optimization-detective/class-od-html-tag-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ final class OD_HTML_Tag_Processor extends WP_HTML_Tag_Processor {
* @since 0.4.0
* @var non-empty-string[]
*/
private $open_stack_tags = array();
private array $open_stack_tags = array();

/**
* Stack of the attributes for open tags.
Expand All @@ -163,15 +163,15 @@ final class OD_HTML_Tag_Processor extends WP_HTML_Tag_Processor {
* @since 1.0.0
* @var array<array<non-empty-string, string>>
*/
private $open_stack_attributes = array();
private array $open_stack_attributes = array();

/**
* Open stack indices.
*
* @since 0.4.0
* @var non-negative-int[]
*/
private $open_stack_indices = array();
private array $open_stack_indices = array();

/**
* Bookmarked open stacks.
Expand All @@ -184,7 +184,7 @@ final class OD_HTML_Tag_Processor extends WP_HTML_Tag_Processor {
* @since 0.4.0
* @var array<string, array{tags: non-empty-string[], attributes: array<array<non-empty-string, string>>, indices: non-negative-int[]}>
*/
private $bookmarked_open_stacks = array();
private array $bookmarked_open_stacks = array();

/**
* (Transitional) XPath for the current tag.
Expand All @@ -195,23 +195,23 @@ final class OD_HTML_Tag_Processor extends WP_HTML_Tag_Processor {
* @since 1.0.0
* @var string|null
*/
private $current_xpath = null;
private ?string $current_xpath = null;

/**
* Whether the previous tag does not expect a closer.
*
* @since 0.4.0
* @var bool
*/
private $previous_tag_without_closer = false;
private bool $previous_tag_without_closer = false;

/**
* Mapping of bookmark name to a list of HTML strings which will be inserted at the time get_updated_html() is called.
*
* @since 0.4.0
* @var array<non-empty-string, string[]>
*/
private $buffered_text_replacements = array();
private array $buffered_text_replacements = array();

/**
* Whether the end of the document was reached.
Expand All @@ -220,7 +220,7 @@ final class OD_HTML_Tag_Processor extends WP_HTML_Tag_Processor {
* @see self::next_token()
* @var bool
*/
private $reached_end_of_document = false;
private bool $reached_end_of_document = false;

/**
* Count for the number of times that the cursor was moved.
Expand All @@ -230,7 +230,7 @@ final class OD_HTML_Tag_Processor extends WP_HTML_Tag_Processor {
* @see self::next_token()
* @see self::seek()
*/
private $cursor_move_count = 0;
private int $cursor_move_count = 0;

/**
* Finds the next tag.
Expand Down
14 changes: 3 additions & 11 deletions plugins/optimization-detective/class-od-link-collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class OD_Link_Collection implements Countable {
*
* @var array<string, Link[]>
*/
private $links_by_rel = array();
private array $links_by_rel = array();

/**
* Adds link.
Expand Down Expand Up @@ -128,18 +128,10 @@ public function add_link( array $attributes, ?int $minimum_viewport_width = null
* @return LinkAttributes[] Prepared links with adjacent-duplicates merged together and media attributes added.
*/
private function get_prepared_links(): array {
$links_by_rel = array_values( $this->links_by_rel );
if ( count( $links_by_rel ) === 0 ) {
// This condition is needed for PHP 7.2 and PHP 7.3 in which array_merge() fails if passed a spread empty array: 'array_merge() expects at least 1 parameter, 0 given'.
return array();
}

return array_merge(
...array_map(
function ( array $links ): array {
return $this->merge_consecutive_links( $links );
},
$links_by_rel
fn ( array $links ): array => $this->merge_consecutive_links( $links ),
array_values( $this->links_by_rel )
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@ final class OD_Tag_Visitor_Context {
* @since 0.4.0
* @var OD_HTML_Tag_Processor
*/
private $processor;
private OD_HTML_Tag_Processor $processor;

/**
* URL Metric group collection.
*
* @since 0.4.0
* @var OD_URL_Metric_Group_Collection
*/
private $url_metric_group_collection;
private OD_URL_Metric_Group_Collection $url_metric_group_collection;

/**
* Link collection.
*
* @since 0.4.0
* @var OD_Link_Collection
*/
private $link_collection;
private OD_Link_Collection $link_collection;

/**
* ID for the od_url_metrics post which provided the URL Metrics in the collection.
Expand All @@ -59,7 +59,7 @@ final class OD_Tag_Visitor_Context {
* @since 1.0.0
* @var positive-int|null
*/
private $url_metrics_id;
private ?int $url_metrics_id;

/**
* Visited tag state.
Expand All @@ -69,7 +69,7 @@ final class OD_Tag_Visitor_Context {
* @since 1.0.0
* @var OD_Visited_Tag_State
*/
private $visited_tag_state;
private OD_Visited_Tag_State $visited_tag_state;

/**
* Constructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class OD_Tag_Visitor_Registry implements Countable, IteratorAggregate {
*
* @var array<non-empty-string, TagVisitorCallback>
*/
private $visitors = array();
private array $visitors = array();

/**
* Registers a tag visitor.
Expand Down
Loading
Loading