Skip to content

Commit 41bd32b

Browse files
Fix issue psalm 1 - part 1. (#260)
1 parent 7dc84ef commit 41bd32b

5 files changed

Lines changed: 78 additions & 29 deletions

File tree

src/ActiveQueryInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ public function getVia(): array|ActiveQueryInterface|null;
320320
*
321321
* Do not prefix or quote the column names as this will be done automatically by Yii. This property is only used in
322322
* relational context.
323+
*
324+
* @psalm-return string[]
323325
*/
324326
public function getLink(): array;
325327

src/ActiveRecordInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ interface ActiveRecordInterface
2121
* @throws Exception
2222
*
2323
* @return array List of attribute names.
24+
*
25+
* @psalm-return string[]
2426
*/
2527
public function attributes(): array;
2628

src/ActiveRelationTrait.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ trait ActiveRelationTrait
3737
{
3838
private bool $multiple = false;
3939
private ActiveRecordInterface|null $primaryModel = null;
40+
/** @psalm-var string[] */
4041
private array $link = [];
4142
/**
4243
* @var string|null the name of the relation that is the inverse of this relation.
@@ -699,6 +700,9 @@ public function getPrimaryModel(): ActiveRecordInterface|null
699700
return $this->primaryModel;
700701
}
701702

703+
/**
704+
* @psalm-return string[]
705+
*/
702706
public function getLink(): array
703707
{
704708
return $this->link;

src/BaseActiveRecord.php

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ abstract class BaseActiveRecord implements ActiveRecordInterface, IteratorAggreg
4747
private array $attributes = [];
4848
private array|null $oldAttributes = null;
4949
private array $related = [];
50+
/** @psalm-var string[][] */
5051
private array $relationsDependencies = [];
5152

5253
public function __construct(
@@ -108,6 +109,9 @@ public function extraFields(): array
108109
return array_combine($fields, $fields);
109110
}
110111

112+
/**
113+
* @psalm-return array<string, string|Closure>
114+
*/
111115
public function fields(): array
112116
{
113117
$fields = array_keys($this->attributes);
@@ -733,6 +737,7 @@ public function updateAttributes(array $attributes): int
733737

734738
$rows = $this->updateAll($values, $this->getOldPrimaryKey(true));
735739

740+
/** @psalm-var array<string, mixed> $value */
736741
foreach ($values as $name => $value) {
737742
$this->oldAttributes[$name] = $this->attributes[$name];
738743
}
@@ -833,33 +838,39 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet
833838
if ($viaRelation !== null) {
834839
if (is_array($viaRelation)) {
835840
[$viaName, $viaRelation] = $viaRelation;
841+
/** @psalm-var ActiveQueryInterface $viaRelation */
836842
$viaClass = $viaRelation->getARInstance();
843+
/** @psalm-var string $viaName */
837844
unset($this->related[$viaName]);
838-
} else {
839-
$from = $viaRelation->getFrom();
840-
$viaTable = reset($from);
841845
}
842846

843847
$columns = [];
848+
$nulls = [];
844849

845-
foreach ($viaRelation->getLink() as $a => $b) {
846-
$columns[$a] = $this->$b;
847-
}
850+
if ($viaRelation instanceof ActiveQueryInterface) {
851+
$from = $viaRelation->getFrom();
852+
/** @psalm-var mixed $viaTable */
853+
$viaTable = reset($from);
848854

849-
$link = $relation?->getLink() ?? [];
855+
foreach ($viaRelation->getLink() as $a => $b) {
856+
/** @psalm-var mixed */
857+
$columns[$a] = $this->$b;
858+
}
850859

851-
foreach ($link as $a => $b) {
852-
$columns[$b] = $arClass->$a;
853-
}
860+
$link = $relation?->getLink() ?? [];
854861

855-
$nulls = [];
862+
foreach ($link as $a => $b) {
863+
/** @psalm-var mixed */
864+
$columns[$b] = $arClass->$a;
865+
}
856866

857-
foreach (array_keys($columns) as $a) {
858-
$nulls[$a] = null;
859-
}
867+
foreach (array_keys($columns) as $a) {
868+
$nulls[$a] = null;
869+
}
860870

861-
if ($viaRelation->getOn() !== null) {
862-
$columns = ['and', $columns, $viaRelation->getOn()];
871+
if ($viaRelation->getOn() !== null) {
872+
$columns = ['and', $columns, $viaRelation->getOn()];
873+
}
863874
}
864875

865876
if ($viaClass instanceof ActiveRecordInterface && is_array($relation?->getVia())) {
@@ -868,7 +879,7 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet
868879
} else {
869880
$viaClass->updateAll($nulls, $columns);
870881
}
871-
} elseif ($viaTable !== null) {
882+
} elseif (is_string($viaTable)) {
872883
$command = $this->db->createCommand();
873884
if ($delete) {
874885
$command->delete($viaTable, $columns)->execute();
@@ -879,6 +890,7 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet
879890
} elseif ($relation instanceof ActiveQueryInterface) {
880891
$p1 = $arClass->isPrimaryKey(array_keys($relation->getLink()));
881892
$p2 = $this->isPrimaryKey(array_values($relation->getLink()));
893+
882894
if ($p2) {
883895
if ($delete) {
884896
$arClass->delete();
@@ -890,10 +902,11 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet
890902
}
891903
} elseif ($p1) {
892904
foreach ($relation->getLink() as $a => $b) {
905+
/** @psalm-var mixed $values */
906+
$values = $this->$b;
893907
/** relation via array valued attribute */
894-
if (is_array($this->$b)) {
895-
if (($key = array_search($arClass->$a, $this->$b, false)) !== false) {
896-
$values = $this->$b;
908+
if (is_array($values)) {
909+
if (($key = array_search($arClass->$a, $values, false)) !== false) {
897910
unset($values[$key]);
898911
$this->$b = array_values($values);
899912
}
@@ -909,9 +922,10 @@ public function unlink(string $name, ActiveRecordInterface $arClass, bool $delet
909922

910923
if ($relation instanceof ActiveQueryInterface && !$relation->getMultiple()) {
911924
unset($this->related[$name]);
912-
} elseif (isset($this->related[$name])) {
913-
/** @var ActiveRecordInterface $b */
914-
foreach ($this->related[$name] as $a => $b) {
925+
} elseif (isset($this->related[$name]) && is_array($this->related[$name])) {
926+
/** @psalm-var array<array-key, ActiveRecordInterface> $related */
927+
$related = $this->related[$name];
928+
foreach ($related as $a => $b) {
915929
if ($arClass->getPrimaryKey() === $b->getPrimaryKey()) {
916930
unset($this->related[$name][$a]);
917931
}
@@ -945,12 +959,14 @@ public function unlinkAll(string $name, bool $delete = false): void
945959

946960
if ($relation instanceof ActiveQueryInterface && $viaRelation !== null) {
947961
if (is_array($viaRelation)) {
948-
/* @var $viaRelation ActiveQuery */
949962
[$viaName, $viaRelation] = $viaRelation;
963+
/** @psalm-var ActiveQueryInterface $viaRelation */
950964
$viaClass = $viaRelation->getARInstance();
965+
/** @psalm-var string $viaName */
951966
unset($this->related[$viaName]);
952967
} else {
953968
$from = $viaRelation->getFrom();
969+
/** @psalm-var mixed $viaTable */
954970
$viaTable = reset($from);
955971
}
956972

@@ -960,6 +976,7 @@ public function unlinkAll(string $name, bool $delete = false): void
960976
if ($viaRelation instanceof ActiveQueryInterface) {
961977
foreach ($viaRelation->getLink() as $a => $b) {
962978
$nulls[$a] = null;
979+
/** @psalm-var mixed */
963980
$condition[$a] = $this->$b;
964981
}
965982

@@ -978,7 +995,7 @@ public function unlinkAll(string $name, bool $delete = false): void
978995
} else {
979996
$viaClass->updateAll($nulls, $condition);
980997
}
981-
} elseif ($viaTable !== null) {
998+
} elseif (is_string($viaTable)) {
982999
$command = $this->db->createCommand();
9831000
if ($delete) {
9841001
$command->delete($viaTable, $condition)->execute();
@@ -1000,6 +1017,7 @@ public function unlinkAll(string $name, bool $delete = false): void
10001017

10011018
foreach ($relation->getLink() as $a => $b) {
10021019
$nulls[$a] = null;
1020+
/** @psalm-var mixed */
10031021
$condition[$a] = $this->$b;
10041022
}
10051023

@@ -1046,6 +1064,10 @@ private function setRelationDependencies(
10461064
} elseif ($via instanceof ActiveQueryInterface) {
10471065
$this->setRelationDependencies($name, $via);
10481066
} elseif (is_array($via)) {
1067+
/**
1068+
* @psalm-var string|null $viaRelationName
1069+
* @psalm-var ActiveQueryInterface $viaQuery
1070+
*/
10491071
[$viaRelationName, $viaQuery] = $via;
10501072
$this->setRelationDependencies($name, $viaQuery, $viaRelationName);
10511073
}
@@ -1113,17 +1135,21 @@ protected function updateInternal(array $attributes = null): int
11131135
return 0;
11141136
}
11151137

1138+
/** @psalm-var mixed $condition */
11161139
$condition = $this->getOldPrimaryKey(true);
11171140
$lock = $this->optimisticLock();
11181141

1119-
if ($lock !== null) {
1120-
$values[$lock] = $this->$lock + 1;
1142+
if ($lock !== null && is_array($condition)) {
1143+
$values[$lock] = (int) $this->$lock + 1;
1144+
/** @psalm-var array<array-key, mixed>|string */
11211145
$condition[$lock] = $this->$lock;
11221146
}
11231147

11241148
/**
11251149
* We do not check the return value of updateAll() because it's possible that the UPDATE statement doesn't
11261150
* change anything and thus returns 0.
1151+
*
1152+
* @psalm-var array<array-key, mixed>|string $condition
11271153
*/
11281154
$rows = $this->updateAll($values, $condition);
11291155

@@ -1137,7 +1163,12 @@ protected function updateInternal(array $attributes = null): int
11371163

11381164
$changedAttributes = [];
11391165

1166+
/**
1167+
* @psalm-var string $name
1168+
* @psalm-var mixed $value
1169+
*/
11401170
foreach ($values as $name => $value) {
1171+
/** @psalm-var mixed */
11411172
$changedAttributes[$name] = $this->oldAttributes[$name] ?? null;
11421173
$this->oldAttributes[$name] = $value;
11431174
}
@@ -1150,7 +1181,9 @@ private function bindModels(
11501181
ActiveRecordInterface $foreignModel,
11511182
ActiveRecordInterface $primaryModel
11521183
): void {
1184+
/** @psalm-var string[] $link */
11531185
foreach ($link as $fk => $pk) {
1186+
/** @psalm-var mixed $value */
11541187
$value = $primaryModel->$pk;
11551188

11561189
if ($value === null) {
@@ -1159,8 +1192,13 @@ private function bindModels(
11591192
);
11601193
}
11611194

1162-
/** relation via array valued attribute */
1195+
/**
1196+
* relation via array valued attribute
1197+
*
1198+
* @psalm-suppress MixedArrayAssignment
1199+
*/
11631200
if (is_array($foreignModel->$fk)) {
1201+
/** @psalm-var mixed */
11641202
$foreignModel->{$fk}[] = $value;
11651203
} else {
11661204
$foreignModel->{$fk} = $value;
@@ -1199,8 +1237,10 @@ public function toArray(): array
11991237

12001238
foreach ($this->fields() as $key => $value) {
12011239
if ($value instanceof Closure) {
1240+
/** @var mixed */
12021241
$data[$key] = $value($this);
12031242
} else {
1243+
/** @var mixed */
12041244
$data[$value] = $this[$value];
12051245
}
12061246
}

src/BaseActiveRecordTrait.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public function __get(string $name)
5656
return $this->related[$name];
5757
}
5858

59+
/** @var mixed $value */
5960
$value = $this->checkRelation($name);
6061

6162
if ($value instanceof ActiveQuery) {
@@ -267,7 +268,7 @@ public function offsetSet(mixed $offset, mixed $item): void
267268
*/
268269
public function offsetUnset(mixed $offset): void
269270
{
270-
if (property_exists($this, $offset)) {
271+
if (is_string($offset) && property_exists($this, $offset)) {
271272
$this->$offset = null;
272273
} else {
273274
unset($this->$offset);

0 commit comments

Comments
 (0)