This is the official documentation of the forestadmin/laravel-forestadmin v2+ and forestadmin/symfony-forestadmin PHP agents.
Steps
Creating a custom data source will require you to work on the 3 following steps:
Declare the structure of the data
Declare the API capabilities
Code a translation layer
Minimal example
<?php
use ForestAdmin\AgentPHP\DatasourceToolkit\Collection;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Caller;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Contracts\DatasourceContract;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Aggregation;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Filters\Filter;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Projection\Projection;
use ForestAdmin\AgentPHP\DatasourceToolkit\Schema\ColumnSchema;
use GuzzleHttp\Client;
// The real work is in writing this module
// Expect a full featured query translation module to be over 1000 LOCs
use QueryGenerator;
class MyCollection extends Collection
{
public function __construct(DatasourceContract $datasource)
{
parent::__construct(
$datasource,
'MyCollection'
);
$this->addField('id', new ColumnSchema(
columnType: 'Number',
// As we are using the query translation strategy => define capabilities
filterOperators: [], // field is not filterable
isPrimaryKey: true,
isReadOnly: true, // field is readonly
isSortable: false // field is not sortable
));
$this->addField('title', new ColumnSchema(
columnType: 'String',
filterOperators: [],
isPrimaryKey: false,
isReadOnly: true,
isSortable: false
));
$this->client = new Client([
'base_uri' => 'https://my-api/',
'timeout' => 5.0,
]);
}
public function list(Caller $caller, Filter $filter, Projection $projection): array
{
$params = QueryGenerator::generateListQueryString($filter, $projection);
try {
$response = $this->client->get('my-collection', [
'query' => $params,
]);
$body = json_decode($response->getBody()->getContents(), true);
return $body['items'] ?? [];
} catch (\Exception $e) {
throw new \RuntimeException('Failed to fetch items: ' . $e->getMessage());
}
}
public function aggregate(Caller $caller, Filter $filter, Aggregation $aggregation, ?int $limit = null)
{
$params = QueryGenerator::generateAggregateQueryString($filter, $aggregation, $limit);
try {
$response = $this->client->get('my-collection', [
'query' => $params,
]);
$body = json_decode($response->getBody()->getContents(), true);
return $body['items'] ?? [];
} catch (\Exception $e) {
throw new \RuntimeException('Failed to fetch items: ' . $e->getMessage());
}
}
}
<?php
use Collections\MyCollection;
use ForestAdmin\AgentPHP\DatasourceToolkit\DataSource;
class MyDataSource extends DataSource
{
public function __construct()
{
parent::__construct();
$this->addCollection(new MyCollection($this)); // List of your collections
}
<?php
use ForestAdmin\AgentPHP\Agent\Builder\AgentFactory;
return static function () {
$dataSource = new MyDataSource();
$agent = new AgentFactory([]);
$agent->addDatasource($dataSource);
return $dataSource;
};
Read more
Implementing a data source using the "query translation" strategy is an advanced concept: you will need to have a deep understanding of Forest Admin internals.
This strategy is a good match when writing data sources for full-featured databases.
Before starting, it is highly advised to read and understand the following sections: