@@ -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 }
@@ -1170,10 +1183,13 @@ protected function hasCamelCaseModelProperties()
11701183 return $ this ->laravel ['config ' ]->get ('ide-helper.model_camel_case_properties ' , false );
11711184 }
11721185
1173- protected function getAttributeReturnType (Model $ model , string $ method ): Collection
1186+ protected function getAttributeReturnType (Model $ model , \ ReflectionMethod $ reflectionMethod ): Collection
11741187 {
1188+ // Private/protected ReflectionMethods require setAccessible prior to PHP 8.1
1189+ $ reflectionMethod ->setAccessible (true );
1190+
11751191 /** @var Attribute $attribute */
1176- $ attribute = $ model ->{ $ method }( );
1192+ $ attribute = $ reflectionMethod -> invoke ( $ model );
11771193
11781194 return collect ([
11791195 'get ' => $ attribute ->get ? optional (new \ReflectionFunction ($ attribute ->get ))->getReturnType () : null ,
@@ -1182,7 +1198,7 @@ protected function getAttributeReturnType(Model $model, string $method): Collect
11821198 ->filter ()
11831199 ->map (function ($ type ) {
11841200 if ($ type instanceof \ReflectionUnionType) {
1185- $ types =collect ($ type ->getTypes ())
1201+ $ types = collect ($ type ->getTypes ())
11861202 /** @var ReflectionType $reflectionType */
11871203 ->map (function ($ reflectionType ) {
11881204 return collect ($ this ->extractReflectionTypes ($ reflectionType ));
@@ -1270,7 +1286,7 @@ protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?
12701286 $ type = implode ('| ' , $ types );
12711287
12721288 if ($ returnType ->allowsNull ()) {
1273- $ type .='|null ' ;
1289+ $ type .= '|null ' ;
12741290 }
12751291
12761292 return $ type ;
@@ -1512,10 +1528,10 @@ protected function getParamType(\ReflectionMethod $method, \ReflectionParameter
15121528 $ type = implode ('| ' , $ types );
15131529
15141530 if ($ paramType ->allowsNull ()) {
1515- if (count ($ types )== 1 ) {
1531+ if (count ($ types ) == 1 ) {
15161532 $ type = '? ' . $ type ;
15171533 } else {
1518- $ type .='|null ' ;
1534+ $ type .= '|null ' ;
15191535 }
15201536 }
15211537
@@ -1592,7 +1608,7 @@ protected function extractReflectionTypes(ReflectionType $reflection_type)
15921608 } else {
15931609 $ types = [];
15941610 foreach ($ reflection_type ->getTypes () as $ named_type ) {
1595- if ($ named_type ->getName ()==='null ' ) {
1611+ if ($ named_type ->getName () === 'null ' ) {
15961612 continue ;
15971613 }
15981614
0 commit comments