In my Symfony Api platform project, I have an entity Community
with a custom method getTotalMembers()
that returns the number of members in the community. However, when I try to order my results, it doesn't work.
#[ApiFilter(OrderFilter::class,
properties: ['id', 'name', 'totalMembers'],
arguments: ['orderParameterName' => 'order']
)]
/**
* @return int current number of users that are members of this community
*/
#[Groups(['community:read','community:read_list'])]
public function getTotalMembers(): ?int
{
return $this->members->count();
}
Is there a simple way to make it work?
After a lot of struggle I was able to solve partially the issue with custom State processor on the many to many join relationship table. It calls method that adds or removes 1 from regular field that I can use for sorting.
<?php
namespace App\State;
use ApiPlatform\Metadata\DeleteOperationInterface;
use App\Entity\Membership;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
final class MembershipStateProcessor implements ProcessorInterface
{
public function __construct(
#[Autowire(service: 'api_platform.doctrine.orm.state.persist_processor')]
private ProcessorInterface $persistProcessor,
#[Autowire(service: 'api_platform.doctrine.orm.state.remove_processor')]
private ProcessorInterface $removeProcessor,
private EntityManagerInterface $entityManager,
) {
}
/**
* @param Membership $data
*/
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): Membership|null
{
// decrease amount of members inside communities
if ($operation instanceof DeleteOperationInterface) {
$subreddit = $data->getSubreddit();
$subreddit->setTotalMembers(isDelete: true);
$this->entityManager->persist($subreddit);
$this->removeProcessor->process($data, $operation, $uriVariables, $context);
return null;
}
// increase amount of members inside communities
$subreddit = $data->getSubreddit();
$subreddit->setTotalMembers(isDelete: false);
$this->entityManager->persist($subreddit);
return $this->persistProcessor->process($data, $operation, $uriVariables, $context);
}
}
The problem now, however, is that factories do not trigger this class and so entities made with factories aren't counted in, which hinders my ability to test this future.