diff --git a/src/AbstractActiveRecord.php b/src/AbstractActiveRecord.php index b89801457..eb3db8185 100644 --- a/src/AbstractActiveRecord.php +++ b/src/AbstractActiveRecord.php @@ -339,7 +339,7 @@ public function link(string $name, ActiveRecordInterface $arClass, array $extraC $viaClass = null; $viaTable = null; $relation = $this->relationQuery($name); - $via = $relation?->getVia(); + $via = $relation->getVia(); if ($via !== null) { if ($this->getIsNewRecord() || $arClass->getIsNewRecord()) { @@ -355,9 +355,7 @@ public function link(string $name, ActiveRecordInterface $arClass, array $extraC // unset $viaName so that it can be reloaded to reflect the change. /** @psalm-var string $viaName */ unset($this->related[$viaName]); - } - - if ($via instanceof ActiveQueryInterface) { + } else { $viaRelation = $via; $from = $via->getFrom(); /** @psalm-var string $viaTable */ @@ -366,8 +364,7 @@ public function link(string $name, ActiveRecordInterface $arClass, array $extraC $columns = []; - /** @psalm-var ActiveQueryInterface|null $viaRelation */ - $viaLink = $viaRelation?->getLink() ?? []; + $viaLink = $viaRelation->getLink(); /** * @psalm-var string $a @@ -378,7 +375,7 @@ public function link(string $name, ActiveRecordInterface $arClass, array $extraC $columns[$a] = $this->$b; } - $link = $relation?->getLink() ?? []; + $link = $relation->getLink(); /** * @psalm-var string $a @@ -398,7 +395,7 @@ public function link(string $name, ActiveRecordInterface $arClass, array $extraC $columns[$k] = $v; } - if ($viaClass instanceof ActiveRecordInterface && is_array($via)) { + if ($viaClass instanceof ActiveRecordInterface) { /** * @psalm-var string $column * @psalm-var mixed $value @@ -411,7 +408,7 @@ public function link(string $name, ActiveRecordInterface $arClass, array $extraC } elseif (is_string($viaTable)) { $this->db->createCommand()->insert($viaTable, $columns)->execute(); } - } elseif ($relation instanceof ActiveQueryInterface) { + } else { $link = $relation->getLink(); $p1 = $arClass->isPrimaryKey(array_keys($link)); $p2 = $this->isPrimaryKey(array_values($link)); @@ -438,13 +435,13 @@ public function link(string $name, ActiveRecordInterface $arClass, array $extraC } // update lazily loaded related objects - if ($relation instanceof ActiveRecordInterface && !$relation->getMultiple()) { + if (!$relation->getMultiple()) { $this->related[$name] = $arClass; } elseif (isset($this->related[$name])) { - $indexBy = $relation?->getIndexBy(); + $indexBy = $relation->getIndexBy(); if ($indexBy !== null) { if ($indexBy instanceof Closure) { - $index = $relation?->indexBy($arClass::class); + $index = $relation->$indexBy($arClass::class); } else { $index = $arClass->$indexBy; } @@ -549,12 +546,8 @@ public function relation(string $name): ActiveRecordInterface|array|null return $this->retrieveRelation($name); } - public function relationQuery(string $name, bool $throwException = true): ActiveQueryInterface|null + public function relationQuery(string $name): ActiveQueryInterface { - if (!$throwException) { - return null; - } - throw new InvalidArgumentException(static::class . ' has no relation named "' . $name . '".'); } @@ -811,7 +804,7 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet $viaClass = null; $viaTable = null; $relation = $this->relationQuery($name); - $viaRelation = $relation?->getVia(); + $viaRelation = $relation->getVia(); if ($viaRelation !== null) { if (is_array($viaRelation)) { @@ -835,7 +828,7 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet $columns[$a] = $this->$b; } - $link = $relation?->getLink() ?? []; + $link = $relation->getLink(); foreach ($link as $a => $b) { /** @psalm-var mixed */ @@ -893,7 +886,7 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet } } - if ($relation instanceof ActiveQueryInterface && !$relation->getMultiple()) { + if (!$relation->getMultiple()) { unset($this->related[$name]); } elseif (isset($this->related[$name]) && is_array($this->related[$name])) { /** @psalm-var array $related */ @@ -928,9 +921,9 @@ public function unlinkAll(string $name, bool $delete = false): void $viaClass = null; $viaTable = null; $relation = $this->relationQuery($name); - $viaRelation = $relation?->getVia(); + $viaRelation = $relation->getVia(); - if ($relation instanceof ActiveQueryInterface && $viaRelation !== null) { + if ($viaRelation !== null) { if (is_array($viaRelation)) { [$viaName, $viaRelation] = $viaRelation; /** @psalm-var ActiveQueryInterface $viaRelation */ @@ -976,7 +969,7 @@ public function unlinkAll(string $name, bool $delete = false): void $command->update($viaTable, $nulls, $condition)->execute(); } } - } elseif ($relation instanceof ActiveQueryInterface) { + } else { $relatedModel = $relation->getARInstance(); $link = $relation->getLink(); diff --git a/src/ActiveRecordInterface.php b/src/ActiveRecordInterface.php index f72a3c70d..4dfafaddd 100644 --- a/src/ActiveRecordInterface.php +++ b/src/ActiveRecordInterface.php @@ -326,7 +326,7 @@ public function relation(string $name): self|array|null; * Relations can be defined using {@see hasOne()} and {@see hasMany()} methods. For example: * * ```php - * public function relationQuery(string $name, bool $throwException = true): ActiveQueryInterface + * public function relationQuery(string $name): ActiveQueryInterface * { * return match ($name) { * 'orders' => $this->hasMany(Order::class, ['customer_id' => 'id']), @@ -337,13 +337,12 @@ public function relation(string $name): self|array|null; * ``` * * @param string $name The relation name, for example `orders` (case-sensitive). - * @param bool $throwException Whether to throw exception if the relation doesn't exist. * * @throws InvalidArgumentException * - * @return ActiveQueryInterface|null The relational query object. + * @return ActiveQueryInterface The relational query object. */ - public function relationQuery(string $name, bool $throwException = true): ActiveQueryInterface|null; + public function relationQuery(string $name): ActiveQueryInterface; /** * Resets relation data for the specified name. diff --git a/src/Trait/MagicRelationsTrait.php b/src/Trait/MagicRelationsTrait.php index c66c48bbe..86ae03247 100644 --- a/src/Trait/MagicRelationsTrait.php +++ b/src/Trait/MagicRelationsTrait.php @@ -37,25 +37,14 @@ trait MagicRelationsTrait * } * ``` * - * @param string $name The relation name, for example `orders` for a relation defined via `getOrdersQuery()` method - * (case-sensitive). - * @param bool $throwException whether to throw exception if the relation does not exist. - * * @throws InvalidArgumentException if the named relation does not exist. * @throws ReflectionException - * - * @return ActiveQueryInterface|null the relational query object. If the relation does not exist and - * `$throwException` is `false`, `null` will be returned. */ - public function relationQuery(string $name, bool $throwException = true): ActiveQueryInterface|null + public function relationQuery(string $name): ActiveQueryInterface { $getter = 'get' . ucfirst($name) . 'Query'; if (!method_exists($this, $getter)) { - if (!$throwException) { - return null; - } - throw new InvalidArgumentException(static::class . ' has no relation named "' . $name . '".'); } @@ -66,10 +55,6 @@ public function relationQuery(string $name, bool $throwException = true): Active $type === null || !is_a('\\' . $type->getName(), ActiveQueryInterface::class, true) ) { - if (!$throwException) { - return null; - } - $typeName = $type === null ? 'mixed' : $type->getName(); throw new InvalidArgumentException( @@ -82,10 +67,6 @@ public function relationQuery(string $name, bool $throwException = true): Active $realName = lcfirst(substr($method->getName(), 3, -5)); if ($realName !== $name) { - if (!$throwException) { - return null; - } - throw new InvalidArgumentException( 'Relation names are case sensitive. ' . static::class . " has a relation named \"$realName\" instead of \"$name\"." diff --git a/tests/ActiveQueryTest.php b/tests/ActiveQueryTest.php index 45417205a..73469fd46 100644 --- a/tests/ActiveQueryTest.php +++ b/tests/ActiveQueryTest.php @@ -2331,9 +2331,6 @@ public function testGetRelationInvalidArgumentException(): void $query = $customer->findOne(1); - /** Without throwing exception */ - $this->assertEmpty($query->relationQuery('items', false)); - /** Throwing exception */ $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( @@ -2350,9 +2347,6 @@ public function testGetRelationInvalidArgumentExceptionHasNoRelationNamed(): voi $query = $customer->findOne(1); - /** Without throwing exception */ - $this->assertEmpty($query->relationQuery('item', false)); - $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( 'Relation query method "Yiisoft\ActiveRecord\Tests\Stubs\ActiveRecord\Customer::getItemQuery()" should' @@ -2369,8 +2363,6 @@ public function testGetRelationInvalidArgumentExceptionCaseSensitive(): void $query = $customer->findOne(1); - $this->assertEmpty($query->relationQuery('expensiveorders', false)); - $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( 'Relation names are case sensitive. Yiisoft\ActiveRecord\Tests\Stubs\ActiveRecord\Customer ' .