@@ -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
}
@@ -1170,10 +1183,13 @@ protected function hasCamelCaseModelProperties()
1170
1183
return $ this ->laravel ['config ' ]->get ('ide-helper.model_camel_case_properties ' , false );
1171
1184
}
1172
1185
1173
- protected function getAttributeReturnType (Model $ model , string $ method ): Collection
1186
+ protected function getAttributeReturnType (Model $ model , \ ReflectionMethod $ reflectionMethod ): Collection
1174
1187
{
1188
+ // Private/protected ReflectionMethods require setAccessible prior to PHP 8.1
1189
+ $ reflectionMethod ->setAccessible (true );
1190
+
1175
1191
/** @var Attribute $attribute */
1176
- $ attribute = $ model ->{ $ method }( );
1192
+ $ attribute = $ reflectionMethod -> invoke ( $ model );
1177
1193
1178
1194
return collect ([
1179
1195
'get ' => $ attribute ->get ? optional (new \ReflectionFunction ($ attribute ->get ))->getReturnType () : null ,
@@ -1182,7 +1198,7 @@ protected function getAttributeReturnType(Model $model, string $method): Collect
1182
1198
->filter ()
1183
1199
->map (function ($ type ) {
1184
1200
if ($ type instanceof \ReflectionUnionType) {
1185
- $ types =collect ($ type ->getTypes ())
1201
+ $ types = collect ($ type ->getTypes ())
1186
1202
/** @var ReflectionType $reflectionType */
1187
1203
->map (function ($ reflectionType ) {
1188
1204
return collect ($ this ->extractReflectionTypes ($ reflectionType ));
@@ -1270,7 +1286,7 @@ protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?
1270
1286
$ type = implode ('| ' , $ types );
1271
1287
1272
1288
if ($ returnType ->allowsNull ()) {
1273
- $ type .='|null ' ;
1289
+ $ type .= '|null ' ;
1274
1290
}
1275
1291
1276
1292
return $ type ;
@@ -1512,10 +1528,10 @@ protected function getParamType(\ReflectionMethod $method, \ReflectionParameter
1512
1528
$ type = implode ('| ' , $ types );
1513
1529
1514
1530
if ($ paramType ->allowsNull ()) {
1515
- if (count ($ types )== 1 ) {
1531
+ if (count ($ types ) == 1 ) {
1516
1532
$ type = '? ' . $ type ;
1517
1533
} else {
1518
- $ type .='|null ' ;
1534
+ $ type .= '|null ' ;
1519
1535
}
1520
1536
}
1521
1537
@@ -1592,7 +1608,7 @@ protected function extractReflectionTypes(ReflectionType $reflection_type)
1592
1608
} else {
1593
1609
$ types = [];
1594
1610
foreach ($ reflection_type ->getTypes () as $ named_type ) {
1595
- if ($ named_type ->getName ()==='null ' ) {
1611
+ if ($ named_type ->getName () === 'null ' ) {
1596
1612
continue ;
1597
1613
}
1598
1614
0 commit comments