/** * Standard method for processing relationships * build an intermediate list of related records * then normalize them for inclusion in the final response * * @param Relation|PhalconRelation $relation * @param array|Row $baseRecord * @throws HTTPException * @return mixed */ protected function processStandardRelationships($relation, $baseRecord) { // store parentModels for later use $parentModels = $this->model->getParentModels(true); // the intermediate set of related records $relatedRecords = []; // store a copy of all related record (PKIDs) // this must be attached w/ the parent records for joining purposes $relatedRecordIds = null; if ($parentModels and in_array($relation->getReferencedModel(), $parentModels)) { // skip any parent relationships because they are merged into the main record } else { $refType = $relation->getType(); $alias = $relation->getAlias(); // figure out if we have a preferred alias if (isset($alias)) { $refModelName = $alias; } else { $refModelName = $relation->getModelName(); } $config = $this->getDI()->get('config'); // harmonize relatedRecords switch ($refType) { case PhalconRelation::BELONGS_TO: // if fastBelongsTo is disabled, use the standard approach to loading belongsTo records if (!array_deep_key($config, 'feature_flags.fastBelongsTo')) { $relatedRecords = $this->getBelongsToRecord($relation); } else { // attempt a shortcut for some belongs to relationships // for simple belongsTo, pluck the related record out of base record since we know its in there // some belongsTo have parent records, revert to the older style to get a complete record if ($relation->getParent()) { $relatedRecords = $this->getBelongsToRecord($relation); } else { $relatedRecords = $this->loadRelationRecords([$baseRecord->{$refModelName}], $relation); } } break; case PhalconRelation::HAS_ONE: // ignore hasOne since they are processed like a parent relation // this means current logic will not merge in a parent's record for a hasOne relationship // it's an edge case but should be supported in the future break; case PhalconRelation::HAS_MANY_THROUGH: $relatedRecords = $this->getHasManyToManyRecords($relation); break; case PhalconRelation::HAS_MANY: if (!array_deep_key($config, 'feature_flags.fastHasMany')) { $relatedRecords = $this->getHasManyRecords($relation); } else { // register a future record request to be processed later $this->registerHasManyRequest($relation); } break; default: // wah! throw new HTTPException("Unknown relationship submitted!", 500, array('code' => '4984846846849494')); break; } // only normalize when some sort of resultset is returned, even an empty array if (isset($relatedRecords) && is_array($relatedRecords)) { return $this->normalizeRelatedRecords($baseRecord, $relatedRecords, $relation); } return true; } }