Skip to main content

Overview

ForkBB provides a robust user management system with authentication, user profiles, group-based permissions, and granular access control. The system is built around the User model and supports various user states and roles.

User Model

The core user functionality is implemented in app/Models/User/User.php:22. Each user has properties and computed attributes that define their permissions and capabilities.

User Status Types

Guest Users

Anonymous visitors with limited permissions. Determined by FORK_GROUP_GUEST group ID or user ID < 1.

Unverified Users

Registered users pending email verification. Restricted from most forum activities.

Admin Users

Full system access with FORK_GROUP_ADMIN group. Can override all permissions.

Moderators

Users with moderation rights for specific forums. Can manage content in assigned areas.

User Groups

Groups define sets of permissions that are inherited by all users in that group. The system uses predefined group constants:
app/Models/User/User.php
protected function getisGuest(): bool
{
    return FORK_GROUP_GUEST === $this->group_id
        || null === $this->group_id
        || $this->id < 1;
}

protected function getisAdmin(): bool
{
    return FORK_GROUP_ADMIN === $this->group_id;
}

protected function getisAdmMod(): bool
{
    return $this->isAdmin
        || 1 === $this->g_moderator;
}

Default Groups

System Groups: FORK_GROUP_ADMIN, FORK_GROUP_MOD, FORK_GROUP_GUEST, and FORK_GROUP_MEMBER cannot be deleted and serve as the foundation of the permission system.

User Authentication

Users are authenticated and their session is maintained throughout their visit:

Current User

The active user is always available via the container:
$currentUser = $this->c->user;

if ($currentUser->isGuest) {
    // Handle guest user
} elseif ($currentUser->isAdmin) {
    // Handle administrator
}

User Status Checks

app/Models/User/User.php
// Check if user is banned
protected function getisBanByName(): bool
{
    return ! $this->isAdmin
        && $this->c->bans->banFromName($this->username) > 0;
}

// Check moderator status for specific forum
public function isModerator(Model $model): bool
{
    if (1 !== $this->g_moderator) {
        return false;
    }
    
    while (! $model instanceof Forum) {
        $model = $model->parent;
        
        if (! $model instanceof Model) {
            throw new RuntimeException('Moderator\'s rights can not be found');
        }
    }
    
    return isset($model->moderators[$this->id]);
}

User Profiles

Each user has a customizable profile with various attributes:
app/Models/User/User.php
// Link to user profile page
protected function getlink(): ?string
{
    if ($this->isGuest) {
        return null;
    } else {
        return $this->c->Router->link(
            'User',
            [
                'id'   => $this->id,
                'name' => $this->c->Func->friendly($this->username),
            ]
        );
    }
}

User Avatars

1

Avatar Storage

Avatars are stored in the configured o_avatars_dir directory and linked to user profiles.
2

Avatar Retrieval

app/Models/User/User.php
protected function getavatar(): ?string
{
    $file = $this->getModelAttr('avatar');
    
    if (! empty($file)) {
        $file = $this->c->config->o_avatars_dir . '/' . $file;
        $path = $this->c->DIR_PUBLIC . $file;
        
        if (\is_file($path)) {
            return $this->c->PUBLIC_URL . $file;
        }
    }
    
    return null;
}
3

Avatar Deletion

Admins and users can delete avatars, which removes the file and clears the reference.

User Titles

app/Models/User/User.php
public function title(): string
{
    if ($this->isGuest) {
        return __('Guest');
    } elseif ($this->isBanByName) {
        return __('Banned');
    } elseif ('' != $this->title) {
        return $this->censorTitle;
    } elseif ('' != $this->g_user_title) {
        return $this->censorG_user_title;
    } elseif ($this->isUnverified) {
        return __('Unverified');
    } else {
        return __('Member');
    }
}

User Signatures

Users can have signatures that appear below their posts:
app/Models/User/User.php
protected function getisSignature(): bool
{
    return $this->g_sig_length > 0
        && $this->g_sig_lines > 0
        && '' != $this->signature;
}

protected function gethtmlSign(): string
{
    return $this->isSignature
        ? $this->c->censorship->censor($this->c->Parser->parseSignature($this->signature))
        : '';
}
Signatures are parsed with BBCode support (if enabled) and run through the censorship filter.

User Preferences

Display Settings

Users can customize their viewing experience:
app/Models/User/User.php
// Topics per page
protected function getdisp_topics(): int
{
    $attr = $this->getModelAttr('disp_topics');
    
    if ($attr < 10) {
        $attr = $this->c->config->i_disp_topics_default;
    }
    
    return $attr;
}

// Posts per page
protected function getdisp_posts(): int
{
    $attr = $this->getModelAttr('disp_posts');
    
    if ($attr < 10) {
        $attr = $this->c->config->i_disp_posts_default;
    }
    
    return $attr;
}

Language and Style

Users can select their preferred language and visual style:
  • Language selection from available translations
  • Style/theme selection from installed themes
  • Defaults to system-wide settings for guests

User Statistics

The system tracks various user statistics:
  • Post Count: Total number of posts created
  • Topic Count: Total number of topics started
  • Last Visit: Timestamp of last login
  • Registration Date: Account creation date
  • Online Status: Currently active users

Online Status

app/Models/User/User.php
protected function getonline(): bool
{
    return $this->c->Online->isOnline($this);
}

User Promotion

Administrators and moderators can promote users based on post count:
app/Models/User/User.php
public function linkPromote(Post $post): ?string
{
    if (
        (
            $this->isAdmin
            || (
                $this->isAdmMod
                && 1 === $this->g_mod_promote_users
            )
        )
        && $this->id !== $post->user->id
        && 0 < $post->user->g_promote_min_posts * $post->user->g_promote_next_group
        && ! $post->user->isBanByName
    ) {
        return $this->c->Router->link(
            'AdminUserPromote',
            [
                'uid' => $post->user->id,
                'pid' => $post->id,
            ]
        );
    } else {
        return null;
    }
}

Email Integration

Email Privacy Settings

Users control how their email is exposed:
app/Models/User/User.php
protected function getlinkEmail(): ?string
{
    if (
        $this->c->user->isGuest
        || $this->id === $this->c->user->id
        || empty($this->email)
    ) {
        return '';
    } elseif (2 === $this->email_setting) {
        return null; // Hidden
    } elseif (
        0 === $this->email_setting
        || (
            $this->isGuest
            && $this->c->user->isAdmMod
        )
    ) {
        return 'mailto:' . $this->censorEmail; // Direct mailto
    } elseif (
        1 === $this->email_setting
        && (
            1 === $this->c->user->g_send_email
            || $this->c->user->isAdmin
        )
    ) {
        return $this->c->Router->link('SendEmail', ['id' => $this->id]); // Form
    } else {
        return '';
    }
}
Email addresses are normalized and censored to prevent harvesting by bots.

Username Normalization

Usernames are normalized for consistent lookups:
app/Models/User/User.php
protected function getusername_normal(): string
{
    return $this->c->users->normUsername($this->username);
}

Private Messaging Access

Users can be granted access to the private messaging system:
app/Models/User/User.php
protected function getusePM(): bool
{
    return 1 === $this->c->config->b_pm
        && (
            1 === $this->g_pm
            || $this->isAdmin
        );
}

Moderation

Learn about user bans, reports, and moderation tools

Private Messaging

Understand the PM system and user communication

Best Practices

Always check user permissions before allowing actions. Use isAdmin, isAdmMod, and isModerator() methods consistently.
Always handle guest users gracefully. Check isGuest before accessing user-specific features.
Verify isBanByName before allowing user actions, as bans override most permissions.