Ejemplo n.º 1
0
 public function includeEntity(EntityMetadata $childMetadata, $collectionAlias = "", $parent = "", TokenSequencerInterface $additionalFilters = null)
 {
     // check we're dealing with a query
     if (!$this->isQuery()) {
         throw new TokenParseException("Cannot include an entity on an expression sequence.");
     }
     // get data on the child entity
     $childEntity = $childMetadata->getEntity();
     $childCollection = $childMetadata->getCollection();
     $childAlias = empty($collectionAlias) ? $childCollection : $collectionAlias;
     // determine which entity to join on (the parent)
     $parentMetadata = $this->getEntityMetadata();
     if (!empty($parent)) {
         if (empty($this->includes[$parent])) {
             throw new TokenParseException("Cannot include the entity '{$childEntity}'. The parent entity '{$parent}' has not yet been included");
         }
         /** @var EntityMetadata $parentMetadata */
         $parentMetadata = $this->includes[$parent];
         if ($parent == $parentMetadata->getEntity()) {
             $parent = $parentMetadata->getCollection();
         }
     }
     // make sure we have a parent that we can use as a table name or alias
     if (empty($parent) || $parent == $parentMetadata->getEntity()) {
         $parent = $parentMetadata->getCollection();
     }
     // get the relationship between the child and parent
     $relationshipAlias = empty($collectionAlias) ? $childEntity : $collectionAlias;
     $relationship = $parentMetadata->getRelationship($relationshipAlias);
     if (empty($relationship)) {
         throw new TokenParseException("The parent entity '{$parentMetadata->getEntity()}' has no relationship defined for '{$relationshipAlias}'");
     }
     // find the fields we will need to use in the join condition
     // we need the primary key and/or the parent field defined in the relationship
     $parentKey = $parentMetadata->getPrimaryKey();
     $parentField = $parent . "." . (empty($relationship[EntityMetadata::METADATA_RELATIONSHIP_OUR_FIELD]) ? $parentKey : $relationship[EntityMetadata::METADATA_RELATIONSHIP_OUR_FIELD]);
     // we need the primary key and/or the child field defined in the relationship
     $childKey = $childMetadata->getPrimaryKey();
     $childField = $childAlias . "." . (empty($relationship[EntityMetadata::METADATA_RELATIONSHIP_THEIR_FIELD]) ? $childKey : $relationship[EntityMetadata::METADATA_RELATIONSHIP_THEIR_FIELD]);
     // many to many relationships require an extra join, so treat them differently
     if ($relationship[EntityMetadata::METADATA_RELATIONSHIP_TYPE] != EntityMetadata::RELATIONSHIP_TYPE_MANY_TO_MANY) {
         // create the join condition
         $onClause = new TokenSequencer($this->tokenFactory);
         $onClause->ref($parentField)->op("=")->ref($childField);
         // if we have additional join filters, add them now
         if (!empty($additionalFilters)) {
             $onClause->andL()->mergeSequence($additionalFilters->getSequence());
         }
         // create the join
         $this->join($childCollection, $onClause, $collectionAlias);
     } else {
         // many to many. Requires intermediary join table
         $joinTable = $relationship[EntityMetadata::METADATA_RELATIONSHIP_JOIN_TABLE];
         // create the join condition from the parent to the intermediate
         $parentToMany = new TokenSequencer($this->tokenFactory);
         $parentToMany->ref($parentField)->op("=")->ref("{$joinTable}.{$parent}_id");
         // create the join condition from the intermediate to the child, including any additional join filters
         $manyToChild = new TokenSequencer($this->tokenFactory);
         $manyToChild->ref("{$joinTable}.{$childAlias}_id")->op("=")->ref($childField);
         if (!empty($additionalFilters)) {
             $manyToChild->andL()->mergeSequence($additionalFilters->getSequence());
         }
         // create the joins
         $this->join($joinTable, $parentToMany)->join($childCollection, $manyToChild, $collectionAlias);
     }
     // add the include
     $this->includes[$childAlias] = $childMetadata;
     return $this;
 }
Ejemplo n.º 2
0
 public function parseTokenSequence(TokenSequencerInterface $tokens)
 {
     $sequence = $tokens->getSequence();
     $type = $tokens->getType();
     $position = $this->parseTokens($type, $sequence);
     if (!empty($sequence[$position])) {
         throw new TokenParseException("Unexpected tokens at the end of the sequence. Reached position {$position} of " . count($sequence));
     }
 }