goldnead / statamic-community
Community for Statamic: curated rooms, posts, comments and reactions, with a chronological feed and optional pre-moderation.
Package info
github.com/goldnead/statamic-community
Type:statamic-addon
pkg:composer/goldnead/statamic-community
Requires
- php: ^8.2
- goldnead/statamic-teams: ^0.4
- laravel/framework: ^12.40|^13.0
- statamic/cms: ^6.0
Requires (Dev)
- goldnead/statamic-accounts: ^0.5
- larastan/larastan: ^3.13
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0 || ^11.0
- phpunit/phpunit: ^11.0 || ^12.0
Suggests
- goldnead/statamic-accounts: Posts, comments, reactions and memberships of a deleted account are erased, and appear in the data export.
- goldnead/statamic-notifications: Notify on new posts and comments (listen to PostCreated, CommentCreated).
Provides
None
Conflicts
None
Replaces
None
README
Curated rooms, posts, comments and reactions with a chronological feed. Posting as a team uses goldnead/statamic-teams. The public side has no routes and no UI: a site builds those on the services. The Control Panel has a moderation backend.
Requirements
- PHP 8.2+, Statamic 6, Laravel 12.40+ or 13
goldnead/statamic-teams(posting as a team, thepost as teampermission)- optional:
goldnead/statamic-accounts(confirmed accounts, personal data export and erasure)
Installation
composer require goldnead/statamic-community php artisan migrate php artisan db:seed --class='Goldnead\Community\Seeders\RoomSeeder' php artisan vendor:publish --tag=community-config # optional
goldnead/statamic-teams and goldnead/statamic-accounts are not on Packagist yet. Until they are, the installing site needs their repositories in its own composer.json (repositories is only read from the root package).
Usage
use Goldnead\Community\Services\PostService; $post = app(PostService::class)->create($user, '<p>Hallo Chor</p>', room: $room, title: 'Willkommen'); $feed = app(PostService::class)->feed($room)->paginate(20);
CommentService, ReactionService and RoomService work the same way. Every write is authorised by CommunityPolicy and throws AuthorizationException when the account may not do it, or CommunityException for an empty, oversized or invalid input.
Control Panel
A Community section in the navigation, with Posts, Comments and Rooms, and a dashboard widget (add it under widgets in config/statamic/cp.php with type => community).
- Posts and Comments: core's listing with search and filters (room, region, status, visibility, author person or team). Approve (pre-moderation), hide with a reason, show again and delete work per row and in bulk, through
PostServiceandCommentService. - Rooms: list with member and post counts, create and edit with core's publish form.
kindmust be one ofRoom::KINDS. Pin one published post per room; it leads that room's feed. - Widget: posts and comments of the last 7 days, posts waiting for approval, hidden items.
- Authors appear by display name only (a team post by the team name), never by e-mail address or account id, and the search never looks at either.
Permissions: view community opens the screens, moderate community (below it) lets you change things.
The CP is written in English; lang/de.json translates it. The built assets in dist/ are committed; after changing resources/ run npm ci && npm run build (CI fails when dist/ is stale).
Model
Room:region,styleortopic(validated againstRoom::KINDS), curated flag,archived_at, an optional pinned post.RoomMembershipper account.Post: author (account, optionally as a team), category, room, region, title, sanitised HTML body,status(published,pending),hiddenwith an optional reason.Comment: one level of replies, sanitised HTML body,hidden.Reaction: one per account and target (post or comment); reacting again changes the kind, and a double click returns the existing reaction instead of failing.
Rules
- Curated rooms live in
community.rooms.RoomSeeder(orRoomService::syncCurated()) creates them by slug, idempotent. - Posting, commenting and reacting need a confirmed account (
email_verified_at, oraccounts.verification.field).community.require_confirmedturns this off. - As a team: only with the team permission
post as team(owner has it). - Edit: author only, and only while the account is confirmed. Delete: author, or a moderator (
moderate community). Moderators hide and restore withPostService::hide(). - Pre-moderation (
community.pre_moderation, default off): a new post ispendinguntilPostService::approve(). Approving is atomic: of two moderators approving at once, only one publishes and firesPostCreated. Moderators and accounts withtrusted_afterpublished posts skip the queue. Off means nobody on a fresh install is silenced; on means the first post of a newcomer needs a moderator. PostService::feed($room, $region)returns a query ordered bypublished_at, then id. Reactions never change the order (the one pinned post of a room leads its feed). An index on(status, hidden, published_at)serves it. Pending and hidden posts are not in it.- Bodies keep only
community.allowed_tagsandallowed_attributes: no scripts, no event handlers, links only withhttp,https,mailtoortel(or relative). Bodies over 60000 bytes are refused, titles and regions are cut at 255 characters. PostCreatedfires when a post becomes public (creation, or approval),CommentCreatedper comment, both after commit.
Personal data
With goldnead/statamic-accounts, CommunityContributor is tagged for export and erasure. Erasing an account deletes its posts, comments, reactions and memberships, plus comments on its posts, replies to its comments and the reactions to them.
Tests
composer install
vendor/bin/phpunit
vendor/bin/phpunit -c phpunit.mysql.xml # needs a MySQL server, see the file
vendor/bin/pint --test
vendor/bin/phpstan analyse

