ClassReflector.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Webapi\Model\Config;
  7. use Zend\Code\Reflection\MethodReflection;
  8. /**
  9. * Class reflector.
  10. */
  11. class ClassReflector
  12. {
  13. /**
  14. * @var \Magento\Framework\Reflection\TypeProcessor
  15. */
  16. protected $_typeProcessor;
  17. /**
  18. * Construct reflector.
  19. *
  20. * @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor
  21. */
  22. public function __construct(\Magento\Framework\Reflection\TypeProcessor $typeProcessor)
  23. {
  24. $this->_typeProcessor = $typeProcessor;
  25. }
  26. /**
  27. * Reflect methods in given class and set retrieved data into reader.
  28. *
  29. * @param string $className
  30. * @param array $methods
  31. * @return array <pre>array(
  32. * $firstMethod => array(
  33. * 'documentation' => $methodDocumentation,
  34. * 'interface' => array(
  35. * 'in' => array(
  36. * 'parameters' => array(
  37. * $firstParameter => array(
  38. * 'type' => $type,
  39. * 'required' => $isRequired,
  40. * 'documentation' => $parameterDocumentation
  41. * ),
  42. * ...
  43. * )
  44. * ),
  45. * 'out' => array(
  46. * 'parameters' => array(
  47. * $firstParameter => array(
  48. * 'type' => $type,
  49. * 'required' => $isRequired,
  50. * 'documentation' => $parameterDocumentation
  51. * ),
  52. * ...
  53. * )
  54. * )
  55. * )
  56. * ),
  57. * ...
  58. * )</pre>
  59. */
  60. public function reflectClassMethods($className, $methods)
  61. {
  62. $data = [];
  63. $classReflection = new \Zend\Code\Reflection\ClassReflection($className);
  64. /** @var \Zend\Code\Reflection\MethodReflection $methodReflection */
  65. foreach ($classReflection->getMethods() as $methodReflection) {
  66. $methodName = $methodReflection->getName();
  67. if (array_key_exists($methodName, $methods)) {
  68. $data[$methodName] = $this->extractMethodData($methodReflection);
  69. }
  70. }
  71. return $data;
  72. }
  73. /**
  74. * Retrieve method interface and documentation description.
  75. *
  76. * @param \Zend\Code\Reflection\MethodReflection $method
  77. * @return array
  78. * @throws \InvalidArgumentException
  79. */
  80. public function extractMethodData(\Zend\Code\Reflection\MethodReflection $method)
  81. {
  82. $methodData = ['documentation' => $this->extractMethodDescription($method), 'interface' => []];
  83. /** @var \Zend\Code\Reflection\ParameterReflection $parameter */
  84. foreach ($method->getParameters() as $parameter) {
  85. $parameterData = [
  86. 'type' => $this->_typeProcessor->register($this->_typeProcessor->getParamType($parameter)),
  87. 'required' => !$parameter->isOptional(),
  88. 'documentation' => $this->_typeProcessor->getParamDescription($parameter),
  89. ];
  90. if ($parameter->isOptional()) {
  91. $parameterData['default'] = $parameter->getDefaultValue();
  92. }
  93. $methodData['interface']['in']['parameters'][$parameter->getName()] = $parameterData;
  94. }
  95. $returnType = $this->_typeProcessor->getGetterReturnType($method);
  96. if ($returnType['type'] != 'void' && $returnType['type'] != 'null') {
  97. $methodData['interface']['out']['parameters']['result'] = [
  98. 'type' => $this->_typeProcessor->register($returnType['type']),
  99. 'documentation' => $returnType['description'],
  100. 'required' => true,
  101. ];
  102. }
  103. $exceptions = $this->_typeProcessor->getExceptions($method);
  104. if (!empty($exceptions)) {
  105. $methodData['interface']['out']['throws'] = $exceptions;
  106. }
  107. return $methodData;
  108. }
  109. /**
  110. * Retrieve method full documentation description.
  111. *
  112. * @param \Zend\Code\Reflection\MethodReflection $method
  113. * @return string
  114. */
  115. protected function extractMethodDescription(\Zend\Code\Reflection\MethodReflection $method)
  116. {
  117. $methodReflection = new MethodReflection(
  118. $method->getDeclaringClass()->getName(),
  119. $method->getName()
  120. );
  121. $docBlock = $methodReflection->getDocBlock();
  122. if (!$docBlock) {
  123. throw new \LogicException(
  124. 'The docBlock of the method '.
  125. $method->getDeclaringClass()->getName() . '::' . $method->getName() . ' is empty.'
  126. );
  127. }
  128. return $this->_typeProcessor->getDescription($docBlock);
  129. }
  130. /**
  131. * Retrieve class full documentation description.
  132. *
  133. * @param string $className
  134. * @return string
  135. */
  136. public function extractClassDescription($className)
  137. {
  138. $classReflection = new \Zend\Code\Reflection\ClassReflection($className);
  139. $docBlock = $classReflection->getDocBlock();
  140. if (!$docBlock) {
  141. return '';
  142. }
  143. return $this->_typeProcessor->getDescription($docBlock);
  144. }
  145. }