protected function addIncludes(TokenSequencerInterface $query, $includeRelationships = null) { $includeRelationships = is_null($includeRelationships) ? $this->includeRelationshipsByDefault : $includeRelationships; if (!empty($includeRelationships)) { if (!is_array($includeRelationships) || isset($includeRelationships[0])) { $includeRelationships = ["this" => $includeRelationships]; } $allRelationships = ["this" => $this->entityMetadata->getRelationships()]; $relationships = []; $parents = []; // add all the relationship metadata we need into the allRelationships array foreach (array_keys($includeRelationships) as $alias) { if ($alias == "this") { // already added the subject entity's relationships continue; } foreach ($allRelationships as $subset) { if (!empty($subset[$alias])) { $relationshipEntity = $subset[$alias][EntityMetadata::METADATA_ENTITY]; $relationshipMetadata = $this->metadataProvider->getEntityMetadata($relationshipEntity); $allRelationships[$alias] = $relationshipMetadata->getRelationships(); break; } } } foreach ($includeRelationships as $alias => $includes) { if (empty($allRelationships[$alias])) { continue; } $thisRelationships = $allRelationships[$alias]; // if we have an array of includes, filter thisRelationships if (is_array($includes)) { $thisRelationships = array_intersect_key($allRelationships[$alias], array_flip($includes)); } // record the parent of each of the child aliases, so we can reference them when we include the entity foreach (array_keys($thisRelationships) as $childAlias) { $parents[$childAlias] = $alias; } // add thisRelationships to the final list $relationships = array_replace($relationships, $thisRelationships); } // get the metadata for each entity and include it on the query foreach ($relationships as $alias => $relationship) { $metadata = $this->metadataProvider->getEntityMetadata($relationship[EntityMetadata::METADATA_ENTITY]); if ($alias == $metadata->getEntity()) { $alias = ""; } $parent = ""; if (!empty($parents[$alias]) && $parents[$alias] != "this") { $parent = $parents[$alias]; } $query->includeEntity($metadata, $alias, $parent); } } }
protected function createFieldTree(array &$fields, array $entityMap, $alias, $entity) { $metadata = $this->metadataProvider->getEntityMetadata($entity); // store the primary key field for this entity $primaryKey = $metadata->getPrimaryKey(); if (!empty($fields[$alias][$primaryKey])) { $this->primaryKeyFields[$fields[$alias][$primaryKey]] = true; } $availableJoins = $metadata->getRelationships(); foreach ($entityMap as $childAlias => $childMetadata) { if (!empty($this->treedEntities[$childAlias])) { // Already done this one. Don't process again continue; } /** @var EntityMetadata $childMetadata */ $childEntity = $childMetadata->getEntity(); $thisJoin = !empty($availableJoins[$childAlias]) ? $availableJoins[$childAlias] : (!empty($availableJoins[$childEntity]) ? $availableJoins[$childEntity] : []); if (empty($thisJoin)) { continue; } if (empty($thisJoin[EntityMetadata::METADATA_RELATIONSHIP_PROPERTY])) { throw new NormalisationException("No property for '{$entity}' defined in the relationship for '{$childAlias}'"); } $property = $thisJoin[EntityMetadata::METADATA_RELATIONSHIP_PROPERTY]; // add the alias to the list of processed children $this->treedEntities[$childAlias] = true; if (empty($fields[$childAlias])) { // get this entities collection from it's metadata and try that $childAlias = $childMetadata->getCollection(); if (empty($fields[$childAlias])) { continue; } } if ($thisJoin[EntityMetadata::METADATA_RELATIONSHIP_TYPE] == EntityMetadata::RELATIONSHIP_TYPE_ONE_TO_ONE) { // mark this branch as a non-collection $fields[$childAlias][""] = true; } $fields[$alias][$property] =& $fields[$childAlias]; $this->createFieldTree($fields, $entityMap, $childAlias, $childEntity); } }