This commit is contained in:
2026-03-20 21:17:26 +01:00
parent 1a62fcb81d
commit 29c3ff8572
229 changed files with 13147 additions and 2577 deletions

View File

@@ -24,6 +24,8 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use Illuminate\Queue\Events\JobFailed;
use App\Services\ReceivedCommentsInboxService;
use Klevze\ControlPanel\Framework\Core\Menu;
class AppServiceProvider extends ServiceProvider
{
@@ -32,6 +34,11 @@ class AppServiceProvider extends ServiceProvider
*/
public function register(): void
{
$this->app->singleton(
\App\Services\Countries\CountryRemoteProviderInterface::class,
\App\Services\Countries\CountryRemoteProvider::class,
);
// Bind UploadDraftService interface to implementation
$this->app->singleton(UploadDraftServiceInterface::class, function ($app) {
return new UploadDraftService($app->make('filesystem'));
@@ -55,6 +62,8 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
$this->registerCpadMenuItems();
// Map the 'legacy' view namespace to resources/views/_legacy so all
// view('legacy::foo') and @include('legacy::foo') calls resolve correctly
// after the folder was renamed from legacy/ to _legacy/.
@@ -66,6 +75,7 @@ class AppServiceProvider extends ServiceProvider
$this->configureDownloadRateLimiter();
$this->configureArtworkRateLimiters();
$this->configureReactionRateLimiters();
$this->configureSocialRateLimiters();
$this->configureSettingsRateLimiters();
$this->configureMailFailureLogging();
@@ -91,10 +101,22 @@ class AppServiceProvider extends ServiceProvider
\App\Events\Posts\PostCommented::class,
\App\Listeners\Posts\SendPostCommentedNotification::class,
);
Event::listen(
\App\Events\Posts\PostCommented::class,
\App\Listeners\Posts\AwardXpForPostCommented::class,
);
Event::listen(
\App\Events\Achievements\AchievementCheckRequested::class,
\App\Listeners\Achievements\CheckUserAchievements::class,
);
Event::listen(
\App\Events\Achievements\UserXpUpdated::class,
\App\Listeners\Achievements\CheckUserAchievements::class,
);
// Provide toolbar counts and user info to layout views (port of legacy toolbar logic)
View::composer(['layouts.nova', 'layouts.nova.*'], function ($view) {
$uploadCount = $favCount = $msgCount = $noticeCount = 0;
$uploadCount = $favCount = $msgCount = $noticeCount = $receivedCommentsCount = 0;
$avatarHash = null;
$displayName = null;
$userId = null;
@@ -130,11 +152,18 @@ class AppServiceProvider extends ServiceProvider
}
try {
$noticeCount = DB::table('notification')->where('user_id', $userId)->where('new', 1)->count();
$noticeCount = DB::table('notifications')->where('user_id', $userId)->whereNull('read_at')->count();
} catch (\Throwable $e) {
$noticeCount = 0;
}
try {
$receivedCommentsCount = $this->app->make(ReceivedCommentsInboxService::class)
->unreadCountForUser(Auth::user());
} catch (\Throwable $e) {
$receivedCommentsCount = 0;
}
try {
$profile = DB::table('user_profiles')->where('user_id', $userId)->first();
$avatarHash = $profile->avatar_hash ?? null;
@@ -145,7 +174,7 @@ class AppServiceProvider extends ServiceProvider
$displayName = Auth::user()->name ?: (Auth::user()->username ?? '');
}
$view->with(compact('userId','uploadCount', 'favCount', 'msgCount', 'noticeCount', 'avatarHash', 'displayName'));
$view->with(compact('userId','uploadCount', 'favCount', 'msgCount', 'noticeCount', 'receivedCommentsCount', 'avatarHash', 'displayName'));
});
// Replace the framework HandleCors with our ConditionalCors so the
@@ -315,6 +344,27 @@ class AppServiceProvider extends ServiceProvider
});
}
private function configureSocialRateLimiters(): void
{
RateLimiter::for('social-write', function (Request $request): array {
$userId = $request->user()?->id ?? 'guest';
return [
Limit::perMinute(60)->by('social-write:user:' . $userId),
Limit::perMinute(120)->by('social-write:ip:' . $request->ip()),
];
});
RateLimiter::for('social-read', function (Request $request): array {
$userId = $request->user()?->id ?? 'guest';
return [
Limit::perMinute(240)->by('social-read:user:' . $userId),
Limit::perMinute(480)->by('social-read:ip:' . $request->ip()),
];
});
}
private function configureSettingsRateLimiters(): void
{
RateLimiter::for('username-check', function (Request $request): Limit {
@@ -336,4 +386,20 @@ class AppServiceProvider extends ServiceProvider
return Limit::perHour(1)->by($key);
});
}
private function registerCpadMenuItems(): void
{
if (! class_exists(Menu::class)) {
return;
}
try {
/** @var Menu $menu */
$menu = $this->app->make(Menu::class);
$menu->addHeaderItem('Countries', 'fa-solid fa-flag', 'admin.cp.countries.main');
$menu->addItem('Users', 'Countries', 'fa-solid fa-flag', 'admin.cp.countries.main');
} catch (\Throwable) {
// Control panel menu registration should never block the app boot.
}
}
}