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