AssociationTableMixinClassReflectionExtension.php 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. * @return void
  22. */
  23. public function setBroker(Broker $broker): void
  24. {
  25. $this->broker = $broker;
  26. }
  27. /**
  28. * @return ClassReflection
  29. */
  30. protected function getTableReflection(): ClassReflection
  31. {
  32. return $this->broker->getClass(Table::class);
  33. }
  34. /**
  35. * @param ClassReflection $classReflection Class reflection
  36. * @param string $methodName Method name
  37. * @return bool
  38. */
  39. public function hasMethod(ClassReflection $classReflection, string $methodName): bool
  40. {
  41. // magic findBy* method
  42. if ($classReflection->isSubclassOf(Table::class) && preg_match('/^find(?:\w+)?By/', $methodName) > 0) {
  43. return true;
  44. }
  45. if (!$classReflection->isSubclassOf(Association::class)) {
  46. return false;
  47. }
  48. return $this->getTableReflection()->hasMethod($methodName);
  49. }
  50. /**
  51. * @param ClassReflection $classReflection Class reflection
  52. * @param string $methodName Method name
  53. * @return MethodReflection
  54. */
  55. public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
  56. {
  57. // magic findBy* method
  58. if ($classReflection->isSubclassOf(Table::class) && preg_match('/^find(?:\w+)?By/', $methodName) > 0) {
  59. return new TableFindByPropertyMethodReflection($methodName, $classReflection);
  60. }
  61. return $this->getTableReflection()->getNativeMethod($methodName);
  62. }
  63. /**
  64. * @param ClassReflection $classReflection Class reflection
  65. * @param string $propertyName Method name
  66. * @return bool
  67. */
  68. public function hasProperty(ClassReflection $classReflection, string $propertyName): bool
  69. {
  70. if (!$classReflection->isSubclassOf(Association::class)) {
  71. return false;
  72. }
  73. return $this->getTableReflection()->hasProperty($propertyName);
  74. }
  75. /**
  76. * @param ClassReflection $classReflection Class reflection
  77. * @param string $propertyName Method name
  78. * @return PropertyReflection
  79. */
  80. public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection
  81. {
  82. return $this->getTableReflection()->getNativeProperty($propertyName);
  83. }
  84. }