## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require baks-dev/reference-region
Ensure your composer.json has "php": "^8.4" in require.
Publish Config (if needed):
php artisan vendor:publish --provider="BaksDev\ReferenceRegion\ReferenceRegionServiceProvider" --tag="config"
Check config/reference-region.php for default settings.
First Use Case: Fetch a region by ID (e.g., for a dropdown or API response):
use BaksDev\ReferenceRegion\Facades\ReferenceRegion;
$region = ReferenceRegion::find(73); // Replace 73 with a valid region ID
dd($region->name); // Output: e.g., "Москва"
Key Classes:
ReferenceRegion facade (main entry point).Region model (extends Illuminate\Database\Eloquent\Model).RegionRepository (handles data logic; extend for custom queries).Where to Look First:
app/Facades/ReferenceRegion.php (if extending).config/reference-region.php (adjust caching, sources, etc.).database/migrations/ (if customizing the regions table).tests/Feature/ (for edge cases like caching or API responses).// Get all regions (cached by default)
$regions = ReferenceRegion::all();
// Get regions for a specific parent (e.g., federal districts)
$federalDistricts = ReferenceRegion::whereParentId(null)->get();
cursor() for large datasets:
foreach (ReferenceRegion::cursor() as $region) {
// Process without loading all into memory
}
class City extends Model {
public function region() {
return $this->belongsTo(Region::class);
}
}
Region model:
// In app/Models/Region.php
public function scopeActive($query) {
return $query->where('is_active', true);
}
Usage:
$activeRegions = ReferenceRegion::active()->get();
config/reference-region.php).
Clear cache manually:
ReferenceRegion::clearCache();
'cache_key' => 'custom_region_cache',
spatie/array-to-xml or spatie/laravel-data for structured responses:
use Spatie\Data\Data;
class RegionResource extends Data {
public function __construct(public string $name, public ?string $parentName) {}
}
$resource = new RegionResource($region->name, $region->parent?->name);
return response()->json($resource);
Region model for Nova:
// In app/Nova/Region.php
public static $search = [
'id', 'name', 'parent_id',
];
Table component:
use Filament\Tables;
Tables::column('name')->searchable();
$this->app->bind(
\BaksDev\ReferenceRegion\Contracts\RegionRepository::class,
\App\Repositories\CustomRegionRepository::class
);
Implement RegionRepository interface to modify logic.spatie/laravel-translatable to store names in multiple languages:
class Region extends Model {
use \Spatie\Translatable\HasTranslations;
public $translatable = ['name'];
}
Fetch translated names:
$region->getTranslation('name', 'ru');
// In EventServiceProvider
protected $listen = [
\BaksDev\ReferenceRegion\Events\RegionUpdated::class => [
\App\Listeners\LogRegionChange::class,
],
];
$this->app->when(ReferenceRegion::class)
->needs(\BaksDev\ReferenceRegion\Contracts\RegionRepository::class)
->give(\App\Repositories\MockRegionRepository::class);
public function handle($request, Closure $next) {
if (!$request->user()->can('view_regions')) {
abort(403);
}
return $next($request);
}
use BaksDev\ReferenceRegion\Facades\ReferenceRegion;
class SyncRegionsCommand extends Command {
protected $signature = 'regions:sync';
public function handle() {
$data = Http::get('https://api.example.com/regions')->json();
foreach ($data as $item) {
Region::updateOrCreate(['id' => $item['id']], $item);
}
$this->info('Regions synced!');
}
}
$this->mock(\BaksDev\ReferenceRegion\Facades\ReferenceRegion::class)
->shouldReceive('find')
->andReturn(new Region(['name' => 'Test Region']));
public function test_region_caching() {
$region = ReferenceRegion::find(1);
cache()->shouldReceive('get')->once();
$this->assertEquals('Cached Region', $region->name);
}
ReferenceRegion::clearCache() after bulk updates or use events:
// In RegionObserver
public function saved(Model $model) {
ReferenceRegion::clearCache();
}
cache()->forget() with the config cache_key for granular control.withDepth() or limit recursion in the repository:
// In RegionRepository
public function withChildren($region, $depth = 0, $maxDepth = 3) {
if ($depth >= $maxDepth) return $region;
$region->children = $this->newQuery()->where('parent_id', $region->id)->get();
return $this->withChildren($region, $depth + 1, $maxDepth);
}
regions table structure.php artisan vendor:publish --tag="migrations"
Then modify database/migrations/[timestamp]_create_regions_table.php.RegionRepository or the Region model directly into services:
public function __construct(private RegionRepository $regionRepo) {}
select() to limit columns:
Region::select('id', 'name', 'parent_id')->get();
parent_id and frequently queried fields.now() in the repository:
public function now() {
How can I help you explore Laravel packages today?