Skip to content

Commit

Permalink
Replace the factory with an instance or Closure
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov committed Jun 21, 2024
1 parent b000730 commit 0d51f69
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 16 deletions.
3 changes: 1 addition & 2 deletions src/AbstractActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ abstract class AbstractActiveRecord implements ActiveRecordInterface

public function __construct(
private ConnectionInterface $db,
private ActiveRecordFactory|null $arFactory = null,
private string $tableName = ''
) {
}
Expand Down Expand Up @@ -323,7 +322,7 @@ public function insert(array $attributes = null): bool
*/
public function instantiateQuery(string $arClass): ActiveQueryInterface
{
return new ActiveQuery($arClass, $this->db, $this->arFactory);
return new ActiveQuery($arClass, $this->db);
}

/**
Expand Down
37 changes: 26 additions & 11 deletions src/ActiveQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,13 @@ class ActiveQuery extends Query implements ActiveQueryInterface
private string|null $sql = null;
private array|string|null $on = null;
private array $joinWith = [];
private ActiveRecordInterface|null $arInstance = null;

/**
* @psalm-param class-string<ActiveRecordInterface> $arClass
* @psalm-param class-string<ActiveRecordInterface>|ActiveRecordInterface|Closure $arClass
*/
final public function __construct(
protected string $arClass,
protected string|ActiveRecordInterface|Closure $arClass,
protected ConnectionInterface $db,
private ActiveRecordFactory|null $arFactory = null,
private string $tableName = ''
) {
parent::__construct($db);
Expand Down Expand Up @@ -301,7 +299,7 @@ private function removeDuplicatedModels(array $models): array
$pks = $this->getARInstance()->primaryKey();

if (empty($pks)) {
throw new InvalidConfigException("Primary key of '$this->arClass' can not be empty.");
throw new InvalidConfigException("Primary key of '{$this->getARClassName()}' can not be empty.");

Check warning on line 302 in src/ActiveQuery.php

View check run for this annotation

Codecov / codecov/patch

src/ActiveQuery.php#L302

Added line #L302 was not covered by tests
}

foreach ($pks as $pk) {
Expand All @@ -323,7 +321,7 @@ private function removeDuplicatedModels(array $models): array
$pks = $model->getPrimaryKey(true);

if (empty($pks)) {
throw new InvalidConfigException("Primary key of '$this->arClass' can not be empty.");
throw new InvalidConfigException("Primary key of '{$this->getARClassName()}' can not be empty.");

Check warning on line 324 in src/ActiveQuery.php

View check run for this annotation

Codecov / codecov/patch

src/ActiveQuery.php#L324

Added line #L324 was not covered by tests
}

foreach ($pks as $pk) {
Expand Down Expand Up @@ -803,7 +801,7 @@ public function orOnCondition(array|string $condition, array $params = []): self

public function viaTable(string $tableName, array $link, callable $callable = null): self
{
$arClass = $this->primaryModel ? $this->primaryModel::class : $this->arClass;
$arClass = $this->primaryModel ?? $this->arClass;
$arClassInstance = new self($arClass, $this->db);

/** @psalm-suppress UndefinedMethod */
Expand Down Expand Up @@ -882,7 +880,7 @@ public function getSql(): string|null
return $this->sql;
}

public function getARClass(): string|null
public function getARClass(): string|ActiveRecordInterface|Closure
{
return $this->arClass;
}
Expand Down Expand Up @@ -976,16 +974,33 @@ public function sql(string|null $value): self
return $this;
}

public function getARClassName(): string
{
if ($this->arClass instanceof ActiveRecordInterface) {
return $this->arClass::class;
}

if ($this->arClass instanceof Closure) {
return ($this->arClass)()::class;
}

return $this->arClass;
}

public function getARInstance(): ActiveRecordInterface
{
if ($this->arFactory !== null) {
return $this->arFactory->createAR($this->arClass, $this->tableName, $this->db);
if ($this->arClass instanceof ActiveRecordInterface) {
return $this->arClass;
}

if ($this->arClass instanceof Closure) {
return ($this->arClass)();
}

/** @psalm-var class-string<ActiveRecordInterface> $class */
$class = $this->arClass;

return new $class($this->db, null, $this->tableName);
return new $class($this->db, $this->tableName);
}

private function createInstance(): static
Expand Down
2 changes: 1 addition & 1 deletion src/ActiveQueryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public function getTablesUsedInFrom(): array;
*/
public function getSql(): string|null;

public function getARClass(): string|null;
public function getARClass(): string|ActiveRecordInterface|Closure;

/**
* Creates an {@see ActiveQuery} instance with a given SQL statement.
Expand Down
29 changes: 29 additions & 0 deletions tests/ActiveQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2664,4 +2664,33 @@ public function testEqual(): void
$customerB = (new ActiveQuery(Item::class, $this->db))->findOne(1);
$this->assertFalse($customerA->equals($customerB));
}

public function testARClassAsString(): void
{
$query = new ActiveQuery(Customer::class, $this->db);

$this->assertSame($query->getARClass(), Customer::class);
$this->assertSame($query->getARClassName(), Customer::class);
$this->assertInstanceOf(Customer::class, $query->getARInstance());
}

public function testARClassAsInstance(): void
{
$customer = new Customer($this->db);
$query = new ActiveQuery($customer, $this->db);

$this->assertSame($query->getARClass(), $customer);
$this->assertSame($query->getARClassName(), Customer::class);
$this->assertInstanceOf(Customer::class, $query->getARInstance());
}

public function testARClassAsClosure(): void
{
$closure = fn () => new Customer($this->db);
$query = new ActiveQuery($closure, $this->db);

$this->assertSame($query->getARClass(), $closure);
$this->assertSame($query->getARClassName(), Customer::class);
$this->assertInstanceOf(Customer::class, $query->getARInstance());
}
}
4 changes: 2 additions & 2 deletions tests/Stubs/ActiveRecord/CustomerWithConstructor.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ final class CustomerWithConstructor extends ActiveRecord
protected bool|string|null $bool_status = false;
protected int|null $profile_id = null;

public function __construct(ConnectionInterface $db, private Aliases $aliases)
public function __construct(ConnectionInterface $db, string $tableName = '', private Aliases|null $aliases = null)
{
parent::__construct($db);
parent::__construct($db, $tableName);
}

public function getTableName(): string
Expand Down

0 comments on commit 0d51f69

Please sign in to comment.