Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ See:
- `docs/public-api.md` (HTTP + WebSocket + frontend entrypoints + reusable PHP APIs)
- `docs/api.md` (message reaction HTTP and WebSocket contracts)
- `docs/user-profiles.md` (profile settings, avatars, themes, and WebSocket presence)
- `docs/channels.md` (public channels, private DMs, APIs, WebSocket routing, and migration operations)

## Troubleshooting

Expand Down
9 changes: 9 additions & 0 deletions app/Config/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
$routes->get('messages', 'MessagesController::list', ['filter' => ['apiFormat', 'auth']]);
$routes->get('messages/search', 'MessagesController::search', ['filter' => ['apiFormat', 'auth']]);
$routes->post('messages', 'MessagesController::create', ['filter' => ['apiFormat', 'auth', 'rate:write', 'validate:message']]);
$routes->get('channels', 'ChannelsController::list', ['filter' => ['apiFormat', 'auth']]);
$routes->post('channels', 'ChannelsController::create', ['filter' => ['apiFormat', 'auth', 'rate:write']]);
$routes->patch('channels/(:num)', 'ChannelsController::update/$1', ['filter' => ['apiFormat', 'auth', 'rate:write']]);
$routes->post('channels/(:num)/join', 'ChannelsController::join/$1', ['filter' => ['apiFormat', 'auth', 'rate:write']]);
$routes->post('channels/(:num)/leave', 'ChannelsController::leave/$1', ['filter' => ['apiFormat', 'auth', 'rate:write']]);
$routes->get('channels/(:num)/messages', 'ChannelsController::messages/$1', ['filter' => ['apiFormat', 'auth']]);
$routes->get('channels/(:num)/messages/search', 'ChannelsController::searchMessages/$1', ['filter' => ['apiFormat', 'auth']]);
$routes->post('channels/(:num)/messages', 'ChannelsController::createMessage/$1', ['filter' => ['apiFormat', 'auth', 'rate:write']]);
$routes->post('dms', 'ChannelsController::createDm', ['filter' => ['apiFormat', 'auth', 'rate:write']]);
$routes->get('messages/(:num)/reactions', 'ReactionsController::list/$1', ['filter' => ['apiFormat', 'auth']]);
$routes->post('messages/(:num)/reactions', 'ReactionsController::create/$1', ['filter' => ['apiFormat', 'auth', 'rate:react']]);
$routes->delete('messages/(:num)/reactions/(:segment)', 'ReactionsController::delete/$1/$2', ['filter' => ['apiFormat', 'auth', 'rate:react']]);
Expand Down
15 changes: 14 additions & 1 deletion app/Config/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

use App\Contracts\AuditLogger as AuditLoggerContract;
use App\Contracts\AuditLogRepository;
use App\Contracts\ChannelRepository;
use App\Contracts\ChatFormatter as ChatFormatterContract;
use App\Contracts\ChatRepository;
use App\Contracts\CspReportRepository;
use App\Contracts\PushSubscriptionRepository;
use App\Contracts\ReactionRepository;
use App\Contracts\UserRepository;
use App\Controllers\Api\V1\ChannelsController;
use App\Controllers\Api\V1\MessagesController;
use App\Controllers\Api\V1\PushSubscriptionsController;
use App\Controllers\Api\V1\ReactionsController;
Expand All @@ -22,6 +24,7 @@
use App\Core\Application;
use App\Libraries\ErrorHandler;
use App\Models\AuditLogModel;
use App\Models\ChannelModel;
use App\Models\ChatModel;
use App\Models\CspReportModel;
use App\Models\MessageReactionModel;
Expand Down Expand Up @@ -71,8 +74,9 @@ public static function controller(string $controllerClass): Controller
Home::class => new Home(),
Chat::class => new Chat(static::chatRepository(), static::chatFormatter()),
MessagesController::class => new MessagesController(static::chatRepository(), static::chatFormatter()),
ChannelsController::class => new ChannelsController(static::channelRepository(), static::chatRepository(), static::userRepository()),
PushSubscriptionsController::class => new PushSubscriptionsController(static::pushSubscriptionRepository()),
ReactionsController::class => new ReactionsController(static::reactionRepository()),
ReactionsController::class => new ReactionsController(static::reactionRepository(), static::channelRepository()),
Auth::class => new Auth(static::userRepository(), static::auditLogger()),
Profile::class => new Profile(static::userRepository()),
CspReport::class => new CspReport(static::cspReportRepository()),
Expand All @@ -90,6 +94,15 @@ public static function chatRepository(bool $getShared = true): ChatRepository
return new ChatModel();
}

public static function channelRepository(bool $getShared = true): ChannelRepository
{
if ($getShared) {
return static::getSharedInstance('channelRepository');
}

return new ChannelModel();
}

public static function userRepository(bool $getShared = true): UserRepository
{
if ($getShared) {
Expand Down
38 changes: 38 additions & 0 deletions app/Contracts/ChannelRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace App\Contracts;

interface ChannelRepository
{
public function generalChannelId(): int;

public function ensureGeneralMembership(int $userId): int;

/** @return list<array<string, mixed>> */
public function listForUser(int $userId): array;

/** @return array<string, mixed>|null */
public function findChannel(int $channelId): ?array;

public function isMember(int $channelId, int $userId): bool;

public function isCreator(int $channelId, int $userId): bool;

public function createPublic(string $name, string $slug, ?string $topic, int $creatorId): int|false;

public function join(int $channelId, int $userId): bool;

public function leave(int $channelId, int $userId): bool;

/** @param array{name?: string, slug?: string, topic?: ?string, archived_at?: ?string} $changes */
public function updateChannel(int $channelId, array $changes): bool;

public function findOrCreateDm(int $firstUserId, int $secondUserId): int|false;

/** @return list<int> */
public function memberIds(int $channelId): array;

public function markRead(int $channelId, int $userId): bool;

public function messageChannelId(int $messageId): ?int;
}
5 changes: 3 additions & 2 deletions app/Contracts/ChatRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface ChatRepository
* pagination: array<string, int|bool|float>
* }
*/
public function getMsgPaginated(int $page = 1, int $perPage = 10): array;
public function getMsgPaginated(int $page = 1, int $perPage = 10, ?int $channelId = null): array;

/**
* @return array{
Expand All @@ -25,7 +25,8 @@ public function searchMessages(
?int $to = null,
int $page = 1,
int $perPage = 10,
?int $channelId = null,
): array;

public function insertMsg(string $name, string $message, int $current): int|bool;
public function insertMsg(string $name, string $message, int $current, ?int $channelId = null): int|bool;
}
Loading
Loading