PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Zend/Filter/Compress/Zip.php

https://bitbucket.org/andrewjleavitt/magestudy
PHP | 355 lines | 277 code | 12 blank | 66 comment | 15 complexity | f1a35886800405c54ea885653b66c20e MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  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@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Filter
  17. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: Zip.php 20126 2010-01-07 18:10:58Z ralph $
  20. */
  21. /**
  22. * @see Zend_Filter_Compress_CompressAbstract
  23. */
  24. #require_once 'Zend/Filter/Compress/CompressAbstract.php';
  25. /**
  26. * Compression adapter for zip
  27. *
  28. * @category Zend
  29. * @package Zend_Filter
  30. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Filter_Compress_Zip extends Zend_Filter_Compress_CompressAbstract
  34. {
  35. /**
  36. * Compression Options
  37. * array(
  38. * 'archive' => Archive to use
  39. * 'password' => Password to use
  40. * 'target' => Target to write the files to
  41. * )
  42. *
  43. * @var array
  44. */
  45. protected $_options = array(
  46. 'archive' => null,
  47. 'target' => null,
  48. );
  49. /**
  50. * Class constructor
  51. *
  52. * @param string|array $options (Optional) Options to set
  53. */
  54. public function __construct($options = null)
  55. {
  56. if (!extension_loaded('zip')) {
  57. #require_once 'Zend/Filter/Exception.php';
  58. throw new Zend_Filter_Exception('This filter needs the zip extension');
  59. }
  60. parent::__construct($options);
  61. }
  62. /**
  63. * Returns the set archive
  64. *
  65. * @return string
  66. */
  67. public function getArchive()
  68. {
  69. return $this->_options['archive'];
  70. }
  71. /**
  72. * Sets the archive to use for de-/compression
  73. *
  74. * @param string $archive Archive to use
  75. * @return Zend_Filter_Compress_Rar
  76. */
  77. public function setArchive($archive)
  78. {
  79. $archive = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $archive);
  80. $this->_options['archive'] = (string) $archive;
  81. return $this;
  82. }
  83. /**
  84. * Returns the set targetpath
  85. *
  86. * @return string
  87. */
  88. public function getTarget()
  89. {
  90. return $this->_options['target'];
  91. }
  92. /**
  93. * Sets the target to use
  94. *
  95. * @param string $target
  96. * @return Zend_Filter_Compress_Rar
  97. */
  98. public function setTarget($target)
  99. {
  100. if (!file_exists(dirname($target))) {
  101. #require_once 'Zend/Filter/Exception.php';
  102. throw new Zend_Filter_Exception("The directory '$target' does not exist");
  103. }
  104. $target = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $target);
  105. $this->_options['target'] = (string) $target;
  106. return $this;
  107. }
  108. /**
  109. * Compresses the given content
  110. *
  111. * @param string $content
  112. * @return string Compressed archive
  113. */
  114. public function compress($content)
  115. {
  116. $zip = new ZipArchive();
  117. $res = $zip->open($this->getArchive(), ZipArchive::CREATE | ZipArchive::OVERWRITE);
  118. if ($res !== true) {
  119. #require_once 'Zend/Filter/Exception.php';
  120. throw new Zend_Filter_Exception($this->_errorString($res));
  121. }
  122. if (file_exists($content)) {
  123. $content = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, realpath($content));
  124. $basename = substr($content, strrpos($content, DIRECTORY_SEPARATOR) + 1);
  125. if (is_dir($content)) {
  126. $index = strrpos($content, DIRECTORY_SEPARATOR) + 1;
  127. $content .= DIRECTORY_SEPARATOR;
  128. $stack = array($content);
  129. while (!empty($stack)) {
  130. $current = array_pop($stack);
  131. $files = array();
  132. $dir = dir($current);
  133. while (false !== ($node = $dir->read())) {
  134. if (($node == '.') || ($node == '..')) {
  135. continue;
  136. }
  137. if (is_dir($current . $node)) {
  138. array_push($stack, $current . $node . DIRECTORY_SEPARATOR);
  139. }
  140. if (is_file($current . $node)) {
  141. $files[] = $node;
  142. }
  143. }
  144. $local = substr($current, $index);
  145. $zip->addEmptyDir(substr($local, 0, -1));
  146. foreach ($files as $file) {
  147. $zip->addFile($current . $file, $local . $file);
  148. if ($res !== true) {
  149. #require_once 'Zend/Filter/Exception.php';
  150. throw new Zend_Filter_Exception($this->_errorString($res));
  151. }
  152. }
  153. }
  154. } else {
  155. $res = $zip->addFile($content, $basename);
  156. if ($res !== true) {
  157. #require_once 'Zend/Filter/Exception.php';
  158. throw new Zend_Filter_Exception($this->_errorString($res));
  159. }
  160. }
  161. } else {
  162. $file = $this->getTarget();
  163. if (!is_dir($file)) {
  164. $file = basename($file);
  165. } else {
  166. $file = "zip.tmp";
  167. }
  168. $res = $zip->addFromString($file, $content);
  169. if ($res !== true) {
  170. #require_once 'Zend/Filter/Exception.php';
  171. throw new Zend_Filter_Exception($this->_errorString($res));
  172. }
  173. }
  174. $zip->close();
  175. return $this->_options['archive'];
  176. }
  177. /**
  178. * Decompresses the given content
  179. *
  180. * @param string $content
  181. * @return string
  182. */
  183. public function decompress($content)
  184. {
  185. $archive = $this->getArchive();
  186. if (file_exists($content)) {
  187. $archive = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, realpath($content));
  188. } elseif (empty($archive) || !file_exists($archive)) {
  189. #require_once 'Zend/Filter/Exception.php';
  190. throw new Zend_Filter_Exception('ZIP Archive not found');
  191. }
  192. $zip = new ZipArchive();
  193. $res = $zip->open($archive);
  194. $target = $this->getTarget();
  195. if (!empty($target) && !is_dir($target)) {
  196. $target = dirname($target);
  197. }
  198. if (!empty($target)) {
  199. $target = rtrim($target, '/\\') . DIRECTORY_SEPARATOR;
  200. }
  201. if (empty($target) || !is_dir($target)) {
  202. #require_once 'Zend/Filter/Exception.php';
  203. throw new Zend_Filter_Exception('No target for ZIP decompression set');
  204. }
  205. if ($res !== true) {
  206. #require_once 'Zend/Filter/Exception.php';
  207. throw new Zend_Filter_Exception($this->_errorString($res));
  208. }
  209. if (version_compare(PHP_VERSION, '5.2.8', '<')) {
  210. for ($i = 0; $i < $zip->numFiles; $i++) {
  211. $statIndex = $zip->statIndex($i);
  212. $currName = $statIndex['name'];
  213. if (($currName{0} == '/') ||
  214. (substr($currName, 0, 2) == '..') ||
  215. (substr($currName, 0, 4) == './..')
  216. )
  217. {
  218. #require_once 'Zend/Filter/Exception.php';
  219. throw new Zend_Filter_Exception('Upward directory traversal was detected inside ' . $archive
  220. . ' please use PHP 5.2.8 or greater to take advantage of path resolution features of '
  221. . 'the zip extension in this decompress() method.'
  222. );
  223. }
  224. }
  225. }
  226. $res = @$zip->extractTo($target);
  227. if ($res !== true) {
  228. #require_once 'Zend/Filter/Exception.php';
  229. throw new Zend_Filter_Exception($this->_errorString($res));
  230. }
  231. $zip->close();
  232. return $target;
  233. }
  234. /**
  235. * Returns the proper string based on the given error constant
  236. *
  237. * @param string $error
  238. */
  239. protected function _errorString($error)
  240. {
  241. switch($error) {
  242. case ZipArchive::ER_MULTIDISK :
  243. return 'Multidisk ZIP Archives not supported';
  244. case ZipArchive::ER_RENAME :
  245. return 'Failed to rename the temporary file for ZIP';
  246. case ZipArchive::ER_CLOSE :
  247. return 'Failed to close the ZIP Archive';
  248. case ZipArchive::ER_SEEK :
  249. return 'Failure while seeking the ZIP Archive';
  250. case ZipArchive::ER_READ :
  251. return 'Failure while reading the ZIP Archive';
  252. case ZipArchive::ER_WRITE :
  253. return 'Failure while writing the ZIP Archive';
  254. case ZipArchive::ER_CRC :
  255. return 'CRC failure within the ZIP Archive';
  256. case ZipArchive::ER_ZIPCLOSED :
  257. return 'ZIP Archive already closed';
  258. case ZipArchive::ER_NOENT :
  259. return 'No such file within the ZIP Archive';
  260. case ZipArchive::ER_EXISTS :
  261. return 'ZIP Archive already exists';
  262. case ZipArchive::ER_OPEN :
  263. return 'Can not open ZIP Archive';
  264. case ZipArchive::ER_TMPOPEN :
  265. return 'Failure creating temporary ZIP Archive';
  266. case ZipArchive::ER_ZLIB :
  267. return 'ZLib Problem';
  268. case ZipArchive::ER_MEMORY :
  269. return 'Memory allocation problem while working on a ZIP Archive';
  270. case ZipArchive::ER_CHANGED :
  271. return 'ZIP Entry has been changed';
  272. case ZipArchive::ER_COMPNOTSUPP :
  273. return 'Compression method not supported within ZLib';
  274. case ZipArchive::ER_EOF :
  275. return 'Premature EOF within ZIP Archive';
  276. case ZipArchive::ER_INVAL :
  277. return 'Invalid argument for ZLIB';
  278. case ZipArchive::ER_NOZIP :
  279. return 'Given file is no zip archive';
  280. case ZipArchive::ER_INTERNAL :
  281. return 'Internal error while working on a ZIP Archive';
  282. case ZipArchive::ER_INCONS :
  283. return 'Inconsistent ZIP archive';
  284. case ZipArchive::ER_REMOVE :
  285. return 'Can not remove ZIP Archive';
  286. case ZipArchive::ER_DELETED :
  287. return 'ZIP Entry has been deleted';
  288. default :
  289. return 'Unknown error within ZIP Archive';
  290. }
  291. }
  292. /**
  293. * Returns the adapter name
  294. *
  295. * @return string
  296. */
  297. public function toString()
  298. {
  299. return 'Zip';
  300. }
  301. }