generate-standalone.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #!/usr/bin/php
  2. <?php
  3. chdir(dirname(__FILE__));
  4. require_once 'common.php';
  5. assertCli();
  6. /**
  7. * @file
  8. * Compiles all of HTML Purifier's library files into one big file
  9. * named HTMLPurifier.standalone.php. This is usually called during the
  10. * release process.
  11. */
  12. /**
  13. * Global hash that tracks already loaded includes
  14. */
  15. $GLOBALS['loaded'] = array();
  16. /**
  17. * Custom FSTools for this script that overloads some behavior
  18. * @warning The overloading of copy() is not necessarily global for
  19. * this script. Watch out!
  20. */
  21. class MergeLibraryFSTools extends FSTools
  22. {
  23. public function copyable($entry)
  24. {
  25. // Skip hidden files
  26. if ($entry[0] == '.') {
  27. return false;
  28. }
  29. return true;
  30. }
  31. public function copy($source, $dest)
  32. {
  33. copy_and_remove_includes($source, $dest);
  34. }
  35. }
  36. $FS = new MergeLibraryFSTools();
  37. /**
  38. * Replaces the includes inside PHP source code with the corresponding
  39. * source.
  40. * @param string $text PHP source code to replace includes from
  41. */
  42. function replace_includes($text)
  43. {
  44. // also remove vim modelines
  45. return preg_replace_callback(
  46. "/require(?:_once)? ['\"]([^'\"]+)['\"];/",
  47. 'replace_includes_callback',
  48. $text
  49. );
  50. }
  51. /**
  52. * Removes leading PHP tags from included files. Assumes that there is
  53. * no trailing tag. Also removes vim modelines.
  54. * @note This is safe for files that have internal <?php
  55. * @param string $text Text to have leading PHP tag from
  56. */
  57. function remove_php_tags($text)
  58. {
  59. $text = preg_replace('#// vim:.+#', '', $text);
  60. return substr($text, 5);
  61. }
  62. /**
  63. * Copies the contents of a directory to the standalone directory
  64. * @param string $dir Directory to copy
  65. */
  66. function make_dir_standalone($dir)
  67. {
  68. global $FS;
  69. return $FS->copyr($dir, 'standalone/' . $dir);
  70. }
  71. /**
  72. * Copies the contents of a file to the standalone directory
  73. * @param string $file File to copy
  74. */
  75. function make_file_standalone($file)
  76. {
  77. global $FS;
  78. $FS->mkdirr('standalone/' . dirname($file));
  79. copy_and_remove_includes($file, 'standalone/' . $file);
  80. return true;
  81. }
  82. /**
  83. * Copies a file to another location recursively, if it is a PHP file
  84. * remove includes
  85. * @param string $file Original file
  86. * @param string $sfile New location of file
  87. */
  88. function copy_and_remove_includes($file, $sfile)
  89. {
  90. $contents = file_get_contents($file);
  91. if (strrchr($file, '.') === '.php') $contents = replace_includes($contents);
  92. return file_put_contents($sfile, $contents);
  93. }
  94. /**
  95. * @param $matches preg_replace_callback matches array, where index 1
  96. * is the filename to include
  97. */
  98. function replace_includes_callback($matches)
  99. {
  100. $file = $matches[1];
  101. $preserve = array(
  102. // PEAR (external)
  103. 'XML/HTMLSax3.php' => 1
  104. );
  105. if (isset($preserve[$file])) {
  106. return $matches[0];
  107. }
  108. if (isset($GLOBALS['loaded'][$file])) return '';
  109. $GLOBALS['loaded'][$file] = true;
  110. return replace_includes(remove_php_tags(file_get_contents($file)));
  111. }
  112. echo 'Generating includes file... ';
  113. shell_exec('php generate-includes.php');
  114. echo "done!\n";
  115. chdir(dirname(__FILE__) . '/../library/');
  116. echo 'Creating full file...';
  117. $contents = replace_includes(file_get_contents('HTMLPurifier.includes.php'));
  118. $contents = str_replace(
  119. // Note that bootstrap is now inside the standalone file
  120. "define('HTMLPURIFIER_PREFIX', realpath(dirname(__FILE__) . '/..'));",
  121. "define('HTMLPURIFIER_PREFIX', dirname(__FILE__) . '/standalone');
  122. set_include_path(HTMLPURIFIER_PREFIX . PATH_SEPARATOR . get_include_path());",
  123. $contents
  124. );
  125. file_put_contents('HTMLPurifier.standalone.php', $contents);
  126. echo ' done!' . PHP_EOL;
  127. echo 'Creating standalone directory...';
  128. $FS->rmdirr('standalone'); // ensure a clean copy
  129. // data files
  130. $FS->mkdirr('standalone/HTMLPurifier/DefinitionCache/Serializer');
  131. make_file_standalone('HTMLPurifier/EntityLookup/entities.ser');
  132. make_file_standalone('HTMLPurifier/ConfigSchema/schema.ser');
  133. // non-standard inclusion setup
  134. make_dir_standalone('HTMLPurifier/ConfigSchema');
  135. make_dir_standalone('HTMLPurifier/Language');
  136. make_dir_standalone('HTMLPurifier/Filter');
  137. make_dir_standalone('HTMLPurifier/Printer');
  138. make_file_standalone('HTMLPurifier/Printer.php');
  139. make_file_standalone('HTMLPurifier/Lexer/PH5P.php');
  140. echo ' done!' . PHP_EOL;
  141. // vim: et sw=4 sts=4