PHPackages                             ihangan/laravel-moldova-cuatm - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. ihangan/laravel-moldova-cuatm

ActiveLibrary[Database &amp; ORM](/categories/database)

ihangan/laravel-moldova-cuatm
=============================

Moldova's CUATM administrative-territorial divisions (raioane, cities, towns and villages) as Eloquent models with multilingual names and coordinates.

v1.0.1(1mo ago)01↓50%[1 PRs](https://github.com/ihangan/laravel-moldova-cuatm/pulls)MITPHPPHP ^8.3CI passing

Since Jun 30Pushed 1mo agoCompare

[ Source](https://github.com/ihangan/laravel-moldova-cuatm)[ Packagist](https://packagist.org/packages/ihangan/laravel-moldova-cuatm)[ Docs](https://github.com/ihangan/laravel-moldova-cuatm)[ RSS](/packages/ihangan-laravel-moldova-cuatm/feed)WikiDiscussions main Synced 2w ago

READMEChangelogDependencies (10)Versions (4)Used By (0)

[![Moldova CUATM for Laravel](art/social-card.png)](art/social-card.png)

Moldova CUATM for Laravel
=========================

[](#moldova-cuatm-for-laravel)

[![Latest version](https://camo.githubusercontent.com/009be9b69846c77f0de695a38dce336e5adc34ff1c464146c1f943064770fbf8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6968616e67616e2f6c61726176656c2d6d6f6c646f76612d637561746d2e737667)](https://packagist.org/packages/ihangan/laravel-moldova-cuatm)[![Tests](https://github.com/ihangan/laravel-moldova-cuatm/actions/workflows/run-tests.yml/badge.svg)](https://github.com/ihangan/laravel-moldova-cuatm/actions/workflows/run-tests.yml)[![PHPStan](https://camo.githubusercontent.com/b6d441ad4fe8332cb16c72aa27f22cc685181dfd74ae34964afc92c6c1146b3c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c2532306d61782d627269676874677265656e2e737667)](https://github.com/ihangan/laravel-moldova-cuatm/actions/workflows/static.yml)[![Total downloads](https://camo.githubusercontent.com/9ec5d787a8a4b7d1b57464a9eff1e90306aee06f97743b249b87df2cc6b805ce/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6968616e67616e2f6c61726176656c2d6d6f6c646f76612d637561746d2e737667)](https://packagist.org/packages/ihangan/laravel-moldova-cuatm)[![License](https://camo.githubusercontent.com/96c14acb920519a0d50ec4356db4c140b8d2fc44d4d6f8ed6497745d8e647e3d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6968616e67616e2f6c61726176656c2d6d6f6c646f76612d637561746d2e737667)](LICENSE.md)

Every administrative-territorial unit of the Republic of Moldova, as an Eloquent model you can query straight away. The data comes from CUATM, the official classifier maintained by the National Bureau of Statistics, so the codes and the hierarchy match what government systems use.

You get the 32 raioane, the municipalities, the sectors of Chișinău, every town and all ~1,600 villages, plus Gagauzia and the Stînga Nistrului units. Each one carries its official CUATM code, a parent link, names in Romanian, Russian and Ukrainian, and WGS84 coordinates.

I built this for a rental classifieds site that needed a real location tree (region → city → sector → village) instead of a free-text address field, and pulled it out into a package because the dataset is useful on its own.

Requirements
------------

[](#requirements)

- PHP 8.3 or higher
- Laravel 12 or 13

Installation
------------

[](#installation)

```
composer require ihangan/laravel-moldova-cuatm
```

Publish and run the migration, then load the data:

```
php artisan vendor:publish --tag="moldova-cuatm-migrations"
php artisan migrate
php artisan cuatm:import
```

`cuatm:import` is idempotent, so you can run it again whenever a new CUATM edition ships without ending up with duplicates.

Usage
-----

[](#usage)

The model is `Ihangan\MoldovaCuatm\Models\Location`. It behaves like any other Eloquent model.

```
use Ihangan\MoldovaCuatm\Models\Location;
use Ihangan\MoldovaCuatm\Enums\LocationType;

// By the official CUATM code or by slug.
Location::whereCode('0111001')->first();
Location::where('slug', 'chisinau')->first();

// Every raion.
Location::ofType(LocationType::Raion)->get();

// Top-level units only.
Location::roots()->get();
```

### Names

[](#names)

Names are translatable (backed by [spatie/laravel-translatable](https://github.com/spatie/laravel-translatable)). Romanian is always present; Russian and Ukrainian exist for most localities; English is filled in for the larger cities.

```
$chisinau = Location::where('slug', 'chisinau')->first();

$chisinau->name;                          // current locale
$chisinau->getTranslation('name', 'ru');  // "Кишинёв"
$chisinau->getTranslation('name', 'uk');  // "Кишинів"
```

Set a fallback once (for example in a service provider) so a missing locale returns Romanian instead of an empty string:

```
use Spatie\Translatable\Facades\Translatable;

Translatable::fallback(fallbackLocale: 'ro', fallbackAny: true);
```

### Hierarchy

[](#hierarchy)

The tree is a self-referencing `parent_id`.

```
$village = Location::where('slug', 'dobrogea')->first();

$village->parent;       // the town it belongs to
$village->ancestors();  // [town, sector, municipality], nearest first

$sector = Location::where('slug', 'botanica')->first();
$sector->children;      // towns and villages under Botanica
```

### Coordinates

[](#coordinates)

```
$location = Location::where('slug', 'chisinau')->first();

[$location->lat, $location->lng]; // 47.005..., 28.857...
```

### Facade

[](#facade)

A small facade wraps the common lookups when you would rather not write the queries by hand:

```
use Ihangan\MoldovaCuatm\Facades\Cuatm;

Cuatm::findByCode('0111001');
Cuatm::findBySlug('chisinau');
Cuatm::roots();          // raioane, municipalities, Gagauzia, Transnistria
Cuatm::raioane();
Cuatm::childrenOf($raion);
Cuatm::tree();           // roots with their children eager-loaded
```

### Cascading location picker

[](#cascading-location-picker)

`roots()` and `childrenOf()` are all you need to build a "pick a region, then a locality below it" selector. The hierarchy isn't a fixed depth (a raion goes straight to its villages, while Chișinău goes municipality → sector → town → village), so the picker keeps offering another dropdown while the chosen unit still has children.

```
use Ihangan\MoldovaCuatm\Facades\Cuatm;
use Livewire\Component;

class LocationPicker extends Component
{
    /** @var array the selected location id at each level */
    public array $path = [];

    public function selectLevel(int $level, ?int $id): void
    {
        $this->path = array_slice($this->path, 0, $level); // drop the deeper levels

        if ($id !== null) {
            $this->path[$level] = $id;
        }
    }

    public function render()
    {
        $levels = collect([Cuatm::roots()]);

        foreach ($this->path as $id) {
            $children = Cuatm::childrenOf($id);

            if ($children->isEmpty()) {
                break; // reached the bottom of the tree
            }

            $levels->push($children);
        }

        return view('livewire.location-picker', ['levels' => $levels]);
    }
}
```

```
{{-- resources/views/livewire/location-picker.blade.php --}}

    @foreach ($levels as $level => $options)

            —
            @foreach ($options as $location)
                id)>
                    {{ $location->name }}

            @endforeach

    @endforeach

```

The selected location is the last entry in `$path`. Outside Livewire the same two calls drive any UI: render `Cuatm::roots()` first, then `Cuatm::childrenOf($id)`each time a level is chosen.

Configuration
-------------

[](#configuration)

Publish the config file if you need to change the table name, the connection or the locales:

```
php artisan vendor:publish --tag="moldova-cuatm-config"
```

```
return [
    'table' => 'cuatm_locations',
    'connection' => null,
    'locales' => ['ro', 'ru', 'uk', 'en'],
    'fallback_locale' => 'ro',
];
```

The table is named `cuatm_locations` rather than `locations` so it does not clash with one your application may already have.

Data and updates
----------------

[](#data-and-updates)

The dataset lives in `database/data/cuatm.json` and ships with the package.

- Codes, hierarchy and Romanian names come from CUATM (Clasificatorul unităților administrativ-teritoriale ale Republicii Moldova), published by the National Bureau of Statistics.
- Russian and Ukrainian names are Wikidata exonyms.
- Coordinates are from public geodata.

CUATM changes rarely. When the Bureau publishes a new edition, replace the JSON file and run `php artisan cuatm:import` again.

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) and the [releases](https://github.com/ihangan/laravel-moldova-cuatm/releases).

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md).

Security
--------

[](#security)

Found a security issue? Email  instead of using the issue tracker. See [SECURITY.md](.github/SECURITY.md).

Credits
-------

[](#credits)

- [Igor Hangan](https://github.com/ihangan)
- The administrative data comes from the CUATM classifier published by the National Bureau of Statistics of Moldova, with Russian and Ukrainian names from Wikidata.

License
-------

[](#license)

The MIT License. See [LICENSE.md](LICENSE.md).

The administrative data is public information from the National Bureau of Statistics of Moldova; Wikidata content is CC0.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance90

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

46d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f57b8b98fa05fa2831b92420b9e126f1978adc9a7c86c31719eb1ebb319139f7?d=identicon)[ihangan](/maintainers/ihangan)

---

Top Contributors

[![ihangan](https://avatars.githubusercontent.com/u/17790228?v=4)](https://github.com/ihangan "ihangan (2 commits)")

---

Tags

laravelgeoMoldovalocationsadministrative-divisionslocalitiescuatm

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/ihangan-laravel-moldova-cuatm/health.svg)

```
[![Health](https://phpackages.com/badges/ihangan-laravel-moldova-cuatm/health.svg)](https://phpackages.com/packages/ihangan-laravel-moldova-cuatm)
```

###  Alternatives

[laravel/ai

The official AI SDK for Laravel.

1.1k4.6M307](/packages/laravel-ai)[spatie/laravel-medialibrary

Associate files with Eloquent models

6.2k45.4M698](/packages/spatie-laravel-medialibrary)[spatie/laravel-health

Monitor the health of a Laravel application

88212.7M185](/packages/spatie-laravel-health)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[illuminate/queue

The Illuminate Queue package.

20433.0M1.8k](/packages/illuminate-queue)[masterix21/laravel-licensing

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1614.1k4](/packages/masterix21-laravel-licensing)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
