Skip to content

Commit 1925c94

Browse files
committed
Merge branch 'master' into _get_list_table
# Conflicts: # tests/testTest.php
2 parents ffe08e4 + f7ff658 commit 1925c94

7 files changed

+124
-1
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# TravisCI configuration for szepeviktor/phpstan-wordpress
22

3+
if: "branch = master"
4+
35
language: "php"
46
os:
57
- "linux"
@@ -23,6 +25,6 @@ install:
2325

2426
script:
2527
- "composer test:syntax -- --no-progress"
26-
- "composer test:phpunit"
28+
- "composer test:phpunit -- --verbose"
2729
- "composer test:cs -- -s"
2830
- "composer test:phpstan -- --ansi --memory-limit=1G --no-progress"

extension.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ services:
4747
class: SzepeViktor\PHPStan\WordPress\MySQL2DateDynamicFunctionReturnTypeExtension
4848
tags:
4949
- phpstan.broker.dynamicFunctionReturnTypeExtension
50+
-
51+
class: SzepeViktor\PHPStan\WordPress\CurrentTimeDynamicFunctionReturnTypeExtension
52+
tags:
53+
- phpstan.broker.dynamicFunctionReturnTypeExtension
5054
parameters:
5155
bootstrapFiles:
5256
- %rootDir%/../../php-stubs/wordpress-stubs/wordpress-stubs.php
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/**
4+
* Set return type of current_time().
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace SzepeViktor\PHPStan\WordPress;
10+
11+
use PhpParser\Node\Expr\FuncCall;
12+
use PHPStan\Analyser\Scope;
13+
use PHPStan\Reflection\FunctionReflection;
14+
use PHPStan\Reflection\ParametersAcceptorSelector;
15+
use PHPStan\Type\Type;
16+
use PHPStan\Type\IntegerType;
17+
use PHPStan\Type\StringType;
18+
use PHPStan\Type\Constant\ConstantStringType;
19+
20+
class CurrentTimeDynamicFunctionReturnTypeExtension implements \PHPStan\Type\DynamicFunctionReturnTypeExtension
21+
{
22+
public function isFunctionSupported(FunctionReflection $functionReflection): bool
23+
{
24+
return in_array($functionReflection->getName(), ['current_time'], true);
25+
}
26+
27+
/**
28+
* @see https://developer.wordpress.org/reference/functions/current_time/
29+
*/
30+
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type
31+
{
32+
$argumentType = $scope->getType($functionCall->args[0]->value);
33+
34+
// When called with a $type that isn't a constant string, return default return type
35+
if (! $argumentType instanceof ConstantStringType) {
36+
return ParametersAcceptorSelector::selectFromArgs(
37+
$scope,
38+
$functionCall->args,
39+
$functionReflection->getVariants()
40+
)->getReturnType();
41+
}
42+
43+
// Called with a constant string $type
44+
switch ($argumentType->getValue()) {
45+
case 'timestamp':
46+
case 'U':
47+
return new IntegerType();
48+
case 'mysql':
49+
default:
50+
return new StringType();
51+
}
52+
}
53+
}

src/GetPostDynamicFunctionReturnTypeExtension.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PhpParser\Node\Expr\FuncCall;
1313
use PHPStan\Analyser\Scope;
1414
use PHPStan\Reflection\FunctionReflection;
15+
use PHPStan\Reflection\ParametersAcceptorSelector;
1516
use PHPStan\Type\Type;
1617
use PHPStan\Type\ArrayType;
1718
use PHPStan\Type\StringType;
@@ -20,6 +21,7 @@
2021
use PHPStan\Type\ObjectType;
2122
use PHPStan\Type\NullType;
2223
use PHPStan\Type\TypeCombinator;
24+
use PHPStan\Type\Constant\ConstantStringType;
2325

2426
class GetPostDynamicFunctionReturnTypeExtension implements \PHPStan\Type\DynamicFunctionReturnTypeExtension
2527
{
@@ -32,6 +34,20 @@ public function isFunctionSupported(FunctionReflection $functionReflection): boo
3234
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type
3335
{
3436
$output = 'OBJECT';
37+
38+
if (count($functionCall->args) >= 2) {
39+
$argumentType = $scope->getType($functionCall->args[1]->value);
40+
41+
// When called with an $output that isn't a constant string, return default return type
42+
if (! $argumentType instanceof ConstantStringType) {
43+
return ParametersAcceptorSelector::selectFromArgs(
44+
$scope,
45+
$functionCall->args,
46+
$functionReflection->getVariants()
47+
)->getReturnType();
48+
}
49+
}
50+
3551
if (count($functionCall->args) >= 2 && $functionCall->args[1]->value instanceof ConstFetch) {
3652
$output = $functionCall->args[1]->value->name->getLast();
3753
}

tests/data/current_time.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SzepeViktor\PHPStan\WordPress\Tests;
6+
7+
use function current_time;
8+
use function PHPStan\Testing\assertType;
9+
use stdClass;
10+
11+
// Integer types
12+
assertType('int', current_time('timestamp'));
13+
assertType('int', current_time('U'));
14+
15+
// String types
16+
assertType('string', current_time('mysql'));
17+
assertType('string', current_time('Hello'));
18+
19+
// Unknown types
20+
assertType('int|string', current_time($_GET['foo']));
21+
assertType('int|string', current_time(get_option('date_format')));
22+
23+
// Unsupported types
24+
assertType('int|string', current_time(new stdClass));
25+
assertType('int|string', current_time(false));

tests/data/get_post.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SzepeViktor\PHPStan\WordPress\Tests;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
// Default output
10+
assertType('WP_Post|null', get_post(1));
11+
assertType('WP_Post|null', get_post(1,OBJECT));
12+
assertType('WP_Post|null', get_post(1,'Hello'));
13+
14+
// Unknown output
15+
assertType('array|\WP_Post|null', get_post(1,_GET['foo']));
16+
17+
// Associative array output
18+
assertType('array<string, mixed>|null', get_post(1,ARRAY_A));
19+
20+
// Numeric array output
21+
assertType('array<int, mixed>|null', get_post(1,ARRAY_N));

tests/testTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ public function dataFileAsserts(): iterable
1616
{
1717
// path to a file with actual asserts of expected types:
1818
yield from $this->gatherAssertTypes(__DIR__ . '/data/_get_list_table.php');
19+
yield from $this->gatherAssertTypes(__DIR__ . '/data/current_time.php');
1920
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_comment.php');
2021
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_object_taxonomies.php');
22+
yield from $this->gatherAssertTypes(__DIR__ . '/data/get_post.php');
2123
yield from $this->gatherAssertTypes(__DIR__ . '/data/mysql2date.php');
2224
}
2325

0 commit comments

Comments
 (0)