AssociationTableMixinClassReflectionExtension.php 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. declare(strict_types=1);
  3. namespace Cake\PHPStan;
  4. use Cake\ORM\Association;
  5. use Cake\ORM\Table;
  6. use PHPStan\Broker\Broker;
  7. use PHPStan\Reflection\BrokerAwareExtension;
  8. use PHPStan\Reflection\ClassReflection;
  9. use PHPStan\Reflection\MethodReflection;
  10. use PHPStan\Reflection\MethodsClassReflectionExtension;
  11. use PHPStan\Reflection\PropertiesClassReflectionExtension;
  12. use PHPStan\Reflection\PropertyReflection;
  13. class AssociationTableMixinClassReflectionExtension implements PropertiesClassReflectionExtension, MethodsClassReflectionExtension, BrokerAwareExtension
  14. {
  15. /**
  16. * @var \PHPStan\Broker\Broker
  17. */
  18. private $broker;
  19. /**
  20. * @param Broker $broker Class reflection broker
  21. */
  22. public function setBroker(Broker $broker): void
  23. {
  24. $this->broker = $broker;
  25. }
  26. protected function getTableReflection(): ClassReflection
  27. {
  28. return $this->broker->getClass(Table::class);
  29. }
  30. /**
  31. * @param ClassReflection $classReflection Class reflection
  32. * @param string $methodName Method name
  33. */
  34. public function hasMethod(ClassReflection $classReflection, string $methodName): bool
  35. {
  36. // magic findBy* method
  37. if ($classReflection->isSubclassOf(Table::class) && preg_match('/^find(?:\w+)?By/', $methodName) > 0) {
  38. return true;
  39. }
  40. if (!$classReflection->isSubclassOf(Association::class)) {
  41. return false;
  42. }
  43. return $this->getTableReflection()->hasMethod($methodName);
  44. }
  45. /**
  46. * @param ClassReflection $classReflection Class reflection
  47. * @param string $methodName Method name
  48. */
  49. public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
  50. {
  51. // magic findBy* method
  52. if ($classReflection->isSubclassOf(Table::class) && preg_match('/^find(?:\w+)?By/', $methodName) > 0) {
  53. return new TableFindByPropertyMethodReflection($methodName, $classReflection);
  54. }
  55. return $this->getTableReflection()->getNativeMethod($methodName);
  56. }
  57. /**
  58. * @param ClassReflection $classReflection Class reflection
  59. * @param string $propertyName Method name
  60. */
  61. public function hasProperty(ClassReflection $classReflection, string $propertyName): bool
  62. {
  63. if (!$classReflection->isSubclassOf(Association::class)) {
  64. return false;
  65. }
  66. return $this->getTableReflection()->hasProperty($propertyName);
  67. }
  68. /**
  69. * @param ClassReflection $classReflection Class reflection
  70. * @param string $propertyName Method name
  71. */
  72. public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection
  73. {
  74. return $this->getTableReflection()->getNativeProperty($propertyName);
  75. }
  76. }