›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-cartographer
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • How a diagram is built
  • Model discovery
  • Relationship detection
  • Schema introspection
  • Scoping a diagram

Operations

  • Diagrams per subsystem
  • Exporting images
  • Themes and fonts
  • Renderer limits
  • Keeping the diagram current
  • Continuous integration

Reference

  • Configuration
  • Console commands
  • Diagram syntax
  • PHP API
  • Testing
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • How a diagram is built
  • Model discovery
  • Relationship detection
  • Schema introspection
  • Scoping a diagram

Operations

  • Diagrams per subsystem
  • Exporting images
  • Themes and fonts
  • Renderer limits
  • Keeping the diagram current
  • Continuous integration

Reference

  • Configuration
  • Console commands
  • Diagram syntax
  • PHP API
  • Testing
  • Troubleshooting

byrcsc/laravel-cartographer · 1.x

Model discovery.

Cartographer scans configured directories and keeps the classes that qualify as Eloquent models.

Before building a diagram, Cartographer needs to find your models. It scans the directories listed in cartographer.paths and checks the PHP classes inside them.

// config/cartographer.php
'paths' => [
    app_path('Models'),
],

Each entry is expanded as a glob against directories. Every matched directory is scanned recursively for .php files.

What qualifies as a model

A class qualifies when all four statements are true:

  1. It is declared in a scanned .php file.
  2. Composer can load the class.
  3. It subclasses Illuminate\Database\Eloquent\Model.
  4. It is not abstract.

Cartographer skips traits, interfaces, enums, plain classes, anonymous classes, and files without a class. A file can contribute two models when it declares two classes and both qualify.

Cartographer reads class declarations from PHP tokens instead of relying on filenames. A HasSlug.php file containing a trait contributes nothing. A Catalog.php file declaring Product and Variant contributes both models.

Discovery is where exclude_models is applied:

'exclude_models' => [
    App\Models\Telemetry::class,
    App\Models\PasswordReset::class,
],

An excluded model produces no entity and no edges. Relations that other models declare towards it are dropped too, because the edge has nowhere to land.

Modular and domain-driven layouts

Globs are the reason paths is a list of patterns rather than a list of directories:

'paths' => [
    app_path('Models'),
    base_path('src/Domain/*/Models'),
    base_path('modules/*/src/Models'),
],

src/Domain/*/Models matches src/Domain/Billing/Models, src/Domain/Catalog/Models, and any domain added later. Nothing needs updating when a new module appears.

Only *-style directory matching is available. Cartographer passes the pattern to PHP's glob() function and keeps directory matches. It does not filter by class name, namespace, or filename. Use exclude_models to remove individual classes from a matched directory.

Overlapping paths are safe

Files are keyed by their resolved real path, so a file reached through two patterns is read once. Listing app_path('Models') twice, or listing both a parent and a child directory, changes nothing about the result.

Ordering

The final list is sorted by fully qualified class name. Directory order, filesystem order, and the order of the paths array have no effect on the output. This is one half of why the diagram is stable between runs.

A path that matches nothing

A pattern matching no directory produces a warning and is skipped:

   WARN  Model discovery path matched no directories: /srv/app/src/Domain/*/Models

The run continues. This is deliberate: a glob for modules that do not exist yet in a given deployment should not break the command.

Warnings are suppressed under --stdout, so piped output stays clean. If you are debugging paths, run without --stdout.

When discovery finds nothing at all, the command fails instead:

   ERROR  No Eloquent models were discovered. Check the paths configured in [cartographer.paths].

Models are still filtered later

Discovery produces candidates, not entities. A discovered model is dropped from the graph at assembly time when either is true:

  • It cannot be instantiated. new Model is called to read the table name; if the constructor throws, the model is skipped with a warning naming the exception.

  • Its table does not exist on the target connection:

       WARN  Skipping model [App\Models\Ghost]: table [missing_ghosts] does not exist.

The second is the common one, and it usually means the database is behind the code. Run your migrations and generate again.

Validation

paths and exclude_models are validated when the command runs, and a bad value fails it:

ProblemMessage
paths is not an array[cartographer.paths] must be an array of strings.
paths contains a non-string or an empty string[cartographer.paths] must contain only non-empty strings.
exclude_models contains a class that is not a model[cartographer.exclude_models] must contain only Eloquent model class names.

exclude_models entries are checked with is_a(..., Model::class, true), so the class must be loadable. A typo in the class name fails the command rather than silently excluding nothing.

What to read next

  • Relationship detection for what happens to each discovered model next.
  • Configuration for the full key reference.
  • Troubleshooting if a model you expected is missing.
PreviousHow a diagram is builtNextRelationship detection
View source

On this page

  1. What qualifies as a model
  2. Modular and domain-driven layouts
  3. Overlapping paths are safe
  4. Ordering
  5. A path that matches nothing
  6. Models are still filtered later
  7. Validation
  8. What to read next