/lib/Mage/Archive.php

https://github.com/rgranadino/magento-mirror · PHP · 222 lines · 109 code · 15 blank · 98 comment · 25 complexity · f7745fb5794efd8e0a2adaef4a3f6f12 MD5 · raw file

  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Archive
  23. * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Class to work with archives
  28. *
  29. * @category Mage
  30. * @package Mage_Archive
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Archive
  34. {
  35. /**
  36. * Archiver is used for compress.
  37. */
  38. const DEFAULT_ARCHIVER = 'gz';
  39. /**
  40. * Default packer for directory.
  41. */
  42. const TAPE_ARCHIVER = 'tar';
  43. /**
  44. * Current archiver is used for compress.
  45. *
  46. * @var Mage_Archiver_Tar|Mage_Archiver_Gz|Mage_Archiver_Bz
  47. */
  48. protected $_archiver=null;
  49. /**
  50. * Accessible formats for compress.
  51. *
  52. * @var array
  53. */
  54. protected $_formats = array(
  55. 'tar' => 'tar',
  56. 'gz' => 'gz',
  57. 'gzip' => 'gz',
  58. 'tgz' => 'tar.gz',
  59. 'tgzip' => 'tar.gz',
  60. 'bz' => 'bz',
  61. 'bzip' => 'bz',
  62. 'bzip2' => 'bz',
  63. 'bz2' => 'bz',
  64. 'tbz' => 'tar.bz',
  65. 'tbzip' => 'tar.bz',
  66. 'tbz2' => 'tar.bz',
  67. 'tbzip2' => 'tar.bz');
  68. /**
  69. * Create object of current archiver by $extension.
  70. *
  71. * @param string $extension
  72. * @return Mage_Archiver_Tar|Mage_Archiver_Gz|Mage_Archiver_Bz
  73. */
  74. protected function _getArchiver($extension)
  75. {
  76. if(array_key_exists(strtolower($extension), $this->_formats)) {
  77. $format = $this->_formats[$extension];
  78. } else {
  79. $format = self::DEFAULT_ARCHIVER;
  80. }
  81. $class = 'Mage_Archive_'.ucfirst($format);
  82. $this->_archiver = new $class();
  83. return $this->_archiver;
  84. }
  85. /**
  86. * Split current format to list of archivers.
  87. *
  88. * @param string $source
  89. * @return array
  90. */
  91. protected function _getArchivers($source)
  92. {
  93. $ext = pathinfo($source, PATHINFO_EXTENSION);
  94. if(!isset($this->_formats[$ext])) {
  95. return array();
  96. }
  97. $format = $this->_formats[$ext];
  98. if ($format) {
  99. $archivers = explode('.', $format);
  100. return $archivers;
  101. }
  102. return array();
  103. }
  104. /**
  105. * Pack file or directory to archivers are parsed from extension.
  106. *
  107. * @param string $source
  108. * @param string $destination
  109. * @param boolean $skipRoot skip first level parent
  110. * @return string Path to file
  111. */
  112. public function pack($source, $destination='packed.tgz', $skipRoot=false)
  113. {
  114. $archivers = $this->_getArchivers($destination);
  115. $interimSource = '';
  116. for ($i=0; $i<count($archivers); $i++ ) {
  117. if ($i == (count($archivers) - 1)) {
  118. $packed = $destination;
  119. } else {
  120. $packed = dirname($destination) . DS . '~tmp-'. microtime(true) . $archivers[$i] . '.' . $archivers[$i];
  121. }
  122. $source = $this->_getArchiver($archivers[$i])->pack($source, $packed, $skipRoot);
  123. if ($interimSource && $i < count($archivers)) {
  124. unlink($interimSource);
  125. }
  126. $interimSource = $source;
  127. }
  128. return $source;
  129. }
  130. /**
  131. * Unpack file from archivers are parsed from extension.
  132. * If $tillTar == true unpack file from archivers till
  133. * meet TAR archiver.
  134. *
  135. * @param string $source
  136. * @param string $destination
  137. * @param boolean $tillTar
  138. * @return string Path to file
  139. */
  140. public function unpack($source, $destination='.', $tillTar=false, $clearInterm = true)
  141. {
  142. $archivers = $this->_getArchivers($source);
  143. $interimSource = '';
  144. for ($i=count($archivers)-1; $i>=0; $i--) {
  145. if ($tillTar && $archivers[$i] == self::TAPE_ARCHIVER) {
  146. break;
  147. }
  148. if ($i == 0) {
  149. $packed = rtrim($destination, DS) . DS;
  150. } else {
  151. $packed = rtrim($destination, DS) . DS . '~tmp-'. microtime(true) . $archivers[$i-1] . '.' . $archivers[$i-1];
  152. }
  153. $source = $this->_getArchiver($archivers[$i])->unpack($source, $packed);
  154. //var_dump($packed, $source);
  155. if ($clearInterm && $interimSource && $i >= 0) {
  156. unlink($interimSource);
  157. }
  158. $interimSource = $source;
  159. }
  160. return $source;
  161. }
  162. /**
  163. * Extract one file from TAR (Tape Archiver).
  164. *
  165. * @param string $file
  166. * @param string $source
  167. * @param string $destination
  168. * @return string Path to file
  169. */
  170. public function extract($file, $source, $destination='.')
  171. {
  172. $tarFile = $this->unpack($source, $destination, true);
  173. $resFile = $this->_getArchiver(self::TAPE_ARCHIVER)->extract($file, $tarFile, $destination);
  174. if (!$this->isTar($source)) {
  175. unlink($tarFile);
  176. }
  177. return $resFile;
  178. }
  179. /**
  180. * Check file is archive.
  181. *
  182. * @param string $file
  183. * @return boolean
  184. */
  185. public function isArchive($file)
  186. {
  187. $archivers = $this->_getArchivers($file);
  188. if (count($archivers)) {
  189. return true;
  190. }
  191. return false;
  192. }
  193. /**
  194. * Check file is TAR.
  195. *
  196. * @param mixed $file
  197. * @return boolean
  198. */
  199. public function isTar($file)
  200. {
  201. $archivers = $this->_getArchivers($file);
  202. if (count($archivers)==1 && $archivers[0] == self::TAPE_ARCHIVER) {
  203. return true;
  204. }
  205. return false;
  206. }
  207. }