Computed foreign keys
Displaying a link to the last message sent by a customer
use ForestAdmin\AgentPHP\DatasourceCustomizer\CollectionCustomizer;
use ForestAdmin\AgentPHP\DatasourceCustomizer\Decorators\Computed\ComputedDefinition;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\ConditionTree\Operators;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Aggregation;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Filters\Filter;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Filters\PaginatedFilter;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\ConditionTree\ConditionTreeFactory;
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Query\Projection\Projection;
$forestAgent->customizeCollection(
'Customer',
function (CollectionCustomizer $builder) {
// Create foreign key
$builder->addField(
'lastMessageId',
new ComputedDefinition(
columnType: 'Number',
dependencies: ['id'],
values: function ($customers, $context) {
$customerIds = array_map(fn ($r) => $r['id'], $customers);
// We're using Forest Admin's query interface
$filter = new Filter(
conditionTree: ConditionTreeFactory::fromArray(
['field' => 'customer_id', 'operator' => 'In', 'value' => $customerIds]
)
);
$aggregation = new Aggregation(operation: 'Max', field: 'id', groups: [[ 'field' =>'customer_id' ]]);
$rows = $context->getDatasource()->getCollection('Message')->aggregate($filter, $aggregation);
return array_map(
function ($customer) use ($rows) {
foreach ($rows as $row) {
if ($row['group']['customer_id'] === $customer['id']) {
return $row['value'] ?? null;
}
}
return 0;
},
$customers
);
}
)
)->replaceFieldOperator(
'lastMessageId',
'In',
function ($lastMessageIds, $context) {
$filter = new PaginatedFilter(
conditionTree: ConditionTreeFactory::fromArray(
['field' => 'id', 'operator' => 'In', 'value' => $lastMessageIds]
)
);
$records = $context->getDatasource()
->getCollection('Message')
->list($filter, new Projection(['customer_id']));
return ['field' => 'id', 'operator' => 'In', 'value' => array_map(fn ($r) => $r['customer_id'], $records)];
}
)->addManyToOneRelation('lastMessage', 'Message', 'lastMessageId');
}
);Connecting collections without having a shared identifier
Last updated