Skip to content

Commit d8ede11

Browse files
committed
Split ActiveRecord model
1 parent ec399f9 commit d8ede11

File tree

105 files changed

+1559
-1465
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+1559
-1465
lines changed

src/AbstractActiveRecord.php

Lines changed: 131 additions & 162 deletions
Large diffs are not rendered by default.

src/AbstractActiveRecordModel.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord;
6+
7+
use ReflectionClass;
8+
use Yiisoft\Db\Connection\ConnectionInterface;
9+
use Yiisoft\Db\Exception\InvalidArgumentException;
10+
11+
/**
12+
* The base class for active record models.
13+
*/
14+
abstract class AbstractActiveRecordModel implements ActiveRecordModelInterface
15+
{
16+
private ActiveRecord $activeRecord;
17+
18+
public function activeRecord(): ActiveRecord
19+
{
20+
/** @psalm-suppress RedundantPropertyInitializationCheck */
21+
return $this->activeRecord ??= new ActiveRecord($this);
22+
}
23+
24+
public function db(): ConnectionInterface
25+
{
26+
return ConnectionProvider::get();
27+
}
28+
29+
public function relationQuery(string $name): ActiveQueryInterface
30+
{
31+
throw new InvalidArgumentException(static::class . ' has no relation named "' . $name . '".');
32+
}
33+
34+
public function tableName(): string
35+
{
36+
$name = (new ReflectionClass($this))->getShortName();
37+
/** @var string $name */
38+
$name = preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $name);
39+
$name = strtolower(ltrim($name, '_'));
40+
41+
return '{{%' . $name . '}}';
42+
}
43+
}

src/ActiveQuery.php

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
* as inverse of another relation and {@see onCondition()} which adds a condition that is to be added to relational
101101
* query join condition.
102102
*
103-
* @psalm-import-type ARClass from ActiveQueryInterface
103+
* @psalm-import-type ModelClass from ActiveQueryInterface
104104
* @psalm-import-type IndexKey from ArArrayHelper
105105
*
106106
* @psalm-property IndexKey|null $indexBy
@@ -116,12 +116,12 @@ class ActiveQuery extends Query implements ActiveQueryInterface
116116
private array $joinWith = [];
117117

118118
/**
119-
* @psalm-param ARClass $arClass
119+
* @psalm-param ModelClass $modelClass
120120
*/
121121
final public function __construct(
122-
protected string|ActiveRecordInterface|Closure $arClass
122+
protected string|ActiveRecordModelInterface|Closure $modelClass
123123
) {
124-
parent::__construct($this->getARInstance()->db());
124+
parent::__construct($this->getModelInstance()->db());
125125
}
126126

127127
public function each(): DataReaderInterface
@@ -169,6 +169,7 @@ public function prepare(QueryBuilderInterface $builder): QueryInterface
169169
if ($this->primaryModel === null) {
170170
$query = $this->createInstance();
171171
} else {
172+
$activeRecord = $this->primaryModel->activeRecord();
172173
$where = $this->getWhere();
173174

174175
if ($this->via instanceof ActiveQueryInterface) {
@@ -183,21 +184,21 @@ public function prepare(QueryBuilderInterface $builder): QueryInterface
183184
if ($viaQuery->getMultiple()) {
184185
if ($viaCallableUsed) {
185186
$viaModels = $viaQuery->all();
186-
} elseif ($this->primaryModel->isRelationPopulated($viaName)) {
187-
/** @var ActiveRecordInterface[]|array[] $viaModels */
188-
$viaModels = $this->primaryModel->relation($viaName);
187+
} elseif ($activeRecord->isRelationPopulated($viaName)) {
188+
/** @var ActiveRecordModelInterface[]|array[] $viaModels */
189+
$viaModels = $activeRecord->relation($viaName);
189190
} else {
190191
$viaModels = $viaQuery->all();
191-
$this->primaryModel->populateRelation($viaName, $viaModels);
192+
$activeRecord->populateRelation($viaName, $viaModels);
192193
}
193194
} else {
194195
if ($viaCallableUsed) {
195196
$model = $viaQuery->one();
196-
} elseif ($this->primaryModel->isRelationPopulated($viaName)) {
197-
$model = $this->primaryModel->relation($viaName);
197+
} elseif ($activeRecord->isRelationPopulated($viaName)) {
198+
$model = $activeRecord->relation($viaName);
198199
} else {
199200
$model = $viaQuery->one();
200-
$this->primaryModel->populateRelation($viaName, $model);
201+
$activeRecord->populateRelation($viaName, $model);
201202
}
202203
$viaModels = $model === null ? [] : [$model];
203204
}
@@ -228,8 +229,8 @@ public function prepare(QueryBuilderInterface $builder): QueryInterface
228229
* @psalm-param list<array> $rows
229230
* @psalm-return (
230231
* $rows is non-empty-list<array>
231-
* ? non-empty-list<ActiveRecordInterface|array>
232-
* : list<ActiveRecordInterface|array>
232+
* ? non-empty-list<ActiveRecordModelInterface|array>
233+
* : list<ActiveRecordModelInterface|array>
233234
* )
234235
*/
235236
public function populate(array $rows): array
@@ -274,8 +275,8 @@ public function populate(array $rows): array
274275
*/
275276
private function removeDuplicatedRows(array $rows): array
276277
{
277-
$instance = $this->getARInstance();
278-
$pks = $instance->primaryKey();
278+
$instance = $this->getModelInstance();
279+
$pks = $instance->activeRecord()->primaryKey();
279280

280281
if (empty($pks)) {
281282
throw new InvalidConfigException('Primary key of "' . $instance::class . '" can not be empty.');
@@ -301,7 +302,7 @@ private function removeDuplicatedRows(array $rows): array
301302
return array_values(array_combine($hash, $rows));
302303
}
303304

304-
public function one(): array|ActiveRecordInterface|null
305+
public function one(): array|ActiveRecordModelInterface|null
305306
{
306307
if ($this->shouldEmulateExecution()) {
307308
return null;
@@ -417,10 +418,10 @@ public function buildJoinWith(): void
417418

418419
$this->join = [];
419420

420-
$arClass = $this->getARInstance();
421+
$model = $this->getModelInstance();
421422

422423
foreach ($this->joinWith as [$with, $eagerLoading, $joinType]) {
423-
$this->joinWithRelations($arClass, $with, $joinType);
424+
$this->joinWithRelations($model, $with, $joinType);
424425

425426
if (is_array($eagerLoading)) {
426427
foreach ($with as $name => $callback) {
@@ -480,7 +481,7 @@ public function innerJoinWith(array|string $with, array|bool $eagerLoading = tru
480481
/**
481482
* Modifies the current query by adding join fragments based on the given relations.
482483
*
483-
* @param ActiveRecordInterface $arClass The primary model.
484+
* @param ActiveRecordModelInterface $model The primary model.
484485
* @param array $with The relations to be joined.
485486
* @param array|string $joinType The join type.
486487
*
@@ -489,7 +490,7 @@ public function innerJoinWith(array|string $with, array|bool $eagerLoading = tru
489490
* @throws NotInstantiableException
490491
* @throws \Yiisoft\Definitions\Exception\InvalidConfigException
491492
*/
492-
private function joinWithRelations(ActiveRecordInterface $arClass, array $with, array|string $joinType): void
493+
private function joinWithRelations(ActiveRecordModelInterface $model, array $with, array|string $joinType): void
493494
{
494495
$relations = [];
495496

@@ -499,7 +500,7 @@ private function joinWithRelations(ActiveRecordInterface $arClass, array $with,
499500
$callback = null;
500501
}
501502

502-
$primaryModel = $arClass;
503+
$primaryModel = $model;
503504
$parent = $this;
504505
$prefix = '';
505506

@@ -518,7 +519,7 @@ private function joinWithRelations(ActiveRecordInterface $arClass, array $with,
518519
}
519520

520521
if ($relation instanceof ActiveQueryInterface) {
521-
$primaryModel = $relation->getARInstance();
522+
$primaryModel = $relation->getModelInstance();
522523
$parent = $relation;
523524
}
524525

@@ -564,7 +565,7 @@ private function getJoinType(array|string $joinType, string $name): string
564565
}
565566

566567
/**
567-
* Returns the table name and the table alias for {@see arClass}.
568+
* Returns the table name and the table alias for {@see $modelClass}.
568569
*
569570
* @throws CircularReferenceException
570571
* @throws InvalidConfigException
@@ -733,9 +734,9 @@ public function orOnCondition(array|string $condition, array $params = []): stat
733734

734735
public function viaTable(string $tableName, array $link, callable $callable = null): static
735736
{
736-
$arClass = $this->primaryModel ?? $this->arClass;
737+
$modelClass = $this->primaryModel ?? $this->modelClass;
737738

738-
$relation = (new static($arClass))
739+
$relation = (new static($modelClass))
739740
->from([$tableName])
740741
->link($link)
741742
->multiple(true)
@@ -791,7 +792,7 @@ public function getTablesUsedInFrom(): array
791792
*/
792793
protected function getPrimaryTableName(): string
793794
{
794-
return $this->getARInstance()->getTableName();
795+
return $this->getModelInstance()->tableName();
795796
}
796797

797798
public function getOn(): array|string|null
@@ -812,9 +813,9 @@ public function getSql(): string|null
812813
return $this->sql;
813814
}
814815

815-
public function getARClass(): string|ActiveRecordInterface|Closure
816+
public function getModelClass(): string|ActiveRecordModelInterface|Closure
816817
{
817-
return $this->arClass;
818+
return $this->modelClass;
818819
}
819820

820821
/**
@@ -823,7 +824,7 @@ public function getARClass(): string|ActiveRecordInterface|Closure
823824
* @throws InvalidConfigException
824825
* @throws Throwable
825826
*/
826-
public function findOne(mixed $condition): array|ActiveRecordInterface|null
827+
public function findOne(mixed $condition): array|ActiveRecordModelInterface|null
827828
{
828829
return $this->findByCondition($condition)->one();
829830
}
@@ -855,21 +856,22 @@ public function findAll(mixed $condition): array
855856
*/
856857
protected function findByCondition(mixed $condition): static
857858
{
858-
$arInstance = $this->getARInstance();
859+
$modelInstance = $this->getModelInstance();
860+
$activeRecord = $modelInstance->activeRecord();
859861

860862
if (!is_array($condition)) {
861863
$condition = [$condition];
862864
}
863865

864866
if (!DbArrayHelper::isAssociative($condition)) {
865867
/** query by primary key */
866-
$primaryKey = $arInstance->primaryKey();
868+
$primaryKey = $activeRecord->primaryKey();
867869

868870
if (isset($primaryKey[0])) {
869871
$pk = $primaryKey[0];
870872

871873
if (!empty($this->getJoins()) || !empty($this->getJoinWith())) {
872-
$pk = $arInstance->getTableName() . '.' . $pk;
874+
$pk = $modelInstance->tableName() . '.' . $pk;
873875
}
874876

875877
/**
@@ -878,11 +880,11 @@ protected function findByCondition(mixed $condition): static
878880
*/
879881
$condition = [$pk => array_values($condition)];
880882
} else {
881-
throw new InvalidConfigException('"' . $arInstance::class . '" must have a primary key.');
883+
throw new InvalidConfigException('"' . $modelInstance::class . '" must have a primary key.');
882884
}
883885
} else {
884-
$aliases = $arInstance->filterValidAliases($this);
885-
$condition = $arInstance->filterCondition($condition, $aliases);
886+
$aliases = $activeRecord->filterValidAliases($this);
887+
$condition = $activeRecord->filterCondition($condition, $aliases);
886888
}
887889

888890
return $this->setWhere($condition);
@@ -905,18 +907,18 @@ public function sql(string|null $value): static
905907
return $this;
906908
}
907909

908-
public function getARInstance(): ActiveRecordInterface
910+
public function getModelInstance(): ActiveRecordModelInterface
909911
{
910-
if ($this->arClass instanceof ActiveRecordInterface) {
911-
return clone $this->arClass;
912+
if ($this->modelClass instanceof ActiveRecordModelInterface) {
913+
return clone $this->modelClass;
912914
}
913915

914-
if ($this->arClass instanceof Closure) {
915-
return ($this->arClass)();
916+
if ($this->modelClass instanceof Closure) {
917+
return ($this->modelClass)();
916918
}
917919

918-
/** @psalm-var class-string<ActiveRecordInterface> $class */
919-
$class = $this->arClass;
920+
/** @psalm-var class-string<ActiveRecordModelInterface> $class */
921+
$class = $this->modelClass;
920922

921923
return new $class();
922924
}
@@ -928,7 +930,7 @@ protected function index(array $rows): array
928930

929931
private function createInstance(): static
930932
{
931-
return (new static($this->arClass))
933+
return (new static($this->modelClass))
932934
->where($this->getWhere())
933935
->limit($this->getLimit())
934936
->offset($this->getOffset())
@@ -946,7 +948,7 @@ private function createInstance(): static
946948
->withQueries($this->withQueries);
947949
}
948950

949-
private function populateOne(array $row): ActiveRecordInterface|array
951+
private function populateOne(array $row): ActiveRecordModelInterface|array
950952
{
951953
return $this->populate([$row])[0];
952954
}

0 commit comments

Comments
 (0)