@@ -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 }
0 commit comments