src/Sql/Manager.php
public function assignRelated($source, $relationNames=null, $meta=null)
    {
        if (!$source) { return; }

        $stack = [];
        $sourceIsArray = is_array($source) || $source instanceof \Traversable;
        if (!$sourceIsArray) {
            $source = array($source);
        }

        if ($meta !== null) {
            $meta = !$meta instanceof Meta ? $this->mapper->getMeta($meta) : $meta;
        } else {
            $meta = $this->mapper->getMeta(get_class($source[0]));
        }

        if (!$relationNames) {
            if ($meta->autoRelations) {
                $relationNames = $meta->autoRelations;
            } else {
                throw new Exception("relationNames not passed, class {$meta->class} does not define autoRelations");
            }
        }

        $relationMap = [];
        foreach ((array)$relationNames as $relationName) {
            if (!isset($meta->relations[$relationName])) {
                throw new Exception("Unknown relation $relationName on {$meta->class}");
            }
            $relationMap[$relationName] = $rel = $meta->relations[$relationName];
            if ($rel['mode'] == 'class') {
                throw new Exception("Relation $relationName is not assignable for class {$meta->class}");
            }
        }

        $done = [];
        foreach ($relationMap as $relationName=>$relation) {
            if (isset($done[$relationName])) {
                continue;
            }
            $done[$relationName] = true;

            $missing = [];
            foreach ($source as $idx=>$item) {
                // we have to assume it's missing if we see a getter as there
                // may be serious unintended side effects from calling a getter
                // that may be unpopulated. it might lazy load if it's an active
                // record, or it might throw an exception because the 'set' hasn't
                // been called.

                // check for isset as well as falsey for the situation where we're using
                // stdClasses as the response object
                if (isset($relation['getter']) || !isset($item->{$relationName}) || !$item->{$relationName}) {
                    $missing[$idx] = $item;
                }
            }

            if ($missing) {
                $result = $this->getRelated($missing, $relationName, ['stack'=>$stack], $meta);
                $relator = $this->getRelator($meta, $relationName);
                $this->populateObjectsWithRelated($missing, $result, $relation);
            }
        }
    }
public function assignRelated($source, $relationNames=null, $meta=null)
    {
        if (!$source) { return; }

        $stack = [];
        $sourceIsArray = is_array($source) || $source instanceof \Traversable;
        if (!$sourceIsArray) {
            $source = array($source);
        }

        if ($meta !== null) {
            $meta = !$meta instanceof Meta ? $this->mapper->getMeta($meta) : $meta;
        } else {
            $meta = $this->mapper->getMeta(get_class($source[0]));
        }

        if (!$relationNames) {
            if ($meta->autoRelations) {
                $relationNames = $meta->autoRelations;
            } else {
                throw new Exception("relationNames not passed, class {$meta->class} does not define autoRelations");
            }
        }

        $relationMap = [];
        foreach ((array)$relationNames as $relationName) {
            if (!isset($meta->relations[$relationName])) {
                throw new Exception("Unknown relation $relationName on {$meta->class}");
            }
            $relationMap[$relationName] = $rel = $meta->relations[$relationName];
            if ($rel['mode'] == 'class') {
                throw new Exception("Relation $relationName is not assignable for class {$meta->class}");
            }
        }

        $done = [];
        foreach ($relationMap as $relationName=>$relation) {
            if (isset($done[$relationName])) {
                continue;
            }
            $done[$relationName] = true;

            $missing = [];
            foreach ($source as $idx=>$item) {
                // we have to assume it's missing if we see a getter as there
                // may be serious unintended side effects from calling a getter
                // that may be unpopulated. it might lazy load if it's an active
                // record, or it might throw an exception because the 'set' hasn't
                // been called.

                // check for isset as well as falsey for the situation where we're using
                // stdClasses as the response object
                if (isset($relation['getter']) || !isset($item->{$relationName}) || !$item->{$relationName}) {
                    $missing[$idx] = $item;
                }
            }

            if ($missing) {
                $result = $this->getRelated($missing, $relationName, ['stack'=>$stack], $meta);
                $relator = $this->getRelator($meta, $relationName);
                $this->populateObjectsWithRelated($missing, $result, $relation);
            }
        }
    }
public function assignRelated ( $ source , $ relationNames = null , $ meta = null ) { if ( ! $ source ) { return ; } $ stack = [ ] ; $ sourceIsArray = is_array ( $ source ) || $ source instanceof \ Traversable ; if ( ! $ sourceIsArray ) { $ source = array ( $ source ) ; } if ( $ meta !== null ) { $ meta = ! $ meta instanceof Meta ? $ this -> mapper -> getMeta ( $ meta ) : $ meta ; } else { $ meta = $ this -> mapper -> getMeta ( get_class ( $ source [ 0 ] ) ) ; } if ( ! $ relationNames ) { if ( $ meta -> autoRelations ) { $ relationNames = $ meta -> autoRelations ; } else { throw new Exception ( "relationNames not passed, class {$meta->class} does not define autoRelations" ) ; } } $ relationMap = [ ] ; foreach ( ( array ) $ relationNames as $ relationName ) { if ( ! isset ( $ meta -> relations [ $ relationName ] ) ) { throw new Exception ( "Unknown relation $relationName on {$meta->class}" ) ; } $ relationMap [ $ relationName ] = $ rel = $ meta -> relations [ $ relationName ] ; if ( $ rel [ 'mode' ] == 'class' ) { throw new Exception ( "Relation $relationName is not assignable for class {$meta->class}" ) ; } } $ done = [ ] ; foreach ( $ relationMap as $ relationName => $ relation ) { if ( isset ( $ done [ $ relationName ] ) ) { continue ; } $ done [ $ relationName ] = true ; $ missing = [ ] ; foreach ( $ source as $ idx => $ item ) { // we have to assume it's missing if we see a getter as there // may be serious unintended side effects from calling a getter // that may be unpopulated. it might lazy load if it's an active // record, or it might throw an exception because the 'set' hasn't // been called. // check for isset as well as falsey for the situation where we're using // stdClasses as the response object if ( isset ( $ relation [ 'getter' ] ) || ! isset ( $ item -> { $ relationName } ) || ! $ item -> { $ relationName } ) { $ missing [ $ idx ] = $ item ; } } if ( $ missing ) { $ result = $ this -> getRelated ( $ missing , $ relationName , [ 'stack' => $ stack ] , $ meta ) ; $ relator = $ this -> getRelator ( $ meta , $ relationName ) ; $ this -> populateObjectsWithRelated ( $ missing , $ result , $ relation ) ; } } }
Retrieve related objects from the database and assign them to the source
if the source field is not yet populated.

@param object|array Source objects to assign relations for
@param string|array The name of the relation(s) to assign
@return void
Retrieve related objects from the database and assign them to the source if the source field is not yet populated .