@@ -605,13 +605,27 @@ public function getPropertiesFromTable($model)
605
605
*/
606
606
public function getPropertiesFromMethods ($ model )
607
607
{
608
- $ methods = get_class_methods ($ model );
609
- if ($ methods ) {
610
- sort ($ methods );
611
- foreach ($ methods as $ method ) {
612
- $ reflection = new \ReflectionMethod ($ model , $ method );
608
+ $ reflectionClass = new ReflectionClass ($ model );
609
+ $ reflections = $ reflectionClass ->getMethods ();
610
+ if ($ reflections ) {
611
+ // Filter out private methods because they can't be used to generate magic properties and HasAttributes'
612
+ // methods that resemble mutators but aren't.
613
+ $ reflections = array_filter ($ reflections , function (\ReflectionMethod $ methodReflection ) {
614
+ return !$ methodReflection ->isPrivate () && !(
615
+ in_array (
616
+ \Illuminate \Database \Eloquent \Concerns \HasAttributes::class,
617
+ $ methodReflection ->getDeclaringClass ()->getTraitNames ()
618
+ ) && (
619
+ $ methodReflection ->getName () === 'setClassCastableAttribute ' ||
620
+ $ methodReflection ->getName () === 'setEnumCastableAttribute '
621
+ )
622
+ );
623
+ });
624
+ sort ($ reflections );
625
+ foreach ($ reflections as $ reflection ) {
613
626
$ type = $ this ->getReturnTypeFromReflection ($ reflection );
614
627
$ isAttribute = is_a ($ type , '\Illuminate\Database\Eloquent\Casts\Attribute ' , true );
628
+ $ method = $ reflection ->getName ();
615
629
if (
616
630
Str::startsWith ($ method , 'get ' ) && Str::endsWith (
617
631
$ method ,
@@ -628,16 +642,15 @@ public function getPropertiesFromMethods($model)
628
642
}
629
643
} elseif ($ isAttribute ) {
630
644
$ name = Str::snake ($ method );
631
- $ types = $ this ->getAttributeReturnType ($ model , $ method );
645
+ $ types = $ this ->getAttributeReturnType ($ model , $ reflection );
646
+ $ comment = $ this ->getCommentFromDocBlock ($ reflection );
632
647
633
648
if ($ types ->has ('get ' )) {
634
649
$ type = $ this ->getTypeInModel ($ model , $ types ['get ' ]);
635
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
636
650
$ this ->setProperty ($ name , $ type , true , null , $ comment );
637
651
}
638
652
639
653
if ($ types ->has ('set ' )) {
640
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
641
654
$ this ->setProperty ($ name , null , null , true , $ comment );
642
655
}
643
656
} elseif (
@@ -713,20 +726,20 @@ public function getPropertiesFromMethods($model)
713
726
$ search = '$this-> ' . $ relation . '( ' ;
714
727
if (stripos ($ code , $ search ) || ltrim ($ impl , '\\' ) === ltrim ((string )$ type , '\\' )) {
715
728
//Resolve the relation's model to a Relation object.
716
- $ methodReflection = new \ReflectionMethod ($ model , $ method );
717
- if ($ methodReflection ->getNumberOfParameters ()) {
729
+ if ($ reflection ->getNumberOfParameters ()) {
718
730
continue ;
719
731
}
720
732
721
733
$ comment = $ this ->getCommentFromDocBlock ($ reflection );
722
734
// Adding constraints requires reading model properties which
723
735
// can cause errors. Since we don't need constraints we can
724
736
// disable them when we fetch the relation to avoid errors.
725
- $ relationObj = Relation::noConstraints (function () use ($ model , $ method ) {
737
+ $ relationObj = Relation::noConstraints (function () use ($ model , $ reflection ) {
726
738
try {
727
- return $ model ->$ method ();
739
+ $ methodName = $ reflection ->getName ();
740
+ return $ model ->$ methodName ();
728
741
} catch (Throwable $ e ) {
729
- $ this ->warn (sprintf ('Error resolving relation model of %s:%s() : %s ' , get_class ($ model ), $ method , $ e ->getMessage ()));
742
+ $ this ->warn (sprintf ('Error resolving relation model of %s:%s() : %s ' , get_class ($ model ), $ reflection -> getName () , $ e ->getMessage ()));
730
743
731
744
return null ;
732
745
}
@@ -1159,10 +1172,13 @@ protected function hasCamelCaseModelProperties()
1159
1172
return $ this ->laravel ['config ' ]->get ('ide-helper.model_camel_case_properties ' , false );
1160
1173
}
1161
1174
1162
- protected function getAttributeReturnType (Model $ model , string $ method ): Collection
1175
+ protected function getAttributeReturnType (Model $ model , \ ReflectionMethod $ reflectionMethod ): Collection
1163
1176
{
1177
+ // Private/protected ReflectionMethods require setAccessible prior to PHP 8.1
1178
+ $ reflectionMethod ->setAccessible (true );
1179
+
1164
1180
/** @var Attribute $attribute */
1165
- $ attribute = $ model ->{ $ method }( );
1181
+ $ attribute = $ reflectionMethod -> invoke ( $ model );
1166
1182
1167
1183
return collect ([
1168
1184
'get ' => $ attribute ->get ? optional (new \ReflectionFunction ($ attribute ->get ))->getReturnType () : null ,
@@ -1171,7 +1187,7 @@ protected function getAttributeReturnType(Model $model, string $method): Collect
1171
1187
->filter ()
1172
1188
->map (function ($ type ) {
1173
1189
if ($ type instanceof \ReflectionUnionType) {
1174
- $ types =collect ($ type ->getTypes ())
1190
+ $ types = collect ($ type ->getTypes ())
1175
1191
/** @var ReflectionType $reflectionType */
1176
1192
->map (function ($ reflectionType ) {
1177
1193
return collect ($ this ->extractReflectionTypes ($ reflectionType ));
@@ -1259,7 +1275,7 @@ protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?
1259
1275
$ type = implode ('| ' , $ types );
1260
1276
1261
1277
if ($ returnType ->allowsNull ()) {
1262
- $ type .='|null ' ;
1278
+ $ type .= '|null ' ;
1263
1279
}
1264
1280
1265
1281
return $ type ;
@@ -1501,10 +1517,10 @@ protected function getParamType(\ReflectionMethod $method, \ReflectionParameter
1501
1517
$ type = implode ('| ' , $ types );
1502
1518
1503
1519
if ($ paramType ->allowsNull ()) {
1504
- if (count ($ types )== 1 ) {
1520
+ if (count ($ types ) == 1 ) {
1505
1521
$ type = '? ' . $ type ;
1506
1522
} else {
1507
- $ type .='|null ' ;
1523
+ $ type .= '|null ' ;
1508
1524
}
1509
1525
}
1510
1526
@@ -1581,7 +1597,7 @@ protected function extractReflectionTypes(ReflectionType $reflection_type)
1581
1597
} else {
1582
1598
$ types = [];
1583
1599
foreach ($ reflection_type ->getTypes () as $ named_type ) {
1584
- if ($ named_type ->getName ()==='null ' ) {
1600
+ if ($ named_type ->getName () === 'null ' ) {
1585
1601
continue ;
1586
1602
}
1587
1603
0 commit comments