evgip / w3a
A custom modular PHP MVC forum matching the HMVC pattern.
Requires
- php: >=8.0
- ext-curl: *
- ext-fileinfo: *
- ext-gd: *
- ext-json: *
- ext-mbstring: *
- ext-openssl: *
- ext-pdo: *
- ext-pdo_mysql: *
- erusev/parsedown: ^1.8
- phpmailer/phpmailer: ^7.1.1
This package is auto-updated.
Last update: 2026-07-13 08:27:35 UTC
README
π¬π§ English | π·πΊ Π ΡΡΡΠΊΠΈΠΉ
A modern, lightweight news aggregator built with PHP 8.1+ and MySQL, inspired by Hacker News and Lobste.rs. Features modular HMVC architecture, custom DI container, event-driven system, RSS feeds, bookmarks, user muting, and comprehensive moderation tools.
π Features
Core Functionality
- Stories β Submit news with URL or text content
- Threaded Comments β Nested comments with unlimited depth
- Global Comments Feed β
/commentspage showing all recent comments across the site (Lobsters-style) - User Comments β
/user/{username}/commentspage showing all comments by a user - User Stories β
/user/{username}/storiespage showing user's publication history - Voting System β Upvote/downvote; downvoting requires minimum karma
- Authentication β Registration, login, "Remember me", email activation, password recovery
- User Profiles β Bio, avatar, karma, activity feed
- Private Messages β Direct messaging between users
- Notifications β Internal notifications for replies, story comments, mentions, moderator actions
- Tag Wiki β Wiki pages linked to tags with edit history and editing permissions
- Edit Suggestions β Users can suggest changes to stories (tags, title) that go through moderation
Personalization & Tracking
- Read Ribbons β Track read comments in each story; "+N new" badges in the feed
- New Comment Highlighting β Visual highlighting of unread comments in stories
- Global Comment Tracking β "β New comments β" divider on
/commentspage - Saved Stories (Bookmarks) β Save stories to a personal "read later" list at
/saved - User Muting β Hide stories, comments, and notifications from muted users
- Tag Filters β Users can hide stories by uninteresting tags
- Story Following β Get notifications for new comments in followed stories
- Notification Settings β Granular control: email, internal notifications, by event type
RSS Feeds
/rssβ All new stories/t/{tag}/rssβ Stories by specific tag/u/{username}/rssβ Stories by user/comments/rssβ All new comments- Browser auto-discovery via
<link rel="alternate">
Ranking & Search
- Hotness Algorithm β Custom formula considering score, age, and tag weight modifier
- Wilson Score Interval β Statistically sound comment ranking by confidence
- Tag System β Stories are tagged; tags are organized into categories
- Full-Text Search β Search across stories and comments
Moderation & Trust
- Invitation System β Can disable open registration; only users with sufficient karma can invite
- Flag System β Users can flag content (spam, abuse, duplicates, etc.); content auto-hidden at threshold
- Domain Management β Ban entire domains; stories from banned domains auto-rejected
- User Bans β Temporary or permanent bans with reason
- IP Bans β Block abusive IP addresses
- Moderator Notes β Private notes on user accounts, visible only to staff
- Moderation Activity Log β Daily statistics of moderator actions
- Audit Log β Complete trail of every administrative action
- Public Moderation Log β Transparency of moderator actions for all users
Architecture & Developer Experience
- DI Container β Lightweight dependency injection container
- Event Dispatcher β Observer pattern:
StoryCreated,CommentCreated,CommentUpdated,UserBanned,FlagResolved, etc. - Middleware Pipeline β HTTP middleware for auth, CSRF, rate limiting, security headers
- Modular HMVC β Each feature is a self-contained module (Controllers / Models / Views / Services / routes)
- Service Providers β Per-module service registration
- Separation of Concerns β Comments, bookmarks, muting, RSS, wiki β in separate modules
Security
- Password Hashing β bcrypt with automatic salting
- CSRF Protection β Token verification on every state-changing form
- SQL Injection Protection β Prepared PDO statements everywhere
- XSS Protection β Output escaping via
htmlspecialchars() - Rate Limiting β Configurable limits per action and IP
- Session Security β HTTP-only cookies, session regeneration
- Input Validation β Server-side validation on every endpoint
- Security Headers β Strict-Transport-Security, X-Frame-Options, etc.
- CAPTCHA β Built-in CAPTCHA for sensitive actions
- Firewall β Request filtering and IP reputation checking
User Experience
- Responsive Design β Mobile-friendly interface
- Light & Dark Themes β Auto-detection from system settings + manual toggle via
localStorage - CSS Variables β Unified theming system via
:rootand[data-theme="dark"] - Keyboard Shortcuts β
Cto collapse comments and others - Markdown Support β Text formatting in comments and stories (via Parsedown)
- Comment Thread Collapsing β With state persistence in
localStorage - Markdown Toolbar β Formatting buttons with live preview
π οΈ Tech Stack
| Component | Technology |
|---|---|
| Backend | PHP 8.1+ (no framework, custom HMVC + DI) |
| Database | MySQL 8.0+ with PDO |
| Frontend | Vanilla JavaScript, CSS3 with CSS Variables |
| Architecture | Modular HMVC, Event Dispatcher, Service Provider |
| PHPMailer 7.x | |
| Markdown | Parsedown 1.8+ |
| Security | CSRF tokens, rate limiting, bcrypt, CAPTCHA |
| Server | Apache / Nginx with URL rewriting |
π¦ Installation
Install via Composer:
composer create-project evgip/w3a
Requirements
- PHP 8.1 or higher
- MySQL 8.0 or higher
- Apache / Nginx with URL rewriting enabled
- Composer (optional, for development)
Step 1 β Clone the Repository
git clone https://github.com/evgip/w3a.git
cd w3a
Step 2 β Create Database
- Create a MySQL database:
CREATE DATABASE w3a CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- Import the schema:
mysql -u your_username -p w3a < db/schema.sql
Step 3 β Configure Application
Rename .env.example to .env and fill in your settings.
Step 4 β Set Permissions
chmod -R 755 storage/ chmod -R 755 public/
Step 5 β Configure Web Server
Apache (.htaccess included):
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L]
Nginx:
location / { try_files $uri $uri/ /index.php?$query_string; }
Step 6 β Default Accounts
| Role | Password | |
|---|---|---|
| Administrator | admin@example.com | password |
| User | test@test.ru | password |
β οΈ Change these passwords immediately after first login.
π Project Structure
w3a/
βββ app/
β βββ Config/
β β βββ config.php # Application settings
β βββ Core/
β β βββ Container.php # DI container
β β βββ Router.php # URL routing
β β βββ Controller.php # Base controller
β β βββ Model.php # Base model
β β βββ Database.php # PDO wrapper
β β βββ Session.php # Session management
β β βββ Request.php # HTTP request handling
β β βββ Security.php # Security headers
β β βββ View.php # Template rendering
β β βββ Validator.php # Input validation
β β βββ Audit.php # Audit log
β β βββ RateLimiter.php # Rate limiting
β β βββ Captcha.php # CAPTCHA generator
β β βββ Firewall.php # Request firewall
β β βββ Logger.php # Application logger
β β βββ Benchmark.php # Performance measurement
β β βββ SvgChart.php # SVG chart generator
β β βββ ModuleServiceProvider.php
β β βββ Events/ # Event system
β β β βββ Event.php
β β β βββ EventDispatcher.php
β β β βββ StoryCreated.php
β β β βββ StoryDeleted.php
β β β βββ CommentCreated.php
β β β βββ CommentUpdated.php
β β β βββ CommentDeleted.php
β β β βββ CommentRestored.php
β β β βββ UserBanned.php
β β β βββ FlagResolved.php
β β β βββ ...
β β βββ Middleware/ # HTTP middleware
β β
β βββ Providers/
β β βββ EventServiceProvider.php
β β
β βββ Lang/ # Localization files
β β
β βββ Modules/ # Feature modules (HMVC)
β β βββ Admin/ # Admin panel
β β βββ Auth/ # Authentication
β β βββ Captcha/ # CAPTCHA generation
β β βββ Comments/ # Comments (global feed, CRUD)
β β βββ Common/ # Shared views, base CSS
β β βββ Content/ # Markdown processor
β β βββ Errors/ # Error handling
β β βββ Flags/ # Content flags
β β βββ Invitations/ # Invitation system
β β βββ Mail/ # Email sending
β β βββ Messages/ # Private messages
β β βββ Moderations/ # Moderation tools
β β βββ Muted/ # User muting
β β βββ Notifications/ # User notifications
β β βββ Origins/ # Domain management
β β βββ Pages/ # Static pages
β β βββ Rss/ # RSS feeds
β β βββ Saved/ # Bookmarks (saved stories)
β β βββ Search/ # Full-text search
β β βββ Stories/ # Stories and feed
β β βββ Suggestions/ # Edit suggestions
β β βββ Tags/ # Tags and categories
β β βββ Users/ # User profiles and settings
β β βββ Votes/ # Voting system
β β βββ Wiki/ # Tag wiki pages
β β
β βββ helpers.php # Global helper functions
β
βββ public/ # Web root
β βββ index.php # Entry point
β βββ css/
β βββ js/
β βββ images/
β
βββ storage/ # Writable storage
β βββ logs/ # Application logs
β βββ cache/ # Cache files
β
βββ db/
β βββ schema.sql # Database schema
β
βββ composer.json
βββ README.md
π Database Schema
Content
| Table | Description |
|---|---|
stories |
Stories (URL or text), with hotness score |
comments |
Threaded comments with confidence score |
votes |
Polymorphic up/down votes |
tags |
Tag definitions with hotness modifier |
taggings |
Many-to-many relationship between stories and tags |
categories |
Tag categories |
tag_filters |
User tag exclusions |
wiki_pages |
Wiki pages linked to tags |
wiki_revisions |
Wiki page edit history |
wiki_permissions |
Wiki editing permissions by tag |
suggestions |
Story edit suggestions (tags, titles) |
Users & Authentication
| Table | Description |
|---|---|
users |
User accounts (role: user / moderator / admin) |
user_profiles |
Bio, avatar |
user_settings |
Notification settings |
user_bans |
Temporary / permanent bans |
banned_ips |
IP blocks |
password_resets |
Password recovery tokens |
email_activations |
Email confirmation tokens |
invitations |
Invitation codes |
invitation_requests |
Public invitation requests |
Social & Personalization
| Table | Description |
|---|---|
conversations |
Private message conversations |
messages |
Individual messages |
user_notifications |
Internal notifications |
read_ribbons |
Last read comment in a story |
saved_stories |
User bookmarks (saved stories) |
muted_users |
Muted/ignored users |
Moderation
| Table | Description |
|---|---|
flags |
Content flags (spam, abuse, etc.) |
domains |
Banned / allowed domains |
mod_notes |
Private moderator notes about users |
mod_activity |
Daily moderator action counts |
audit_logs |
Complete administrative action log |
Infrastructure
| Table | Description |
|---|---|
sessions |
Active user sessions |
rate_limits |
Rate limit counters |
Full schema with indexes and foreign keys β in db/schema.sql.
πΊοΈ URL Map
Public Pages
| URL | Description |
|---|---|
/ |
Main story feed |
/story/{id} |
View story with comments |
/comments |
Global comments feed |
/comments/rss |
RSS of all new comments |
/rss |
RSS of all new stories |
/t/{tag} |
Stories with specific tag |
/t/{tag}/rss |
RSS of stories by tag |
/t/{tag}/wiki |
Wiki pages for tag |
/t/{tag}/wiki/{slug} |
Specific wiki page |
/u/{username} |
User profile |
/u/{username}/stories |
User's publications |
/u/{username}/comments |
User's comments |
/u/{username}/rss |
RSS of user's publications |
/search |
Full-text search |
/tags |
List of all tags |
/stats |
Site statistics |
Authenticated Pages
| URL | Description |
|---|---|
/saved |
User bookmarks |
/muted |
List of muted users |
/notifications |
Internal notifications |
/messages |
Private messages |
/settings |
Account settings |
/tags/filters |
User tag filters |
/story/create |
Create new story |
π€ Contributing
Contributions are welcome!
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
π License
This project is licensed under the MIT License β see the LICENSE file for details.
π Acknowledgments
- Inspired by the functionality and design of Hacker News and Lobste.rs
- Speed and simplicity philosophy from HLEB framework
- Built with pure PHP β no heavy frameworks
- Modular HMVC architecture with DI and events
π§ Contact
- Author: Evgeny Konchik (Evg)
- Repository: https://github.com/evgip/w3a
- Bugs & Suggestions: https://github.com/evgip/w3a/issues
β If you find this project useful, please star it on GitHub!


