@@ -605,13 +605,27 @@ public function getPropertiesFromTable($model)
605605 */
606606 public function getPropertiesFromMethods ($ model )
607607 {
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 ) {
613626 $ type = $ this ->getReturnTypeFromReflection ($ reflection );
614627 $ isAttribute = is_a ($ type , '\Illuminate\Database\Eloquent\Casts\Attribute ' , true );
628+ $ method = $ reflection ->getName ();
615629 if (
616630 Str::startsWith ($ method , 'get ' ) && Str::endsWith (
617631 $ method ,
@@ -628,16 +642,15 @@ public function getPropertiesFromMethods($model)
628642 }
629643 } elseif ($ isAttribute ) {
630644 $ name = Str::snake ($ method );
631- $ types = $ this ->getAttributeReturnType ($ model , $ method );
645+ $ types = $ this ->getAttributeReturnType ($ model , $ reflection );
646+ $ comment = $ this ->getCommentFromDocBlock ($ reflection );
632647
633648 if ($ types ->has ('get ' )) {
634649 $ type = $ this ->getTypeInModel ($ model , $ types ['get ' ]);
635- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
636650 $ this ->setProperty ($ name , $ type , true , null , $ comment );
637651 }
638652
639653 if ($ types ->has ('set ' )) {
640- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
641654 $ this ->setProperty ($ name , null , null , true , $ comment );
642655 }
643656 } elseif (
@@ -713,20 +726,20 @@ public function getPropertiesFromMethods($model)
713726 $ search = '$this-> ' . $ relation . '( ' ;
714727 if (stripos ($ code , $ search ) || ltrim ($ impl , '\\' ) === ltrim ((string )$ type , '\\' )) {
715728 //Resolve the relation's model to a Relation object.
716- $ methodReflection = new \ReflectionMethod ($ model , $ method );
717- if ($ methodReflection ->getNumberOfParameters ()) {
729+ if ($ reflection ->getNumberOfParameters ()) {
718730 continue ;
719731 }
720732
721733 $ comment = $ this ->getCommentFromDocBlock ($ reflection );
722734 // Adding constraints requires reading model properties which
723735 // can cause errors. Since we don't need constraints we can
724736 // 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 ) {
726738 try {
727- return $ model ->$ method ();
739+ $ methodName = $ reflection ->getName ();
740+ return $ model ->$ methodName ();
728741 } 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 ()));
730743
731744 return null ;
732745 }
@@ -1159,10 +1172,13 @@ protected function hasCamelCaseModelProperties()
11591172 return $ this ->laravel ['config ' ]->get ('ide-helper.model_camel_case_properties ' , false );
11601173 }
11611174
1162- protected function getAttributeReturnType (Model $ model , string $ method ): Collection
1175+ protected function getAttributeReturnType (Model $ model , \ ReflectionMethod $ reflectionMethod ): Collection
11631176 {
1177+ // Private/protected ReflectionMethods require setAccessible prior to PHP 8.1
1178+ $ reflectionMethod ->setAccessible (true );
1179+
11641180 /** @var Attribute $attribute */
1165- $ attribute = $ model ->{ $ method }( );
1181+ $ attribute = $ reflectionMethod -> invoke ( $ model );
11661182
11671183 return collect ([
11681184 'get ' => $ attribute ->get ? optional (new \ReflectionFunction ($ attribute ->get ))->getReturnType () : null ,
@@ -1171,7 +1187,7 @@ protected function getAttributeReturnType(Model $model, string $method): Collect
11711187 ->filter ()
11721188 ->map (function ($ type ) {
11731189 if ($ type instanceof \ReflectionUnionType) {
1174- $ types =collect ($ type ->getTypes ())
1190+ $ types = collect ($ type ->getTypes ())
11751191 /** @var ReflectionType $reflectionType */
11761192 ->map (function ($ reflectionType ) {
11771193 return collect ($ this ->extractReflectionTypes ($ reflectionType ));
@@ -1259,7 +1275,7 @@ protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?
12591275 $ type = implode ('| ' , $ types );
12601276
12611277 if ($ returnType ->allowsNull ()) {
1262- $ type .='|null ' ;
1278+ $ type .= '|null ' ;
12631279 }
12641280
12651281 return $ type ;
@@ -1501,10 +1517,10 @@ protected function getParamType(\ReflectionMethod $method, \ReflectionParameter
15011517 $ type = implode ('| ' , $ types );
15021518
15031519 if ($ paramType ->allowsNull ()) {
1504- if (count ($ types )== 1 ) {
1520+ if (count ($ types ) == 1 ) {
15051521 $ type = '? ' . $ type ;
15061522 } else {
1507- $ type .='|null ' ;
1523+ $ type .= '|null ' ;
15081524 }
15091525 }
15101526
@@ -1581,7 +1597,7 @@ protected function extractReflectionTypes(ReflectionType $reflection_type)
15811597 } else {
15821598 $ types = [];
15831599 foreach ($ reflection_type ->getTypes () as $ named_type ) {
1584- if ($ named_type ->getName ()==='null ' ) {
1600+ if ($ named_type ->getName () === 'null ' ) {
15851601 continue ;
15861602 }
15871603
0 commit comments