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.

112 lines
3.3 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. */
  11. /**
  12. * @todo Refactoring writing, locking
  13. */
  14. class AutoloadBuilder
  15. {
  16. protected $autoload;
  17. protected $dirs;
  18. protected $exclude;
  19. protected $handler;
  20. protected $regex = '/(class|interface) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/';
  21. public function __construct($autoload, $dirs = array(), $exclude = array())
  22. {
  23. $this->autoload = $autoload;
  24. $this->dirs = $dirs;
  25. $this->exclude = $exclude;
  26. }
  27. public function build()
  28. {
  29. $array_string = "<?php\n// This file is autogenerated by \n// " . __FILE__ . " script.\nreturn array(\n";
  30. // for dublicates check
  31. $classes = array();
  32. foreach ($this->dirs as $dir) {
  33. $iterator = new RecursiveIteratorIterator(
  34. new RecursiveDirectoryIterator($dir),
  35. RecursiveIteratorIterator::LEAVES_ONLY
  36. );
  37. foreach ($iterator as $file) {
  38. if ($this->isExcluded($file->getRealPath())) {
  39. continue;
  40. }
  41. // skip non php files
  42. $e = explode('.', $file->getFileName());
  43. if ((end($e) !== 'php') || $this->rightSubstr($file->getFileName(), 8) == 'Test.php') {
  44. continue;
  45. }
  46. $content = file_get_contents($file->getRealPath());
  47. $matches = array();
  48. $relative_path = substr($file->getRealPath(), strlen(PATH));
  49. if (preg_match_all($this->regex, $content, $matches, PREG_SET_ORDER)) {
  50. foreach ($matches as $match) {
  51. if (array_key_exists($match[2], $classes)) {
  52. continue;
  53. }
  54. $array_string .= "'{$match[2]}'=>'" . $relative_path . "',\n";
  55. $classes[$match[2]] = $file->getRealPath();
  56. }
  57. }
  58. }
  59. unset($file); // without this line trigger_error throws 'Serialization of 'SplFileInfo' is not allowed' exception under PHPUnit
  60. }
  61. $array_string .= ');';
  62. $this->writeAutoload($array_string);
  63. if (!$this->isFileConsistent()) {
  64. unlink($this->autoload);
  65. trigger_error("Error while generating autoload file.", E_USER_ERROR);
  66. }
  67. }
  68. protected function writeAutoload($string)
  69. {
  70. $pid = getmypid();
  71. $tmp = dirname($this->autoload) . '/' . md5(time() + $pid);
  72. file_put_contents($tmp, $string);
  73. rename($tmp, $this->autoload);
  74. }
  75. protected function isFileConsistent()
  76. {
  77. $autoload_array = include($this->autoload);
  78. if (!is_array($autoload_array)) {
  79. return false;
  80. }
  81. return true;
  82. }
  83. protected function isExcluded($file)
  84. {
  85. foreach ($this->exclude as $dir) {
  86. if (stripos($file, $dir) === 0) {
  87. return true;
  88. }
  89. }
  90. return false;
  91. }
  92. protected function rightSubstr($string, $nchars)
  93. {
  94. $right = substr($string, strlen($string) - $nchars, $nchars);
  95. return $right;
  96. }
  97. }