Weave 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

Teryt Database Bundle Laravel Package

fsi/teryt-database-bundle

Symfony bundle for integrating Poland’s TERYT territorial register. Provides entities, import commands, and query helpers for voivodeships, counties, municipalities, localities, streets, and postal data, simplifying address and location validation in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. It is built around Symfony DI, Doctrine ORM, and console commands, so do not expect php artisan package:discover, publishable migrations, or Eloquent models. Treat it as either a reference implementation for TERYT data or as a sidecar import tool.

First steps:

  1. Read the README and inspect:
    • src/Entity/ for the TERYT schema
    • src/Command/ for import commands
    • Resources/config/ for service wiring and parameters
    • entity mappings for table/column names and TERYT code fields
  2. Decide your integration strategy before writing application code:
    • Sidecar Symfony console imports TERYT into a shared database; Laravel reads the tables with read-only Eloquent models. This is the lowest-friction path.
    • Port the schema/importer into Laravel migrations and a custom import command. More work, but no Symfony/Doctrine runtime in production.
    • Run Doctrine inside Laravel only if you already use Doctrine; otherwise avoid it.
  3. Minimal sidecar flow:
    composer require fsi/teryt-database-bundle
    # configure a Symfony console app or existing Symfony app with DB credentials
    php bin/console list teryt
    php bin/console teryt:import   # exact command name depends on the bundle version
    
  4. Inspect the resulting tables and confirm TERYT codes, parent relationships, and active/inactive date columns.

First Laravel use case: an address picker backed by TERYT hierarchy — voivodeship → county → municipality → locality → street. Store TERYT codes on your addresses table, not display names, and hydrate selects from the imported reference tables.

Implementation Patterns

Keep TERYT data read-only in Laravel. Map the bundle tables with lightweight Eloquent models:

class TerytVoivodeship extends Model
{
    protected $table = 'teryt_voivodeships'; // verify actual table name
    protected $primaryKey = 'id';
    public $timestamps = false;
    protected $guarded = [];
}

Use string primary keys/codes, disable timestamps, and avoid assuming Laravel-style pluralized table names. Inspect the Doctrine mappings first.

Import on a schedule, not in a request. Run the Symfony importer from a Laravel scheduled command or queued job:

$schedule->exec('php /path/to/symfony/bin/console teryt:import')
    ->weekly()
    ->withoutOverlapping()
    ->runInBackground();

For large TERYT releases, import into staging tables and swap/upsert in a transaction. Keep a teryt_version or imported_at column so you can trace which dataset an address was validated against.

Build hierarchical API endpoints. Example:

Route::get('/teryt/counties', function (Request $request) {
    return TerytCounty::where('voivodeship_id', $request->string('voivodeship_id'))
        ->orderBy('name')
        ->get(['id', 'name']);
});

Cache voivodeships and counties aggressively; localities and streets are larger and may need search endpoints with prefix matching.

Validate parent-child consistency. A common bug is accepting a municipality ID that does not belong to the selected county. Add a custom validation rule:

Validator::extend('teryt_child_of', function ($attribute, $value, $parameters) {
    return TerytMunicipality::whereKey($value)
        ->where('county_id', request($parameters[0]))
        ->exists();
});

Store codes, denormalize names selectively. Persist TERYT codes for joins and validation. Store a snapshot of the selected name on orders/addresses if historical display matters, because TERYT names and boundaries change.

If porting to Laravel: use the bundle entities as your schema reference, then write Laravel migrations and a custom importer. Use Http::get() or curl for downloads, XMLReader for large XML files, chunked inserts, and insertOrIgnore/upsert. Do not load the entire TERYT dataset into memory.

Expose search carefully. Street names are the hardest TERYT layer: many localities, diacritics, and duplicate names. Use indexed LIKE 'prefix%' queries, normalize case, and always require a locality context.

Gotchas and Tips

  • No Laravel integration exists. There is no service provider auto-discovery, no vendor:publish, no Eloquent, and no Laravel migrations. Any tutorial implying php artisan support is wrong.
  • Doctrine is a hard dependency. Installing this into a Laravel app may pull Symfony/Doctrine packages and create version conflicts. Prefer the sidecar approach or copy the schema/importer logic.
  • TERYT codes are strings, not integers. Codes contain leading zeros. Never cast them to int; use CHAR/VARCHAR and string casts in Eloquent.
  • Parent IDs may not match your naming assumptions. The bundle may use Polish column names or Doctrine-generated names. Verify mappings instead of guessing voivodeship_id.
  • Respect validity dates. TERYT records can have valid-from/valid-to fields. Filter active records for current address forms, but keep historical rows if you need auditability.
  • Imports are heavy. Run from CLI with sufficient memory and time limits, disable query logging, wrap in transactions, and avoid importing during peak traffic. Index foreign keys and name columns after import.
  • Data changes. Municipalities, streets, and locality names change. Do not treat imported rows as immutable; schedule regular re-imports and handle deleted/merged codes gracefully.
  • Encoding and collation. TERYT data is Polish and UTF-8. Ensure database/table collation supports diacritics and case-insensitive search as needed.
  • Low adoption risk. Five stars and zero dependents mean limited community testing. Pin the package version, review the import commands, and keep your own fixtures/tests around the tables you depend on.
  • Debugging: run the Symfony command with -vvv, inspect Doctrine SQL logs, and verify the TERYT source URL still points to the current official dataset. Government download URLs and file formats change.
  • Extension points: in Symfony you can override bundle services/configuration. In Laravel, do not extend bundle classes directly; wrap access in your own repositories/services so you can replace the sidecar later.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo