LazyRecord\BaseModel::getRelationalRecords PHP Method

getRelationalRecords() public method

public getRelationalRecords ( $key, $relation = null )
    public function getRelationalRecords($key, $relation = null)
    {
        // check for the object cache
        $cacheKey = 'relationship::' . $key;
        if ($this->hasInternalCache($cacheKey)) {
            return clone $this->_cache[$cacheKey];
        }
        if (!$relation) {
            $relation = $this->getSchema()->getRelation($key);
        }
        /*
        switch($relation['type']) {
            case Relationship::HAS_ONE:
            case Relationship::HAS_MANY:
            break;
        }
        */
        if (Relationship::HAS_ONE === $relation['type']) {
            $sColumn = $relation['self_column'];
            $fSchema = $relation->newForeignSchema();
            $fColumn = $relation['foreign_column'];
            if (!$this->hasValue($sColumn)) {
                return;
            }
            // throw new Exception("The value of $sColumn of " . get_class($this) . ' is not defined.');
            $sValue = $this->getValue($sColumn);
            $model = $relation->newForeignModel();
            $model->load(array($fColumn => $sValue));
            return $this->setInternalCache($cacheKey, $model);
        } elseif (Relationship::HAS_MANY === $relation['type']) {
            // TODO: migrate this code to Relationship class.
            $sColumn = $relation['self_column'];
            $fSchema = $relation->newForeignSchema();
            $fColumn = $relation['foreign_column'];
            if (!$this->hasValue($sColumn)) {
                return;
            }
            // throw new Exception("The value of $sColumn of " . get_class($this) . ' is not defined.');
            $sValue = $this->getValue($sColumn);
            $collection = $relation->getForeignCollection();
            $collection->where()->equal($collection->getAlias() . '.' . $fColumn, $sValue);
            // where 'm' is the default alias.
            // For if we need to create relational records
            // though collection object, we need to pre-set
            // the relational record id.
            $collection->setPresetVars(array($fColumn => $sValue));
            return $this->setInternalCache($cacheKey, $collection);
        } elseif (Relationship::BELONGS_TO === $relation['type']) {
            $sColumn = $relation['self_column'];
            $fSchema = $relation->newForeignSchema();
            $fColumn = $relation['foreign_column'];
            $fpSchema = SchemaLoader::load($fSchema->getSchemaProxyClass());
            if (!$this->hasValue($sColumn)) {
                return;
            }
            $sValue = $this->getValue($sColumn);
            $model = $fpSchema->newModel();
            $ret = $model->load(array($fColumn => $sValue));
            return $this->setInternalCache($cacheKey, $model);
        } elseif (Relationship::MANY_TO_MANY === $relation['type']) {
            $rId = $relation['relation_junction'];
            // use relationId to get middle relation. (author_books)
            $rId2 = $relation['relation_foreign'];
            // get external relationId from the middle relation. (book from author_books)
            $middleRelation = $this->getSchema()->getRelation($rId);
            if (!$middleRelation) {
                throw new InvalidArgumentException("first level relationship of many-to-many {$rId} is empty");
            }
            // eg. author_books
            $sColumn = $middleRelation['foreign_column'];
            $sSchema = $middleRelation->newForeignSchema();
            $spSchema = SchemaLoader::load($sSchema->getSchemaProxyClass());
            $foreignRelation = $spSchema->getRelation($rId2);
            if (!$foreignRelation) {
                throw new InvalidArgumentException("second level relationship of many-to-many {$rId2} is empty.");
            }
            $fSchema = $foreignRelation->newForeignSchema();
            $fColumn = $foreignRelation['foreign_column'];
            $fpSchema = SchemaLoader::load($fSchema->getSchemaProxyClass());
            $collection = $fpSchema->newCollection();
            /*
             * join middle relation ship
             *
             *    Select * from books b (r2) left join author_books ab on ( ab.book_id = b.id )
             *       where b.author_id = :author_id
             */
            $collection->join($sSchema->getTable())->as('b')->on()->equal('b.' . $foreignRelation['self_column'], array($collection->getAlias() . '.' . $fColumn));
            $value = $this->getValue($middleRelation['self_column']);
            $collection->where()->equal('b.' . $middleRelation['foreign_column'], $value);
            /*
             * for many-to-many creation:
             *
             *    $author->books[] = array(
             *        ':author_books' => array( 'created_on' => date('c') ),
             *        'title' => 'Book Title',
             *    );
             */
            $collection->setPostCreate(function ($record, $args) use($spSchema, $rId, $middleRelation, $foreignRelation, $value) {
                // arguments for creating middle-relationship record
                $a = array($foreignRelation['self_column'] => $record->getValue($foreignRelation['foreign_column']), $middleRelation['foreign_column'] => $value);
                if (isset($args[':' . $rId])) {
                    $a = array_merge($args[':' . $rId], $a);
                }
                // create relationship
                $middleRecord = $spSchema->newModel();
                $ret = $middleRecord->create($a);
                if (!$ret->success) {
                    throw new Exception("{$rId} create failed.");
                }
                return $middleRecord;
            });
            return $this->setInternalCache($cacheKey, $collection);
        }
        throw new Exception("The relationship type of {$key} is not supported.");
    }