blemli / swissstreets-for-filament
Every Swiss address. Offline.
Package info
github.com/blemli/swissstreets-for-filament
pkg:composer/blemli/swissstreets-for-filament
Requires
- php: ^8.2
- filament/filament: ^4.0|^5.0
- spatie/laravel-package-tools: ^1.15.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.7|^4.0
- pestphp/pest-plugin-arch: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
- pestphp/pest-plugin-livewire: ^3.0|^4.0
- rector/rector: ^2.0
- spatie/laravel-activitylog: ^4.10
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Every Swiss address. Offline. Daily.
Address field for Filament backed by the official Swiss building address register. Nightly update from the official source, works fully offline, sorts by vicinity — no spatial extension required. Support for foreign addresses, because life is messy.
Install
composer require blemli/swissstreets-for-filament
php artisan swissstreets:install # add -n for provisioning scripts: migrates, schedules, imports
The installer schedules the nightly swissstreets:import in routes/console.php (suggested time 03:00–04:59, hashed from the app name so not every app hits swisstopo in the same minute) and runs the first import. Transient network errors against swisstopo are retried (2 s / 5 s / 10 s); a failed import exits non-zero and says what to do. A run killed mid-import leaves its lock behind — the next run says who held it since when, heals itself when that process is gone from the same host, or takes php artisan swissstreets:import --unlock.
Use
// Panel ->plugin(SwissstreetsPlugin::make()->cantons(['BS', 'BL'])->table()->notify(User::class)) // Model class Customer extends Model { use HasAddress; } // needs an address_id column // Form: "spalen 113" → Spalenring 113, 4055 Basel Address::make('address_id')->nonresidential()->nearMe()->allowCustom('address_text') Address::cascade('address_id')->nearMe()->freetext() // same, as three selects: town → street → number // Map picker: search the register or drop the pin anywhere (swisstopo tiles, dark mode aware) MapPicker::make('location')->lat('latitude')->lng('longitude')->address('address_id') // Table / infolist AddressColumn::make('address')->map() AddressEntry::make('address')->map() // Query Address::search('bahnhof zürich')->near($lat, $lng, withinKm: 5)->used() // Global search: "spalen 113" finds the customer living there class CustomerResource extends Resource { use SearchesAddressGlobally; } // then list 'address' in getGloballySearchableAttributes()
Events: AddressAdded, AddressRemoved, AddressRestored (per address, import or ->freetext() form) and ImportFinished (with the ImportResult) under Blemli\Swissstreets\Events.
Plugin options: ->cantons([...]) limits the import, ->table() adds the browsable addresses table to the panel (with an "Import from swisstopo" button that queues the import — gate it with AddressPolicy::import(), which Filament Shield generates as import_address), ->notify(User::class) (or a closure returning users) sends a database notification after each import that changed something, ->swissgrid() keeps LV95 easting/northing, ->unofficial(), ->planned(), ->health() registers the health check below. Removed addresses are soft-deleted and logged. Remove everything with php artisan swissstreets:uninstall.
Supported plugins
- spatie/laravel-health (shown in the panel by shuvroroy/filament-spatie-laravel-health):
SwissstreetsPlugin::make()->health()(orhealth.enabledin the config; the installer offers it when the package is installed) registers the "Swiss address register" check — red when no address was created, updated or removed for 21 days, yellow when the last 3 imports failed. Thresholds:->health(maxAgeDays: 21, maxFailedRuns: 3). - spatie/laravel-activitylog: every added, removed and restored address is recorded as an activity (log name
swissstreets) when the package is installed; switch off with theactivitylogconfig key.
MIT © blemli
