/** * @param EntityManager $manager * @param EntityMapper $owner * @param array $options * @return LazyLoader */ protected function getLazyLoader(EntityManager $manager, EntityMapper $owner, array $options) { $related = $manager->resolveEntityMapper($this->entityClass); if ($this->foreignKey === null) { $this->foreignKey = $owner->getForeignKey(); } $ids = []; $pk = $owner->getPrimaryKey(); foreach ($options['results'] as $result) { $ids[] = $result[$pk]; } $statement = new SQLStatement(); $select = new EntityQuery($manager, $related, $statement); $select->where($this->foreignKey)->in($ids); if ($options['callback'] !== null) { $options['callback'](new Query($statement)); } $select->with($options['with'], $options['immediate']); return new LazyLoader($select, $pk, $this->foreignKey, $this->hasMany, $options['immediate']); }
protected function hydrate() { if (!$this->dehidrated) { return; } $pk = $this->mapper->getPrimaryKey(); $select = new Select($this->manager->getConnection(), $this->mapper->getTable()); $columns = $select->where($pk)->is($this->rawColumns[$pk])->select()->fetchAssoc()->first(); if ($columns === false) { $this->deleted = true; return; } $this->rawColumns = $columns; $this->columns = []; $this->dehidrated = false; }
/** * @param array $results * @return array */ protected function getLazyLoaders(array $results) : array { if (empty($this->with) || empty($results)) { return []; } $loaders = []; $attr = $this->getWithAttributes(); $relations = $this->mapper->getRelations(); $lazyLoader = function (EntityManager $manager, EntityMapper $owner, array $options) { return $this->getLazyLoader($manager, $owner, $options); }; foreach ($attr['with'] as $with => $callback) { if (!isset($relations[$with])) { continue; } $loader = $lazyLoader->call($relations[$with], $this->manager, $this->mapper, ['results' => $results, 'callback' => $callback, 'with' => $attr[$with]['extra'] ?? [], 'immediate' => $this->immediate]); if (null === $loader) { continue; } $loaders[$with] = $loader; } return $loaders; }
/** * @param EntityManager $manager * @param EntityMapper $owner * @param array $options * @return LazyLoader */ protected function getLazyLoader(EntityManager $manager, EntityMapper $owner, array $options) { $related = $manager->resolveEntityMapper($this->entityClass); if ($this->junctionTable === null) { $table = [$owner->getTable(), $related->getTable()]; sort($table); $this->junctionTable = implode('_', $table); } if ($this->juctionKey === null) { $this->juctionKey = $related->getForeignKey(); } if ($this->foreignKey === null) { $this->foreignKey = $owner->getForeignKey(); } if ($this->joinTable === null) { $this->joinTable = $related->getTable(); } if ($this->joinColumn === null) { $this->joinColumn = $related->getPrimaryKey(); } $ids = []; $pk = $owner->getPrimaryKey(); foreach ($options['results'] as $result) { $ids[] = $result[$pk]; } $statement = new SQLStatement(); $select = new class($manager, $related, $statement, $this->junctionTable) extends EntityQuery { protected $junctionTable; public function __construct(EntityManager $entityManager, EntityMapper $entityMapper, $statement, $table) { parent::__construct($entityManager, $entityMapper, $statement); $this->junctionTable = $table; } protected function buildQuery() { $this->locked = true; $this->sql->addTables([$this->junctionTable]); return $this; } protected function isReadOnly() : bool { return count($this->sql->getJoins()) > 1; } }; $linkKey = 'hidden_' . $this->junctionTable . '_' . $this->foreignKey; $select->join($this->joinTable, function (Join $join) { $join->on($this->junctionTable . '.' . $this->juctionKey, $this->joinTable . '.' . $this->joinColumn); })->where($this->junctionTable . '.' . $this->foreignKey)->in($ids); $statement->addColumn($this->joinTable . '.*'); $statement->addColumn($this->junctionTable . '.' . $this->foreignKey, $linkKey); if ($options['callback'] !== null) { $options['callback'](new Query($statement)); } $select->with($options['with'], $options['immediate']); return new LazyLoader($select, $pk, $linkKey, $this->hasMany, $options['immediate']); }