@@ -569,101 +569,108 @@ public function getPropertiesFromTable($model)
569
569
*/
570
570
public function getPropertiesFromMethods ($ model )
571
571
{
572
- $ methods = get_class_methods ($ model );
573
- if ($ methods ) {
574
- sort ($ methods );
575
- foreach ($ methods as $ method ) {
576
- $ reflection = new \ReflectionMethod ($ model , $ method );
577
- $ type = $ this ->getReturnTypeFromReflection ($ reflection );
572
+ $ reflectionClass = new ReflectionClass ($ model );
573
+ $ methodReflections = $ reflectionClass ->getMethods ();
574
+ if ($ methodReflections ) {
575
+ $ methodReflections = array_filter ($ methodReflections , function ($ methodReflection ) {
576
+ return !(
577
+ $ methodReflection ->getDeclaringClass ()->getName () === \Illuminate \Database \Eloquent \Model::class && (
578
+ $ methodReflection ->getName () === 'setClassCastableAttribute ' ||
579
+ $ methodReflection ->getName () === 'setEnumCastableAttribute '
580
+ )
581
+ );
582
+ });
583
+ sort ($ methodReflections );
584
+ foreach ($ methodReflections as $ methodReflection ) {
585
+ $ type = $ this ->getReturnTypeFromReflection ($ methodReflection );
578
586
$ isAttribute = is_a ($ type , '\Illuminate\Database\Eloquent\Casts\Attribute ' , true );
579
587
if (
580
- Str::startsWith ($ method , 'get ' ) && Str::endsWith (
581
- $ method ,
588
+ Str::startsWith ($ methodReflection -> getName () , 'get ' ) && Str::endsWith (
589
+ $ methodReflection -> getName () ,
582
590
'Attribute '
583
- ) && $ method !== 'getAttribute '
591
+ ) && $ methodReflection -> getName () !== 'getAttribute '
584
592
) {
585
593
//Magic get<name>Attribute
586
- $ name = Str::snake (substr ($ method , 3 , -9 ));
594
+ $ name = Str::snake (substr ($ methodReflection -> getName () , 3 , -9 ));
587
595
if (!empty ($ name )) {
588
- $ type = $ this ->getReturnType ($ reflection );
596
+ $ type = $ this ->getReturnType ($ methodReflection );
589
597
$ type = $ this ->getTypeInModel ($ model , $ type );
590
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
598
+ $ comment = $ this ->getCommentFromDocBlock ($ methodReflection );
591
599
$ this ->setProperty ($ name , $ type , true , null , $ comment );
592
600
}
593
601
} elseif ($ isAttribute ) {
594
- $ name = Str::snake ($ method );
595
- $ types = $ this ->getAttributeReturnType ($ model , $ method );
602
+ $ name = Str::snake ($ methodReflection ->getName ());
603
+ $ types = $ this ->getAttributeReturnType ($ model , $ methodReflection );
604
+ $ comment = $ this ->getCommentFromDocBlock ($ methodReflection );
596
605
597
606
if ($ types ->has ('get ' )) {
598
607
$ type = $ this ->getTypeInModel ($ model , $ types ['get ' ]);
599
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
600
608
$ this ->setProperty ($ name , $ type , true , null , $ comment );
601
609
}
602
610
603
611
if ($ types ->has ('set ' )) {
604
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
605
612
$ this ->setProperty ($ name , null , null , true , $ comment );
606
613
}
607
614
} elseif (
608
- Str::startsWith ($ method , 'set ' ) && Str::endsWith (
609
- $ method ,
615
+ Str::startsWith ($ methodReflection -> getName () , 'set ' ) && Str::endsWith (
616
+ $ methodReflection -> getName () ,
610
617
'Attribute '
611
- ) && $ method !== 'setAttribute '
618
+ ) && $ methodReflection -> getName () !== 'setAttribute '
612
619
) {
613
620
//Magic set<name>Attribute
614
- $ name = Str::snake (substr ($ method , 3 , -9 ));
621
+ $ name = Str::snake (substr ($ methodReflection -> getName () , 3 , -9 ));
615
622
if (!empty ($ name )) {
616
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
623
+ $ comment = $ this ->getCommentFromDocBlock ($ methodReflection );
617
624
$ this ->setProperty ($ name , null , null , true , $ comment );
618
625
}
619
- } elseif (Str::startsWith ($ method , 'scope ' ) && $ method !== 'scopeQuery ' ) {
626
+ } elseif (Str::startsWith ($ methodReflection -> getName () , 'scope ' ) && $ methodReflection -> getName () !== 'scopeQuery ' ) {
620
627
//Magic set<name>Attribute
621
- $ name = Str::camel (substr ($ method , 5 ));
628
+ $ name = Str::camel (substr ($ methodReflection -> getName () , 5 ));
622
629
if (!empty ($ name )) {
623
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
624
- $ args = $ this ->getParameters ($ reflection );
630
+ $ comment = $ this ->getCommentFromDocBlock ($ methodReflection );
631
+ $ args = $ this ->getParameters ($ methodReflection );
625
632
//Remove the first ($query) argument
626
633
array_shift ($ args );
627
634
$ builder = $ this ->getClassNameInDestinationFile (
628
- $ reflection ->getDeclaringClass (),
635
+ $ methodReflection ->getDeclaringClass (),
629
636
get_class ($ model ->newModelQuery ())
630
637
);
631
638
$ modelName = $ this ->getClassNameInDestinationFile (
632
- $ reflection ->getDeclaringClass (),
633
- $ reflection ->getDeclaringClass ()->getName ()
639
+ $ methodReflection ->getDeclaringClass (),
640
+ $ methodReflection ->getDeclaringClass ()->getName ()
634
641
);
635
642
$ this ->setMethod ($ name , $ builder . '| ' . $ modelName , $ args , $ comment );
636
643
}
637
- } elseif (in_array ($ method , ['query ' , 'newQuery ' , 'newModelQuery ' ])) {
644
+ } elseif (in_array ($ methodReflection -> getName () , ['query ' , 'newQuery ' , 'newModelQuery ' ])) {
638
645
$ builder = $ this ->getClassNameInDestinationFile ($ model , get_class ($ model ->newModelQuery ()));
639
646
640
647
$ this ->setMethod (
641
- $ method ,
648
+ $ methodReflection -> getName () ,
642
649
$ builder . '| ' . $ this ->getClassNameInDestinationFile ($ model , get_class ($ model ))
643
650
);
644
651
645
652
if ($ this ->write_model_external_builder_methods ) {
646
653
$ this ->writeModelExternalBuilderMethods ($ model );
647
654
}
648
655
} elseif (
649
- !method_exists ('Illuminate\Database\Eloquent\Model ' , $ method )
650
- && !Str::startsWith ($ method , 'get ' )
656
+ !method_exists ('Illuminate\Database\Eloquent\Model ' , $ methodReflection -> getName () )
657
+ && !Str::startsWith ($ methodReflection -> getName () , 'get ' )
651
658
) {
652
659
//Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
653
- if ($ returnType = $ reflection ->getReturnType ()) {
660
+ if ($ returnType = $ methodReflection ->getReturnType ()) {
654
661
$ type = $ returnType instanceof ReflectionNamedType
655
662
? $ returnType ->getName ()
656
663
: (string )$ returnType ;
657
664
} else {
658
665
// php 7.x type or fallback to docblock
659
- $ type = (string )$ this ->getReturnTypeFromDocBlock ($ reflection );
666
+ $ type = (string )$ this ->getReturnTypeFromDocBlock ($ methodReflection );
660
667
}
661
668
662
- $ file = new \SplFileObject ($ reflection ->getFileName ());
663
- $ file ->seek ($ reflection ->getStartLine () - 1 );
669
+ $ file = new \SplFileObject ($ methodReflection ->getFileName ());
670
+ $ file ->seek ($ methodReflection ->getStartLine () - 1 );
664
671
665
672
$ code = '' ;
666
- while ($ file ->key () < $ reflection ->getEndLine ()) {
673
+ while ($ file ->key () < $ methodReflection ->getEndLine ()) {
667
674
$ code .= $ file ->current ();
668
675
$ file ->next ();
669
676
}
@@ -677,20 +684,20 @@ public function getPropertiesFromMethods($model)
677
684
$ search = '$this-> ' . $ relation . '( ' ;
678
685
if (stripos ($ code , $ search ) || ltrim ($ impl , '\\' ) === ltrim ((string )$ type , '\\' )) {
679
686
//Resolve the relation's model to a Relation object.
680
- $ methodReflection = new \ReflectionMethod ($ model , $ method );
681
687
if ($ methodReflection ->getNumberOfParameters ()) {
682
688
continue ;
683
689
}
684
690
685
- $ comment = $ this ->getCommentFromDocBlock ($ reflection );
691
+ $ comment = $ this ->getCommentFromDocBlock ($ methodReflection );
686
692
// Adding constraints requires reading model properties which
687
693
// can cause errors. Since we don't need constraints we can
688
694
// disable them when we fetch the relation to avoid errors.
689
- $ relationObj = Relation::noConstraints (function () use ($ model , $ method ) {
695
+ $ relationObj = Relation::noConstraints (function () use ($ model , $ methodReflection ) {
690
696
try {
691
- return $ model ->$ method ();
697
+ $ methodName = $ methodReflection ->getName ();
698
+ return $ model ->$ methodName ();
692
699
} catch (Throwable $ e ) {
693
- $ this ->warn (sprintf ('Error resolving relation model of %s:%s() : %s ' , get_class ($ model ), $ method , $ e ->getMessage ()));
700
+ $ this ->warn (sprintf ('Error resolving relation model of %s:%s() : %s ' , get_class ($ model ), $ methodReflection -> getName () , $ e ->getMessage ()));
694
701
695
702
return null ;
696
703
}
@@ -711,15 +718,15 @@ public function getPropertiesFromMethods($model)
711
718
$ collectionClass
712
719
);
713
720
$ this ->setProperty (
714
- $ method ,
721
+ $ methodReflection -> getName () ,
715
722
$ collectionClassNameInModel . '| ' . $ relatedModel . '[] ' ,
716
723
true ,
717
724
null ,
718
725
$ comment
719
726
);
720
727
if ($ this ->write_model_relation_count_properties ) {
721
728
$ this ->setProperty (
722
- Str::snake ($ method ) . '_count ' ,
729
+ Str::snake ($ methodReflection -> getName () ) . '_count ' ,
723
730
'int|null ' ,
724
731
true ,
725
732
false
@@ -729,7 +736,7 @@ public function getPropertiesFromMethods($model)
729
736
} elseif ($ relation === 'morphTo ' ) {
730
737
// Model isn't specified because relation is polymorphic
731
738
$ this ->setProperty (
732
- $ method ,
739
+ $ methodReflection -> getName () ,
733
740
$ this ->getClassNameInDestinationFile ($ model , Model::class) . '|\Eloquent ' ,
734
741
true ,
735
742
null ,
@@ -738,7 +745,7 @@ public function getPropertiesFromMethods($model)
738
745
} else {
739
746
//Single model is returned
740
747
$ this ->setProperty (
741
- $ method ,
748
+ $ methodReflection -> getName () ,
742
749
$ relatedModel ,
743
750
true ,
744
751
null ,
@@ -1082,10 +1089,10 @@ protected function hasCamelCaseModelProperties()
1082
1089
return $ this ->laravel ['config ' ]->get ('ide-helper.model_camel_case_properties ' , false );
1083
1090
}
1084
1091
1085
- protected function getAttributeReturnType (Model $ model , string $ method ): Collection
1092
+ protected function getAttributeReturnType (Model $ model , \ ReflectionMethod $ reflectionMethod ): Collection
1086
1093
{
1087
1094
/** @var Attribute $attribute */
1088
- $ attribute = $ model ->{ $ method }( );
1095
+ $ attribute = $ reflectionMethod -> invoke ( $ model );
1089
1096
1090
1097
return collect ([
1091
1098
'get ' => $ attribute ->get ? optional (new \ReflectionFunction ($ attribute ->get ))->getReturnType () : null ,
0 commit comments