generate_filelist_xml.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #!/usr/bin/env php
  2. <?php
  3. /* Copyright (C) 2015-2017 Laurent Destailleur <eldy@users.sourceforge.net>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * \file build/generate_filelist_xml.php
  20. * \ingroup dev
  21. * \brief This script create a xml checksum file
  22. */
  23. if (!defined('NOREQUIREDB')) {
  24. define('NOREQUIREDB', '1'); // Do not create database handler $db
  25. }
  26. $sapi_type = php_sapi_name();
  27. $script_file = basename(__FILE__);
  28. $path = dirname(__FILE__).'/';
  29. // Test if batch mode
  30. if (substr($sapi_type, 0, 3) == 'cgi') {
  31. echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n";
  32. exit(1);
  33. }
  34. require_once $path."../htdocs/master.inc.php";
  35. require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
  36. /*
  37. * Main
  38. */
  39. $includecustom = 0;
  40. $includeconstants = array();
  41. $buildzip = 0;
  42. if (empty($argv[1])) {
  43. print "Usage: ".$script_file." release=autostable|auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] [buildzip=1]\n";
  44. print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=FR:INVOICE_CAN_ALWAYS_BE_REMOVED:0 includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n";
  45. exit(1);
  46. }
  47. $i = 0;
  48. $result = array();
  49. while ($i < $argc) {
  50. if (!empty($argv[$i])) {
  51. parse_str($argv[$i], $result); // set all params $release, $includecustom, $includeconstant, $buildzip ...
  52. }
  53. if (!empty($result["release"])) {
  54. $release = $result["release"];
  55. }
  56. if (!empty($result["includecustom"])) {
  57. $includecustom = $result["includecustom"];
  58. }
  59. if (!empty($result["includeconstant"])) {
  60. $includeconstants[$i] = $result["includeconstant"];
  61. }
  62. if (!empty($result["buildzip"])) {
  63. $buildzip = 1;
  64. }
  65. if (preg_match('/includeconstant=/', strval($argv[$i]))) {
  66. $tmp = explode(':', $result['includeconstant'], 3); // $includeconstant has been set with previous parse_str()
  67. if (count($tmp) != 3) {
  68. print "Error: Bad parameter includeconstant=".$result['includeconstant'] ."\n";
  69. exit -1;
  70. }
  71. $includeconstants[$tmp[0]][$tmp[1]] = $tmp[2];
  72. }
  73. $i++;
  74. }
  75. if (empty($release)) {
  76. print "Error: Missing release parameter\n";
  77. print "Usage: ".$script_file." release=autostable|auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
  78. exit(2);
  79. }
  80. $savrelease = $release;
  81. // If release is auto, we take current version
  82. $tmpver = explode('-', $release, 2);
  83. if ($tmpver[0] == 'auto' || $tmpver[0] == 'autostable') {
  84. $release = DOL_VERSION;
  85. if ($tmpver[1] && $tmpver[0] == 'auto') {
  86. $release .= '-'.$tmpver[1];
  87. }
  88. }
  89. if (empty($includecustom)) {
  90. $tmpverbis = explode('-', $release, 2);
  91. if (empty($tmpverbis[1]) || $tmpver[0] == 'autostable') {
  92. if (DOL_VERSION != $tmpverbis[0] && $savrelease != 'auto') {
  93. print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
  94. print "Usage: ".$script_file." release=autostable|auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
  95. exit(3);
  96. }
  97. } else {
  98. $tmpverter = explode('-', DOL_VERSION, 2);
  99. if ($tmpverter[0] != $tmpverbis[0]) {
  100. print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must have value without prefix ('.$tmpverter[0].') that is exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
  101. print "Usage: ".$script_file." release=autostable|auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
  102. exit(4);
  103. }
  104. }
  105. } else {
  106. if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'-/', $release)) {
  107. print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parameter (ex: '.DOL_VERSION.'-mydistrib).'."\n";
  108. print "Usage: ".$script_file." release=autostable|auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
  109. exit(5);
  110. }
  111. }
  112. print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
  113. print "Release : ".$release."\n";
  114. print "Include custom in signature : ".$includecustom."\n";
  115. print "Include constants in signature : ";
  116. foreach ($includeconstants as $countrycode => $tmp) {
  117. foreach ($tmp as $constname => $constvalue) {
  118. print $constname.'='.$constvalue." ";
  119. }
  120. }
  121. print "\n";
  122. //$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
  123. $outputdir = dirname(dirname(__FILE__)).'/htdocs/install';
  124. print 'Delete current files '.$outputdir.'/filelist*.xml*'."\n";
  125. dol_delete_file($outputdir.'/filelist*.xml*', 0, 1, 1);
  126. $checksumconcat = array();
  127. $outputfile = $outputdir.'/filelist-'.$release.'.xml';
  128. $fp = fopen($outputfile, 'w');
  129. if (empty($fp)) {
  130. print 'Failed to open file '.$outputfile."\n";
  131. exit(6);
  132. }
  133. fputs($fp, '<?xml version="1.0" encoding="UTF-8" ?>'."\n");
  134. fputs($fp, '<checksum_list version="'.$release.'" date="'.dol_print_date(dol_now(), 'dayhourrfc').'" generator="'.$script_file.'">'."\n");
  135. foreach ($includeconstants as $countrycode => $tmp) {
  136. fputs($fp, '<dolibarr_constants country="'.$countrycode.'">'."\n");
  137. foreach ($tmp as $constname => $constvalue) {
  138. $valueforchecksum = (empty($constvalue) ? '0' : $constvalue);
  139. $checksumconcat[] = $valueforchecksum;
  140. fputs($fp, ' <constant name="'.$constname.'">'.$valueforchecksum.'</constant>'."\n");
  141. }
  142. fputs($fp, '</dolibarr_constants>'."\n");
  143. }
  144. fputs($fp, '<dolibarr_htdocs_dir includecustom="'.$includecustom.'">'."\n");
  145. /*$dir_iterator1 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../htdocs/');
  146. $iterator1 = new RecursiveIteratorIterator($dir_iterator1);
  147. // Need to ignore document custom etc. Note: this also ignore natively symbolic links.
  148. $files = new RegexIterator($iterator1, '#^(?:[A-Z]:)?(?:/(?!(?:'.($includecustom?'':'custom\/|').'documents\/|conf\/|install\/))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i');
  149. */
  150. // Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
  151. $regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
  152. $regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
  153. $files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
  154. $dir = '';
  155. $needtoclose = 0;
  156. foreach ($files as $filetmp) {
  157. $file = $filetmp['fullname'];
  158. //$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
  159. $newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
  160. if ($newdir != $dir) {
  161. if ($needtoclose) {
  162. fputs($fp, ' </dir>'."\n");
  163. }
  164. fputs($fp, ' <dir name="'.$newdir.'">'."\n");
  165. $dir = $newdir;
  166. $needtoclose = 1;
  167. }
  168. if (filetype($file) == "file") {
  169. $md5 = md5_file($file);
  170. $checksumconcat[] = $md5;
  171. fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
  172. }
  173. }
  174. fputs($fp, ' </dir>'."\n");
  175. fputs($fp, '</dolibarr_htdocs_dir>'."\n");
  176. asort($checksumconcat); // Sort list of checksum
  177. //var_dump($checksumconcat);
  178. fputs($fp, '<dolibarr_htdocs_dir_checksum>'."\n");
  179. fputs($fp, md5(join(',', $checksumconcat))."\n");
  180. fputs($fp, '</dolibarr_htdocs_dir_checksum>'."\n");
  181. $checksumconcat = array();
  182. fputs($fp, '<dolibarr_script_dir version="'.$release.'">'."\n");
  183. // TODO Replace RecursiveDirectoryIterator with dol_dir_list
  184. /*$dir_iterator2 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../scripts/');
  185. $iterator2 = new RecursiveIteratorIterator($dir_iterator2);
  186. // Need to ignore document custom etc. Note: this also ignore natively symbolic links.
  187. $files = new RegexIterator($iterator2, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i');
  188. */
  189. $regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
  190. $regextoexclude = '(custom|documents|conf|install)$'; // Exclude dirs
  191. $files = dol_dir_list(dirname(__FILE__).'/../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
  192. $dir = '';
  193. $needtoclose = 0;
  194. foreach ($files as $filetmp) {
  195. $file = $filetmp['fullname'];
  196. //$newdir = str_replace(dirname(__FILE__).'/../scripts', '', dirname($file));
  197. $newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
  198. $newdir = str_replace(dirname(__FILE__).'/../scripts', '', dirname($file));
  199. if ($newdir != $dir) {
  200. if ($needtoclose) {
  201. fputs($fp, ' </dir>'."\n");
  202. }
  203. fputs($fp, ' <dir name="'.$newdir.'" >'."\n");
  204. $dir = $newdir;
  205. $needtoclose = 1;
  206. }
  207. if (filetype($file) == "file") {
  208. $md5 = md5_file($file);
  209. $checksumconcat[] = $md5;
  210. fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
  211. }
  212. }
  213. fputs($fp, ' </dir>'."\n");
  214. fputs($fp, '</dolibarr_script_dir>'."\n");
  215. asort($checksumconcat); // Sort list of checksum
  216. fputs($fp, '<dolibarr_script_dir_checksum>'."\n");
  217. fputs($fp, md5(join(',', $checksumconcat))."\n");
  218. fputs($fp, '</dolibarr_script_dir_checksum>'."\n");
  219. fputs($fp, '</checksum_list>'."\n");
  220. fclose($fp);
  221. if (empty($buildzip)) {
  222. print "File ".$outputfile." generated\n";
  223. } else {
  224. if ($buildzip == '1' || $buildzip == 'zip') {
  225. $result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip');
  226. if ($result > 0) {
  227. dol_delete_file($outputfile);
  228. print "File ".$outputfile.".zip generated\n";
  229. }
  230. } elseif ($buildzip == '2' || $buildzip == 'gz') {
  231. $result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz');
  232. if ($result > 0) {
  233. dol_delete_file($outputfile);
  234. print "File ".$outputfile.".gz generated\n";
  235. }
  236. }
  237. }
  238. exit(0);