Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Locations Laravel Package

tomatophp/filament-locations

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require tomatophp/filament-locations
    

    Publish the package assets and migrations:

    php artisan vendor:publish --provider="TomatoPHP\FilamentLocations\FilamentLocationsServiceProvider" --tag="filament-locations:migrations"
    php artisan vendor:publish --provider="TomatoPHP\FilamentLocations\FilamentLocationsServiceProvider" --tag="filament-locations:config"
    php artisan migrate
    
  2. Run Seeder Seed the database with default locations data:

    php artisan db:seed --class=FilamentLocationsSeeder
    
  3. Register Resources Add the provided Filament resources to your app/Providers/Filament/AdminPanelProvider.php:

    public function panel(Panel $panel): Panel
    {
        return $panel
            ->resources([
                \TomatoPHP\FilamentLocations\Resources\CountryResource::class,
                \TomatoPHP\FilamentLocations\Resources\CityResource::class,
                \TomatoPHP\FilamentLocations\Resources\AreaResource::class,
                \TomatoPHP\FilamentLocations\Resources\LanguageResource::class,
                \TomatoPHP\FilamentLocations\Resources\CurrencyResource::class,
            ]);
    }
    
  4. First Use Case Access the Filament admin panel (/admin) and navigate to the Countries resource to view, create, or edit entries. Use the hierarchical relationship between Countries → Cities → Areas for location-based applications.


Implementation Patterns

Core Workflows

  1. Hierarchical Data Management

    • Countries → Cities → Areas: Use the belongsTo/hasMany relationships to fetch nested locations:
      $country = Country::with(['cities.areas'])->find(1);
      
    • Filtering: Leverage Filament’s built-in filters to search or filter locations (e.g., by country name or city population).
  2. Multi-Language Support

    • The Language resource includes ISO codes and names. Use it to localize your app:
      $language = Language::where('iso', 'en')->first();
      
    • Attach languages to models via a morphToMany relationship:
      public function languages()
      {
          return $this->morphToMany(Language::class, 'translatable');
      }
      
  3. Currency Integration

    • Use the Currency resource for financial applications (e.g., e-commerce):
      $usd = Currency::where('code', 'USD')->first();
      
    • Store currency associations on order/models:
      public function currency()
      {
          return $this->belongsTo(Currency::class);
      }
      
  4. Customizing Resources

    • Extend the provided resources (e.g., add custom fields or actions):
      use TomatoPHP\FilamentLocations\Resources\CountryResource;
      
      class CustomCountryResource extends CountryResource
      {
          public static function form(Form $form): Form
          {
              return parent::form($form)
                  ->columns(2)
                  ->schema([
                      // Add custom fields here
                      TextInput::make('custom_field')->columnSpanFull(),
                  ]);
          }
      }
      
  5. API Endpoints

    • Expose resources via Filament’s API for frontend consumption:
      // In Filament API routes (e.g., routes/filament.php)
      Filament::registerApiRoutes();
      
    • Fetch data via HTTP:
      GET /api/admin/resources/countries
      

Integration Tips

  1. Seed Custom Data Override the seeder to add custom locations:

    use TomatoPHP\FilamentLocations\Database\Seeders\FilamentLocationsSeeder;
    
    class CustomSeeder extends FilamentLocationsSeeder
    {
        public function run()
        {
            parent::run();
            // Add custom entries
            City::create(['name' => 'My Custom City', 'country_id' => 1]);
        }
    }
    
  2. Localization Use the Language resource to dynamically switch app language:

    $currentLanguage = Language::where('iso', app()->getLocale())->first();
    
  3. Validation Validate location fields in forms:

    use TomatoPHP\FilamentLocations\Rules\ValidCountry;
    
    $form->schema([
        TextInput::make('country_id')
            ->rules([new ValidCountry]),
    ]);
    
  4. Performance

    • Eager Load: Avoid N+1 queries when fetching hierarchical data:
      Country::with(['cities.areas'])->get();
      
    • Caching: Cache frequently accessed locations (e.g., countries):
      Cache::remember('all_countries', now()->addHours(1), function () {
          return Country::all();
      });
      

Gotchas and Tips

Pitfalls

  1. Seeder Conflicts

    • Running the seeder multiple times may cause duplicate entries. Use --force cautiously:
      php artisan db:seed --class=FilamentLocationsSeeder --force
      
    • Solution: Check for existing records before seeding:
      if (!Country::exists()) {
          parent::run();
      }
      
  2. Hierarchy Dependencies

    • Areas require a City, and Cities require a Country. Deleting a parent may orphan children.
    • Solution: Use soft deletes or cascade deletes in migrations:
      $table->foreignId('country_id')->constrained()->cascadeOnDelete();
      
  3. Filament Resource Conflicts

    • If you register the same resource twice (e.g., CountryResource), Filament will throw a ResourceAlreadyRegistered error.
    • Solution: Unregister duplicates in AdminPanelProvider:
      $panel->resources([
          // Ensure no duplicates
      ]);
      
  4. JSON vs. Database Data

    • The package provides both JSON and database-based data. Ensure your app uses the correct source (e.g., avoid mixing JSON and DB queries).

Debugging

  1. Missing Migrations

    • If resources don’t appear, verify migrations were published and run:
      php artisan migrate:status
      
  2. Permission Issues

    • Ensure the Filament admin user has access to the resources. Check AdminPanelProvider:
      $panel->users([
          \Filament\Panel\Contracts\User::class,
      ]);
      
  3. Relationship Errors

    • If relationships fail (e.g., City not found), check:
      • Database constraints (e.g., country_id exists).
      • Case sensitivity in foreign keys (e.g., country_id vs CountryId).

Tips

  1. Custom Fields Add custom fields to resources without modifying the package:

    class CustomCountryResource extends CountryResource
    {
        public static function table(Table $table): Table
        {
            return parent::table($table)
                ->columns([
                    // Add custom columns
                    TextColumn::make('custom_field'),
                ]);
        }
    }
    
  2. Bulk Actions Use Filament’s bulk actions to manage locations (e.g., delete multiple cities):

    public static function table(Table $table): Table
    {
        return parent::table($table)
            ->actions([
                Tables\Actions\DeleteAction::make(),
            ])
            ->bulkActions([
                Tables\Actions\DeleteBulkAction::make(),
            ]);
    }
    
  3. Local Development

    • Use tinker to explore seeded data:
      php artisan tinker
      >>> \TomatoPHP\FilamentLocations\Models\Country::all();
      
  4. Testing

    • Reset the database between tests to avoid stale data:
      public function tearDown(): void
      {
          Artisan::call('migrate:fresh --seed');
          parent::tearDown();
      }
      
  5. Extending Models Add methods to models (e.g., Country) in a service provider:

    \TomatoPHP\FilamentLocations\Models\Country::macro('getFullName', function () {
        return "Country: {$this->name}";
    });
    
  6. Performance for Large Datasets

    • Paginate queries when listing locations:
      Country::paginate(20);
      
    • Use database indexes for frequently queried fields (e.g., name on cities).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope