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

Arbol Laravel Package

calvient/arbol

calvient/arbol is a Laravel package for managing hierarchical tree data in Eloquent models, with helpers for ancestors, descendants, nested sets, and ordered category structures. It simplifies building trees, querying relationships, and maintaining sorted node hierarchies.

View on GitHub
Deep Wiki
Context7

Getting Started

Arbol is a Laravel package for building database-driven reports (columns, filters, sorts, groupings, aggregates, exports) without hand-rolling a query UI each time. The 1.0.4 release is a small bugfix, so the onboarding path is unchanged.

Minimal steps:

  1. composer require calvient/arbol, then publish and run migrations (saved_reports and related tables store user-defined report state) and publish the config.
  2. Skim config/arbol.php first — it controls route registration, middleware/auth guard for the report UI and saved-report endpoints, export drivers, and pagination defaults. Most "why is this 403 / 404" questions are answered here.
  3. Create your first report class (extend the package's base Report). Start with the smallest possible definition: a base query, 3–4 columns, one filter, one sort. Resist adding aggregates until the simple report renders and exports.
  4. Look at the package's own test fixtures/example reports before reading the source — they demonstrate the intended shape of columns(), filters(), sorts(), groups(), and aggregates() far faster than the API surface.
  5. First real use case: a read-only "Orders" report scoped to the current tenant, with a date-range filter, sortable amount column, and CSV export. That exercises the whole pipeline (query → columns → filter → export) in one pass.

Implementation Patterns

One report class per dataset, thin definitions. Keep column/filter declarations declarative and push business logic into Eloquent scopes or query builder macros. Reports become long and brittle when they contain inline DB::raw conditionals.

Sections are the unit of composition. A report can hold multiple sections, each with its own query and its own filters/sorts/columns. Treat a section as "one table/grid" — dashboards are usually several sections in one report rather than several report classes.

Saved reports are the persistence layer. Users define a report config (filters, sorts, visible columns, groupings) and you persist it. Build features against the saved-report object rather than re-deriving config from request input on every load, so saved state and live state stay consistent.

Per-section saved filters (1.0.4). Saved filters are now scoped to the report section that created them. This is the correct model — previously a filter saved against one section could bleed into another section of the same report. Design new saved-report features assuming filters belong to a section, and key any of your own caching/ETag logic on (saved_report_id, section).

Exports. Route anything non-trivial through the queue. Large exports against aggregate-heavy sections are the most common source of timeouts; keep a separate "export" code path that skips UI-only columns.

Testing. Assert on the report's declared structure (column keys, filter names, compiled query bindings) rather than snapshotting rendered HTML. A test that boots the report with a fixed input payload and asserts the resulting SQL/bindings catches most regressions cheaply.

Gotchas and Tips

  • 1.0.4 is a behavior change, not just a fix. If you relied on a saved filter applying across every section of a report, it no longer will. Audit saved reports created before the upgrade; users may see a section silently lose a filter. There is no data migration implied by the note, so existing rows keep their filter payloads but they're now interpreted per-section.
  • N+1 in column accessors. Columns that reach into relations are evaluated per row. Eager-load everything a column touches on the report's base query; don't rely on lazy loading.
  • Grouping and aggregates interact badly with column definitions. A column that isn't grouped or aggregated will break under strict SQL modes. Validate report definitions with ONLY_FULL_GROUP_BY enabled locally — this is the single most common "works on my machine" report failure.
  • Join column collisions. Qualify every column with its table. Unqualified id/name/created_at will silently resolve to the wrong table once the report joins more than one.
  • Auth and tenancy are config, not code. Reports execute raw-ish queries; make sure the configured middleware/guard in config/arbol.php is actually applied in your environment, and scope base queries by tenant explicitly. Don't assume the package does it for you.
  • Debugging: log the compiled SQL and bindings from the report's query after filters/sorts are applied — most filter bugs are "filter applied twice" or "filter ignored because the key didn't match the column name."
  • Extension points worth knowing: custom column types (renderers), custom filter types, and overriding the export path. Prefer a custom filter type over a bespoke controller endpoint — it keeps the saved-report payload schema consistent.
  • Pin the minor version in composer.json if you ship saved reports to end users; filter persistence semantics have now changed once in a patch release, so treat report-config serialization as a de facto public API.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
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