Commit c413d56b69 for wordpress.org
commit c413d56b690720751cfded335af2c8786d07b5f3
Author: westonruter <westonruter@git.wordpress.org>
Date: Wed Oct 7 20:52:52 2026 +0000
Docs: Add refined string types for PHPStan.
Adds `non-empty-string`, `non-falsy-string`, and `lowercase-string` return types where a function always produces such a string, mostly taken from [https://github.com/php-stubs/wordpress-stubs php-stubs/wordpress-stubs]. Where PHPStan cannot infer the refinement from the function body, such as from a static cache or a `sprintf()` call, the type is asserted inline so that the narrower types introduce no new errors.
Registration functions now require a lowercase key where it is documented or validated as lowercase. This covers post types, post statuses, and taxonomies, as well as the names used by the abilities, block bindings, block types, block templates, connectors, and icons registries. Static analysis describes what callers should supply, so these follow the documented contract even where a function lowercases the key itself. Admin menu slugs are only narrowed to `non-falsy-string`: although they are documented as lowercase, established plugins register mixed-case slugs which appear in admin URLs and cannot be changed without breaking links. Script and style handles are left as plain strings for the same reason, since mixed-case handles are widespread and other code must pass them verbatim as dependencies.
The only runtime change is in `wp_internal_hosts()`, which now re-indexes the deduplicated hosts with `array_values()` so that it returns a list.
Developed in https://github.com/WordPress/wordpress-develop/pull/13892.
Follow-up to r55289, r64163.
Props marian1, swissspidy, westonruter.
See #65817.
Built from https://develop.svn.wordpress.org/trunk@64235
git-svn-id: http://core.svn.wordpress.org/trunk@63386 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-admin/includes/class-wp-comments-list-table.php b/wp-admin/includes/class-wp-comments-list-table.php
index 2b927a7f81..7294f89d1b 100644
--- a/wp-admin/includes/class-wp-comments-list-table.php
+++ b/wp-admin/includes/class-wp-comments-list-table.php
@@ -62,6 +62,8 @@ class WP_Comments_List_Table extends WP_List_Table {
* @param string $name Comment author name.
* @param int $comment_id Comment ID.
* @return string Avatar with the user name.
+ *
+ * @phpstan-return non-falsy-string
*/
public function floated_admin_avatar( $name, $comment_id ) {
$comment = get_comment( $comment_id );
diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php
index 6134db45b6..42de0269a0 100644
--- a/wp-admin/includes/media.php
+++ b/wp-admin/includes/media.php
@@ -1315,6 +1315,8 @@ function image_size_input_fields( $post, $check = '' ) {
* @param WP_Post $post
* @param string $url_type
* @return string HTML markup for the link URL buttons.
+ *
+ * @phpstan-return non-falsy-string
*/
function image_link_input_fields( $post, $url_type = '' ) {
@@ -1348,6 +1350,8 @@ function image_link_input_fields( $post, $url_type = '' ) {
*
* @param WP_Post $edit_post Attachment WP_Post object.
* @return string HTML markup for the textarea element.
+ *
+ * @phpstan-return non-falsy-string
*/
function wp_caption_input_textarea( $edit_post ) {
// Post data is already escaped.
@@ -1637,6 +1641,8 @@ function get_media_items( $post_id, $errors ) {
* @param int $attachment_id Attachment ID for modification.
* @param string|array $args Optional. Override defaults.
* @return string HTML form for attachment.
+ *
+ * @phpstan-return non-falsy-string
*/
function get_media_item( $attachment_id, $args = null ) {
global $redir_tab;
@@ -3013,6 +3019,8 @@ function media_upload_library_form( $errors ) {
*
* @param string $default_view
* @return string HTML content of the form.
+ *
+ * @phpstan-return non-falsy-string
*/
function wp_media_insert_url_form( $default_view = 'image' ) {
/** This filter is documented in wp-admin/includes/media.php */
diff --git a/wp-admin/includes/ms.php b/wp-admin/includes/ms.php
index 155170aaf4..0ae6381ee9 100644
--- a/wp-admin/includes/ms.php
+++ b/wp-admin/includes/ms.php
@@ -1211,6 +1211,8 @@ function get_site_screen_help_tab_args() {
* @since 4.9.0
*
* @return string Help sidebar content.
+ *
+ * @phpstan-return non-falsy-string
*/
function get_site_screen_help_sidebar_content() {
return '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
diff --git a/wp-admin/includes/plugin.php b/wp-admin/includes/plugin.php
index 39b6295f77..c627e6d8f5 100644
--- a/wp-admin/includes/plugin.php
+++ b/wp-admin/includes/plugin.php
@@ -1399,6 +1399,8 @@ function uninstall_plugin( $plugin ) {
* * Pass 'none' to leave div.wp-menu-image empty so an icon can be added via CSS.
* @param int|float $position Optional. The position in the menu order this item should appear.
* @return string The resulting page's hook_suffix.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $icon_url = '', $position = null ) {
global $menu, $admin_page_hooks, $_registered_pages, $_parent_pages;
@@ -1494,6 +1496,8 @@ function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $call
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int|float $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
global $submenu, $menu, $_wp_real_parent_file, $_wp_submenu_nopriv,
@@ -1607,6 +1611,8 @@ function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability,
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1631,6 +1637,8 @@ function add_management_page( $page_title, $menu_title, $capability, $menu_slug,
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1655,6 +1663,8 @@ function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $c
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1679,6 +1689,8 @@ function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $cal
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1703,6 +1715,8 @@ function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $c
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
if ( current_user_can( 'edit_users' ) ) {
@@ -1732,6 +1746,8 @@ function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $cal
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1756,6 +1772,8 @@ function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug,
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1780,6 +1798,8 @@ function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $cal
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1804,6 +1824,8 @@ function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $cal
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1828,6 +1850,8 @@ function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $cal
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -1852,6 +1876,8 @@ function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $cal
* @param callable $callback Optional. The function to be called to output the content for this page.
* @param int $position Optional. The position in the menu order this item should appear.
* @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
+ *
+ * @phpstan-param non-falsy-string $menu_slug
*/
function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
@@ -2147,6 +2173,8 @@ function get_plugin_page_hook( $plugin_page, $parent_page ) {
* @param string $parent_page The slug name for the parent menu (or the file name of a standard
* WordPress admin page).
* @return string Hook name for the plugin page.
+ *
+ * @phpstan-return non-falsy-string
*/
function get_plugin_page_hookname( $plugin_page, $parent_page ) {
global $admin_page_hooks;
diff --git a/wp-admin/includes/template.php b/wp-admin/includes/template.php
index e8f6c4f5ba..c01d9ffaf8 100644
--- a/wp-admin/includes/template.php
+++ b/wp-admin/includes/template.php
@@ -2654,6 +2654,8 @@ function submit_button( $text = '', $type = 'primary', $name = 'submit', $wrap =
* e.g. `id="search-submit"`, though the array format is generally preferred.
* Default empty string.
* @return string Submit button HTML.
+ *
+ * @phpstan-return non-falsy-string
*/
function get_submit_button( $text = '', $type = 'primary large', $name = 'submit', $wrap = true, $other_attributes = '' ) {
if ( ! is_array( $type ) ) {
diff --git a/wp-admin/includes/widgets.php b/wp-admin/includes/widgets.php
index e751602866..5697a6e9ff 100644
--- a/wp-admin/includes/widgets.php
+++ b/wp-admin/includes/widgets.php
@@ -322,6 +322,8 @@ function wp_widget_control( $sidebar_args ) {
/**
* @param string $classes
* @return string Modified body classes.
+ *
+ * @phpstan-return non-falsy-string
*/
function wp_widgets_access_body_class( $classes ) {
return "$classes widgets_access ";
diff --git a/wp-includes/abilities-api.php b/wp-includes/abilities-api.php
index 393e40b56e..abd3684273 100644
--- a/wp-includes/abilities-api.php
+++ b/wp-includes/abilities-api.php
@@ -292,6 +292,8 @@ declare( strict_types = 1 );
* of ability behavior.
* }
* @return WP_Ability|null The registered ability instance on success, `null` on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $name
*/
function wp_register_ability( string $name, array $args ): ?WP_Ability {
if ( ! doing_action( 'wp_abilities_api_init' ) ) {
@@ -652,6 +654,8 @@ function _wp_get_abilities_match_meta( array $meta, array $conditions ): bool {
* @type array<string, mixed> $meta Optional. Additional metadata for the ability category.
* }
* @return WP_Ability_Category|null The registered ability category instance on success, `null` on failure.
+ *
+ * @phpstan-param lowercase-string&non-empty-string $slug
*/
function wp_register_ability_category( string $slug, array $args ): ?WP_Ability_Category {
if ( ! doing_action( 'wp_abilities_api_categories_init' ) ) {
diff --git a/wp-includes/abilities-api/class-wp-abilities-registry.php b/wp-includes/abilities-api/class-wp-abilities-registry.php
index 813c3dd49f..90a2349a89 100644
--- a/wp-includes/abilities-api/class-wp-abilities-registry.php
+++ b/wp-includes/abilities-api/class-wp-abilities-registry.php
@@ -84,6 +84,8 @@ final class WP_Abilities_Registry {
* @type string $ability_class Optional. Custom class to instantiate instead of WP_Ability.
* }
* @return WP_Ability|null The registered ability instance on success, null on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $name
*/
public function register( string $name, array $args ): ?WP_Ability {
if ( ! preg_match( '/^[a-z0-9-]+\/[a-z0-9-]+$/', $name ) ) {
diff --git a/wp-includes/abilities-api/class-wp-ability-categories-registry.php b/wp-includes/abilities-api/class-wp-ability-categories-registry.php
index 58bc4323ce..92e6dbdd84 100644
--- a/wp-includes/abilities-api/class-wp-ability-categories-registry.php
+++ b/wp-includes/abilities-api/class-wp-ability-categories-registry.php
@@ -53,6 +53,8 @@ final class WP_Ability_Categories_Registry {
* @type array<string, mixed> $meta Optional. Additional metadata for the ability category.
* }
* @return WP_Ability_Category|null The registered ability category instance on success, null on failure.
+ *
+ * @phpstan-param lowercase-string&non-empty-string $slug
*/
public function register( string $slug, array $args ): ?WP_Ability_Category {
if ( $this->is_registered( $slug ) ) {
diff --git a/wp-includes/block-bindings.php b/wp-includes/block-bindings.php
index e3425c1538..1250f92e99 100644
--- a/wp-includes/block-bindings.php
+++ b/wp-includes/block-bindings.php
@@ -90,6 +90,8 @@
* @type string[] $uses_context Optional. Array of values to add to block `uses_context` needed by the source.
* }
* @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $source_name
*/
function register_block_bindings_source( string $source_name, array $source_properties ) {
return WP_Block_Bindings_Registry::get_instance()->register( $source_name, $source_properties );
diff --git a/wp-includes/block-supports/elements.php b/wp-includes/block-supports/elements.php
index fe9543a5d5..e8076cc1bd 100644
--- a/wp-includes/block-supports/elements.php
+++ b/wp-includes/block-supports/elements.php
@@ -13,6 +13,8 @@
* @access private
*
* @return string The unique class name.
+ *
+ * @phpstan-return lowercase-string&non-falsy-string
*/
function wp_get_elements_class_name(): string {
return wp_unique_prefixed_id( 'wp-elements-' );
diff --git a/wp-includes/block-template-utils.php b/wp-includes/block-template-utils.php
index 9c6be11c7d..5f829e3eab 100644
--- a/wp-includes/block-template-utils.php
+++ b/wp-includes/block-template-utils.php
@@ -1491,6 +1491,8 @@ function wp_is_theme_directory_ignored( $path ) {
* @since 6.0.0 Adds the whole theme to the export archive.
*
* @return WP_Error|string Path of the ZIP file or error on failure.
+ *
+ * @phpstan-return non-falsy-string|WP_Error
*/
function wp_generate_block_templates_export_file() {
$wp_version = wp_get_wp_version();
diff --git a/wp-includes/block-template.php b/wp-includes/block-template.php
index 8c34b05d01..3f24933dfc 100644
--- a/wp-includes/block-template.php
+++ b/wp-includes/block-template.php
@@ -501,6 +501,8 @@ function _resolve_template_for_new_post( $wp_query ) {
* @type string $plugin Optional. Slug of the plugin that registers the template.
* }
* @return WP_Block_Template|WP_Error The registered template object on success, WP_Error object on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $template_name
*/
function register_block_template( $template_name, $args = array() ) {
return WP_Block_Templates_Registry::get_instance()->register( $template_name, $args );
diff --git a/wp-includes/blocks.php b/wp-includes/blocks.php
index beaf08d402..1701548d8d 100644
--- a/wp-includes/blocks.php
+++ b/wp-includes/blocks.php
@@ -843,6 +843,7 @@ function register_block_type( $block_type, $args = array() ) {
return register_block_type_from_metadata( $block_type, $args );
}
+ /** @var (lowercase-string&non-falsy-string)|WP_Block_Type $block_type A string that is not a path to block metadata should be a block type name. */
return WP_Block_Type_Registry::get_instance()->register( $block_type, $args );
}
@@ -3084,6 +3085,8 @@ function build_query_vars_from_query_block( $block, $page ) {
* @param WP_Block $block Block instance.
* @param bool $is_next Flag for handling `next/previous` blocks.
* @return string|null The pagination arrow HTML or null if there is none.
+ *
+ * @phpstan-return non-falsy-string|null
*/
function get_query_pagination_arrow( $block, $is_next ) {
$arrow_map = array(
@@ -3184,6 +3187,8 @@ function build_comment_query_vars_from_block( $block ) {
* @param string $pagination_type Optional. Type of the arrow we will be rendering.
* Accepts 'next' or 'previous'. Default 'next'.
* @return string|null The pagination arrow HTML or null if there is none.
+ *
+ * @phpstan-return non-falsy-string|null
*/
function get_comments_pagination_arrow( $block, $pagination_type = 'next' ) {
$arrow_map = array(
diff --git a/wp-includes/class-wp-ajax-response.php b/wp-includes/class-wp-ajax-response.php
index ab747618e0..b9946343ac 100644
--- a/wp-includes/class-wp-ajax-response.php
+++ b/wp-includes/class-wp-ajax-response.php
@@ -63,6 +63,8 @@ class WP_Ajax_Response {
* element as CDATA. Default empty array.
* }
* @return string XML response.
+ *
+ * @phpstan-return non-falsy-string
*/
public function add( $args = '' ) {
$defaults = array(
diff --git a/wp-includes/class-wp-block-bindings-registry.php b/wp-includes/class-wp-block-bindings-registry.php
index f4591656e7..b20f0a692c 100644
--- a/wp-includes/class-wp-block-bindings-registry.php
+++ b/wp-includes/class-wp-block-bindings-registry.php
@@ -80,6 +80,8 @@ final class WP_Block_Bindings_Registry {
* @type string[] $uses_context Optional. Array of values to add to block `uses_context` needed by the source.
* }
* @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $source_name
*/
public function register( string $source_name, array $source_properties ) {
if ( ! is_string( $source_name ) ) {
diff --git a/wp-includes/class-wp-block-templates-registry.php b/wp-includes/class-wp-block-templates-registry.php
index 6d47158cf8..fa1c180988 100644
--- a/wp-includes/class-wp-block-templates-registry.php
+++ b/wp-includes/class-wp-block-templates-registry.php
@@ -36,6 +36,8 @@ final class WP_Block_Templates_Registry {
* @param string $template_name Template name including namespace.
* @param array $args Optional. Array of template arguments.
* @return WP_Block_Template|WP_Error The registered template on success, or WP_Error on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $template_name
*/
public function register( $template_name, $args = array() ) {
diff --git a/wp-includes/class-wp-block-type-registry.php b/wp-includes/class-wp-block-type-registry.php
index 93a8615b52..d3fe35d15f 100644
--- a/wp-includes/class-wp-block-type-registry.php
+++ b/wp-includes/class-wp-block-type-registry.php
@@ -44,6 +44,8 @@ final class WP_Block_Type_Registry {
* of `WP_Block_Type`. See WP_Block_Type::__construct() for information
* on accepted arguments. Default empty array.
* @return WP_Block_Type|false The registered block type on success, or false on failure.
+ *
+ * @phpstan-param (lowercase-string&non-falsy-string)|WP_Block_Type $name
*/
public function register( $name, $args = array() ) {
$block_type = null;
diff --git a/wp-includes/class-wp-connector-registry.php b/wp-includes/class-wp-connector-registry.php
index eed6e2654a..70b967e8ab 100644
--- a/wp-includes/class-wp-connector-registry.php
+++ b/wp-includes/class-wp-connector-registry.php
@@ -127,6 +127,7 @@ final class WP_Connector_Registry {
* }
* @return array|null The registered connector data on success, null on failure.
*
+ * @phpstan-param lowercase-string&non-empty-string $id
* @phpstan-param array{
* name: non-empty-string,
* description?: string,
diff --git a/wp-includes/class-wp-dependencies.php b/wp-includes/class-wp-dependencies.php
index 8f87607c15..9aef3af3ef 100644
--- a/wp-includes/class-wp-dependencies.php
+++ b/wp-includes/class-wp-dependencies.php
@@ -539,6 +539,8 @@ class WP_Dependencies {
*
* @param string[] $load Array of script or style handles to load.
* @return string Etag header.
+ *
+ * @phpstan-return non-falsy-string
*/
public function get_etag( $load ) {
/*
diff --git a/wp-includes/class-wp-icon-collections-registry.php b/wp-includes/class-wp-icon-collections-registry.php
index dcfe842285..e7e19d02b1 100644
--- a/wp-includes/class-wp-icon-collections-registry.php
+++ b/wp-includes/class-wp-icon-collections-registry.php
@@ -51,6 +51,8 @@ class WP_Icon_Collections_Registry {
* via {@see wp_get_icon()}. Default true.
* }
* @return bool True if the collection was registered successfully, false otherwise.
+ *
+ * @phpstan-param lowercase-string&non-empty-string $collection_slug
*/
public function register( $collection_slug, $collection_properties ) {
if ( ! isset( $collection_slug ) || ! is_string( $collection_slug ) ) {
diff --git a/wp-includes/class-wp-icons-registry.php b/wp-includes/class-wp-icons-registry.php
index 361506a67e..6186a0b489 100644
--- a/wp-includes/class-wp-icons-registry.php
+++ b/wp-includes/class-wp-icons-registry.php
@@ -62,6 +62,8 @@ class WP_Icons_Registry {
* `get_registered_icons()` alongside the name and label.
* }
* @return bool True if the icon was registered with success and false otherwise.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $icon_name
*/
public function register( $icon_name, $icon_properties ) {
if ( ! isset( $icon_name ) || ! is_string( $icon_name ) ) {
diff --git a/wp-includes/class-wp-widget.php b/wp-includes/class-wp-widget.php
index b131c50db3..7a1a8ae51d 100644
--- a/wp-includes/class-wp-widget.php
+++ b/wp-includes/class-wp-widget.php
@@ -213,6 +213,8 @@ class WP_Widget {
*
* @param string $field_name Field name.
* @return string Name attribute for `$field_name`.
+ *
+ * @phpstan-return non-falsy-string
*/
public function get_field_name( $field_name ) {
$pos = strpos( $field_name, '[' );
@@ -238,6 +240,8 @@ class WP_Widget {
*
* @param string $field_name Field name.
* @return string ID attribute for `$field_name`.
+ *
+ * @phpstan-return non-falsy-string
*/
public function get_field_id( $field_name ) {
$field_name = str_replace( array( '[]', '[', ']' ), array( '', '-', '' ), $field_name );
diff --git a/wp-includes/connectors.php b/wp-includes/connectors.php
index 9aed5f1f4d..9c83a973eb 100644
--- a/wp-includes/connectors.php
+++ b/wp-includes/connectors.php
@@ -384,6 +384,7 @@ function _wp_connectors_register_default_ai_providers( WP_Connector_Registry $re
}
// Register all default connectors directly on the registry.
+ /** @var lowercase-string&non-empty-string $id AI Client provider IDs are validated as lowercase by ProviderMetadata. */
foreach ( $defaults as $id => $args ) {
if ( 'api_key' === $args['authentication']['method'] ) {
$sanitized_id = str_replace( '-', '_', $id );
diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php
index 5f6a1cd9f6..552c5f17c2 100644
--- a/wp-includes/formatting.php
+++ b/wp-includes/formatting.php
@@ -622,8 +622,11 @@ function wp_html_split( $input ) {
* @since 4.4.0
*
* @return string The regular expression.
+ *
+ * @phpstan-return non-falsy-string
*/
function get_html_split_regex() {
+ /** @var non-falsy-string|null $regex */
static $regex;
if ( ! isset( $regex ) ) {
@@ -2278,6 +2281,8 @@ function sanitize_title_for_query( $title ) {
* When set to 'save', additional entities are converted to hyphens
* or stripped entirely. Default 'display'.
* @return string The sanitized title.
+ *
+ * @phpstan-return lowercase-string
*/
function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) {
$title = strip_tags( $title );
@@ -2397,6 +2402,7 @@ function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'displa
$title = preg_replace( '|-+|', '-', $title );
$title = trim( $title, '-' );
+ /** @var lowercase-string $title Only lowercase characters remain after the replacements above. */
return $title;
}
@@ -2870,6 +2876,8 @@ function backslashit( $value ) {
*
* @param string $value Value to which trailing slash will be added.
* @return string String with trailing slash added.
+ *
+ * @phpstan-return non-falsy-string
*/
function trailingslashit( $value ) {
return untrailingslashit( $value ) . '/';
diff --git a/wp-includes/functions.php b/wp-includes/functions.php
index 3bcfcb6102..114a9484f5 100644
--- a/wp-includes/functions.php
+++ b/wp-includes/functions.php
@@ -2150,6 +2150,7 @@ function wp_mkdir_p( $target ) {
* @return bool True if path is absolute, false is not absolute.
*
* @phpstan-return ( $path is non-falsy-string ? bool : false )
+ * @phpstan-assert-if-true non-falsy-string $path
*/
function path_is_absolute( $path ) {
/*
@@ -2192,6 +2193,8 @@ function path_is_absolute( $path ) {
* @param string $base Base path.
* @param string $path Path relative to $base.
* @return string The path with the base or absolute path.
+ *
+ * @phpstan-return non-falsy-string
*/
function path_join( $base, $path ) {
if ( path_is_absolute( $path ) ) {
@@ -2957,7 +2960,8 @@ function _wp_check_existing_file_names( $filename, $files ) {
* @type string|false $error Error message, if there has been an error.
* }
*
- * @phpstan-param null $deprecated
+ * @phpstan-param non-empty-string $name
+ * @phpstan-param null $deprecated
* @phpstan-return array{ file: non-empty-string, url: non-empty-string, type: string|false, error: false }
* |array{ error: string, ... }
*/
@@ -4480,6 +4484,8 @@ function _wp_die_process_input( $message, $title = '', $args = array() ) {
* @param int $depth Optional. Maximum depth to walk through $value. Must be
* greater than 0. Default 512.
* @return string|false The JSON encoded string, or false if it cannot be encoded.
+ *
+ * @phpstan-return non-empty-string|false
*/
function wp_json_encode( $value, $flags = 0, $depth = 512 ) {
$json = json_encode( $value, $flags, $depth );
@@ -8178,6 +8184,8 @@ function wp_raise_memory_limit( $context = 'admin' ) {
* @since 7.0.0 Uses wp_rand if available.
*
* @return string UUID.
+ *
+ * @phpstan-return lowercase-string&non-falsy-string
*/
function wp_generate_uuid4() {
static $backup_randomizer = false;
@@ -8193,7 +8201,8 @@ function wp_generate_uuid4() {
$randomizer = $backup_randomizer;
}
- return sprintf(
+ /** @var lowercase-string&non-falsy-string $uuid The %x conversion only produces lowercase hex digits. */
+ $uuid = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
$randomizer( 0, 0xffff ),
$randomizer( 0, 0xffff ),
@@ -8204,6 +8213,8 @@ function wp_generate_uuid4() {
$randomizer( 0, 0xffff ),
$randomizer( 0, 0xffff )
);
+
+ return $uuid;
}
/**
@@ -9212,6 +9223,8 @@ function clean_dirsize_cache( $path ) {
* @since 6.7.0
*
* @return string The current WordPress version.
+ *
+ * @phpstan-return non-falsy-string
*/
function wp_get_wp_version() {
static $wp_version;
@@ -9220,6 +9233,7 @@ function wp_get_wp_version() {
require ABSPATH . WPINC . '/version.php';
}
+ /** @var non-falsy-string $wp_version */
return $wp_version;
}
@@ -9479,6 +9493,8 @@ function wp_is_heic_image_mime_type( $mime_type ) {
*
* @param string $message The message to hash.
* @return string The hash of the message.
+ *
+ * @phpstan-return non-falsy-string
*/
function wp_fast_hash(
#[\SensitiveParameter]
diff --git a/wp-includes/icons.php b/wp-includes/icons.php
index 05588c3cf4..156592e8d6 100644
--- a/wp-includes/icons.php
+++ b/wp-includes/icons.php
@@ -25,6 +25,8 @@
* via {@see wp_get_icon()}. Default true.
* }
* @return bool True if the icon collection was registered successfully, else false.
+ *
+ * @phpstan-param lowercase-string&non-empty-string $slug
*/
function wp_register_icon_collection( $slug, $args ) {
return WP_Icon_Collections_Registry::get_instance()->register( $slug, $args );
@@ -65,6 +67,8 @@ function wp_unregister_icon_collection( $slug ) {
* `get_registered_icons()` alongside the name and label.
* }
* @return bool True if the icon was registered successfully, else false.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $icon_name
*/
function wp_register_icon( $icon_name, $args ) {
return WP_Icons_Registry::get_instance()->register( $icon_name, $args );
@@ -125,6 +129,14 @@ function _wp_register_default_icons() {
return;
}
+ /**
+ * @var array<lowercase-string&non-falsy-string, array{
+ * label: string,
+ * filePath: non-empty-string,
+ * collections: non-empty-list<lowercase-string&non-falsy-string>,
+ * keywords?: list<string>
+ * }> $collection
+ */
$collection = include $manifest_path;
if ( empty( $collection ) ) {
diff --git a/wp-includes/link-template.php b/wp-includes/link-template.php
index 4a7300f5bf..a35203c65e 100644
--- a/wp-includes/link-template.php
+++ b/wp-includes/link-template.php
@@ -4898,8 +4898,11 @@ function get_the_privacy_policy_link( $before = '', $after = '' ) {
* @since 6.2.0
*
* @return string[] An array of URL hosts.
+ *
+ * @phpstan-return list<lowercase-string>
*/
function wp_internal_hosts() {
+ /** @var list<lowercase-string>|null $internal_hosts */
static $internal_hosts;
if ( empty( $internal_hosts ) ) {
@@ -4916,8 +4919,10 @@ function wp_internal_hosts() {
wp_parse_url( home_url(), PHP_URL_HOST ),
)
);
- $internal_hosts = array_unique(
- array_map( 'strtolower', (array) $internal_hosts )
+ $internal_hosts = array_values(
+ array_unique(
+ array_map( 'strtolower', (array) $internal_hosts )
+ )
);
}
diff --git a/wp-includes/pluggable.php b/wp-includes/pluggable.php
index 4126f25d7c..d13769cf84 100644
--- a/wp-includes/pluggable.php
+++ b/wp-includes/pluggable.php
@@ -2540,6 +2540,8 @@ if ( ! function_exists( 'wp_create_nonce' ) ) :
*
* @param string|int $action Scalar value to add context to the nonce.
* @return string The token.
+ *
+ * @phpstan-return lowercase-string&non-falsy-string
*/
function wp_create_nonce( $action = -1 ) {
$user = wp_get_current_user();
@@ -2722,6 +2724,8 @@ if ( ! function_exists( 'wp_hash' ) ) :
* @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce).
* @param string $algo Hashing algorithm to use. Default: 'md5'.
* @return string Hash of $data.
+ *
+ * @phpstan-return lowercase-string&non-falsy-string
*/
function wp_hash( $data, $scheme = 'auth', $algo = 'md5' ) {
$salt = wp_salt( $scheme );
diff --git a/wp-includes/post.php b/wp-includes/post.php
index 3708c578ea..a95288700b 100644
--- a/wp-includes/post.php
+++ b/wp-includes/post.php
@@ -1453,6 +1453,8 @@ function _wp_privacy_statuses() {
* Default to false.
* }
* @return object
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $post_status
*/
function register_post_status( $post_status, $args = array() ) {
global $wp_post_statuses;
@@ -1828,6 +1830,8 @@ function get_post_types( $args = array(), $output = 'names', $operator = 'and' )
* }
* @return WP_Post_Type|WP_Error The registered post type object on success,
* WP_Error object on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $post_type
*/
function register_post_type( $post_type, $args = array() ) {
global $wp_post_types;
diff --git a/wp-includes/rewrite.php b/wp-includes/rewrite.php
index 976d2a014b..06c4a96507 100644
--- a/wp-includes/rewrite.php
+++ b/wp-includes/rewrite.php
@@ -247,6 +247,8 @@ function remove_permastruct( $name ) {
* @param string $feedname Feed name. Should not start with '_'.
* @param callable $callback Callback to run on feed display.
* @return string Feed action name.
+ *
+ * @phpstan-return non-falsy-string
*/
function add_feed( $feedname, $callback ) {
global $wp_rewrite;
diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php
index c8505d9d0c..2d839af4a1 100644
--- a/wp-includes/script-loader.php
+++ b/wp-includes/script-loader.php
@@ -3521,6 +3521,8 @@ function wp_enqueue_editor_format_library_assets() {
*
* @param array<string, string|bool> $attributes Key-value pairs representing `<script>` tag attributes.
* @return string String containing `<script>` opening and closing tags.
+ *
+ * @phpstan-return non-falsy-string
*/
function wp_get_script_tag( $attributes ) {
/**
diff --git a/wp-includes/shortcodes.php b/wp-includes/shortcodes.php
index 2727a992fa..bd5f74a1ec 100644
--- a/wp-includes/shortcodes.php
+++ b/wp-includes/shortcodes.php
@@ -59,6 +59,8 @@ $shortcode_tags = array();
* including an array of attributes (`$atts`), the shortcode content
* or null if not set (`$content`), and finally the shortcode tag
* itself (`$shortcode_tag`), in that order.
+ *
+ * @phpstan-param non-empty-string $tag
*/
function add_shortcode( $tag, $callback ) {
global $shortcode_tags;
@@ -322,6 +324,8 @@ function _filter_do_shortcode_context() {
*
* @param array $tagnames Optional. List of shortcodes to find. Defaults to all registered shortcodes.
* @return string The shortcode search regular expression.
+ *
+ * @phpstan-return non-falsy-string
*/
function get_shortcode_regex( $tagnames = null ) {
global $shortcode_tags;
@@ -591,6 +595,8 @@ function unescape_invalid_shortcodes( $content ) {
* @since 4.4.0
*
* @return string The shortcode attribute regular expression.
+ *
+ * @phpstan-return non-falsy-string
*/
function get_shortcode_atts_regex() {
return '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|\'([^\']*)\'(?:\s|$)|(\S+)(?:\s|$)/';
diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php
index 1159ca64e6..ea13e99271 100644
--- a/wp-includes/taxonomy.php
+++ b/wp-includes/taxonomy.php
@@ -518,6 +518,8 @@ function is_taxonomy_hierarchical( $taxonomy ) {
* Default false.
* }
* @return WP_Taxonomy|WP_Error The registered taxonomy object on success, WP_Error object on failure.
+ *
+ * @phpstan-param lowercase-string&non-falsy-string $taxonomy
*/
function register_taxonomy( $taxonomy, $object_type, $args = array() ) {
global $wp_taxonomies;
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 4d9f1df09e..04f87dafb3 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-alpha-64234';
+$wp_version = '7.2-alpha-64235';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.