Build Your First Data Source
After this page, you can define a clean source with safe fields, operators, and aggregates for your report engine.
What you are building
A data source called orders that exposes only trusted fields:
customer_namestatustotal_amountcreated_at
Step 1: Create a source class
You can keep this as an app class and register it during boot.
php
<?php
namespace App\Reporting;
use App\Models\Order;
use Ihasan\ReportBuilder\DataSources\EloquentDataSource;
use Ihasan\ReportBuilder\Enums\AggregateFunction;
use Ihasan\ReportBuilder\Enums\FilterOperator;
use Ihasan\ReportBuilder\Support\Field;
class OrdersDataSource extends EloquentDataSource
{
public function __construct()
{
parent::__construct(
key: 'orders',
label: 'Orders',
model: Order::class,
fields: [
Field::string('status')
->label('Status')
->column('orders.status')
->sortable()
->filterable([FilterOperator::Equals, FilterOperator::In]),
Field::string('customer_name')
->label('Customer Name')
->column('orders.customer_name')
->sortable()
->filterable([FilterOperator::Like]),
Field::decimal('total_amount')
->label('Total Amount')
->column('orders.total_amount')
->sortable()
->groupable()
->filterable([
FilterOperator::Equals,
FilterOperator::GreaterThan,
FilterOperator::Between,
])
->aggregates([AggregateFunction::Sum, AggregateFunction::Avg]),
Field::dateTime('created_at')
->label('Created At')
->column('orders.created_at')
->sortable()
->filterable([
FilterOperator::DateAfter,
FilterOperator::DateBefore,
FilterOperator::ThisMonth,
]),
],
);
}
}Step 2: Register the class
php
$reportBuilder->registerDataSource(new OrdersDataSource());Verify
Run a small preview:
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'),
],
)
);Check that:
- preview
columnsmatch your selected fields - preview
rowsreturn data without exposing private/internal columns - no validation error is raised for selected fields and operators
Common mistakes
- Duplicate field keys in one source.
- Using old operator names like
Eq,Gt,Gte,Lte. - Missing
column()mapping for renamed keys. - Making all fields groupable/filterable without reason.
- Using date fields with generic numeric operators when date operators are clearer.
Next
Continue with Use Field Metadata in UI.