[ 'phone:phonecode,mobile,strict', 'regex:/^[\d+()\s-]+$/', ], 'phonecode' => 'required_with:state.phone,mobile', 'state.phone_public' =>'boolean|nullable', ]; /** * Prepare the component. * * @return void */ public function mount(Request $request, Repository $config) { $activeProfile = getActiveProfile(); $phonePublic = isset($activeProfile->phone_public); $this->state = array_merge([ 'phone' => $activeProfile->phone, 'phone_public' => $phonePublic == true ? $activeProfile->phone_public : null, ], $activeProfile->withoutRelations()->toArray()); $phoneCodeOptions = DB::table('countries')->get()->sortBy('code'); $this->phoneCodeOptions = $phoneCodeOptions->Map(function ($options, $key) { return [ 'id' => $options->id, 'code' => $options->code, 'label' => $options->flag, ]; }); $this->getPhonecode(); } public function getPhonecode() { $activeProfile = getActiveProfile(); // Fill country code dropdown $this->phoneCodeOptions->toArray(); // Ensure the profile is authenticated and retrieve the phone field $profilePhone = $activeProfile->phone ?? ''; if (!empty($profilePhone)) { try { $country = new PhoneNumber($profilePhone); $this->phonecode = $country->getCountry(); $phone = new PhoneNumber($profilePhone, $this->phonecode); $this->state['phone'] = $phone->formatNational(); } catch (\Exception) { // If phone parsing fails, reset to empty and set default country $this->state['phone'] = ''; $this->setDefaultCountryCode($activeProfile); } } else { $this->setDefaultCountryCode($activeProfile); } } private function setDefaultCountryCode($activeProfile) { // Try to get country from profile locations if available $countryIds = []; if (method_exists($activeProfile, 'locations')) { $countryIds = get_class($activeProfile)::find($this->state['id'])->locations() ->with('city:id,country_id') ->get() ->pluck('city.country_id') ->filter() // Remove null values ->toArray(); } $countries = ($this->phoneCodeOptions)->pluck('id')->toArray(); // Get the first valid country ID from the profile's locations $firstCountryId = !empty($countryIds) ? $countryIds[0] : null; if ($firstCountryId && in_array($firstCountryId, $countries)) { $this->phonecode = DB::table('countries')->select('code')->where('id', $firstCountryId)->pluck('code')->first(); } else { // Fallback to first available country code $this->phonecode = $this->phoneCodeOptions[0]['code'] ?? 'NL'; } } /** * Validate phone field when updated. * This is the 1st validation method on this form. * * @return void */ public function updatedStatePhone() { if (!empty($this->state['phone']) && !empty($this->phonecode)) { try { $this->validateOnly('state.phone'); $phone = new PhoneNumber($this->state['phone'], $this->phonecode); $this->state['phone'] = $phone->formatNational(); } catch (\Exception) { $this->addError('state.phone', __('Invalid phone number format.')); } } } /** * Update the profile's phone information. * * @return void */ public function updateProfilePhone() { $activeProfile = getActiveProfile(); // CRITICAL SECURITY: Validate user has ownership/access to this profile \App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile); if (!empty($this->state['phone'])) { $this->validate(); // 2nd validation, just before save method $this->resetErrorBag(); try { $phone = new PhoneNumber($this->state['phone'], $this->phonecode); $activeProfile->phone = $phone; // Check for the existence of phone_public column and update if exists if (in_array('phone_public', $activeProfile->getFillable())) { $activeProfile->phone_public = $this->state['phone_public'] ?? false; } } catch (\Exception) { $this->addError('state.phone', __('Invalid phone number format.')); return; } } else { $this->resetErrorBag(); $activeProfile->phone = null; // Clear the phone_public field if it exists if (in_array('phone_public', $activeProfile->getFillable())) { $activeProfile->phone_public = false; } } $activeProfile->save(); $this->dispatch('saved'); } /** * Get the current active profile of the application. * * @return mixed */ public function getUserProperty() { return getActiveProfile(); } public function render() { return view('livewire.profile.update-profile-phone-form'); } }