app->bind( 'Matchish\ScoutElasticSearch\ElasticSearch\EloquentHitsIteratorAggregate', 'app\Overrides\Matchish\ScoutElasticSearch\ElasticSearch\EloquentHitsIteratorAggregate' ); // Override WireChat Attachment model so URL generation returns the authenticated // controller route instead of calling Storage::disk('local')->url() which throws. $this->app->bind( \Namu\WireChat\Models\Attachment::class, \App\Models\WireChatAttachment::class ); // Register custom Blade directive to conditionally check on activeProfile type (User, Organization, Bank, Admin) Blade::directive('profile', function ($expression) { return ""; }); Blade::directive('endprofile', function () { return ""; }); // Register PresenceService $this->app->singleton(PresenceService::class); // Register the poll question types enabled in the platform config $this->app->singleton(QuestionTypeRegistry::class); // Register custom SocialShare service to support custom icons $this->app->bind(\Enflow\SocialShare\SocialShare::class, \App\Services\CustomSocialShare::class); } /** * Bootstrap any application services. * * @return void */ public function boot() { // Fix manifest not found error: enforce the correct location of the manifest.json file Vite::useManifestFilename('.vite/manifest.json'); // Fix 'Specified key was too long error' when storing emoji's as string in DB. Schema::defaultStringLength(191); if (!Collection::hasMacro('paginate')) { Collection::macro( 'paginate', function ($perPage = 15, $page = null, $options = []) { $page = $page ?: (Paginator::resolveCurrentPage() ?: 1); return (new LengthAwarePaginator( $this->forPage($page, $perPage), $this->count(), $perPage, $page, $options )) ->withPath(''); } ); } // Manual Elasticsearch driver registration resolve(EngineManager::class)->extend('matchish-elasticsearch', function ($app) { return resolve(ElasticSearchEngine::class); }); // Register Guest Layout Blade::component('guest-layout', GuestLayout::class); // Override vendor flatpickr component to fix UTC timezone date shift bug Blade::component('flatpickr', \App\Overrides\Asdh\LaravelFlatpickr\Components\Flatpickr::class); // Register lay-outs depending ob authorization Blade::directive('layout', function () { return Auth::check() ? 'app-layout' : 'guest-layout'; }); Blade::if('usercan', function ($permission) { // Get the web user (all permissions are assigned to Users, not to Organizations/Banks/Admins) $webUser = Auth::guard('web')->user(); if (!$webUser) { return false; } // Use request-level cache to prevent recursion during view rendering static $permissionCache = []; $cacheKey = $webUser->id . '_' . $permission; if (isset($permissionCache[$cacheKey])) { return $permissionCache[$cacheKey]; } // Permissions are always checked on the web user (guard 'web') // Organizations/Banks/Admins don't have their own permissions try { // Use can() method instead of hasPermissionTo to avoid loading all permissions $result = $webUser->can($permission); $permissionCache[$cacheKey] = $result; return $result; } catch (\Exception $e) { // Any error - return false and cache it $permissionCache[$cacheKey] = false; return false; } }); // Override the vendor Wirechat components with custom extended ones Livewire::component('wirechat.chat', \App\Http\Livewire\WireChat\Chat\Chat::class); Livewire::component('wirechat.chats', \App\Http\Livewire\WireChat\Chats\Chats::class); Livewire::component('wirechat.new.chat', \App\Http\Livewire\WireChat\New\Chat::class); Livewire::component('wirechat.new.group', \App\Http\Livewire\WireChat\New\Group::class); Livewire::component('wirechat.chat.group.add-members', \App\Http\Livewire\WireChat\Chat\Group\AddMembers::class); Livewire::component('wirechat.chat.group.members', \App\Http\Livewire\WireChat\Chat\Group\Members::class); Livewire::component('wire-chat.typing-indicator', \App\Http\Livewire\WireChat\TypingIndicator::class); // Register Bank observer to auto-register new banks as love reacters/reactables Bank::observe(BankObserver::class); // Register Post observer to auto-register new posts as love reactables Post::observe(PostObserver::class); // Register Call observer to auto-register new calls as love reactables Call::observe(CallObserver::class); // Pause calls when spending profile runs out of credits after a transaction Transaction::observe(TransactionObserver::class); // Register Conversation observer to auto-set disappearing_started_at \Namu\WireChat\Models\Conversation::observe(\App\Observers\ConversationObserver::class); } }