diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:38:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:38:04 +0000 |
commit | 1ff5c35de5dbd70a782875a91dd2232fd01b002b (patch) | |
tree | 77d9ce5e1bf78b3e6ef79f8f6e7861e2ced3c09b /vendor/ipl/orm/src/Relation/BelongsToMany.php | |
parent | Initial commit. (diff) | |
download | icinga-php-library-1ff5c35de5dbd70a782875a91dd2232fd01b002b.tar.xz icinga-php-library-1ff5c35de5dbd70a782875a91dd2232fd01b002b.zip |
Adding upstream version 0.10.1.upstream/0.10.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | vendor/ipl/orm/src/Relation/BelongsToMany.php | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/vendor/ipl/orm/src/Relation/BelongsToMany.php b/vendor/ipl/orm/src/Relation/BelongsToMany.php new file mode 100644 index 0000000..132fe55 --- /dev/null +++ b/vendor/ipl/orm/src/Relation/BelongsToMany.php @@ -0,0 +1,199 @@ +<?php + +namespace ipl\Orm\Relation; + +use ipl\Orm\Model; +use ipl\Orm\Relation; +use ipl\Orm\Relations; + +use function ipl\Stdlib\get_php_type; + +/** + * Many-to-many relationship + */ +class BelongsToMany extends Relation +{ + protected $isOne = false; + + /** @var string Name of the join table or junction model class */ + protected $throughClass; + + /** @var Model The junction model */ + protected $through; + + /** @var string|array Column name(s) of the target model's foreign key found in the join table */ + protected $targetForeignKey; + + /** @var string|array Candidate key column name(s) in the target table which references the target foreign key */ + protected $targetCandidateKey; + + /** + * Get the name of the join table or junction model class + * + * @return string + */ + public function getThroughClass() + { + return $this->throughClass; + } + + /** + * Set the join table name or junction model class + * + * @param string $through + * + * @return $this + */ + public function through($through) + { + $this->throughClass = $through; + + return $this; + } + + /** + * Get the junction model + * + * @return Model|Junction + */ + public function getThrough() + { + if ($this->through === null) { + $throughClass = $this->getThroughClass(); + + if (class_exists($throughClass)) { + $this->through = new $throughClass(); + } else { + $this->through = (new Junction()) + ->setTableName($throughClass); + } + } + + return $this->through; + } + + /** + * Set the junction model + * + * @param Model $through + * + * @return $this + */ + public function setThrough($through) + { + $this->through = $through; + + return $this; + } + + /** + * Get the column name(s) of the target model's foreign key found in the join table + * + * @return string|array Array if the foreign key is compound, string otherwise + */ + public function getTargetForeignKey() + { + return $this->targetForeignKey; + } + + /** + * Set the column name(s) of the target model's foreign key found in the join table + * + * @param string|array $targetForeignKey Array if the foreign key is compound, string otherwise + * + * @return $this + */ + public function setTargetForeignKey($targetForeignKey) + { + $this->targetForeignKey = $targetForeignKey; + + return $this; + } + + /** + * Get the candidate key column name(s) in the target table which references the target foreign key + * + * @return string|array Array if the foreign key is compound, string otherwise + */ + public function getTargetCandidateKey() + { + return $this->targetCandidateKey; + } + + /** + * Set the candidate key column name(s) in the target table which references the target foreign key + * + * @param string|array $targetCandidateKey Array if the foreign key is compound, string otherwise + * + * @return $this + */ + public function setTargetCandidateKey($targetCandidateKey) + { + $this->targetCandidateKey = $targetCandidateKey; + + return $this; + } + + public function resolve() + { + $source = $this->getSource(); + + $possibleCandidateKey = [$this->getCandidateKey()]; + $possibleForeignKey = [$this->getForeignKey()]; + + $target = $this->getTarget(); + + $possibleTargetCandidateKey = [$this->getTargetForeignKey() ?: static::getDefaultForeignKey($target)]; + $possibleTargetForeignKey = [$this->getTargetCandidateKey() ?: static::getDefaultCandidateKey($target)]; + + $junction = $this->getThrough(); + + if (! $junction instanceof Junction) { + $relations = new Relations(); + $junction->createRelations($relations); + + if ($relations->has($source->getTableName())) { + $sourceRelation = $relations->get($source->getTableName()); + + $possibleCandidateKey[] = $sourceRelation->getForeignKey(); + $possibleForeignKey[] = $sourceRelation->getCandidateKey(); + } + + if ($relations->has($target->getTableName())) { + $targetRelation = $relations->get($target->getTableName()); + + $possibleTargetCandidateKey[] = $targetRelation->getCandidateKey(); + $possibleTargetForeignKey[] = $targetRelation->getForeignKey(); + } + } + + $toJunction = (new HasMany()) + ->setName($junction->getTableName()) + ->setSource($source) + ->setTarget($junction) + ->setCandidateKey($this->extractKey($possibleCandidateKey)) + ->setForeignKey($this->extractKey($possibleForeignKey)); + + $toTarget = (new HasMany()) + ->setName($this->getName()) + ->setSource($junction) + ->setTarget($target) + ->setCandidateKey($this->extractKey($possibleTargetCandidateKey)) + ->setForeignKey($this->extractKey($possibleTargetForeignKey)); + + foreach ($toJunction->resolve() as $k => $v) { + yield $k => $v; + } + + foreach ($toTarget->resolve() as $k => $v) { + yield $k => $v; + } + } + + protected function extractKey(array $possibleKey) + { + $filtered = array_filter($possibleKey); + + return array_pop($filtered); + } +} |