Snapshot of main at 9f39a6e1e (2026-11-02)
This commit is contained in:
commit
6ccf1792d7
2580 files changed
+1040202
No files matched your search
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PhpCsFixer\Config;
|
||||
use PhpCsFixer\Finder;
|
||||
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;
|
||||
|
||||
return (new Config())
|
||||
->setParallelConfig(ParallelConfigFactory::detect()) // @TODO 4.0 no need to call this manually
|
||||
->setRiskyAllowed(false)
|
||||
->setRules([
|
||||
'@auto' => true
|
||||
])
|
||||
// 💡 by default, Fixer looks for `*.php` files excluding `./vendor/` - here, you can groom this config
|
||||
->setFinder(
|
||||
(new Finder())
|
||||
// 💡 root folder to check
|
||||
->in(__DIR__)
|
||||
// 💡 additional files, eg bin entry file
|
||||
// ->append([__DIR__.'/bin-entry-file'])
|
||||
// 💡 folders to exclude, if any
|
||||
// ->exclude([/* ... */])
|
||||
// 💡 path patterns to exclude, if any
|
||||
// ->notPath([/* ... */])
|
||||
// 💡 extra configs
|
||||
// ->ignoreDotFiles(false) // true by default in v3, false in v4 or future mode
|
||||
// ->ignoreVCS(true) // true by default
|
||||
)
|
||||
;
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Mailings;
|
||||
|
||||
use App\Models\Locations\City;
|
||||
use App\Models\Locations\Country;
|
||||
use App\Models\Locations\District;
|
||||
use App\Models\Locations\Division;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Component;
|
||||
|
||||
class LocationFilter extends Component
|
||||
{
|
||||
public array $selectedCountries = [];
|
||||
public array $selectedDivisions = [];
|
||||
public array $selectedCities = [];
|
||||
public array $selectedDistricts = [];
|
||||
|
||||
public function mount(
|
||||
array $selectedCountries = [],
|
||||
array $selectedDivisions = [],
|
||||
array $selectedCities = [],
|
||||
array $selectedDistricts = []
|
||||
) {
|
||||
$this->selectedCountries = $selectedCountries;
|
||||
$this->selectedDivisions = $selectedDivisions;
|
||||
$this->selectedCities = $selectedCities;
|
||||
$this->selectedDistricts = $selectedDistricts;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Setters — called from the view via x-on:change="@this.setSelected*(…)"
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public function setSelectedCountries(array $values): void
|
||||
{
|
||||
$removed = array_diff($this->selectedCountries, $values);
|
||||
|
||||
$this->selectedCountries = $values;
|
||||
|
||||
// When countries are removed, cascade-remove divisions/cities/districts
|
||||
// that no longer belong to any selected country.
|
||||
if (!empty($removed)) {
|
||||
$keptDivisionIds = !empty($values)
|
||||
? Division::whereIn('country_id', $values)->pluck('id')->toArray()
|
||||
: [];
|
||||
$this->selectedDivisions = array_values(array_intersect($this->selectedDivisions, $keptDivisionIds));
|
||||
|
||||
$keptCityIds = !empty($this->selectedDivisions)
|
||||
? City::whereIn('division_id', $this->selectedDivisions)->pluck('id')->toArray()
|
||||
: [];
|
||||
$this->selectedCities = array_values(array_intersect($this->selectedCities, $keptCityIds));
|
||||
|
||||
$keptDistrictIds = !empty($this->selectedCities)
|
||||
? District::whereIn('city_id', $this->selectedCities)->pluck('id')->toArray()
|
||||
: [];
|
||||
$this->selectedDistricts = array_values(array_intersect($this->selectedDistricts, $keptDistrictIds));
|
||||
}
|
||||
|
||||
$this->emitSelectionUpdate();
|
||||
}
|
||||
|
||||
public function setSelectedDivisions(array $values): void
|
||||
{
|
||||
$removed = array_diff($this->selectedDivisions, $values);
|
||||
|
||||
$this->selectedDivisions = $values;
|
||||
|
||||
// When divisions are removed, cascade-remove cities/districts that no
|
||||
// longer belong to any selected division.
|
||||
if (!empty($removed)) {
|
||||
$keptCityIds = !empty($values)
|
||||
? City::whereIn('division_id', $values)->pluck('id')->toArray()
|
||||
: [];
|
||||
$this->selectedCities = array_values(array_intersect($this->selectedCities, $keptCityIds));
|
||||
|
||||
$keptDistrictIds = !empty($this->selectedCities)
|
||||
? District::whereIn('city_id', $this->selectedCities)->pluck('id')->toArray()
|
||||
: [];
|
||||
$this->selectedDistricts = array_values(array_intersect($this->selectedDistricts, $keptDistrictIds));
|
||||
}
|
||||
|
||||
$this->emitSelectionUpdate();
|
||||
}
|
||||
|
||||
public function setSelectedCities(array $values): void
|
||||
{
|
||||
$removed = array_diff($this->selectedCities, $values);
|
||||
|
||||
$this->selectedCities = $values;
|
||||
|
||||
// When cities are removed, cascade-remove districts that no longer
|
||||
// belong to any selected city.
|
||||
if (!empty($removed)) {
|
||||
$keptDistrictIds = !empty($values)
|
||||
? District::whereIn('city_id', $values)->pluck('id')->toArray()
|
||||
: [];
|
||||
$this->selectedDistricts = array_values(array_intersect($this->selectedDistricts, $keptDistrictIds));
|
||||
}
|
||||
|
||||
$this->emitSelectionUpdate();
|
||||
}
|
||||
|
||||
public function setSelectedDistricts(array $values): void
|
||||
{
|
||||
$this->selectedDistricts = $values;
|
||||
$this->emitSelectionUpdate();
|
||||
}
|
||||
|
||||
#[On('resetLocationFilter')]
|
||||
public function resetLocationFilter(): void
|
||||
{
|
||||
$this->selectedCountries = [];
|
||||
$this->selectedDivisions = [];
|
||||
$this->selectedCities = [];
|
||||
$this->selectedDistricts = [];
|
||||
$this->emitSelectionUpdate();
|
||||
}
|
||||
|
||||
#[On('loadLocationFilterData')]
|
||||
public function loadLocationFilterData(array $data = []): void
|
||||
{
|
||||
$this->selectedCountries = $data['countries'] ?? [];
|
||||
$this->selectedDivisions = $data['divisions'] ?? [];
|
||||
$this->selectedCities = $data['cities'] ?? [];
|
||||
$this->selectedDistricts = $data['districts'] ?? [];
|
||||
}
|
||||
|
||||
private function emitSelectionUpdate(): void
|
||||
{
|
||||
$this->dispatch('locationFilterUpdated', [
|
||||
'countries' => $this->selectedCountries,
|
||||
'divisions' => $this->selectedDivisions,
|
||||
'cities' => $this->selectedCities,
|
||||
'districts' => $this->selectedDistricts,
|
||||
]);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
// Always derive display data fresh from the current selected state.
|
||||
// Never store Eloquent collections as public properties — Livewire serializes
|
||||
// them to plain arrays, breaking ->sortBy() and ->count() in the blade view.
|
||||
$countries = Country::with('translations')->get();
|
||||
|
||||
$divisions = !empty($this->selectedCountries)
|
||||
? Division::with('translations')->whereIn('country_id', $this->selectedCountries)->get()
|
||||
: collect();
|
||||
|
||||
if (!empty($this->selectedDivisions)) {
|
||||
$cities = City::with('translations')->whereIn('division_id', $this->selectedDivisions)->get();
|
||||
} elseif (!empty($this->selectedCountries)) {
|
||||
$cities = City::with('translations')->whereIn('country_id', $this->selectedCountries)->get();
|
||||
} else {
|
||||
$cities = collect();
|
||||
}
|
||||
|
||||
$districts = !empty($this->selectedCities)
|
||||
? District::with('translations')->whereIn('city_id', $this->selectedCities)->get()
|
||||
: collect();
|
||||
|
||||
return view('livewire.mailings.location-filter', compact(
|
||||
'countries', 'divisions', 'cities', 'districts'
|
||||
));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user