public function setup()
 {
     $this->metadata = \Mockery::mock("Silktide\\Reposition\\Metadata\\EntityMetadata");
     $this->metadata->shouldReceive("getCollection")->andReturn("test", "one");
     $this->intermediaryMetadata = \Mockery::mock("Silktide\\Reposition\\Metadata\\EntityMetadata");
     $this->metadataProvider = \Mockery::mock("Silktide\\Reposition\\Metadata\\EntityMetadataProviderInterface");
     $this->metadataProvider->shouldReceive("getEntityMetadata")->andReturn($this->metadata);
     $this->metadataProvider->shouldReceive("getEntityMetadataForIntermediary")->andReturn($this->intermediaryMetadata);
     $this->outputDir = vfsStream::url($this->testDir);
     vfsStreamWrapper::register();
     vfsStreamWrapper::setRoot(new vfsStreamDirectory($this->testDir, 0777));
 }
 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);
     }
 }