Giter Site home page Giter Site logo

php-stubs / wordpress-stubs Goto Github PK

View Code? Open in Web Editor NEW
131.0 131.0 19.0 8.52 MB

Up-to-date WordPress function and class declaration stubs for static analysis by PHPStan

Home Page: https://packagist.org/packages/php-stubs/wordpress-stubs

License: MIT License

PHP 99.91% Shell 0.09%
definitions phpstan static-analysis stubs wordpress

wordpress-stubs's People

Contributors

giacocorsiglia avatar gin0115 avatar herndlm avatar iandelmar avatar janw-me avatar johnbillion avatar lipemat avatar localheinz avatar mociof avatar swissspidy avatar szepeviktor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wordpress-stubs's Issues

PHPStan documentation of wp_update_post() seems to be too restrictive

Since wordpress-stubs 6.0.2 PHPstan triggers errors when we pass $args parameter as an object to wp_update_post() function as it's allowed.
https://github.com/WordPress/WordPress/blob/6.0.2/wp-includes/post.php#L4703-L4718

The issue is closer than @Chouby one, however it seems to us that the PHPStan documentation isn't correct in the wp_update_post() function case.

for example

$post = get_post( $post_id );
$post->post_status = 'draft';
wp_update_post( $post );

triggers

 ------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  178    Parameter #1 $postarr of function wp_update_post expects array{ID?: int, post_author?: int, post_date?: string, post_date_gmt?: string, post_content?: string, post_content_filtered?: string, post_title?: string, post_excerpt?: string, ...}, WP_Post given.
 ------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

`WP_Filesystem_Base::dirlist` returns an array<array>

Types from PHPDocs

@return array|false {                                                                                  
    Array of files. False if unable to list directory contents.                                        
                                                                                                       
    @type string $name        Name of the file or directory.                                           
    @type string $perms       *nix representation of permissions.                                      
    @type string $permsn      Octal representation of permissions.                                     
    @type string $owner       Owner name or ID.                                                        
    @type int    $size        Size of file in bytes.                                                   
    @type int    $lastmodunix Last modified unix timestamp.                                            
    @type mixed  $lastmod     Last modified month (3 letter) and day (without leading 0).              
    @type int    $time        Last modified time.                                                      
    @type string $type        Type of resource. 'f' for file, 'd' for directory.                       
    @type mixed  $files       If a directory and `$recursive` is true, contains another array of files.
}       

Types inferred in stubs

 @phpstan-return false|array{          
   name: string,                       
   perms: string,                      
   permsn: string,                     
   owner: string,                      
   size: int,                          
   lastmodunix: int,                   
   lastmod: mixed,                     
   time: int,                          
   type: string,                       
   files: mixed,                       
 }                                     

Actual return type

false|array<string, array<{          
   name: string,                       
   perms: string,                      
   permsn: string,                     
   owner: string,                      
   size: int,                          
   lastmodunix: int,                   
   lastmod: mixed,                     
   time: int,                          
   type: string,                       
   files: mixed,                       
 }>

Notice the code returns a multidimensional array, not a single associative array.

https://github.com/WordPress/WordPress/blob/e3d1a1291fd3bbfdca3af409e8007d35f2109fa4/wp-admin/includes/class-wp-filesystem-direct.php#L670

Same issue in classes which use the base interface:

  1. WP_Filesystem_Direct
  2. WP_Filesystem_FTPext
  3. WP_Filesystem_MockFS
  4. WP_Filesystem_SSH2
  5. WP_Filesystem_ftpsockets

PHP8.1 "readonly" function

As of PHP 8.1 "readonly" is a reserved keyword.

WP has a "function readonly" (as of WP 5.9/trunk it will be moved to the php-compat file and renamed in the main file).

Problem however:
the "readonly" function will be there in WP 5.9 stubs still (since it's still in WP core, just in php-compat file).

if you run psalm (phpstan?) with phpVersion=8.1, this will however trigger multiple ParseError for the stubs
(e.g. Syntax error, unexpected ')' on line 98413)

DocblockTypeContradiction with get_settings_errors()

The get_settings_errors() returns an array of setting errors but WordPress' docblock incorrectly returns a single setting error which causes a contradiction such as in Psalm:

ERROR: DocblockTypeContradiction - includes/class-admin-controller.php:262:7 - Operand of type false is always false (see https://psalm.dev/155)
	    	! get_settings_errors( self::OPTIONS_KEY )

I've submitted a ticket with a patch to address it.

Until then, is there a way to introduce exceptions within this package?

   * }
-  * @phpstan-return array{
-  *   setting: string,
-  *   code: string,
-  *   message: string,
-  *   type: string,
-  * }
-  */
+  * @phpstan-return array<int|string, array{
+  *   setting: string,
+  *   code: string,
+  *   message: string,
+  *   type: string,
+  * }>
   */
  function get_settings_errors($setting = '', $sanitize = \false)

WP_UnitTestCase and other WordPress testing classes

WordPress stubs is great and a massive help in my day to day development!

At the moment I'm struggling with a bunch of undefined errors because I have no way of referencing (primary) the WP_UnitTestCase class anywhere within my plugin or theme files.

Is there the possibility of adding support for classes like WP_UnitTestCase in php-stubs/wordpress-stubs?

WP_CLI stubs

First of, great great repo that helps getting WP plugins properly checked.

Would it be possible to add stubs for the WP_CLI class?
As I have a few plugins that add a WP_CLI (sub)command. (which are now reported as UndefinedClass bc of missing stub)

Add GitHub Actions to automate updating stubs

It would be nice if this was done in a weekly or so GitHub action that could perhaps also be run manually if needed.

That would make maintenance a breeze.

I might take a stab at it if I find some spare time and if this is something you're interested in.

Undefined function errors

I get undefined function errors for loads of function in my plugin, e.g. when using wc_get_product within my plugin.

Is there any way to solve this (without generating woocommerce stubs)?

EDIT: wouldnt it make more sense to use a clone WP repo with all dependency plugins and use an autoloader instead of stubbing like we do now? This would resolve this problem, wouldn't it?

add_meta_box() function map is not accurate

Regarding the add_meta_box() documentation, the $context parameter is not limited to "normal"|"side"|"advanced" IMHO.
Indeed, anyone can create a new WP_Screen and thus define its own context for which to display meta boxes in do_meta_boxes() (see: https://github.com/WordPress/wordpress-develop/blob/01ba03de1d208492608b36d21aa90a8389f32ded/src/wp-admin/includes/template.php#L1247).

Source of the change:

'add_meta_box' => ['void', 'context'=>'"normal"|"side"|"advanced"', 'priority'=>'"high"|"core"|"default"|"low"'],

Pluggable functions non-pluggable in stubs

Every function from the pluggable.php file in WP core is wrapped in an if ( ! function_exist ) block. The stubs for these should ideally be treated the same. This will allow use for the wordpress stubs outside of the current scope. Specifically if being applied to a larger project scope than plugin/theme alone.

Add type declarations to WP_Widget methods

I'm using intelephense with VS Code and am aiming to add type declarations to my widget methods. Intelephense supposedly uses this repo for its wordpress stubs.

When I add a type to my form method, I get an error, because the stubs don't have types.

For example:

/**
 * Creates the backend form in the customizer
 */
public function form(array $instance): string {
  // echo stuff to create the form
  return '';
}

Shows the error:

Intelephense: Method 'My_Widget::form()' is not compatible with method 'WP_Widget::form()'

May I submit a PR with types added to at least these widget methods?

False positive: Function apply_filters invoked with 3 parameters, 2 required.

apply_filters requires at least two arguments, but it can accept more as well.

The problem is that this information is only in the PHPDoc, while the function signature is just function apply_filters($tag, $value).

For instance, do_action requires at least one argument (the hook tag), but, like apply_filters, it can accept more arguments and this is specified in both the PHPDoc and the function signature: function do_action($tag, ...$arg).

This causes problems when the WP stubs are used in projects where apply_filters is called with more than two arguments.

A quick tweak to the stub file solved the issue: function apply_filters( $tag, $value, ...$args ) {.

However, I don't know if it's the right thing to do and since the stub file is generated, I suppose it might not be that easy to modify the output with that fix.

6.4 new see tag

-         * @param array   $args              An array of arguments. @see wp_terms_checklist()
+         * @param array   $args              An array of arguments. See {@see wp_terms_checklist()}.

It makes phpstan-param tag disappear.
@johnbillion Please help me. You are WordPress for me.

1ad360f 👀

Fix page link types

$ grep -Erni 'bool\s+\$(prev_text|next_text)'
wp-includes/general-template.php:4200: *     @type bool   $prev_text          The previous page text. Default '&laquo; Previous'.
wp-includes/general-template.php:4201: *     @type bool   $next_text          The next page text. Default 'Next &raquo;'.

Replace bool with string.

@johnbillion Does core trac have a ticket for this?

Incorrect stubs since >5.9.3 + mismatch between packagist.org and GitHub

There seems to be something broken since the 5.9.4 release.

I noticed this because psalm started to report missing classes from the included PHPMailer package.

v5.9.3 has the correct stubs for PHPMailer, since 5.9.4 they are missing.

Check out the two branches in this reproduction repo:

https://github.com/calvinalkan/stubs-bug

Now, here comes the weird part.

The file in the GitHub repo:

https://raw.githubusercontent.com/php-stubs/wordpress-stubs/master/wordpress-stubs.php

does contain the PHPMailer namespace.

So there seems to be a mismatch between the code in the GitHub repo and the code that is downloaded from packagist.

I have no idea why this is happening. Maybe you can try synching the package again in the packagist UI

Ondřej says: It doesn't make sense to combine void with something else in a union type.

We have a few of string|void-s:

'single_term_title' => ['($display is true ? void : string|void)'],
'single_cat_title' => ['($display is true ? void : string|void)'],
'single_month_title' => ['($display is true ? false|void : false|string)'],
'single_post_title' => ['($display is true ? void : string|void)'],
'single_tag_title' => ['($display is true ? void : string|void)'],

phpstan/phpstan#9288

stubs for release candidates

It would be greatly appreciated, if you could also provide the stubs of RC/release candidates, so we can check if anything changed in newer versions before they are released.

Great project!

functionMap.php wrong

ac0c474

the functionMap changes here seem to be mostly wrong - the param is called $index not $offset for e.g. offsetExists

Then for some reason there is a new functionMap file created for 6.2 where those changes are missing altogether?

Tests for functionMap.php

As the function map expands, we should incorporate some checks. I suggest:

  • Relocating the parameter name check outside the visitor.
  • Verifying whether types have already been added through other parts of the visitor.
  • Ensuring the uniqueness of map entries.
  • Checking for unmatched parentheses.

Does anyone know when Request v2 will be part of core?

https://core.trac.wordpress.org/changeset/54997 👀

Need to update this:

# Add ReturnTypeWillChange attribute to PHP 8-incompatible methods.
declare -r -a REQUESTS_V1_METHODS=(
"Requests_Cookie_Jar::getIterator"
"Requests_Cookie_Jar::offsetExists"
"Requests_Cookie_Jar::offsetGet"
"Requests_Cookie_Jar::offsetSet"
"Requests_Cookie_Jar::offsetUnset"
"Requests_Utility_CaseInsensitiveDictionary::getIterator"
"Requests_Utility_CaseInsensitiveDictionary::offsetExists"
"Requests_Utility_CaseInsensitiveDictionary::offsetGet"
"Requests_Utility_CaseInsensitiveDictionary::offsetSet"
"Requests_Utility_CaseInsensitiveDictionary::offsetUnset"
"Requests_Utility_FilteredIterator::current"
"Requests_Utility_FilteredIterator::__unserialize"
"Requests_Utility_FilteredIterator::unserialize"
)
for METHOD in "${REQUESTS_V1_METHODS[@]}"; do
# Get the line number where the method is defined.
LINE="$(php -r "require 'wordpress-stubs.php'; print (new ReflectionMethod('${METHOD}'))->getStartLine();")"
if [ -z "${LINE}" ]; then
continue
fi
echo "${METHOD} is defined on line ${LINE}."
# Check the previous line forr ReturnTypeWillChange attribute.
if sed -e "$((LINE - 1)) !d" "${FILE}" | grep -q -F '#[ReturnTypeWillChange]'; then
continue
fi
# Grab leading whitespace on the current line so we can indent ReturnTypeWillChange correctly.
LEADING_WHITESPACES="$(sed -e "${LINE} !d;s#^\\(\\s\\+\\).*\$#\\1#" "${FILE}")"
# Insert the ReturnTypeWillChange attribute.
sed -i -e "${LINE} i\\" -e "${LEADING_WHITESPACES}#[ReturnTypeWillChange]" "${FILE}"
done

Why globals are not included?

The question as in title: why globals are not included? They would be handy, because some WordPress plugins are using globals. Without stubs with globals, the tool I use for static code analysis will not be able to resolve them in analyzed code.

Using `literal-string` for `wpdb::prepare()`

Both Psalm 4.8 and PHPStan 0.12.97 have the literal-string type, which can be used to ensure a string is defined by the developer (i.e. does not contain any user values). This is really useful and simple way to prevent SQL Injection Vulnerabilities.

I have created patches for #52506 so identifiers (table/field names) can be escaped via a new %i parameter; and #54042 makes it easier/safer to do WHERE id IN (%...d) style queries.

Hopefully these will be accepted for WordPress 6.1. I've had a few reviews already, and the first patch will be discussed at the next "Early Scrub" meeting (on the 19th May 2022, 18:00 UTC on the Slack #core channel.

Both of these patches will allow the $query parameter to be a literal-string, e.g.

$wpdb->prepare('SELECT * FROM %i WHERE ID IN (%...d)', $table, $ids);

While it might be worth waiting for WordPress 6.1... would it be ok to try setting @param literal-string $query on the wpdb::prepare() method?

InvalidTag is not handled

@johnbillion in "johnpbloch/wordpress": "4.7.23" there is an invalid param tag.
wp-includes/class-wp-term-query.php:297: * @param 4.6.0

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to class@anonymous::getAdditionFromParam() must be an instance of phpDocumentor\Reflection\DocBlock\Tags\Param, instance of phpDocumentor\Reflection\DocBlock\Tags\InvalidTag given, called in /home/viktor/src/php-stubs/wordpress-stubs/visitor.php on line 113 and defined in /home/viktor/src/php-stubs/wordpress-stubs/visitor.php:178

https://github.com/php-stubs/wordpress-stubs/blob/master/visitor.php#L112

I'm trying to fix it...

stubs for wpdb::get_row() and wpdb::get_results() are wrong

I think we should have the following

--- a/tests/data/wpdb.php
+++ b/tests/data/wpdb.php
@@ -10,12 +10,12 @@ use function PHPStan\Testing\assertType;
 // wpdb::get_row()
 assertType('stdClass|void|null', wpdb::get_row());
 assertType('stdClass|void|null', wpdb::get_row(null, 'OBJECT'));
-assertType('array<string, mixed>|void|null', wpdb::get_row(null, 'ARRAY_A'));
-assertType('array<int, mixed>|void|null', wpdb::get_row(null, 'ARRAY_N'));
+assertType('array<mixed>|void|null', wpdb::get_row(null, 'ARRAY_A'));
+assertType('list<mixed>|void|null', wpdb::get_row(null, 'ARRAY_N'));

 // wpdb::get_results()
 assertType('stdClass|null', wpdb::get_results());
 assertType('stdClass|null', wpdb::get_results(null, 'OBJECT'));
-assertType('array<string, stdClass>|null', wpdb::get_results(null, 'OBJECT_K'));
-assertType('array<string, mixed>|null', wpdb::get_results(null, 'ARRAY_A'));
-assertType('array<int, mixed>|null', wpdb::get_results(null, 'ARRAY_N'));
+assertType('stdClass|null', wpdb::get_results(null, 'OBJECT_K'));
+assertType('list<array<mixed>>|null', wpdb::get_results(null, 'ARRAY_A'));
+assertType('list<list<mixed>>|null', wpdb::get_results(null, 'ARRAY_N'));

the changes for get_row() are just improvements:

  • I would use array<mixed> instead of array<string, mixed> because the keys will be int if they are numeric-strings
  • list is a narrower type that is also correct

get_results() on the other hand has a fix:

  • it seems to never return an object, WP is lying there. it always returns an array of rows and the rows are either object or array sorry my bad, this is not true
  • it also returns an object for OBJECT_K
  • the rest are the same improvements as mentioned above

bonus improvement:

  • the null return type is interesting. according to code and some playing around it seems to only occur if either the $query arg is null or the $output arg is invalid (none of the supported output "modes"). I don't consider this important.

briefly tried fixing it myself, but failed, too much magic already and I ran out of time :)

PHP Deprecated: Return type of Requests_* on 8.1 with PHPStan

PHP Deprecated:  Return type of Requests_Utility_FilteredIterator::unserialize($serialized) should either be compatible with ArrayIterator::unserialize(string $data): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 21682
Deprecated: Return type of Requests_Utility_FilteredIterator::unserialize($serialized) should either be compatible with ArrayIterator::unserialize(string $data): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 21682
PHP Deprecated:  Return type of Requests_Utility_FilteredIterator::__unserialize($serialized) should either be compatible with ArrayIterator::__unserialize(array $data): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 21690
Deprecated: Return type of Requests_Utility_FilteredIterator::__unserialize($serialized) should either be compatible with ArrayIterator::__unserialize(array $data): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 21690
PHP Deprecated:  Return type of Requests_Utility_FilteredIterator::current() should either be compatible with ArrayIterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 21676
Deprecated: Return type of Requests_Utility_FilteredIterator::current() should either be compatible with ArrayIterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 21676
PHP Deprecated:  Return type of Requests_Cookie_Jar::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18918
Deprecated: Return type of Requests_Cookie_Jar::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18918
PHP Deprecated:  Return type of Requests_Cookie_Jar::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18927
Deprecated: Return type of Requests_Cookie_Jar::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18927
PHP Deprecated:  Return type of Requests_Cookie_Jar::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18938
Deprecated: Return type of Requests_Cookie_Jar::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18938
PHP Deprecated:  Return type of Requests_Cookie_Jar::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18946
Deprecated: Return type of Requests_Cookie_Jar::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18946
PHP Deprecated:  Return type of Requests_Cookie_Jar::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18954
Deprecated: Return type of Requests_Cookie_Jar::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 18954
PHP Deprecated:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20909
Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20909
PHP Deprecated:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20918
Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20918
PHP Deprecated:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20929
Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20929
PHP Deprecated:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20937
Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20937
PHP Deprecated:  Return type of Requests_Utility_CaseInsensitiveDictionary::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20945
Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/www/VVV/www/woocommerce/public_html/wp-content/plugins/plugin/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php on line 20945

With PHP 8.1 I am getting all those warning. I know that WP itself doesn't support that version but they are very annoying so I wasn't sure if it was to fix there instead on the phpstan-wordpress package.

Maybe it is possible to add #[\ReturnTypeWillChange] comment on the stubs for those methods so this error is silenced until WP support that version.

Add "require" packages

  • php >= 5.6
  • "suggest"? ext-sodium
  • phpmailer/phpmailer 6.1.6
  • and exclude wp-includes/PHPMailer

Problem: this is only for v5.5.0+

composer require --dev "james-heinrich/getid3:1.9.21"
# Add to bootstrapFiles: vendor/james-heinrich/getid3/getid3/getid3.php
composer require --dev "phpmailer/phpmailer:6.6.0"
composer require --dev "simplepie/simplepie:1.5.8"
composer require --dev "rmccue/requests:1.8.1"

Using `literal-string` for `wpdb::prepare()`

Both Psalm 4.8 and PHPStan 0.12.97 have the literal-string type, which can be used to ensure a string is defined by the developer (i.e. does not contain any user values). This is really useful and simple way to prevent SQL Injection Vulnerabilities.

I have created patches for #52506 so identifiers (table/field names) can be escaped via a new %i parameter; and #54042 makes it easier/safer to do WHERE id IN (%...d) style queries.

Hopefully these will be accepted for WordPress 6.1. I've had a few reviews already, and the first patch will be discussed at the next "Early Scrub" meeting (on the 19th May 2022, 18:00 UTC on the Slack #core channel.

Both of these patches will allow the $query parameter to be a literal-string, e.g.

$wpdb->prepare('SELECT * FROM %i WHERE ID IN (%...d)', $table, $ids);

While it might be worth waiting for WordPress 6.1... would it be ok to try setting @param literal-string $query on the wpdb::prepare() method?

Check if function exists in wordpress-stubs.php

Hello,

When using WordPress as a composer dependency (with Bedrock), the phpstan command results to

Fatal error: Cannot redeclare wp_hash_password() (previously declared in xxx/vendor/roots/wp-password-bcrypt/wp-password-bcrypt.php:70). It is the same for wp_check_password and wp_set_password

The workaround I found is to encapsulate them with a function_exists in the wordpress-stubs/wordpress-stubs.php. Do you think you could add this to the code? I can make a PR if you want.

Thanks

php deprication notices in 8.1

When running php8.1 to run phpstan I get 24 Deprication notices.
I have not tested 8.0, these notices do not appear on 7.4

These can be fixed. And I'm up for that.
I've checked a couple and these fixed will cause errors when lower then running php7.0.

So would you be open for a PR with these fixes of 8+ notices at the cost of dropping support of 5.6 and lower.

To be clear, I'm not talking about the version you set in phpstan.neon.dist I'm talking about the php cli version.

How to avoid getting errors for drop-in classes?

e.g. class WP_Object_Cache dropin overwrites the native class.

If you now redefine a function, e.g. flush to accept 2 instead of 1 arg (like WP default), it will obviously give an error now.

Is there any way to solve this?

Include `wp-includes/compat.php`

Right now compat functions WordPress ships with, such as str_contains, are excluded from the stubs.

That means when a project's PHP version is < 8.0, PHPStan thinks the function does not exist and will report an error, even though WP actually provides this compat version

I can of course simply ignore the error in my config, but in my quick testing it seems like it should possible to include wp-includes/compat.php in the stubs, so that PHPStan will pick them up— as long as they are all still wrapped in function_exists() checks

Previously/related: #20 (though readonly is special because it's a syntax clash

Implement short inline syntax for array parameters and return values

Neither PHPStan nor Psalm support the hash-style notation used by WordPress for its array parameters and array return values.

@param array $args {
    Array of arguments used to display the help tab.

    @type string   $title    Title for the tab. Default false.
    @type string   $id       Tab ID. Must be HTML-safe and should be unique for this menu.
                             It is NOT allowed to contain any empty spaces. Default false.
    @type string   $content  Optional. Help tab content in plain text or HTML. Default empty string.
    @type callable $callback Optional. A callback to generate the tab content. Default false.
    @type int      $priority Optional. The priority of the tab, used for ordering. Default 10.
}

This means there's currently no way to inform static analysis tools of the types of the array elements passed to or returned by functions such as wp_remote_post() and classes such as WP_Query.

It would be great to:

  1. Post-process the stubs after they're generated and convert hash-style array notation in the docblocks into short inline syntax. Example:
    - * @param array $args {
    - *     Array of arguments used to display the help tab.
    - *
    - *     @type string   $title    Title for the tab. Default false.
    - *     @type string   $id       Tab ID. Must be HTML-safe and should be unique for this menu.
    - *                              It is NOT allowed to contain any empty spaces. Default false.
    - *     @type string   $content  Optional. Help tab content in plain text or HTML. Default empty string.
    - *     @type callable $callback Optional. A callback to generate the tab content. Default false.
    - *     @type int      $priority Optional. The priority of the tab, used for ordering. Default 10.
    - * }
    + * @param array{
    + *     title?: string,
    + *     id?: string,
    + *     content?: string,
    + *     callback?: callable,
    + *     priority?: int,
    + * } $args
  2. Create a mapping from function parameters such as wp_remote_post() $args to their canonical function parameter such as WP_Http::request() $args and then apply the same docblock from the canonical function in its wrapper functions. This allows for parameter type checking in wrapper functions which are more commonly used. This likely needs to happen as a separate second step as it will be a manual process to create the mapping. WordPress core isn't well documented or consistently documented in this regard.

Approach

It's possible that johnbillion/wp-parser-lib could be used to aid the transformation as it's able to tokenise the hash style array notation.

Considerations

Unfortunately the short inline syntax supported by PHPStan and Psalm don't allow for human-readable documentation of the array elements. This means the stubs will be better for PHPStan and Psalm but worse for humans. Maybe two sets of stubs needs to be created, one with the human-readable docblock from core and one with the short inline syntax for use in static analysis.

Refs

How do you add this to an IDE

I'm using PHPStorm and I was hoping this would help with code completion while developing WP Plugins.
Is it possible to use it for that purpose?

False positive when slashing data for wp_insert_post() and wp_update_post()

wp_insert_post() is expecting slashed data. So I'm used to prepare data passed to wp_insert_post() and wp_update_post() with wp_slash().
Here is a small sample to demonstrate the issue:

$post = get_post( $post_id, ARRAY_A );
$post['post_status'] = 'draft';
wp_update_post( wp_slash( $post ) );

Since the version 6.0.2 (I suppose since #49), PHPStan reports the following error on:

Parameter #1 $postarr of function wp_update_post expects
  array{ID?: int, post_author?: int, post_date?: string, post_date_gmt?: string, post_content?: string, post_content_filtered?: string, post_title?: string, post_excerpt?: string, ...},
  array<string, string> given.

If I remove wp_slash(), PHPstan would report nothing.

Widget::widget() has never return type

The Widget::widget() method has a return type of never because in WP it's a stub it terminates execution if a developer hasn't overridden the method. Not sure how you'd go about avoiding this for stub implementations.

Improve types for `WP_REST_Request`

Right now in my project I have a bunch of REST controllers that take some request params and then do something with them. With WP_REST_Request implementing ArrayAccess and things like $request['foo'] being mixed, I need to use inline @var tags to tell PHPStan what type I am expecting.

Example:

/**
 * @param WP_REST_Request $request Full details about the request.
 * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure.
 */
public function create_item( $request ) {
	/**
	 * Parent post.
	 *
	 * @var int $parent_post
	 */
	$parent_post = ! empty( $request['post'] ) ? $request['post'] : null;

	/**
	 * Field to order by.
	 *
	 * @var string $orderby
	 */
	$orderby = ! empty( $request['orderby'] ) ? $request['orderby'] : 'date';

	// ...
}

That works fine so far.

However, with PHPStan 1.10 there is an effort underway to get rid of these inline @var tags. The suggestion is to fix the wrong 3P docblocks instead of having to provide these inline tags myself.

So how can we fix the WP_REST_Request docblocks? I am asking this here because this can be done at the stub level and there's no need for a custom PHPStan extension.

According to this post we should be able to add something like this to WP_REST_Request in the stubs:

/**
 * @template T
 * @implements Collection<T>
 */

Note: the same goes for WP_Theme, which also implements ArrayAccess

Custom HTML attribute in wp_get_attachment_image() call

I'm getting the following PHP stan error:

image

It looks to be due to how the function (wp_get_attachment_image) PHP doc is defined in https://github.com/php-stubs/wordpress-stubs/blob/master/wordpress-stubs.php

Here's how the function is being used:

image

As per the doc this is fine...the last param should be able to take a string or array: https://developer.wordpress.org/reference/functions/wp_get_attachment_image/

@szepeviktor Are we doing something wrong?

Handle `@type` tags without static keys

eg this @type tag with the ...$0 dynamic keys notation:

* @return array[] {
*     Array of meta data arrays for the given post ID.
*
*     @type array ...$0 {
*         Associative array of meta data.
*
*         @type string $meta_key   Meta key.
*         @type mixed  $meta_value Meta value.
*         @type string $meta_id    Meta ID as a numeric string.
*         @type string $post_id    Post ID as a numeric string.
*     }
* }

should result in this tag being added:

* @phpstan-return array<int|string,array{
*   meta_key: string,
*   meta_value: mixed,
*   meta_id: string,
*   post_id: string,
* }>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.