diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 624436f..fd93f0f 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -7,5 +7,6 @@ jobs: uses: flarum/framework/.github/workflows/REUSABLE_backend.yml@main with: enable_backend_testing: true + enable_phpstan: true backend_directory: . diff --git a/composer.json b/composer.json index 6383e18..7f5f781 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ } ], "require": { - "flarum/core": "^1.8.1", + "flarum/core": "^1.8.3", "rinvex/countries": "^6.1.2 || ^7.0.1 || ^8.1.0", "league/csv": "^9.7", "ianm/iso-639": "^1.0", @@ -69,7 +69,8 @@ "require-dev": { "fof/byobu": "*", "fof/follow-tags": "*", - "flarum/testing": "^1.0.0" + "flarum/testing": "^1.0.0", + "flarum/phpstan": "*" }, "autoload-dev": { "psr-4": { @@ -83,12 +84,15 @@ ], "test:unit": "phpunit -c tests/phpunit.unit.xml", "test:integration": "phpunit -c tests/phpunit.integration.xml", - "test:setup": "@php tests/integration/setup.php" + "test:setup": "@php tests/integration/setup.php", + "analyse:phpstan": "phpstan analyse", + "clear-cache:phpstan": "phpstan clear-result-cache" }, "scripts-descriptions": { "test": "Runs all tests.", "test:unit": "Runs all unit tests.", "test:integration": "Runs all integration tests.", - "test:setup": "Sets up a database for use with integration tests. Execute this only once." + "test:setup": "Sets up a database for use with integration tests. Execute this only once.", + "analyse:phpstan": "Run static analysis" } } diff --git a/extend.php b/extend.php index 6b829e0..c61837b 100644 --- a/extend.php +++ b/extend.php @@ -24,6 +24,8 @@ use Flarum\Extend; use Flarum\Tags\Api\Serializer\TagSerializer; use Flarum\Tags\Event\Creating as TagCreating; +use Flarum\Tags\Tag; +use Flarum\Tags\TagState; use FoF\DiscussionLanguage\Api\Serializers\DiscussionLanguageSerializer; use FoF\DiscussionLanguage\Api\Serializers\TagLocalizedLastDiscussionSerializer; use FoF\FollowTags\Event\SubscriptionChanging; @@ -48,8 +50,15 @@ ->add(Middleware\AddLanguageFilter::class), (new Extend\Model(Discussion::class)) + ->cast('language_id', 'int') ->hasOne('language', DiscussionLanguage::class, 'id', 'language_id'), + (new Extend\Model(Tag::class)) + ->cast('localised_last_discussion', 'string'), + + (new Extend\Model(TagState::class)) + ->cast('dl_language_id', 'int'), + (new Extend\Event()) ->listen(Saving::class, Listener\AddDiscussionLanguage::class) ->listen(TagCreating::class, Listener\TagCreating::class) @@ -104,14 +113,16 @@ ->attributes(TagLocalizedLastDiscussionSerializer::class), (new Extend\Conditional()) - ->whenExtensionEnabled('fof-follow-tags', [ - (new Extend\ApiSerializer(TagSerializer::class)) - ->attributes(AddTagSerializerAttributes::class), + ->whenExtensionEnabled('fof-follow-tags', function () { + return [ + (new Extend\ApiSerializer(TagSerializer::class)) + ->attributes(AddTagSerializerAttributes::class), - (new Extend\Event()) - ->listen(SubscriptionChanging::class, Listener\SaveLanguageOnSubscription::class), + (new Extend\Event()) + ->listen(SubscriptionChanging::class, Listener\SaveLanguageOnSubscription::class), - (new Extend\Notification()) - ->beforeSending(CheckNotificationRecipients::class), - ]), + (new Extend\Notification()) + ->beforeSending(CheckNotificationRecipients::class), + ]; + }), ]; diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..03cf261 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,13 @@ +includes: + - vendor/flarum/phpstan/extension.neon + +parameters: + # The level will be increased in Flarum 2.0 + level: 5 + paths: + - extend.php + - src + excludePaths: + - *.blade.php + checkMissingIterableValueType: false + databaseMigrationsPath: ['migrations'] diff --git a/src/Api/Serializers/DiscussionLanguageSerializer.php b/src/Api/Serializers/DiscussionLanguageSerializer.php index 8ec6813..c5bca5b 100644 --- a/src/Api/Serializers/DiscussionLanguageSerializer.php +++ b/src/Api/Serializers/DiscussionLanguageSerializer.php @@ -54,7 +54,7 @@ public function __construct(SettingsRepositoryInterface $settings, ISO639 $iso, } /** - * {@inheritdoc} + * @param \FoF\DiscussionLanguage\DiscussionLanguage $model */ protected function getDefaultAttributes($model) { @@ -92,7 +92,7 @@ protected function getLanguageName(string $code, bool $native) return $this->translator->trans('fof-discussion-language.forum.index_language.any'); } - if (!$this->records) { + if ($this->records === null) { $csv = Reader::createFromPath(__DIR__.'/../../../resources/wikipedia-iso-639-2-codes.csv'); $csv->setHeaderOffset(0); diff --git a/src/CheckNotificationRecipients.php b/src/CheckNotificationRecipients.php index 615b187..7365b65 100644 --- a/src/CheckNotificationRecipients.php +++ b/src/CheckNotificationRecipients.php @@ -36,7 +36,11 @@ public function __invoke(BlueprintInterface $blueprint, array $users): array return $users; } - /** @var Tag[] */ + /** + * @var Tag[] $tags + * + * @phpstan-ignore-next-line + */ $tags = $discussion->tags()->get(); // Build a map of users and an array of their respective dl_language_id values @@ -69,6 +73,6 @@ public function __invoke(BlueprintInterface $blueprint, array $users): array */ protected function isFollowTagsBlueprint(BlueprintInterface $blueprint): bool { - return strpos($blueprint::class, 'FoF\FollowTags\Notification') === 0; + return strpos(get_class($blueprint), 'FoF\FollowTags\Notification') === 0; } } diff --git a/src/Commands/CreateLanguageCommandHandler.php b/src/Commands/CreateLanguageCommandHandler.php index e882236..7933680 100644 --- a/src/Commands/CreateLanguageCommandHandler.php +++ b/src/Commands/CreateLanguageCommandHandler.php @@ -13,24 +13,17 @@ use FoF\DiscussionLanguage\DiscussionLanguage; use FoF\DiscussionLanguage\Validators\DiscussionLanguageValidator; -use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Support\Arr; class CreateLanguageCommandHandler { - /** - * @var Dispatcher - */ - private $events; - /** * @var DiscussionLanguageValidator */ private $validator; - public function __construct(Dispatcher $events, DiscussionLanguageValidator $validator) + public function __construct(DiscussionLanguageValidator $validator) { - $this->events = $events; $this->validator = $validator; } diff --git a/src/Commands/UpdateLanguageCommandHandler.php b/src/Commands/UpdateLanguageCommandHandler.php index f5bcdd9..26b1b11 100644 --- a/src/Commands/UpdateLanguageCommandHandler.php +++ b/src/Commands/UpdateLanguageCommandHandler.php @@ -13,24 +13,17 @@ use FoF\DiscussionLanguage\DiscussionLanguage; use FoF\DiscussionLanguage\Validators\DiscussionLanguageValidator; -use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Support\Arr; class UpdateLanguageCommandHandler { - /** - * @var Dispatcher - */ - private $events; - /** * @var DiscussionLanguageValidator */ private $validator; - public function __construct(Dispatcher $events, DiscussionLanguageValidator $validator) + public function __construct(DiscussionLanguageValidator $validator) { - $this->events = $events; $this->validator = $validator; } diff --git a/src/DiscussionLanguage.php b/src/DiscussionLanguage.php index 53c2262..fc58f24 100644 --- a/src/DiscussionLanguage.php +++ b/src/DiscussionLanguage.php @@ -15,9 +15,9 @@ use Flarum\Discussion\Discussion; /** - * @property $id string - * @property $code string - * @property $country string + * @property string $id + * @property string $code + * @property string $country */ class DiscussionLanguage extends AbstractModel { diff --git a/src/Listener/SaveLanguageOnSubscription.php b/src/Listener/SaveLanguageOnSubscription.php index f89617c..14e95ba 100644 --- a/src/Listener/SaveLanguageOnSubscription.php +++ b/src/Listener/SaveLanguageOnSubscription.php @@ -29,7 +29,9 @@ public function handle(SubscriptionChanging $event): void } // Fetch the language ID using the provided language string - $languageId = DiscussionLanguage::where('code', $language)->pluck('id')->first(); + $languageId = DiscussionLanguage::query() + ->where('code', $language) + ->value('id'); $event->state->dl_language_id = $languageId; } diff --git a/src/Listener/UpdateTagMetadata.php b/src/Listener/UpdateTagMetadata.php index df33ea9..71744b6 100644 --- a/src/Listener/UpdateTagMetadata.php +++ b/src/Listener/UpdateTagMetadata.php @@ -23,6 +23,7 @@ use Flarum\Tags\Event\DiscussionWasTagged; use Flarum\Tags\Tag; use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Arr; class UpdateTagMetadata @@ -70,6 +71,7 @@ public function whenDiscussionIsDeleted(Deleted $event) { $this->updateTags($event->discussion, -1); + /** @phpstan-ignore-next-line */ $event->discussion->tags()->detach(); } @@ -124,12 +126,13 @@ public function whenPostIsRestored(PostRestored $event) /** * @param \Flarum\Discussion\Discussion $discussion * @param int $delta - * @param Tag[]|null $tags - * @param Post $post: This is only used when a post has been hidden + * @param Collection|null $tags + * @param \Flarum\Post\Post $post: This is only used when a post has been hidden */ protected function updateTags(Discussion $discussion, $delta = 0, $tags = null, $post = null) { if (!$tags) { + /** @phpstan-ignore-next-line */ $tags = $discussion->tags; } diff --git a/src/LoadForumDiscussionLanguageRelationship.php b/src/LoadForumDiscussionLanguageRelationship.php index f833add..c6f2bfc 100644 --- a/src/LoadForumDiscussionLanguageRelationship.php +++ b/src/LoadForumDiscussionLanguageRelationship.php @@ -12,8 +12,8 @@ namespace FoF\DiscussionLanguage; use Flarum\Api\Controller\ShowForumController; -use Flarum\Database\Eloquent\Collection; use Flarum\Settings\SettingsRepositoryInterface; +use Illuminate\Database\Eloquent\Collection; use Psr\Http\Message\ServerRequestInterface; /** diff --git a/src/Middleware/AddLanguageFilter.php b/src/Middleware/AddLanguageFilter.php index 96d2fb4..2a85e8a 100644 --- a/src/Middleware/AddLanguageFilter.php +++ b/src/Middleware/AddLanguageFilter.php @@ -163,7 +163,6 @@ protected function determineLanguageFromBrowserRequest(string $acceptLangs): str if ($this->locales->hasLocale($lang)) { // Once we find a match, return it return $lang; - break; } }