Bundle/WidgetMapBundle/Warmer/WidgetDataWarmer.php
private function extractAssociatedEntities(array $entities)
    {
        $linkIds = $associatedEntities = [];

        foreach ($entities as $entity) {
            $reflect = new \ReflectionClass($entity);

            //If Widget is already in cache, extract only its Criterias (used outside Widget rendering)
            $widgetCached = ($entity instanceof Widget && $this->widgetHelper->isCacheEnabled($entity));

            //If Widget has LinkTrait, store the entity link id
            if (!$widgetCached && $this->hasLinkTrait($reflect) && $entity->getLink()) {
                $linkIds[] = $entity->getLink()->getId();
            }

            //Pass through all entity associations
            $metaData = $this->em->getClassMetadata(get_class($entity));
            foreach ($metaData->getAssociationMappings() as $association) {
                $targetClass = $association['targetEntity'];

                //Skip already set WidgetMap association
                if ($targetClass == WidgetMap::class) {
                    continue;
                }

                //If Widget has OneToOne or ManyToOne association, store target entity id to construct
                //a single query for this entity type
                if ($metaData->isSingleValuedAssociation($association['fieldName'])
                    && !$widgetCached
                ) {
                    //If target Entity is not null, treat it
                    if ($targetEntity = $this->accessor->getValue($entity, $association['fieldName'])) {
                        $associatedEntities[$targetClass]['id']['unsorted']['entitiesToWarm'][] = new AssociatedEntityToWarm(
                            AssociatedEntityToWarm::TYPE_MANY_TO_ONE,
                            $entity,
                            $association['fieldName'],
                            $targetEntity->getId()
                        );
                    }
                }

                //If Widget has OneToMany association, store owner entity id and mappedBy value
                //to construct a single query for this entity type
                elseif ($metaData->isCollectionValuedAssociation($association['fieldName'])) {

                    //Even if Widget is cached, we need its Criterias used before cache call
                    if (!$widgetCached || $targetClass === Criteria::class) {

                        //If Collection is not null, treat it
                        if ($this->accessor->getValue($entity, $association['fieldName'])) {

                            //Don't use Collection getter directly and override Collection
                            //default behaviour to avoid useless query
                            $getter = 'get'.ucwords($association['fieldName']);
                            $entity->$getter()->setDirty(false);
                            $entity->$getter()->setInitialized(true);
                            $orderByToken = 'unsorted';

                            if (isset($association['orderBy'])) {
                                $orderByToken = implode($association['orderBy']);
                                $associatedEntities[$targetClass][$association['mappedBy']][$orderByToken]['orderBy'] = $association['orderBy'];
                            }

                            $associatedEntities[$targetClass][$association['mappedBy']][$orderByToken]['entitiesToWarm'][] = new AssociatedEntityToWarm(
                                AssociatedEntityToWarm::TYPE_ONE_TO_MANY,
                                $entity,
                                $association['fieldName'],
                                $entity->getId()
                            );
                        }
                    }
                }
            }
        }

        $newEntities = $this->setAssociatedEntities($associatedEntities);
        $this->setPagesForLinks($linkIds);

        //Recursive call if previous has return new entities to warm
        if ($newEntities) {
            $this->extractAssociatedEntities($newEntities);
        }
    }
private function extractAssociatedEntities(array $entities)
    {
        $linkIds = $associatedEntities = [];

        foreach ($entities as $entity) {
            $reflect = new \ReflectionClass($entity);

            //If Widget is already in cache, extract only its Criterias (used outside Widget rendering)
            $widgetCached = ($entity instanceof Widget && $this->widgetHelper->isCacheEnabled($entity));

            //If Widget has LinkTrait, store the entity link id
            if (!$widgetCached && $this->hasLinkTrait($reflect) && $entity->getLink()) {
                $linkIds[] = $entity->getLink()->getId();
            }

            //Pass through all entity associations
            $metaData = $this->em->getClassMetadata(get_class($entity));
            foreach ($metaData->getAssociationMappings() as $association) {
                $targetClass = $association['targetEntity'];

                //Skip already set WidgetMap association
                if ($targetClass == WidgetMap::class) {
                    continue;
                }

                //If Widget has OneToOne or ManyToOne association, store target entity id to construct
                //a single query for this entity type
                if ($metaData->isSingleValuedAssociation($association['fieldName'])
                    && !$widgetCached
                ) {
                    //If target Entity is not null, treat it
                    if ($targetEntity = $this->accessor->getValue($entity, $association['fieldName'])) {
                        $associatedEntities[$targetClass]['id']['unsorted']['entitiesToWarm'][] = new AssociatedEntityToWarm(
                            AssociatedEntityToWarm::TYPE_MANY_TO_ONE,
                            $entity,
                            $association['fieldName'],
                            $targetEntity->getId()
                        );
                    }
                }

                //If Widget has OneToMany association, store owner entity id and mappedBy value
                //to construct a single query for this entity type
                elseif ($metaData->isCollectionValuedAssociation($association['fieldName'])) {

                    //Even if Widget is cached, we need its Criterias used before cache call
                    if (!$widgetCached || $targetClass === Criteria::class) {

                        //If Collection is not null, treat it
                        if ($this->accessor->getValue($entity, $association['fieldName'])) {

                            //Don't use Collection getter directly and override Collection
                            //default behaviour to avoid useless query
                            $getter = 'get'.ucwords($association['fieldName']);
                            $entity->$getter()->setDirty(false);
                            $entity->$getter()->setInitialized(true);
                            $orderByToken = 'unsorted';

                            if (isset($association['orderBy'])) {
                                $orderByToken = implode($association['orderBy']);
                                $associatedEntities[$targetClass][$association['mappedBy']][$orderByToken]['orderBy'] = $association['orderBy'];
                            }

                            $associatedEntities[$targetClass][$association['mappedBy']][$orderByToken]['entitiesToWarm'][] = new AssociatedEntityToWarm(
                                AssociatedEntityToWarm::TYPE_ONE_TO_MANY,
                                $entity,
                                $association['fieldName'],
                                $entity->getId()
                            );
                        }
                    }
                }
            }
        }

        $newEntities = $this->setAssociatedEntities($associatedEntities);
        $this->setPagesForLinks($linkIds);

        //Recursive call if previous has return new entities to warm
        if ($newEntities) {
            $this->extractAssociatedEntities($newEntities);
        }
    }
private function extractAssociatedEntities ( array $ entities ) { $ linkIds = $ associatedEntities = [ ] ; foreach ( $ entities as $ entity ) { $ reflect = new \ ReflectionClass ( $ entity ) ; //If Widget is already in cache, extract only its Criterias (used outside Widget rendering) $ widgetCached = ( $ entity instanceof Widget && $ this -> widgetHelper -> isCacheEnabled ( $ entity ) ) ; //If Widget has LinkTrait, store the entity link id if ( ! $ widgetCached && $ this -> hasLinkTrait ( $ reflect ) && $ entity -> getLink ( ) ) { $ linkIds [ ] = $ entity -> getLink ( ) -> getId ( ) ; } //Pass through all entity associations $ metaData = $ this -> em -> getClassMetadata ( get_class ( $ entity ) ) ; foreach ( $ metaData -> getAssociationMappings ( ) as $ association ) { $ targetClass = $ association [ 'targetEntity' ] ; //Skip already set WidgetMap association if ( $ targetClass == WidgetMap :: class ) { continue ; } //If Widget has OneToOne or ManyToOne association, store target entity id to construct //a single query for this entity type if ( $ metaData -> isSingleValuedAssociation ( $ association [ 'fieldName' ] ) && ! $ widgetCached ) { //If target Entity is not null, treat it if ( $ targetEntity = $ this -> accessor -> getValue ( $ entity , $ association [ 'fieldName' ] ) ) { $ associatedEntities [ $ targetClass ] [ 'id' ] [ 'unsorted' ] [ 'entitiesToWarm' ] [ ] = new AssociatedEntityToWarm ( AssociatedEntityToWarm :: TYPE_MANY_TO_ONE , $ entity , $ association [ 'fieldName' ] , $ targetEntity -> getId ( ) ) ; } } //If Widget has OneToMany association, store owner entity id and mappedBy value //to construct a single query for this entity type elseif ( $ metaData -> isCollectionValuedAssociation ( $ association [ 'fieldName' ] ) ) { //Even if Widget is cached, we need its Criterias used before cache call if ( ! $ widgetCached || $ targetClass === Criteria :: class ) { //If Collection is not null, treat it if ( $ this -> accessor -> getValue ( $ entity , $ association [ 'fieldName' ] ) ) { //Don't use Collection getter directly and override Collection //default behaviour to avoid useless query $ getter = 'get' . ucwords ( $ association [ 'fieldName' ] ) ; $ entity -> $ getter ( ) -> setDirty ( false ) ; $ entity -> $ getter ( ) -> setInitialized ( true ) ; $ orderByToken = 'unsorted' ; if ( isset ( $ association [ 'orderBy' ] ) ) { $ orderByToken = implode ( $ association [ 'orderBy' ] ) ; $ associatedEntities [ $ targetClass ] [ $ association [ 'mappedBy' ] ] [ $ orderByToken ] [ 'orderBy' ] = $ association [ 'orderBy' ] ; } $ associatedEntities [ $ targetClass ] [ $ association [ 'mappedBy' ] ] [ $ orderByToken ] [ 'entitiesToWarm' ] [ ] = new AssociatedEntityToWarm ( AssociatedEntityToWarm :: TYPE_ONE_TO_MANY , $ entity , $ association [ 'fieldName' ] , $ entity -> getId ( ) ) ; } } } } } $ newEntities = $ this -> setAssociatedEntities ( $ associatedEntities ) ; $ this -> setPagesForLinks ( $ linkIds ) ; //Recursive call if previous has return new entities to warm if ( $ newEntities ) { $ this -> extractAssociatedEntities ( $ newEntities ) ; } }
Pass through all widgets and associated entities to extract all missing associations,
store it by repository to group queries by entity type.

@param Widget[] $entities Widgets and associated entities
Pass through all widgets and associated entities to extract all missing associations store it by repository to group queries by entity type .