evgip/w3a

A custom modular PHP MVC forum matching the HMVC pattern.

Maintainers

Package info

github.com/evgip/w3a

Type:project

pkg:composer/evgip/w3a

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 3

Open Issues: 0

v0.1.2 2026-07-05 17:55 UTC

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.

W3A home

W3A admin

W3A setting

πŸš€ Features

Core Functionality

  • Stories β€” Submit news with URL or text content
  • Threaded Comments β€” Nested comments with unlimited depth
  • Global Comments Feed β€” /comments page showing all recent comments across the site (Lobsters-style)
  • User Comments β€” /user/{username}/comments page showing all comments by a user
  • User Stories β€” /user/{username}/stories page 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 /comments page
  • 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 :root and [data-theme="dark"]
  • Keyboard Shortcuts β€” C to 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
Email 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

  1. Create a MySQL database:
CREATE DATABASE w3a CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  1. 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 Email 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!

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. 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

⭐ If you find this project useful, please star it on GitHub!