@@ -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
}
@@ -714,15 +721,15 @@ public function getPropertiesFromMethods($model)
714
721
$ collectionClass
715
722
);
716
723
$ this ->setProperty (
717
- $ method ,
724
+ $ methodReflection -> getName () ,
718
725
$ collectionClassNameInModel . '| ' . $ relatedModel . '[] ' ,
719
726
true ,
720
727
null ,
721
728
$ comment
722
729
);
723
730
if ($ this ->write_model_relation_count_properties ) {
724
731
$ this ->setProperty (
725
- Str::snake ($ method ) . '_count ' ,
732
+ Str::snake ($ methodReflection -> getName () ) . '_count ' ,
726
733
'int|null ' ,
727
734
true ,
728
735
false
@@ -735,7 +742,7 @@ public function getPropertiesFromMethods($model)
735
742
) {
736
743
// Model isn't specified because relation is polymorphic
737
744
$ this ->setProperty (
738
- $ method ,
745
+ $ methodReflection -> getName () ,
739
746
$ this ->getClassNameInDestinationFile ($ model , Model::class) . '|\Eloquent ' ,
740
747
true ,
741
748
null ,
@@ -744,7 +751,7 @@ public function getPropertiesFromMethods($model)
744
751
} else {
745
752
//Single model is returned
746
753
$ this ->setProperty (
747
- $ method ,
754
+ $ methodReflection -> getName () ,
748
755
$ relatedModel ,
749
756
true ,
750
757
null ,
@@ -1105,10 +1112,10 @@ protected function hasCamelCaseModelProperties()
1105
1112
return $ this ->laravel ['config ' ]->get ('ide-helper.model_camel_case_properties ' , false );
1106
1113
}
1107
1114
1108
- protected function getAttributeReturnType (Model $ model , string $ method ): Collection
1115
+ protected function getAttributeReturnType (Model $ model , \ ReflectionMethod $ reflectionMethod ): Collection
1109
1116
{
1110
1117
/** @var Attribute $attribute */
1111
- $ attribute = $ model ->{ $ method }( );
1118
+ $ attribute = $ reflectionMethod -> invoke ( $ model );
1112
1119
1113
1120
return collect ([
1114
1121
'get ' => $ attribute ->get ? optional (new \ReflectionFunction ($ attribute ->get ))->getReturnType () : null ,
0 commit comments