Initial commit
This commit is contained in:
203
app/Http/Livewire/Profile/SocialsForm.php
Normal file
203
app/Http/Livewire/Profile/SocialsForm.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Profile;
|
||||
|
||||
use App\Models\Social;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Livewire\Component;
|
||||
|
||||
class SocialsForm extends Component
|
||||
{
|
||||
public $socialsOptions;
|
||||
public $socialsOptionSelected;
|
||||
public $socials;
|
||||
public $userOnSocial;
|
||||
public $serverOfSocial;
|
||||
public $sociables_id;
|
||||
public $updateMode = false;
|
||||
public $selectedPlaceholder;
|
||||
|
||||
|
||||
private function resetInputFields()
|
||||
{
|
||||
$this->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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user