symfonyorocrm

ORO platform - how to pass collection of related entities to datagrid column template?


I have an entity with related entities in ORO platform. Built-in User entity can have many built-in Access Roles. I want to display those roles in Users datagrid using custom twig template so I can wrap them in some labels or styling.

This is my section datagrids.yaml that overrides the default users datagrid:

    users-grid:
        source:
            query:
                select:
                    - What to pass here?
                join:
                    left:
                        - { join: u.roles, alias: r }
                groupBy: u.id
        columns:
            roles:
                inline_editing:
                    enable: false
                label: 'Roles'
                type: twig
                frontend_type: html
                template: 'MyBundle:User:Property/roles.html.twig'

What do I have to do to be able to access Collection of Role object in roles.html.twig?


Solution

  • It's not possible to do just with the YAML configuration. Instead, you have to create a datagrid listener that will populate the roles column with the data on the "result after" event. Here is an example:

    <?php
    
    namespace AcmeDemoBundle\EventListener;
    
    use Oro\Bundle\DataGridBundle\Datasource\ResultRecord;
    use Oro\Bundle\DataGridBundle\Event\OrmResultAfter;
    use Oro\Bundle\EntityBundle\ORM\DoctrineHelper;
    use Oro\Bundle\UserBundle\Entity\User;
    
    class UserRolesGridListener
    {
        /** @var DoctrineHelper */
        protected $doctrineHelper;
    
        /**
         * @param DoctrineHelper $doctrineHelper
         */
        public function __construct(DoctrineHelper $doctrineHelper)
        {
            $this->doctrineHelper = $doctrineHelper;
        }
    
        /**
         * @param OrmResultAfter $event
         */
        public function onResultAfter(OrmResultAfter $event)
        {
            $userIds = [];
            /** @var ResultRecord[] $records */
            $records = $event->getRecords();
            foreach ($records as $record) {
                $userIds[] = $record->getValue('id');
            }
    
            $repository = $this->doctrineHelper->getEntityRepository(User::class);
            $userRoles = $repository->createQueryBuilder('user')
                ->select('partial user.{id}, partial roles.{id, label}')
                ->indexBy('user','user.id')
                ->leftJoin('user.roles','roles')
                ->where('user.id in (:userIds)')
                ->setParameter('userIds', $userIds)
                ->getQuery()
                ->getArrayResult();
            foreach ($records as $record) {
                $id = $record->getValue('id');
                $record->addData(['roles' => $userRoles[$id]['roles']]);
            }
        }
    }
    
    services:
        AcmeDemoBundle\EventListener\UserRolesGridListener:
            arguments:
                - '@oro_entity.doctrine_helper'
            tags:
                - { name: kernel.event_listener, event: oro_datagrid.orm_datasource.result.after.users-grid, method: onResultAfter }
    
    datagrids:
        users-grid:
            columns:
                roles:
                    inline_editing:
                        enable: false
                    label: 'Roles'
                    type: twig
                    frontend_type: html
                    template: 'AcmeDemoBundle:User:Column/roles.html.twig'
    
    {% for role in record.getValue('roles') %}
      <div class="role-{{ role.id }}">{{ role.label }}</div>
    {% endfor %}