classmethods.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. class Kint_Parsers_ClassMethods extends kintParser
  3. {
  4. private static $cache = array();
  5. protected function _parse( &$variable )
  6. {
  7. if ( !KINT_PHP53 || !is_object( $variable ) ) return false;
  8. $className = get_class( $variable );
  9. # assuming class definition will not change inside one request
  10. if ( !isset( self::$cache[ $className ] ) ) {
  11. $reflection = new ReflectionClass( $variable );
  12. $public = $private = $protected = array();
  13. // Class methods
  14. foreach ( $reflection->getMethods() as $method ) {
  15. $params = array();
  16. // Access type
  17. $access = implode( ' ', Reflection::getModifierNames( $method->getModifiers() ) );
  18. // Method parameters
  19. foreach ( $method->getParameters() as $param ) {
  20. $paramString = '';
  21. if ( $param->isArray() ) {
  22. $paramString .= 'array ';
  23. } else {
  24. try {
  25. if ( $paramClassName = $param->getClass() ) {
  26. $paramString .= $paramClassName->name . ' ';
  27. }
  28. } catch ( ReflectionException $e ) {
  29. preg_match( '/\[\s\<\w+?>\s([\w]+)/s', $param->__toString(), $matches );
  30. $paramClassName = isset( $matches[1] ) ? $matches[1] : '';
  31. $paramString .= ' UNDEFINED CLASS (' . $paramClassName . ') ';
  32. }
  33. }
  34. $paramString .= ( $param->isPassedByReference() ? '&' : '' ) . '$' . $param->getName();
  35. if ( $param->isDefaultValueAvailable() ) {
  36. if ( is_array( $param->getDefaultValue() ) ) {
  37. $arrayValues = array();
  38. foreach ( $param->getDefaultValue() as $key => $value ) {
  39. $arrayValues[] = $key . ' => ' . $value;
  40. }
  41. $defaultValue = 'array(' . implode( ', ', $arrayValues ) . ')';
  42. } elseif ( $param->getDefaultValue() === null ) {
  43. $defaultValue = 'NULL';
  44. } elseif ( $param->getDefaultValue() === false ) {
  45. $defaultValue = 'false';
  46. } elseif ( $param->getDefaultValue() === true ) {
  47. $defaultValue = 'true';
  48. } elseif ( $param->getDefaultValue() === '' ) {
  49. $defaultValue = '""';
  50. } else {
  51. $defaultValue = $param->getDefaultValue();
  52. }
  53. $paramString .= ' = ' . $defaultValue;
  54. }
  55. $params[] = $paramString;
  56. }
  57. $output = new kintVariableData;
  58. // Simple DocBlock parser, look for @return
  59. if ( ( $docBlock = $method->getDocComment() ) ) {
  60. $matches = array();
  61. if ( preg_match_all( '/@(\w+)\s+(.*)\r?\n/m', $docBlock, $matches ) ) {
  62. $lines = array_combine( $matches[1], $matches[2] );
  63. if ( isset( $lines['return'] ) ) {
  64. $output->operator = '->';
  65. # since we're outputting code, assumption that the string is utf8 is most likely correct
  66. # and saves resources
  67. $output->type = self::escape( $lines['return'], 'UTF-8' );
  68. }
  69. }
  70. }
  71. $output->name = ( $method->returnsReference() ? '&' : '' ) . $method->getName() . '('
  72. . implode( ', ', $params ) . ')';
  73. $output->access = $access;
  74. if ( is_string( $docBlock ) ) {
  75. $lines = array();
  76. foreach ( explode( "\n", $docBlock ) as $line ) {
  77. $line = trim( $line );
  78. if ( in_array( $line, array( '/**', '/*', '*/' ) ) ) {
  79. continue;
  80. } elseif ( strpos( $line, '*' ) === 0 ) {
  81. $line = substr( $line, 1 );
  82. }
  83. $lines[] = self::escape( trim( $line ), 'UTF-8' );
  84. }
  85. $output->extendedValue = implode( "\n", $lines ) . "\n\n";
  86. }
  87. $declaringClass = $method->getDeclaringClass();
  88. $declaringClassName = $declaringClass->getName();
  89. if ( $declaringClassName !== $className ) {
  90. $output->extendedValue .= "<small>Inherited from <i>{$declaringClassName}</i></small>\n";
  91. }
  92. $fileName = Kint::shortenPath( $method->getFileName() ) . ':' . $method->getStartLine();
  93. $output->extendedValue .= "<small>Defined in {$fileName}</small>";
  94. $sortName = $access . $method->getName();
  95. if ( $method->isPrivate() ) {
  96. $private[ $sortName ] = $output;
  97. } elseif ( $method->isProtected() ) {
  98. $protected[ $sortName ] = $output;
  99. } else {
  100. $public[ $sortName ] = $output;
  101. }
  102. }
  103. if ( !$private && !$protected && !$public ) {
  104. self::$cache[ $className ] = false;
  105. }
  106. ksort( $public );
  107. ksort( $protected );
  108. ksort( $private );
  109. self::$cache[ $className ] = $public + $protected + $private;
  110. }
  111. if ( count( self::$cache[ $className ] ) === 0 ) {
  112. return false;
  113. }
  114. $this->value = self::$cache[ $className ];
  115. $this->type = 'Available methods';
  116. $this->size = count( self::$cache[ $className ] );
  117. }
  118. }