original_string: 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);
              }
          }
      }
code: 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);
              }
          }
      }
code_tokens: 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 ) ; } } }
docstring: 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
docstring_tokens: Retrieve related objects from the database and assign them to the source if the source field is not yet populated .