You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.1 KiB

  1. <?php
  2. /**
  3. * Generates array of classes for autoload
  4. *
  5. * @copyright NetMonsters <team@netmonsters.ru>
  6. * @link http://netmonsters.ru
  7. * @package Majestic
  8. * @subpackage util
  9. * @since 2010-02-24
  10. * @version SVN: $Id$
  11. * @filesource $URL$
  12. */
  13. /**
  14. * @todo Refactoring writing, locking
  15. */
  16. class AutoloadBuilder
  17. {
  18. protected $autoload;
  19. protected $dirs;
  20. protected $exclude;
  21. protected $handler;
  22. protected $regex = '/(class|interface) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/';
  23. public function __construct($autoload, $dirs = array(), $exclude = array())
  24. {
  25. $this->autoload = $autoload;
  26. $this->dirs = $dirs;
  27. $this->exclude = $exclude;
  28. }
  29. public function build()
  30. {
  31. $this->openAutoload();
  32. // for dublicates check
  33. $classes = array();
  34. foreach ($this->dirs as $dir) {
  35. $iterator = new RecursiveIteratorIterator(
  36. new RecursiveDirectoryIterator($dir),
  37. RecursiveIteratorIterator::LEAVES_ONLY
  38. );
  39. foreach ($iterator as $file) {
  40. if($this->isExcluded($file->getRealPath())) {
  41. continue;
  42. }
  43. // skip non php files
  44. $e = explode('.', $file->getFileName());
  45. if ((end($e) !== 'php') || $this->rightSubstr($file->getFileName(), 8) == 'Test.php') {
  46. continue;
  47. }
  48. $content = file_get_contents($file->getRealPath());
  49. $matches = array();
  50. $relative_path = substr($file->getRealPath(), strlen(PATH));
  51. if (preg_match_all($this->regex, $content, $matches, PREG_SET_ORDER)) {
  52. foreach ($matches as $match) {
  53. if (array_key_exists($match[2], $classes)) {
  54. continue;
  55. }
  56. $string = "'{$match[2]}'=>'" . $relative_path . "',\n";
  57. $this->write($string);
  58. $classes[$match[2]] = $file->getRealPath();
  59. }
  60. }
  61. }
  62. }
  63. $this->closeAutoload();
  64. }
  65. protected function isExcluded($file)
  66. {
  67. foreach ($this->exclude as $dir) {
  68. if (stripos($file, PATH . $dir) === 0) {
  69. return true;
  70. }
  71. }
  72. return false;
  73. }
  74. protected function openAutoload()
  75. {
  76. $this->write("<?php\n// This file is autogenerated by \n// " . __FILE__ . " script.\nreturn array(\n");
  77. }
  78. protected function closeAutoload()
  79. {
  80. if ($this->write(');')) {
  81. fclose($this->handler);
  82. }
  83. }
  84. protected function write($string)
  85. {
  86. if (!$this->handler) {
  87. if (!$this->handler = fopen($this->autoload, 'w')) {
  88. trigger_error("{$this->autoload} is not writable", E_USER_ERROR);
  89. }
  90. }
  91. return (bool) fwrite($this->handler, $string);
  92. }
  93. protected function rightSubstr($string, $nchars)
  94. {
  95. $right = substr($string, strlen($string) - $nchars, $nchars);
  96. return $right;
  97. }
  98. }