This is the official documentation of the forestadmin/laravel-forestadmin v2+ and forestadmin/symfony-forestadmin PHP agents.
Forest Admin can connect to any data source, as long as it can be represented as a collection of records that have a common structure.
To achieve that, Forest Admin needs to abstract away data source differences: each connector "speaks" the language of a given API on one side and exposes the Forest Admin Query Interface on the other.
This interface is called the Forest Admin Query Interface, it is not a full-featured ORM: its objective is to be "just enough" to fuel Forest Admin.
Choosing how to query your data
The Forest Admin Query Interface is used to implement all native features of the admin panel, however, when writing custom code (creating new actions, fields, ...), you can either access your data using the Forest Admin Query Interface or using the native driver.
The choice is yours, and you will probably use both depending on the situation.
In practice
Querying with the native driver
As the name implies, native drivers have different interfaces for each data source.
useForestAdmin\AgentPHP\DatasourceCustomizer\CollectionCustomizer;$forestAgent->customizeCollection('Customer',function (CollectionCustomizer $builder) { $builder->addSegment('highPrice',function ($context) {/** @var\Doctrine\ORM\EntityManager $em */ $em = $context->getCollection()->getNativeDriver(); $qb = $em->createQueryBuilder()->select('p.id as product_id','count(o.id) as nb')->from(\App\Entity\Order::class,'o')->innerJoin(\App\Entity\Product::class,'p','WITH','o.product = p.id')->groupBy('p.id')->orderBy('nb','DESC')->setMaxResults(10); $query = $qb->getQuery();// OR with DQL string// $query = $em->createQuery('// SELECT p.id as product_id, count(o.id) as nb// FROM App\Entity\Order o// INNER JOIN App\Entity\Product p WITH o.product = p.id// GROUP BY p.id// ORDER BY nb DESC')// OR// $conn = $context->getCollection()->getNativeDriver()->getConnection();// $sql = '// SELECT p.id as product_id, count(o.id) as nb// FROM Order o// INNER JOIN Product p ON o.product = p.id// GROUP BY p.id// ORDER BY nb DESC';// $query = $conn->executeQuery($sql);// then use $query->fetchAllAssociative(); $ids =array_reduce($query->getResult(),function ($result, $item) { $result[] = $item['product_id'];return $result; }, []);return ['field'=>'id','operator'=>'In','value'=> $ids, ]; }); });
Querying with the Forest Admin Query Interface
Queries can be executed directly, by calling the methods exposed by context.dataSource and context.collection.
useForestAdmin\AgentPHP\DatasourceToolkit\Components\Caller;useForestAdmin\AgentPHP\DatasourceToolkit\Components\Charts\Chart;useIlluminate\Support\Collectionas IlluminateCollection;interfaceDatasourceContract{/** Retrieve list of all collection within the data source */publicfunctiongetCollections():IlluminateCollection;/** Retrieve list of all charts within the data source */publicfunctiongetCharts():IlluminateCollection;/** Get collection by name */publicfunctiongetCollection(string $name):CollectionContract;/** Add collection to the data source */publicfunctionaddCollection(CollectionContract $collection):void;/** Render the chart given by name */publicfunctionrenderChart(Caller $caller,string $name):Chart|array;}
Collection Interface
Parameters are explained in depth on the following pages:
useForestAdmin\AgentPHP\DatasourceToolkit\Components\Caller;useForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Aggregation;useForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Filters\Filter;useForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Filters\PaginatedFilter;useForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Projection\Projection;interfaceCollectionContract{publicfunctiongetDataSource():DatasourceContract;publicfunctiongetName():string;/** Execute the action given by name */publicfunctionexecute(Caller $caller,string $name,array $formValues,?Filter $filter =null);/** Get the form of the action given by name */publicfunctiongetForm(Caller $caller,string $name,?array $formValues =null,?Filter $filter =null):array;/** Create new records */publicfunctioncreate(Caller $caller,array $data);/** List records matching filter */publicfunctionlist(Caller $caller,PaginatedFilter $filter,Projection $projection):array;/** Update records matching filter */publicfunctionupdate(Caller $caller,Filter $filter,array $patch);/** Delete records matching filter */publicfunctiondelete(Caller $caller,Filter $filter):void;/** Compute aggregated version of records matching filter */ public function aggregate(Caller $caller, Filter $filter, Aggregation $aggregation, ?int $limit = null, ?string $chartType = null);
/** Render chart for a given record */publicfunctionrenderChart(Caller $caller,string $name,array $recordId);}