'required_if:validateCountry,true|integer', 'division' => 'required_if:validateDivision,true|nullable|integer', 'city' => 'required_if:validateCity,true|nullable|integer', 'district' => 'nullable|integer' ]; } /** * Prepare the component. * * @return void */ public function mount() { $this->state = session('activeProfileType')::find(session('activeProfileId')) ->load([ // 'locations', 'locations.country', 'locations.division', 'locations.city', 'locations.district']); if ($this->state->locations->isNotEmpty()) { if ($this->state->locations->first()->country) { // For now we only use a single location. In the future this can become an array of locations. $this->country = $this->state->locations->first()->country->id; $this->dispatch('countryToChildren', $this->country); } if ($this->state->locations->first()->division) { // For now we only use a single location. In the future this can become an array of locations. $this->division = $this->state->locations->first()->division->id; } if ($this->state->locations->first()->city) { // For now we only use a single location. In the future this can become an array of locations. $this->city = $this->state->locations->first()->city->id; // In case a location has a city without a country in the db: if (!$this->state->locations->first()->country) { $this->country = City::find($this->city)->country_id; } } if ($this->state->locations->first()->district) { // For now we only use a single location. In the future this can become an array of locations. $this->district = $this->state->locations->first()->district->id; // In case a location has a district without a city in the db: if (!$this->state->locations->first()->city) { $this->city = District::find($this->district)->city_id; } } } $this->setValidationOptions(); } public function countryToParent($value) { $this->country = $value; $this->setValidationOptions(); } public function divisionToParent($value) { $this->division = $value; $this->setValidationOptions(); } public function cityToParent($value) { $this->city = $value; $this->setValidationOptions(); } public function districtToParent($value) { $this->district = $value; $this->setValidationOptions(); } public function emitLocationToChildren() { $this->dispatch('countryToChildren', $this->country); $this->dispatch('divisionToChildren', $this->division); $this->dispatch('cityToChildren', $this->city); $this->dispatch('districtToChildren', $this->district); } public function setValidationOptions() { $this->validateCountry = $this->validateDivision = $this->validateCity = true; // In case no cities or divisions for selected country are seeded in database if ($this->country) { $countDivisions = Country::find($this->country)->divisions()->count(); $countCities = Country::find($this->country)->cities()->count(); if ($countDivisions > 0 && $countCities < 1) { $this->validateDivision = true; $this->validateCity = false; } elseif ($countDivisions < 1 && $countCities > 1) { $this->validateDivision = false; $this->validateCity = true; } elseif ($countDivisions < 1 && $countCities < 1) { $this->validateDivision = false; $this->validateCity = false; } elseif ($countDivisions > 0 && $countCities > 0) { $this->validateDivision = false; $this->validateCity = true; } } // In case no country is selected, no need to show other validation errors if (!$this->country) { $this->validateCountry = true; $this->validateDivision = $this->validateCity = false; } } public function updateProfileInformation() { $this->validate(); // Use a transaction. DB::transaction(function (): void { $activeProfile = getActiveProfile(); // CRITICAL SECURITY: Validate user has ownership/access to this profile \App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile); // For now we only use a single location. In the future this can become an array of locations. if ($this->state->locations && $this->state->locations->isNotEmpty()) { $location = Location::find($this->state->locations->first()->id); } else { $location = new Location(); $activeProfile->locations()->save($location); // create a new location } // Set country, division, and city IDs on the location $location->country_id = $this->country; $location->division_id = $this->division; $location->city_id = $this->city; $location->district_id = $this->district; // Save the location with the updated relationship IDs $location->save(); $activeProfile->touch(); // Observer catches this and reindexes search index $this->dispatch('saved'); }); } public function render() { return view('livewire.locations.update-profile-location-form'); } }