code_utilities.class.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. /**
  3. * Description of code_utilities
  4. *
  5. * @license see /license.txt
  6. * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
  7. */
  8. class CodeUtilities
  9. {
  10. const CLASS_PATTERN = '/(?:\s+class\s+[a-zA-Z_0-9\x7f-\xff]+\s*{)|(?:\s+class\s+[a-zA-Z_0-9\x7f-\xff]+\s*extends)|(?:\s+class\s+[a-zA-Z_0-9\x7f-\xff]+\s*implements)|(?:\s+interface\s+[a-zA-Z_0-9\x7f-\xff]+\s*{)|(?:\s+interface\s+[a-zA-Z_0-9\x7f-\xff]+\s*extends)/mi';
  11. const INLINE_COMMENT_PATTERN = '#//.*$#m';
  12. const MULTILINE_COMMENT_PATTERN = '#/\*.*?\*/#ms';
  13. const NAMESPACE_PATTERN = '/namespace\s*(.*);/';
  14. const IDENTIFIER_PATTERN = '/^[a-zA-Z_][a-zA-Z0-9_]*$/';
  15. static function remove_comments($content)
  16. {
  17. $content = preg_replace(self::INLINE_COMMENT_PATTERN, '', $content);
  18. $content = preg_replace(self::MULTILINE_COMMENT_PATTERN, '', $content);
  19. return $content;
  20. }
  21. /**
  22. * Returns the name of classes and interfaces contained in content.
  23. *
  24. * @param text $content
  25. * @return array
  26. */
  27. static function get_classes($content)
  28. {
  29. $result = array();
  30. $cls_pattern = self::CLASS_PATTERN;
  31. $content = self::remove_comments($content); //comments may contains class declaration we don't want to capture.
  32. $matches = array();
  33. if (preg_match_all($cls_pattern, $content, $matches))
  34. {
  35. $matches = reset($matches);
  36. foreach ($matches as $match)
  37. {
  38. $match = str_replace("\n", ' ', $match);
  39. $match = str_replace('{', ' ', $match);
  40. $words = explode(' ', $match);
  41. foreach ($words as $word)
  42. {
  43. $word = trim($word);
  44. //we capture the interface/class name with the current pattern
  45. if (strtolower($word) != 'class' && strtolower($word) != 'interface' && strtolower($word) != 'implements' && strtolower($word) != 'extends' && !empty($word))
  46. {
  47. $result[] = $word;
  48. break; //we only take the first name as we don't want to capture the name of the interface or of the parent class name
  49. }
  50. }
  51. }
  52. }
  53. return $result;
  54. }
  55. static function get_namespace($content)
  56. {
  57. $namespace_pattern = self::NAMESPACE_PATTERN;
  58. if (preg_match($namespace_pattern, $content, $matches))
  59. {
  60. $result = end($matches);
  61. if (self::is_valid_identifier($result))
  62. {
  63. return $result;
  64. }
  65. else
  66. {
  67. return false;
  68. }
  69. }
  70. else
  71. {
  72. return false;
  73. }
  74. }
  75. static function is_valid_identifier($name)
  76. {
  77. $pattern = self::IDENTIFIER_PATTERN;
  78. $r = preg_match($pattern, $name);
  79. return $r;
  80. }
  81. /**
  82. * Make path relative to root.
  83. *
  84. * @param string $root
  85. * @param string $path
  86. * @return string
  87. */
  88. static function relative_path($root, $path)
  89. {
  90. $path = realpath($path);
  91. $root = realpath($root);
  92. $path = str_ireplace($root, '', $path);
  93. $path = str_ireplace('\\', '/', $path);
  94. return $path;
  95. }
  96. }