From 67ee5568b91917085eb220232bbfcd7915c0a12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Sat, 24 Oct 2020 12:02:43 +0000 Subject: [PATCH 1/4] Fix all problems from PHPStan --- composer.json | 5 +- composer.lock | 128 ++++++++++++------ greg.php | 17 ++- phpstan.neon.dist | 15 +- phpunit.xml.dist | 6 +- src/Event.php | 4 + src/EventQuery.php | 1 + src/api.php | 5 +- {test => tests}/bootstrap.php | 0 {test => tests}/integration/EventTest.php | 0 {test => tests}/integration/GregTest.php | 0 .../integration/IntegrationTest.php | 0 {phpstan => tests/phpstan}/bootstrap.php | 0 {test => tests}/unit/BaseTest.php | 0 {test => tests}/unit/CalendarTest.php | 0 {test => tests}/unit/EventQueryTest.php | 0 16 files changed, 114 insertions(+), 67 deletions(-) rename {test => tests}/bootstrap.php (100%) rename {test => tests}/integration/EventTest.php (100%) rename {test => tests}/integration/GregTest.php (100%) rename {test => tests}/integration/IntegrationTest.php (100%) rename {phpstan => tests/phpstan}/bootstrap.php (100%) rename {test => tests}/unit/BaseTest.php (100%) rename {test => tests}/unit/CalendarTest.php (100%) rename {test => tests}/unit/EventQueryTest.php (100%) diff --git a/composer.json b/composer.json index bfd8bd0..ffd1aaf 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,10 @@ "mnsami/composer-custom-directory-installer": "^1.1", "squizlabs/php_codesniffer": "3.*", "wp-coding-standards/wpcs": "^2.3", - "szepeviktor/phpstan-wordpress": "^0.6.5", + "szepeviktor/phpstan-wordpress": "^0.6.6", "paulthewalton/acf-stubs": "^5.8.7", - "timber/timber": "2.x-dev" + "timber/timber": "2.x-dev", + "php-stubs/wp-cli-stubs": "^2.4.0" }, "config": { "platform": { diff --git a/composer.lock b/composer.lock index 68548ee..d070e3f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18b5cb23871cd9ad4b9510fc1eccb899", + "content-hash": "5288587f22ff15062b88ccdad34919f6", "packages": [ { "name": "rlanvin/php-rrule", @@ -640,6 +640,46 @@ ], "time": "2020-09-02T05:31:36+00:00" }, + { + "name": "php-stubs/wp-cli-stubs", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wp-cli-stubs.git", + "reference": "38fda2907e052ce42fe02e2bfa9f063371ee21c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wp-cli-stubs/zipball/38fda2907e052ce42fe02e2bfa9f063371ee21c3", + "reference": "38fda2907e052ce42fe02e2bfa9f063371ee21c3", + "shasum": "" + }, + "require": { + "php-stubs/wordpress-stubs": "^4.7 || ^5.0" + }, + "require-dev": { + "giacocorsiglia/stubs-generator": "^0.5.0", + "php": "~7.1" + }, + "suggest": { + "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WP-CLI function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wp-cli-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress", + "wp-cli" + ], + "time": "2020-08-04T21:22:17+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "dev-master", @@ -855,12 +895,12 @@ "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "bb6b32f9d04224d30e2c9c04ff18b42df4dd9ef8" + "reference": "aeaf2bfb3e71bebd7472db75b54a95ec04641224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bb6b32f9d04224d30e2c9c04ff18b42df4dd9ef8", - "reference": "bb6b32f9d04224d30e2c9c04ff18b42df4dd9ef8", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/aeaf2bfb3e71bebd7472db75b54a95ec04641224", + "reference": "aeaf2bfb3e71bebd7472db75b54a95ec04641224", "shasum": "" }, "require": { @@ -903,7 +943,7 @@ "type": "tidelift" } ], - "time": "2020-10-14T18:04:00+00:00" + "time": "2020-10-23T20:59:13+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1864,12 +1904,12 @@ "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "d4ba5fc8183e6fc0c5e2b891bc1d8f9f0d34512d" + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d4ba5fc8183e6fc0c5e2b891bc1d8f9f0d34512d", - "reference": "d4ba5fc8183e6fc0c5e2b891bc1d8f9f0d34512d", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", "shasum": "" }, "require": { @@ -1907,24 +1947,24 @@ "phpcs", "standards" ], - "time": "2020-10-13T22:05:34+00:00" + "time": "2020-10-23T02:01:07+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "dev-master", + "version": "dev-main", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" @@ -1932,7 +1972,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1983,24 +2023,24 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "dev-master", + "version": "dev-main", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "48928d471ede0548b399f54b0286fe0d0ed79267" + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/48928d471ede0548b399f54b0286fe0d0ed79267", - "reference": "48928d471ede0548b399f54b0286fe0d0ed79267", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" @@ -2008,7 +2048,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2060,29 +2100,29 @@ "type": "tidelift" } ], - "time": "2020-09-14T11:01:58+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-php73", - "version": "dev-master", + "version": "dev-main", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca" + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fffa1a52a023e782cdcc221d781fe1ec8f87fcca", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2136,20 +2176,20 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "szepeviktor/phpstan-wordpress", - "version": "v0.6.5", + "version": "v0.6.6", "source": { "type": "git", "url": "https://github.com/szepeviktor/phpstan-wordpress.git", - "reference": "b931433daa21e7e757d93906283337c1be174f21" + "reference": "f5040549dc5f46d81ea2432de726c2a0a4ad1141" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/szepeviktor/phpstan-wordpress/zipball/b931433daa21e7e757d93906283337c1be174f21", - "reference": "b931433daa21e7e757d93906283337c1be174f21", + "url": "https://api.github.com/repos/szepeviktor/phpstan-wordpress/zipball/f5040549dc5f46d81ea2432de726c2a0a4ad1141", + "reference": "f5040549dc5f46d81ea2432de726c2a0a4ad1141", "shasum": "" }, "require": { @@ -2196,7 +2236,7 @@ "type": "custom" } ], - "time": "2020-09-25T16:39:39+00:00" + "time": "2020-10-18T12:11:45+00:00" }, { "name": "theseer/tokenizer", @@ -2250,12 +2290,12 @@ "source": { "type": "git", "url": "https://github.com/timber/timber.git", - "reference": "5c974f3462787edf613bd7c2d54b0c946c28c8fa" + "reference": "d9ec0333ca0c81bf67ae3d4a3a0fff503e248bae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/timber/timber/zipball/5c974f3462787edf613bd7c2d54b0c946c28c8fa", - "reference": "5c974f3462787edf613bd7c2d54b0c946c28c8fa", + "url": "https://api.github.com/repos/timber/timber/zipball/d9ec0333ca0c81bf67ae3d4a3a0fff503e248bae", + "reference": "d9ec0333ca0c81bf67ae3d4a3a0fff503e248bae", "shasum": "" }, "require": { @@ -2308,7 +2348,7 @@ "timber", "twig" ], - "time": "2020-10-18T08:54:56+00:00" + "time": "2020-10-22T13:19:46+00:00" }, { "name": "twig/cache-extension", @@ -2383,16 +2423,16 @@ "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "fa2f1ccdb44a973571235c4a78487c040f26f116" + "reference": "78173b3c850e344cb8515fc2a05138d39a6c39e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/fa2f1ccdb44a973571235c4a78487c040f26f116", - "reference": "fa2f1ccdb44a973571235c4a78487c040f26f116", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/78173b3c850e344cb8515fc2a05138d39a6c39e0", + "reference": "78173b3c850e344cb8515fc2a05138d39a6c39e0", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3" }, @@ -2450,7 +2490,7 @@ "type": "tidelift" } ], - "time": "2020-10-14T06:37:57+00:00" + "time": "2020-10-21T12:45:52+00:00" }, { "name": "webmozart/assert", diff --git a/greg.php b/greg.php index c1f2b31..2f8021a 100644 --- a/greg.php +++ b/greg.php @@ -33,7 +33,7 @@ define('GREG_PLUGIN_VIEW_PATH', __DIR__ . '/views'); -add_action('init', function() { +add_action('init', function() : void { register_post_type('greg_event', [ 'public' => true, 'description' => 'Calendar Events, potentially with recurrences', @@ -102,7 +102,7 @@ /* * Add REST Routes */ -add_action('rest_api_init', function() { +add_action('rest_api_init', function() : void { $controller = new RestController(); $controller->register_routes(); }); @@ -112,8 +112,7 @@ * Add WP-CLI tooling */ if (defined('WP_CLI') && WP_CLI) { - $command = new GregCommand(); - WP_CLI::add_command('greg', $command); + WP_CLI::add_command('greg', GregCommand::class); } /** @@ -138,7 +137,7 @@ return $data; }); -add_filter('timber/locations', function(array $paths) { +add_filter('timber/locations', function(array $paths) : array { $paths['greg'] = [ get_template_directory() . '/views/greg', GREG_PLUGIN_VIEW_PATH . '/twig', @@ -147,10 +146,10 @@ return $paths; }); -add_filter('timber/twig', function(Environment $twig) { - $twig->addFunction(new TwigFunction('greg_compile', Greg\compile::class)); - $twig->addFunction(new TwigFunction('greg_render', Greg\render::class)); - $twig->addFunction(new TwigFunction('greg_get_events', Greg\get_events::class)); +add_filter('timber/twig', function(Environment $twig) : Environment { + $twig->addFunction(new TwigFunction('greg_compile', '\\Greg\\compile')); + $twig->addFunction(new TwigFunction('greg_render', '\\Greg\\render')); + $twig->addFunction(new TwigFunction('greg_get_events', '\\Greg\\get_events')); return $twig; }); diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 37ece81..5686133 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,11 +5,14 @@ parameters: inferPrivatePropertyTypeFromConstructor: true checkMissingIterableValueType: false bootstrapFiles: - - phpstan/bootstrap.php + - tests/phpstan/bootstrap.php + scanFiles: + - vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php paths: - - src + - greg.php + - src/ + #- tests/unit/ + #- tests/integration/ ignoreErrors: - # TODO Figure out how to discover the WP_CLI class - - '#^Call to static method success\(\) on an unknown class WP_CLI\.$#' - # We can't have strong typehints without union types :( - - '#has no return typehint specified\.#' + # WP-CLI accepts a class as callable + - '/^Parameter #2 \$callable of static method WP_CLI::add_command\(\) expects callable\(\): mixed, \S+ given\.$/' diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5e77ff3..10dec55 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,5 @@ - ./test/unit + ./tests/unit - ./test/integration + ./tests/integration diff --git a/src/Event.php b/src/Event.php index 75c6dd7..ff9a800 100644 --- a/src/Event.php +++ b/src/Event.php @@ -116,6 +116,7 @@ public static function post_to_calendar_series(Post $post) : array { * Create a new Event wrapper object from a Post * * @internal + * @return self */ public static function from_post(Post $post) { return new self($post); @@ -126,6 +127,7 @@ public static function from_post(Post $post) { * of a recurring event, which MUST include a `post` index. * * @internal + * @return self */ public static function from_assoc(array $event) { $fallbacks = array_intersect_key($event, array_flip([ @@ -140,6 +142,7 @@ public static function from_assoc(array $event) { * @internal * @param string $method the method name * @param array $args the method args + * @return mixed */ public function __call($method, $args) { $func = [$this->post, $method]; @@ -154,6 +157,7 @@ public function __call($method, $args) { * * @internal * @param string $field the field name + * @return mixed */ public function __get($field) { return $this->post->$field; diff --git a/src/EventQuery.php b/src/EventQuery.php index f676f79..332dea2 100644 --- a/src/EventQuery.php +++ b/src/EventQuery.php @@ -137,6 +137,7 @@ protected function init_end_date(array $params, DateTimeImmutable $start) : Date * Get the results for this EventQuery as a collection of zero or more Events * * @internal + * @return list<\Timber\Post>|bool|null */ public function get_results() { return Timber::get_posts($this->params()); diff --git a/src/api.php b/src/api.php index 1723c2a..3ba8125 100644 --- a/src/api.php +++ b/src/api.php @@ -112,7 +112,7 @@ function get_events(array $params = []) { $events = $query->get_results(); - if (!$events) { + if (!is_array($events)) { return false; } @@ -123,9 +123,8 @@ function get_events(array $params = []) { $calendar = new Calendar($events); return array_map([Event::class, 'from_assoc'], $calendar->recurrences()); - } else { - return array_map([Event::class, 'from_post'], $events->to_array()); } + return array_map([Event::class, 'from_post'], $events->to_array()); } /** diff --git a/test/bootstrap.php b/tests/bootstrap.php similarity index 100% rename from test/bootstrap.php rename to tests/bootstrap.php diff --git a/test/integration/EventTest.php b/tests/integration/EventTest.php similarity index 100% rename from test/integration/EventTest.php rename to tests/integration/EventTest.php diff --git a/test/integration/GregTest.php b/tests/integration/GregTest.php similarity index 100% rename from test/integration/GregTest.php rename to tests/integration/GregTest.php diff --git a/test/integration/IntegrationTest.php b/tests/integration/IntegrationTest.php similarity index 100% rename from test/integration/IntegrationTest.php rename to tests/integration/IntegrationTest.php diff --git a/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php similarity index 100% rename from phpstan/bootstrap.php rename to tests/phpstan/bootstrap.php diff --git a/test/unit/BaseTest.php b/tests/unit/BaseTest.php similarity index 100% rename from test/unit/BaseTest.php rename to tests/unit/BaseTest.php diff --git a/test/unit/CalendarTest.php b/tests/unit/CalendarTest.php similarity index 100% rename from test/unit/CalendarTest.php rename to tests/unit/CalendarTest.php diff --git a/test/unit/EventQueryTest.php b/tests/unit/EventQueryTest.php similarity index 100% rename from test/unit/EventQueryTest.php rename to tests/unit/EventQueryTest.php From 3f3a2e23712a6006ca17e352148b1c343d7d4192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Sat, 24 Oct 2020 12:10:15 +0000 Subject: [PATCH 2/4] Remove one temporary variable --- src/api.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/api.php b/src/api.php index 3ba8125..a003fad 100644 --- a/src/api.php +++ b/src/api.php @@ -119,8 +119,7 @@ function get_events(array $params = []) { // Unless recurrence expansion is explicitly disabled, expand each // (potentially) recurring event into its comprising recurrences. if ($params['expand_recurrences'] ?? true) { - $events = array_map([Event::class, 'post_to_calendar_series'], $events->to_array()); - $calendar = new Calendar($events); + $calendar = new Calendar(array_map([Event::class, 'post_to_calendar_series'], $events->to_array())); return array_map([Event::class, 'from_assoc'], $calendar->recurrences()); } From 9777537f7ca5de36ccc352d807f6d9a490d1d6dd Mon Sep 17 00:00:00 2001 From: Coby Tamayo Date: Mon, 26 Oct 2020 10:41:23 -0700 Subject: [PATCH 3/4] #2 always return an array from Event::get_results() --- src/EventQuery.php | 7 ++++--- src/api.php | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/EventQuery.php b/src/EventQuery.php index 332dea2..eb15762 100644 --- a/src/EventQuery.php +++ b/src/EventQuery.php @@ -137,10 +137,11 @@ protected function init_end_date(array $params, DateTimeImmutable $start) : Date * Get the results for this EventQuery as a collection of zero or more Events * * @internal - * @return list<\Timber\Post>|bool|null + * @return array */ - public function get_results() { - return Timber::get_posts($this->params()); + public function get_results() : array { + $posts = Timber::get_posts($this->params()); + return $posts ? $posts->to_array() : []; } /** diff --git a/src/api.php b/src/api.php index a003fad..c3830bd 100644 --- a/src/api.php +++ b/src/api.php @@ -112,18 +112,18 @@ function get_events(array $params = []) { $events = $query->get_results(); - if (!is_array($events)) { - return false; - } - // Unless recurrence expansion is explicitly disabled, expand each // (potentially) recurring event into its comprising recurrences. if ($params['expand_recurrences'] ?? true) { - $calendar = new Calendar(array_map([Event::class, 'post_to_calendar_series'], $events->to_array())); + $calendar = new Calendar(array_map( + [Event::class, 'post_to_calendar_series'], + $events + )); return array_map([Event::class, 'from_assoc'], $calendar->recurrences()); } - return array_map([Event::class, 'from_post'], $events->to_array()); + + return array_map([Event::class, 'from_post'], $events); } /** From 94f53581c30e1ba760c5cf14996e09a11785d0f7 Mon Sep 17 00:00:00 2001 From: Coby Tamayo Date: Mon, 26 Oct 2020 10:56:11 -0700 Subject: [PATCH 4/4] be specific about array contents --- src/EventQuery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EventQuery.php b/src/EventQuery.php index eb15762..1355431 100644 --- a/src/EventQuery.php +++ b/src/EventQuery.php @@ -137,7 +137,7 @@ protected function init_end_date(array $params, DateTimeImmutable $start) : Date * Get the results for this EventQuery as a collection of zero or more Events * * @internal - * @return array + * @return array<\Timber\Post> */ public function get_results() : array { $posts = Timber::get_posts($this->params());