reset(['updateMode', 'socialsOptionSelected', 'userOnSocial', 'serverOfSocial']); } public function mount() { $this->socialsOptions = Social::select("*")->orderBy("name")->get(); $this->getSocials(); } public function getSocials() { $this->socials = getActiveProfile()->socials; } public function socialsUpdated() { $this->resetErrorBag(); // clears all validation errors } public function store() { $validatedSocial = $this->validate([ 'socialsOptionSelected' => 'required|integer', 'userOnSocial' => 'required|string|max:150', ]); $activeProfile = getActiveProfile(); // CRITICAL SECURITY: Validate user has ownership/access to this profile \App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile); // Limit to max 10 socials per profile $currentCount = $activeProfile->socials()->count(); if ($currentCount >= $limit = 10) { $this->addError('socialsOptionSelected', __('validation.custom.social_limit', ['limit' => $limit])); return; } DB::table('sociables')->insert([ 'social_id' => $this->socialsOptionSelected, 'sociable_type' => session('activeProfileType'), 'sociable_id' => session('activeProfileId'), 'user_on_social' => $this->formatUserHandle($this->socialsOptionSelected, $this->userOnSocial), 'server_of_social' => $this->formatServer($this->socialsOptionSelected, $this->serverOfSocial), 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ]); session()->flash('message', __('Saved')); $this->resetInputFields(); $this->getSocials(); } public function edit($id) { $activeProfile = getActiveProfile(); // CRITICAL SECURITY: Validate user has ownership/access to this profile \App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile); $this->sociables_id = $id; $this->socialsOptionSelected = $activeProfile->socials->where('pivot.id', $id)->first()->pivot->social_id; $this->userOnSocial = $activeProfile->socials->where('pivot.id', $id)->first()->pivot->user_on_social; $this->serverOfSocial = $activeProfile->socials->where('pivot.id', $id)->first()->pivot->server_of_social; $this->selectedPlaceholder = Social::find($this->socialsOptionSelected); $this->updateMode = true; $this->dispatch('contentChanged'); } public function cancel() { $this->updateMode = false; $this->resetInputFields(); $this->resetErrorBag(); // clears all validation errors } public function update() { $validatedDate = $this->validate([ 'socialsOptionSelected' => 'required|integer', 'userOnSocial' => 'required|string|max:150', ]); $activeProfile = getActiveProfile(); // CRITICAL SECURITY: Validate user has ownership/access to this profile \App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile); if ($this->sociables_id) { DB::table('sociables')->insert([ 'social_id' => $this->socialsOptionSelected, 'sociable_type' => session('activeProfileType'), 'sociable_id' => session('activeProfileId'), 'user_on_social' => $this->formatUserHandle($this->socialsOptionSelected, $this->userOnSocial), 'server_of_social' => $this->formatServer($this->socialsOptionSelected, $this->serverOfSocial), 'updated_at' => Carbon::now(), ]); $this->dispatch('emitSaved'); $this->resetInputFields(); } } public function delete($id) { $activeProfile = getActiveProfile(); // CRITICAL SECURITY: Validate user has ownership/access to this profile \App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile); if ($id) { DB::table('sociables')->where('id', $id)->delete(); // refresh the local list $this->getSocials(); $this->resetErrorBag(); // clears all validation errors $this->dispatch('emitSaved'); session()->flash('message', __('Deleted')); } } private function formatUserHandle($socialId, $handle) { $handle = str_replace('@', '', $handle); // For Blue Sky, the handle already contains the domain if ($socialId == 3) { // Blue Sky ID is 3 return $handle; // handle.bsky.social } return $handle; } private function formatServer($socialId, $server) { $server = str_replace('@', '', $server); // Only Mastodon (4) and Blue Sky (3) use server info if (!in_array($socialId, [3, 4])) { return null; } // For Blue Sky, extract domain from handle if needed if ($socialId == 3) { if (str_contains($this->userOnSocial, '.')) { return substr(strrchr($this->userOnSocial, '.'), 1); } return $server ?: 'bsky.social'; } return $server; } public function getSocialUrlAttribute() { $urlStructure = $this->social->url_structure; switch ($this->social_id) { case 3: // Blue Sky return "https://bsky.app/profile/{$this->user_on_social}"; case 4: // Mastodon return str_replace('#', $this->server_of_social, $urlStructure) . $this->user_on_social; default: return $urlStructure . $this->user_on_social; } } public function render() { $this->getSocials(); return view('livewire.profile.socials-form'); } }