diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml new file mode 100644 index 0000000..c88f255 --- /dev/null +++ b/.github/workflows/backend.yml @@ -0,0 +1,11 @@ +name: FoF Follow Tags PHP + +on: [workflow_dispatch, push, pull_request] + +jobs: + run: + uses: flarum/framework/.github/workflows/REUSABLE_backend.yml@main + with: + enable_backend_testing: false + + backend_directory: . diff --git a/.github/workflows/build.yml b/.github/workflows/frontend.yml similarity index 87% rename from .github/workflows/build.yml rename to .github/workflows/frontend.yml index e6c7f2e..dd544ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/frontend.yml @@ -1,4 +1,4 @@ -name: Javascript +name: FoF Follow Tags JS on: [workflow_dispatch, push, pull_request] @@ -8,11 +8,12 @@ jobs: with: enable_bundlewatch: false enable_prettier: true - enable_typescript: false + enable_typescript: true frontend_directory: ./js backend_directory: . js_package_manager: yarn main_git_branch: master + secrets: bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }} diff --git a/composer.json b/composer.json index f370df4..54e236d 100644 --- a/composer.json +++ b/composer.json @@ -1,65 +1,80 @@ { - "name": "fof/follow-tags", - "description": "Follow tags and be notified of new discussions and replies", - "keywords": [ - "flarum" - ], - "type": "flarum-extension", - "license": "MIT", - "support": { - "issues": "https://github.com/FriendsOfFlarum/follow-tags/issues", - "source": "https://github.com/FriendsOfFlarum/follow-tags", - "forum": "https://discuss.flarum.org/d/20525" - }, - "homepage": "https://friendsofflarum.org", - "funding": [ - { - "type": "website", - "url": "https://opencollective.com/fof/donate" - } - ], - "require": { - "flarum/core": "^1.3.0", - "flarum/tags": "^1.3.0", - "fof/extend": "^1.0.0" - }, - "authors": [ - { - "name": "David Sevilla Martín", - "email": "me+fof@datitisev.me", - "role": "Developer" + "name": "fof/follow-tags", + "description": "Follow tags and be notified of new discussions and replies", + "keywords": [ + "flarum" + ], + "type": "flarum-extension", + "license": "MIT", + "support": { + "issues": "https://github.com/FriendsOfFlarum/follow-tags/issues", + "source": "https://github.com/FriendsOfFlarum/follow-tags", + "forum": "https://discuss.flarum.org/d/20525" }, - { - "name": "IanM", - "email": "ian@flarum.org", - "role": "Developer" - } - ], - "autoload": { - "psr-4": { - "FoF\\FollowTags\\": "src/" - } - }, - "extra": { - "flarum-extension": { - "title": "FoF Follow Tags", - "category": "feature", - "icon": { - "name": "fas fa-user-tag", - "backgroundColor": "#e74c3c", - "color": "#fff" - }, - "optional-dependencies": [ - "flarum/subscriptions", - "flarum/approval" - ] + "homepage": "https://friendsofflarum.org", + "funding": [ + { + "type": "website", + "url": "https://opencollective.com/fof/donate" + } + ], + "require": { + "flarum/core": "^1.8.3", + "flarum/tags": "^1.8.0", + "fof/extend": "^1.2.0" + }, + "authors": [ + { + "name": "David Sevilla Martín", + "email": "me+fof@datitisev.me", + "role": "Developer" + }, + { + "name": "IanM", + "email": "ian@flarum.org", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "FoF\\FollowTags\\": "src/" + } + }, + "extra": { + "flarum-extension": { + "title": "FoF Follow Tags", + "category": "feature", + "icon": { + "name": "fas fa-user-tag", + "backgroundColor": "#e74c3c", + "color": "#fff" + }, + "optional-dependencies": [ + "flarum/subscriptions", + "flarum/approval", + "flarum/mentions" + ] + }, + "flagrow": { + "discuss": "https://discuss.flarum.org/d/20525" + }, + "flarum-cli": { + "modules": { + "githubActions": true + } + } + }, + "require-dev": { + "flarum/approval": "*", + "flarum/subscriptions": "*", + "flarum/phpstan": "*", + "flarum/mentions": "*" + }, + "scripts": { + "analyse:phpstan": "phpstan analyse", + "clear-cache:phpstan": "phpstan clear-result-cache" }, - "flagrow": { - "discuss": "https://discuss.flarum.org/d/20525" + "scripts-descriptions": { + "analyse:phpstan": "Run static analysis" } - }, - "require-dev": { - "flarum/approval": "*", - "flarum/subscriptions": "*" - } } diff --git a/extend.php b/extend.php index fe1c019..4cfa0b6 100644 --- a/extend.php +++ b/extend.php @@ -17,6 +17,7 @@ use Flarum\Extend; use Flarum\Post\Event as Post; use Flarum\Tags\Api\Serializer\TagSerializer; +use Flarum\Tags\TagState; use FoF\Extend\Extend\ExtensionSettings; return [ @@ -29,6 +30,9 @@ new Extend\Locales(__DIR__.'/resources/locale'), + (new Extend\Model(TagState::class)) + ->cast('subscription', 'string'), + (new Extend\Routes('api')) ->post('/tags/{id}/subscription', 'fof-follow-tags.subscription', Controllers\ChangeTagSubscription::class), diff --git a/migrations/2022_05_20_000000_add_timestamps_to_tag_user_table.php b/migrations/2022_05_20_000000_add_timestamps_to_tag_user_table.php index 8871b4e..4366551 100644 --- a/migrations/2022_05_20_000000_add_timestamps_to_tag_user_table.php +++ b/migrations/2022_05_20_000000_add_timestamps_to_tag_user_table.php @@ -22,8 +22,8 @@ // do this manually because dbal doesn't recognize timestamp columns $connection = $schema->getConnection(); $prefix = $connection->getTablePrefix(); - $connection->statement("ALTER TABLE `${prefix}tag_user` MODIFY created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP"); - $connection->statement("ALTER TABLE `${prefix}tag_user` MODIFY updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"); + $connection->statement("ALTER TABLE `{$prefix}tag_user` MODIFY created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP"); + $connection->statement("ALTER TABLE `{$prefix}tag_user` MODIFY updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"); }, 'down' => function (Builder $schema) { 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/AddTagSubscriptionAttribute.php b/src/AddTagSubscriptionAttribute.php index 2266ff9..e09d2ed 100644 --- a/src/AddTagSubscriptionAttribute.php +++ b/src/AddTagSubscriptionAttribute.php @@ -13,11 +13,13 @@ use Flarum\Tags\Api\Serializer\TagSerializer; use Flarum\Tags\Tag; +use Flarum\Tags\TagState; class AddTagSubscriptionAttribute { public function __invoke(TagSerializer $serializer, Tag $tag, array $attributes): array { + /** @var TagState $state */ $state = $tag->stateFor($serializer->getActor()); $attributes['subscription'] = $state->subscription; diff --git a/src/Controllers/ChangeTagSubscription.php b/src/Controllers/ChangeTagSubscription.php index d214caf..b36700a 100644 --- a/src/Controllers/ChangeTagSubscription.php +++ b/src/Controllers/ChangeTagSubscription.php @@ -15,6 +15,7 @@ use Flarum\Http\RequestUtil; use Flarum\Tags\Api\Serializer\TagSerializer; use Flarum\Tags\Tag; +use Flarum\Tags\TagState; use Flarum\User\User; use FoF\FollowTags\Event; use Illuminate\Contracts\Events\Dispatcher; @@ -24,9 +25,6 @@ class ChangeTagSubscription extends AbstractShowController { - /** - * {@inheritdoc} - */ public $serializer = TagSerializer::class; /** @@ -39,14 +37,8 @@ public function __construct(Dispatcher $events) $this->events = $events; } - /** - * {@inheritdoc} - */ protected function data(ServerRequestInterface $request, Document $document) { - /** - * @var User - */ $actor = RequestUtil::getActor($request); $id = Arr::get($request->getQueryParams(), 'id'); $subscription = Arr::get($request->getParsedBody(), 'data.subscription'); @@ -54,6 +46,8 @@ protected function data(ServerRequestInterface $request, Document $document) $actor->assertRegistered(); $tag = Tag::whereVisibleTo($actor)->findOrFail($id); + + /** @var TagState $state */ $state = $tag->stateFor($actor); if (!in_array($subscription, ['follow', 'lurk', 'ignore', 'hide'])) { diff --git a/src/Jobs/NotificationJob.php b/src/Jobs/NotificationJob.php index 00710cd..a771b10 100644 --- a/src/Jobs/NotificationJob.php +++ b/src/Jobs/NotificationJob.php @@ -11,12 +11,13 @@ namespace FoF\FollowTags\Jobs; -use Flarum\Database\Eloquent\Collection; use Flarum\Notification\Blueprint\BlueprintInterface; use Flarum\Notification\NotificationSyncer; use Flarum\Queue\AbstractJob; +use Flarum\User\User; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Database\Eloquent\Collection; class NotificationJob extends AbstractJob implements ShouldQueue { @@ -30,7 +31,7 @@ class NotificationJob extends AbstractJob implements ShouldQueue * * @param NotificationSyncer $syncer * @param BlueprintInterface $blueprint - * @param Collection $recipients + * @param Collection $recipients */ protected function sync(NotificationSyncer $syncer, BlueprintInterface $blueprint, Collection $recipients): void { diff --git a/src/Jobs/SendNotificationWhenDiscussionIsReTagged.php b/src/Jobs/SendNotificationWhenDiscussionIsReTagged.php index 8a8fba7..3d17b69 100644 --- a/src/Jobs/SendNotificationWhenDiscussionIsReTagged.php +++ b/src/Jobs/SendNotificationWhenDiscussionIsReTagged.php @@ -13,6 +13,7 @@ use Flarum\Discussion\Discussion; use Flarum\Notification\NotificationSyncer; +use Flarum\Tags\Tag; use Flarum\User\User; use FoF\FollowTags\Notifications\NewDiscussionTagBlueprint; use Illuminate\Support\Collection; @@ -42,8 +43,8 @@ public function handle(NotificationSyncer $notifications) } /** - * @var Collection - * @var $tagIds Collection + * @var Collection|null $tags + * @phpstan-ignore-next-line */ $tags = $this->discussion->tags; $tagIds = $tags->map->id; diff --git a/src/Jobs/SendNotificationWhenDiscussionIsStarted.php b/src/Jobs/SendNotificationWhenDiscussionIsStarted.php index 3390608..c627743 100644 --- a/src/Jobs/SendNotificationWhenDiscussionIsStarted.php +++ b/src/Jobs/SendNotificationWhenDiscussionIsStarted.php @@ -36,8 +36,8 @@ public function handle(NotificationSyncer $notifications) } /** - * @var Collection - * @var $tagIds Collection + * @var Collection|null $tags + * @phpstan-ignore-next-line */ $tags = $this->discussion->tags; $tagIds = $tags->map->id; diff --git a/src/Jobs/SendNotificationWhenReplyIsPosted.php b/src/Jobs/SendNotificationWhenReplyIsPosted.php index cfb5657..80df4e8 100644 --- a/src/Jobs/SendNotificationWhenReplyIsPosted.php +++ b/src/Jobs/SendNotificationWhenReplyIsPosted.php @@ -25,7 +25,7 @@ class SendNotificationWhenReplyIsPosted extends NotificationJob protected $post; /** - * @var Post + * @var int */ protected $lastPostNumber; @@ -41,11 +41,13 @@ public function handle(NotificationSyncer $notifications) return; } + + $discussion = $this->post->discussion; + /** - * @var Collection - * @var $tagIds Collection + * @var Collection|null $tags + * @phpstan-ignore-next-line */ - $discussion = $this->post->discussion; $tags = $discussion->tags; $tagIds = $tags->map->id; diff --git a/src/Listeners/PreventMentionNotificationsFromIgnoredTags.php b/src/Listeners/PreventMentionNotificationsFromIgnoredTags.php index 23d8dd4..80f979b 100644 --- a/src/Listeners/PreventMentionNotificationsFromIgnoredTags.php +++ b/src/Listeners/PreventMentionNotificationsFromIgnoredTags.php @@ -24,12 +24,8 @@ public function __invoke(BlueprintInterface $blueprint, array $recipients): arra return $recipients; } - /** - * @var PostMentionedBlueprint|UserMentionedBlueprint - * @var $ids \Illuminate\Support\Collection - * @var $tags \Illuminate\Support\Collection - */ $ids = collect($recipients)->pluck('id'); + /** @phpstan-ignore-next-line */ $tags = $blueprint->post->discussion->tags->pluck('id'); if ($tags->isEmpty()) {