filters.compression.inc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <?php
  2. /**
  3. * @file
  4. * A filter for compressing bckups with zip, gz bzip etc.
  5. */
  6. /**
  7. * A filter for compressing backup files.
  8. *
  9. * @ingroup backup_migrate_filters
  10. */
  11. class backup_migrate_filter_compression extends backup_migrate_filter {
  12. public $op_weights = array('backup' => 100, 'restore' => -100);
  13. /**
  14. * This function is called on a backup file after the backup has been completed.
  15. */
  16. public function backup($file, $settings) {
  17. return $this->_backup_migrate_file_compress($file, $settings);
  18. }
  19. /**
  20. * This function is called on a backup file before importing it.
  21. */
  22. public function restore($file, $settings) {
  23. return $this->_backup_migrate_file_decompress($file, $settings);
  24. }
  25. /**
  26. * Get the form for the settings for this filter.
  27. */
  28. public function backup_settings_default() {
  29. $options = $this->_backup_migrate_get_compression_form_item_options();
  30. return array('compression' => isset($options['gzip']) ? 'gzip' : 'none');
  31. }
  32. /**
  33. * Get the form for the settings for this filter.
  34. */
  35. public function backup_settings_form($settings) {
  36. $form = array();
  37. $compression_options = $this->_backup_migrate_get_compression_form_item_options();
  38. $form['file']['compression'] = array(
  39. "#type" => count($compression_options) > 1 ? "select" : 'value',
  40. "#title" => t("Compression"),
  41. "#options" => $compression_options,
  42. "#default_value" => $settings['compression'],
  43. );
  44. return $form;
  45. }
  46. /**
  47. * Return a list of backup filetypes.
  48. */
  49. public function file_types() {
  50. return array(
  51. "gzip" => array(
  52. "extension" => "gz",
  53. "filemime" => "application/x-gzip",
  54. "backup" => TRUE,
  55. "restore" => TRUE,
  56. ),
  57. "bzip" => array(
  58. "extension" => "bz",
  59. "filemime" => "application/x-bzip",
  60. "backup" => TRUE,
  61. "restore" => TRUE,
  62. ),
  63. "bzip2" => array(
  64. "extension" => "bz2",
  65. "filemime" => "application/x-bzip",
  66. "backup" => TRUE,
  67. "restore" => TRUE,
  68. ),
  69. "zip" => array(
  70. "extension" => "zip",
  71. "filemime" => "application/zip",
  72. "backup" => TRUE,
  73. "restore" => TRUE,
  74. ),
  75. );
  76. }
  77. /**
  78. * Get the compression options as an options array for a form item.
  79. */
  80. public function _backup_migrate_get_compression_form_item_options() {
  81. $compression_options = array("none" => t("No Compression"));
  82. if (@function_exists("gzencode")) {
  83. $compression_options['gzip'] = t("GZip");
  84. }
  85. if (@function_exists("bzcompress")) {
  86. $compression_options['bzip'] = t("BZip");
  87. }
  88. if (class_exists('ZipArchive')) {
  89. $compression_options['zip'] = t("Zip", array(), array('context' => 'compression format'));
  90. }
  91. return $compression_options;
  92. }
  93. /**
  94. * Gzip encode a file.
  95. */
  96. public function _backup_migrate_gzip_encode($source, $dest, $level = 9, $settings) {
  97. $success = FALSE;
  98. // Try command line gzip first.
  99. if (!empty($settings->filters['use_cli'])) {
  100. $success = backup_migrate_exec("gzip -c -$level %input > %dest", array('%input' => $source, '%dest' => $dest, '%level' => $level));
  101. }
  102. if (!$success && @function_exists("gzopen")) {
  103. if (($fp_out = gzopen($dest, 'wb' . $level)) && ($fp_in = fopen($source, 'rb'))) {
  104. while (!feof($fp_in)) {
  105. gzwrite($fp_out, fread($fp_in, 1024 * 512));
  106. }
  107. $success = TRUE;
  108. }
  109. @fclose($fp_in);
  110. @gzclose($fp_out);
  111. }
  112. return $success;
  113. }
  114. /**
  115. * Gzip decode a file.
  116. */
  117. public function _backup_migrate_gzip_decode($source, $dest, $settings) {
  118. $success = FALSE;
  119. if (!empty($settings->filters['use_cli'])) {
  120. $success = backup_migrate_exec("gzip -d -c %input > %dest", array('%input' => $source, '%dest' => $dest));
  121. }
  122. if (!$success && @function_exists("gzopen")) {
  123. if (($fp_out = fopen($dest, 'wb')) && ($fp_in = gzopen($source, 'rb'))) {
  124. while (!feof($fp_in)) {
  125. fwrite($fp_out, gzread($fp_in, 1024 * 512));
  126. }
  127. $success = TRUE;
  128. }
  129. @gzclose($fp_in);
  130. @fclose($fp_out);
  131. }
  132. return $success;
  133. }
  134. /**
  135. * Bzip encode a file.
  136. */
  137. public function _backup_migrate_bzip_encode($source, $dest) {
  138. $success = FALSE;
  139. if (@function_exists("bzopen")) {
  140. if (($fp_out = bzopen($dest, 'w')) && ($fp_in = fopen($source, 'rb'))) {
  141. while (!feof($fp_in)) {
  142. bzwrite($fp_out, fread($fp_in, 1024 * 512));
  143. }
  144. $success = TRUE;
  145. }
  146. else {
  147. $error = TRUE;
  148. }
  149. @fclose($fp_in);
  150. @bzclose($fp_out);
  151. }
  152. return $success;
  153. }
  154. /**
  155. * Bzip decode a file.
  156. */
  157. public function _backup_migrate_bzip_decode($source, $dest) {
  158. $success = FALSE;
  159. if (@function_exists("bzopen")) {
  160. if (($fp_out = fopen($dest, 'w')) && ($fp_in = bzopen($source, 'r'))) {
  161. while (!feof($fp_in)) {
  162. fwrite($fp_out, gzread($fp_in, 1024 * 512));
  163. }
  164. $success = TRUE;
  165. }
  166. else {
  167. $error = TRUE;
  168. }
  169. @bzclose($fp_in);
  170. @fclose($fp_out);
  171. }
  172. return $success;
  173. }
  174. /**
  175. * Zip encode a file.
  176. */
  177. public function _backup_migrate_zip_encode($source, $dest, $filename) {
  178. $success = FALSE;
  179. if (class_exists('ZipArchive')) {
  180. $zip = new ZipArchive();
  181. $res = $zip->open($dest, constant("ZipArchive::CREATE"));
  182. if ($res === TRUE) {
  183. $zip->addFile($source, $filename);
  184. $success = $zip->close();
  185. }
  186. }
  187. return $success;
  188. }
  189. /**
  190. * Zip decode a file.
  191. */
  192. public function _backup_migrate_zip_decode($source, $dest) {
  193. $success = FALSE;
  194. if (class_exists('ZipArchive')) {
  195. $zip = new ZipArchive();
  196. if (($fp_out = fopen($dest, "w")) && ($zip->open($source))) {
  197. $filename = ($zip->getNameIndex(0));
  198. if ($fp_in = $zip->getStream($filename)) {
  199. while (!feof($fp_in)) {
  200. fwrite($fp_out, fread($fp_in, 1024 * 512));
  201. }
  202. $success = TRUE;
  203. }
  204. }
  205. @fclose($fp_in);
  206. @fclose($fp_out);
  207. }
  208. return $success;
  209. }
  210. /**
  211. * Compress a file with the given settings.
  212. * Also updates settings to reflect new file mime and file extension.
  213. */
  214. public function _backup_migrate_file_compress($file, $settings) {
  215. switch ($settings->filters['compression']) {
  216. case "gzip":
  217. $from = $file->push_type('gzip');
  218. if (!$success = $this->_backup_migrate_gzip_encode($from, $file->filepath(), 9, $settings)) {
  219. $file = NULL;
  220. }
  221. break;
  222. case "bzip":
  223. $from = $file->push_type('bzip2');
  224. if (!$success = $this->_backup_migrate_bzip_encode($from, $file->filepath())) {
  225. $file = NULL;
  226. }
  227. break;
  228. case "zip":
  229. $filename = $file->filename();
  230. $from = $file->push_type('zip');
  231. if (!$success = $this->_backup_migrate_zip_encode($from, $file->filepath(), $filename)) {
  232. $file = NULL;
  233. }
  234. break;
  235. }
  236. if (!$file) {
  237. _backup_migrate_message("Could not compress backup file. Try backing up without compression.", array(), 'error');
  238. }
  239. return $file;
  240. }
  241. /**
  242. * Decompress a file with the given settings.
  243. * Also updates settings to reflect new file mime and file extension.
  244. */
  245. public function _backup_migrate_file_decompress($file, $settings) {
  246. $success = FALSE;
  247. switch ($file->type_id()) {
  248. case "gzip":
  249. $from = $file->pop_type();
  250. $success = $this->_backup_migrate_gzip_decode($from->filepath(), $file->filepath(), $settings);
  251. break;
  252. case "bzip":
  253. case "bzip2":
  254. $from = $file->pop_type();
  255. $success = $this->_backup_migrate_bzip_decode($from->filepath(), $file->filepath());
  256. break;
  257. case "zip":
  258. $from = $file->pop_type();
  259. $success = $this->_backup_migrate_zip_decode($from->filepath(), $file->filepath());
  260. break;
  261. default:
  262. return $file;
  263. break;
  264. }
  265. if (!$success) {
  266. _backup_migrate_message("Could not decompress backup file. Please check that the file is valid.", array(), 'error');
  267. }
  268. return $success ? $file : NULL;
  269. }
  270. }