Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion functionMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
'absint' => ['($maybeint is T&int<0, max> ? T : ($maybeint is int<min, -1> ? int<1, max> : ($maybeint is empty ? 0 : ($maybeint is numeric-string ? int<0, max> : ($maybeint is string ? 0 : ($maybeint is true|non-empty-array ? 1 : ($maybeint is bool ? 0|1 : int<0, max>)))))))', '@phpstan-template T' => 'of int', 'maybeint' => 'T|scalar|array|resource|null'],
'add_comments_page' => [null, 'callback' => "''|callable"],
'add_dashboard_page' => [null, 'callback' => "''|callable"],
'add_link' => ['int<0, max>'],
'add_links_page' => [null, 'callback' => "''|callable"],
'add_management_page' => [null, 'callback' => "''|callable"],
'add_media_page' => [null, 'callback' => "''|callable"],
Expand All @@ -59,12 +60,14 @@
'comment_class' => ['($display is true ? void : string)'],
'current_time' => ["(\$type is 'timestamp'|'U' ? int : string)"],
'did_action' => ['int<0, max>'],
'edit_link' => ['int<0, max>'],
'edit_term_link' => ['($display is true ? void : string|void)'],
'get_approved_comments' => ["(\$args is array{count: true}&array ? int : (\$args is array{fields: 'ids'}&array ? array<int, int> : array<int, \WP_Comment>))"],
'get_attachment_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<string, \WP_Taxonomy>)"],
'get_available_post_statuses' => ['list<string>'],
'get_block_wrapper_attributes' => ['($extra_attributes is empty ? string : non-falsy-string)', 'extra_attributes' => 'array<string, string>'],
'get_bookmark' => ["null|(\$output is 'ARRAY_A' ? array<string, mixed> : (\$output is 'ARRAY_N' ? array<int, mixed> : \stdClass))", 'output' => "'OBJECT'|'ARRAY_A'|'ARRAY_N'"],
'get_bookmark_field' => ['array<int, int<1, max>>|int|string|\WP_Error', 'field' => "'link_id'|'link_url'|'link_name'|'link_image'|'link_target'|'link_description'|'link_visible'|'link_owner'|'link_rating'|'link_updated'|'link_rel'|'link_notes'|'link_rss'|'link_category'"],
'get_calendar' => ['($args is array{display: false}&array ? string : void)'],
'get_categories' => ["(\$args is array{fields: 'count'}&array ? list<numeric-string> : (\$args is array{fields: 'names'|'slugs'}&array ? list<string> : (\$args is array{fields: 'id=>name'|'id=>slug'}&array ? array<int, string> : (\$args is array{fields: 'id=>parent'}&array ? array<int, int> : (\$args is array{fields: 'ids'|'tt_ids'}&array ? list<int> : array<int, \WP_Term>)))))"],
'get_category' => ["(\$category is object ? array<array-key, mixed>|\WP_Term : array<array-key, mixed>|\WP_Term|\WP_Error|null) & (\$output is 'ARRAY_A' ? array<string, mixed>|\WP_Error|null : (\$output is 'ARRAY_N' ? array<int, mixed>|\WP_Error|null : \WP_Term|\WP_Error|null))", 'output' => "'OBJECT'|'ARRAY_A'|'ARRAY_N'"],
Expand All @@ -74,6 +77,7 @@
'get_compat_media_markup' => ['array{item: string, meta: string}'],
'get_current_blog_id' => ['int<0, max>'],
'get_current_user_id' => ['int<0, max>'],
'get_default_link_to_edit' => ["object{link_url: string, link_name: string, link_visible: 'Y'}&\stdClass", '@phpstan-impure' => ''],
'get_html_split_regex' => ['non-falsy-string'],
'get_object_taxonomies' => ["(\$output is 'names' ? array<int, string> : array<string, \WP_Taxonomy>)"],
'get_page_by_path' => ["(\$output is 'ARRAY_A' ? array<string, mixed>|null : (\$output is 'ARRAY_N' ? array<int, mixed>|null : \WP_Post|null))"],
Expand Down Expand Up @@ -119,6 +123,7 @@
'rest_authorization_required_code' => ['401|403'],
'rest_sanitize_boolean' => ["(T is bool ? T : (T is ''|'false'|'FALSE'|'0'|0 ? false : true))", '@phpstan-template T' => 'of bool|string|int', 'value' => 'T'],
'rest_ensure_response' => ['($response is \WP_Error ? \WP_Error : \WP_REST_Response)'],
'sanitize_bookmark_field' => ['array<int, int>|int|string', 'field' => "'link_id'|'link_url'|'link_name'|'link_image'|'link_target'|'link_description'|'link_visible'|'link_owner'|'link_rating'|'link_updated'|'link_rel'|'link_notes'|'link_rss'|'link_category'"],
'sanitize_category' => ['T', '@phpstan-template' => 'T of array|object', 'category' => 'T'],
'sanitize_post' => ['T', '@phpstan-template' => 'T of array|object', 'post' => 'T'],
'sanitize_sql_orderby' => ['(T is non-falsy-string ? T|false : false)', '@phpstan-template T' => 'of string', 'orderby' => 'T'],
Expand Down Expand Up @@ -159,6 +164,7 @@
'wp_get_archives' => ['($args is array{echo: false|0}&array ? string|void : void)'],
'wp_get_comment_status' => ["'approved'|'spam'|'trash'|'unapproved'|false"],
'wp_get_inline_script_tag' => ['non-falsy-string', 'attributes' => 'array<string, string|true>'],
'wp_get_link_cats' => ['($link_id is empty ? array{} : array<int, int<1, max>>)'],
'wp_get_object_terms' => ["(\$object_ids is empty ? array{} : (\$taxonomies is empty ? array{} : ((\$args is array{fields: 'names'|'slugs'}&array ? list<string> : (\$args is array{fields: 'id=>name'|'id=>slug'}&array ? array<int, string> : (\$args is array{fields: 'id=>parent'}&array ? array<int, int> : (\$args is array{fields: 'ids'|'tt_ids'}&array ? list<int> : (\$args is array{fields: 'count'}&array ? numeric-string : array<int, \WP_Term>)))))|\WP_Error)))"],
'wp_get_post_categories' => ["(\$post_id is 0 ? array{} : ((\$args is array{fields: 'names'|'slugs'}&array ? list<string> : (\$args is array{fields: 'id=>name'|'id=>slug'}&array ? array<int, string> : (\$args is array{fields: 'id=>parent'}&array ? array<int, int> : (\$args is array{fields: 'all'|'all_with_object_id'}&array ? array<int, \WP_Term> : (\$args is array{fields: 'count'}&array ? numeric-string : list<int>)))))|\WP_Error))"],
'wp_get_post_tags' => ["(\$post_id is 0 ? array{} : ((\$args is array{fields: 'names'|'slugs'}&array ? list<string> : (\$args is array{fields: 'id=>name'|'id=>slug'}&array ? array<int, string> : (\$args is array{fields: 'id=>parent'}&array ? array<int, int> : (\$args is array{fields: 'ids'|'tt_ids'}&array ? list<int> : (\$args is array{fields: 'count'}&array ? numeric-string : array<int, \WP_Term>)))))|\WP_Error))"],
Expand Down Expand Up @@ -217,7 +223,7 @@
'wp_unslash' => ['T', '@phpstan-template' => 'T', 'value' => 'T'],
'wp_update_category' => ['int<0, max>|false'],
'wp_update_comment' => ['($wp_error is false ? 0|1|false : 0|1|\WP_Error)'],
'wp_update_link' => ['int<0, max>|\WP_Error'],
'wp_update_link' => ['int<0, max>'],
'wp_update_post' => ['($wp_error is false ? int<0, max> : int<1, max>|\WP_Error)'],
'wp_verify_nonce' => ['1|2|false', 'action' => '-1|string'],
'wp_widget_rss_form' => ['void', 'args' => $wpWidgetRssFormArgsType, 'inputs' => $wpWidgetRssFormInputsType],
Expand Down
19 changes: 19 additions & 0 deletions tests/CallToParameterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,25 @@ public function testAddMenuPage(): void
);
}

public function testBookmarks(): void
{
$field = "'link_category'|'link_description'|'link_id'|'link_image'|'link_name'|'link_notes'|'link_owner'|'link_rating'|'link_rel'|'link_rss'|'link_target'|'link_updated'|'link_url'|'link_visible'";

$this->analyse(
__DIR__ . '/data/bookmark-params.php',
[
["Parameter #1 \$field of function get_bookmark_field expects $field, 'foo' given.", 16],
["Parameter #1 \$field of function get_bookmark_field expects $field, 'foo' given.", 17],
["Parameter #1 \$field of function get_bookmark_field expects $field, int given.", 18],
["Parameter #1 \$field of function sanitize_bookmark_field expects $field, 'foo' given.", 21],
["Parameter #1 \$field of function sanitize_bookmark_field expects $field, int given.", 22],
// Maybes
["Parameter #1 \$field of function get_bookmark_field expects $field, string given.", 30],
["Parameter #1 \$field of function sanitize_bookmark_field expects $field, string given.", 32],
]
);
}

public function testWpdbGetRow(): void
{
$this->analyse(
Expand Down
4 changes: 2 additions & 2 deletions tests/TypeInferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/_get_list_table.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/absint.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/block_version.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bookmark-admin.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bookmark.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bool_from_yn.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/current_time.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/echo_parameter.php');
Expand All @@ -23,7 +25,6 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_attachment_taxonomies.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_available_post_statuses.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_block_wrapper_attributes.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_bookmark.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_categories.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_category.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_category_by_path.php');
Expand Down Expand Up @@ -113,7 +114,6 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_translations.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_unique_id.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_update_category.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_update_link.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_widget_factory.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_widget_rss.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_widgets_access_body_class.php');
Expand Down
56 changes: 56 additions & 0 deletions tests/data/bookmark-admin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace PhpStubs\WordPress\Core\Tests;

use function add_link;
use function edit_link;
use function get_default_link_to_edit;
use function wp_insert_link;
use function wp_update_link;
use function PHPStan\Testing\assertType;

/*
* add_link()
* calls wp_insert_link() with default $wp_error (false)
*/
assertType('int<0, max>', add_link());

/*
* edit_link()
* calls wp_update_link() if ! empty($link_id), wp_insert_link() with default $wp_error (false) otherwise
*/
assertType('int<0, max>', edit_link());
assertType('int<0, max>', edit_link(0));
assertType('int<0, max>', edit_link(123));
assertType('int<0, max>', edit_link(Faker::int()));

/*
* wp_insert_link()
*/
assertType('int<0, max>', wp_insert_link([]));
assertType('int<0, max>', wp_insert_link([], false));
assertType('int<0, max>|WP_Error', wp_insert_link([], true));
assertType('int<0, max>|WP_Error', wp_insert_link([], Faker::bool()));

/*
* wp_update_link()
* calls wp_insert_link() with default $wp_error (false)
*/
assertType('int<0, max>', wp_update_link([]));
assertType('int<0, max>', wp_update_link(['link_id' => 123]));
assertType('int<0, max>', wp_update_link(Faker::array()));

/*
* get_default_link_to_edit()
*/
assertType("object{link_url: string, link_name: string, link_visible: 'Y'}&stdClass", get_default_link_to_edit());

/*
* wp_get_link_cats()
*/
assertType('array{}', wp_get_link_cats());
assertType('array{}', wp_get_link_cats(0));
assertType('array<int, int<1, max>>', wp_get_link_cats(123));
assertType('array<int, int<1, max>>', wp_get_link_cats(Faker::int()));
69 changes: 69 additions & 0 deletions tests/data/bookmark-params.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace PhpStubs\WordPress\Core\Tests;

use function get_bookmark_field;
use function sanitize_bookmark_field;

/*
* Incorrect usage of
* - get_bookmark_field
* - sanitize_bookmark_field
*/

get_bookmark_field('foo', Faker::int()); // incorrect field
get_bookmark_field('foo', Faker::int(), Faker::string()); // incorrect field
get_bookmark_field(Faker::int(), Faker::int(), Faker::string()); // incorrect field

// $context narrowed by Visitor - not part of testing yet
sanitize_bookmark_field('foo', Faker::mixed(), Faker::int(), 'raw'); // incorrect field & correct context
sanitize_bookmark_field(Faker::int(), Faker::mixed(), Faker::int(), 'raw'); // incorrect field & correct context

/*
* Maybe incorrect usage of
* - get_bookmark_field
* - sanitize_bookmark_field
*/

get_bookmark_field(Faker::string(), Faker::int(), Faker::string()); // maybe incorrect field

sanitize_bookmark_field(Faker::string(), Faker::mixed(), Faker::int(), 'raw'); // maybe incorrect field & correct context

/*
* Correct usage of
* - get_bookmark_field
* - sanitize_bookmark_field
*/

get_bookmark_field('link_id', Faker::int()); // correct field
get_bookmark_field('link_url', Faker::int()); // correct field
get_bookmark_field('link_name', Faker::int()); // correct field
get_bookmark_field('link_image', Faker::int()); // correct field
get_bookmark_field('link_target', Faker::int()); // correct field
get_bookmark_field('link_description', Faker::int()); // correct field
get_bookmark_field('link_visible', Faker::int()); // correct field
get_bookmark_field('link_owner', Faker::int()); // correct field
get_bookmark_field('link_rating', Faker::int()); // correct field
get_bookmark_field('link_updated', Faker::int()); // correct field
get_bookmark_field('link_rel', Faker::int()); // correct field
get_bookmark_field('link_notes', Faker::int()); // correct field
get_bookmark_field('link_rss', Faker::int()); // correct field
get_bookmark_field('link_category', Faker::int()); // correct field
get_bookmark_field('link_category', Faker::int(), Faker::string()); // correct field

sanitize_bookmark_field('link_id', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_url', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_name', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_image', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_target', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_description', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_visible', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_owner', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_rating', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_updated', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_rel', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_notes', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_rss', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
sanitize_bookmark_field('link_category', Faker::mixed(), Faker::int(), 'raw'); // correct field & context
37 changes: 37 additions & 0 deletions tests/data/bookmark.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace PhpStubs\WordPress\Core\Tests;

use function get_bookmark;
use function get_bookmark_field;
use function sanitize_bookmark_field;
use function PHPStan\Testing\assertType;

$stdClassOrInt = Faker::union(Faker::stdClass(), Faker::int());

/*
* get_bookmark()
*/

assertType('stdClass|null', get_bookmark($stdClassOrInt));
assertType('stdClass|null', get_bookmark($stdClassOrInt, 'OBJECT'));
assertType('array<string, mixed>|null', get_bookmark($stdClassOrInt, 'ARRAY_A'));
assertType('array<int, mixed>|null', get_bookmark($stdClassOrInt, 'ARRAY_N'));

/*
* get_bookmark_field()
*/

assertType('array<int, int<1, max>>|int|string|WP_Error', get_bookmark_field('link_id', Faker::int()));
assertType('array<int, int<1, max>>|int|string|WP_Error', get_bookmark_field('foo', Faker::int()));
assertType('array<int, int<1, max>>|int|string|WP_Error', get_bookmark_field(Faker::string(), Faker::int()));

/*
* sanitize_bookmark_field()
*/

assertType('array<int, int>|int|string', sanitize_bookmark_field('link_id', Faker::mixed(), Faker::int(), 'raw'));
assertType('array<int, int>|int|string', sanitize_bookmark_field('foo', Faker::mixed(), Faker::int(), 'raw'));
assertType('array<int, int>|int|string', sanitize_bookmark_field(Faker::string(), Faker::mixed(), Faker::int(), 'raw'));
15 changes: 0 additions & 15 deletions tests/data/get_bookmark.php

This file was deleted.

9 changes: 0 additions & 9 deletions tests/data/wp_error_parameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use function wp_clear_scheduled_hook;
use function wp_insert_attachment;
use function wp_insert_category;
use function wp_insert_link;
use function wp_insert_post;
use function wp_reschedule_event;
use function wp_schedule_event;
Expand All @@ -19,14 +18,6 @@
use function wp_update_post;
use function PHPStan\Testing\assertType;

/*
* wp_insert_link()
*/
assertType('int<0, max>', wp_insert_link([]));
assertType('int<0, max>', wp_insert_link([], false));
assertType('int<0, max>|WP_Error', wp_insert_link([], true));
assertType('int<0, max>|WP_Error', wp_insert_link([], Faker::bool()));

/*
* wp_insert_category()
*/
Expand Down
12 changes: 0 additions & 12 deletions tests/data/wp_update_link.php

This file was deleted.

Loading