Register a Source Safely
Use this page to register a source that exposes only intentional fields and executes safely in production.
Problem
You need a report source that is usable by product teams without exposing internal query details.
Prerequisites
- Package installed
- A model like
Order
Steps
- Create an
EloquentDataSource. - Add explicit
Fielddefinitions. - Add source scope and authorization rules.
- Register it in app boot.
php
<?php
use App\Models\Order;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Ihasan\ReportBuilder\DataSources\EloquentDataSource;
use Ihasan\ReportBuilder\Enums\AggregateFunction;
use Ihasan\ReportBuilder\Enums\FilterOperator;
use Ihasan\ReportBuilder\ReportBuilder;
use Ihasan\ReportBuilder\Support\Field;
$reportBuilder->registerDataSource(
new EloquentDataSource(
key: 'orders',
label: 'Orders',
model: Order::class,
fields: [
Field::string('customer_name')
->label('Customer Name')
->column('orders.customer_name')
->sortable()
->filterable([FilterOperator::Like]),
Field::string('status')
->label('Order Status')
->column('orders.status')
->sortable()
->filterable([FilterOperator::Equals, FilterOperator::In]),
Field::decimal('total_amount')
->label('Total Amount')
->column('orders.total_amount')
->sortable()
->groupable()
->filterable([FilterOperator::Equals, FilterOperator::Between])
->aggregates([AggregateFunction::Sum]),
Field::dateTime('created_at')
->label('Created At')
->column('orders.created_at')
->sortable()
->filterable([
FilterOperator::DateAfter,
FilterOperator::DateBefore,
FilterOperator::ThisMonth,
]),
],
scope: static function (Builder $query, Request $request): Builder {
$tenantId = $request->user()?->tenant_id;
if ($tenantId !== null) {
$query->where('orders.tenant_id', $tenantId);
}
return $query;
},
authorization: static function (Request $request): bool {
return $request->user()?->can('view_reports') === true;
},
)
);Verify
Run a small preview against this source:
php
<?php
use Ihasan\ReportBuilder\DTOs\ReportDefinition;
use Ihasan\ReportBuilder\DTOs\SelectedColumn;
use Ihasan\ReportBuilder\Execution\PreviewRunner;
$preview = app(PreviewRunner::class)->preview(
new ReportDefinition(
sourceKey: 'orders',
selectedColumns: [
new SelectedColumn('customer_name'),
new SelectedColumn('status'),
new SelectedColumn('total_amount'),
],
),
perPage: 5,
page: 1,
);Confirm that:
columnscontains exactly your selected fields in order.rowscontains only tenant-scoped data.paginationis returned.
Common mistakes
- Registering sources in the wrong lifecycle location.
- Using old enum names like
FilterOperator::Eq. - Missing
column()when the public key differs from the trusted DB column. - Overexposing fields that should stay private.
- Forgetting authorization/scope, which can leak cross-tenant data.