skip to Main Content

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?

2

Answers


  1. Chosen as BEST ANSWER

    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 AppState;
    
    use ApiPlatformMetadataDeleteOperationInterface;
    use AppEntityMembership;
    use ApiPlatformMetadataOperation;
    use ApiPlatformStateProcessorInterface;
    use DoctrineORMEntityManagerInterface;
    use SymfonyComponentDependencyInjectionAttributeAutowire;
    
    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.


  2. Consider changing the method to a regular field that recalculates when members change. Your current implementation is a very "hacky" way to approach the subject and might struggle in a production environment.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search