Lib_Mage - Version 1.7.0.0

Version Notes

1.7.0.0

Download this release

Release Info

Developer Magento Core Team
Extension Lib_Mage
Version 1.7.0.0
Comparing to
See all releases


Code changes from version 1.6.1.0 to 1.7.0.0

Files changed (37) hide show
  1. lib/Mage/Archive.php +5 -6
  2. lib/Mage/Archive/Abstract.php +8 -5
  3. lib/Mage/Archive/Bz.php +26 -16
  4. lib/Mage/Archive/Gz.php +26 -16
  5. lib/Mage/Archive/Helper/File.php +274 -0
  6. lib/Mage/Archive/Helper/File/Bz.php +92 -0
  7. lib/Mage/Archive/Helper/File/Gz.php +83 -0
  8. lib/Mage/Archive/Interface.php +2 -2
  9. lib/Mage/Archive/Tar.php +366 -50
  10. lib/Mage/Backup.php +59 -0
  11. lib/Mage/Backup/Abstract.php +318 -0
  12. lib/Mage/Backup/Archive/Tar.php +82 -0
  13. lib/Mage/Backup/Db.php +119 -0
  14. lib/Mage/Backup/Exception.php +36 -0
  15. lib/Mage/Backup/Exception/CantLoadSnapshot.php +36 -0
  16. lib/Mage/Backup/Exception/FtpConnectionFailed.php +36 -0
  17. lib/Mage/Backup/Exception/FtpValidationFailed.php +36 -0
  18. lib/Mage/Backup/Exception/NotEnoughFreeSpace.php +36 -0
  19. lib/Mage/Backup/Exception/NotEnoughPermissions.php +36 -0
  20. lib/Mage/Backup/Filesystem.php +284 -0
  21. lib/Mage/Backup/Filesystem/Helper.php +137 -0
  22. lib/Mage/Backup/Filesystem/Iterator/File.php +112 -0
  23. lib/Mage/Backup/Filesystem/Iterator/Filter.php +77 -0
  24. lib/Mage/Backup/Filesystem/Rollback/Abstract.php +57 -0
  25. lib/Mage/Backup/Filesystem/Rollback/Fs.php +78 -0
  26. lib/Mage/Backup/Filesystem/Rollback/Ftp.php +198 -0
  27. lib/Mage/Backup/Interface.php +88 -0
  28. lib/Mage/Backup/Media.php +99 -0
  29. lib/Mage/Backup/Nomedia.php +82 -0
  30. lib/Mage/Backup/Snapshot.php +140 -0
  31. lib/Mage/Connect/Ftp.php +2 -460
  32. lib/Mage/Connect/Packager.php +33 -29
  33. lib/Mage/Exception.php +3 -2
  34. lib/Mage/System/Args.php +4 -4
  35. lib/Mage/System/Dirs.php +1 -1
  36. lib/Mage/System/Ftp.php +509 -0
  37. package.xml +5 -5
lib/Mage/Archive.php CHANGED
@@ -20,7 +20,7 @@
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
 
@@ -143,7 +143,8 @@ class Mage_Archive
143
  *
144
  * @param string $source
145
  * @param string $destination
146
- * @param boolean $tillTar
 
147
  * @return string Path to file
148
  */
149
  public function unpack($source, $destination='.', $tillTar=false, $clearInterm = true)
@@ -160,9 +161,7 @@ class Mage_Archive
160
  $packed = rtrim($destination, DS) . DS . '~tmp-'. microtime(true) . $archivers[$i-1] . '.' . $archivers[$i-1];
161
  }
162
  $source = $this->_getArchiver($archivers[$i])->unpack($source, $packed);
163
-
164
- //var_dump($packed, $source);
165
-
166
  if ($clearInterm && $interimSource && $i >= 0) {
167
  unlink($interimSource);
168
  }
@@ -218,5 +217,5 @@ class Mage_Archive
218
  }
219
  return false;
220
  }
 
221
 
222
- }
20
  *
21
  * @category Mage
22
  * @package Mage_Archive
23
+ * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
143
  *
144
  * @param string $source
145
  * @param string $destination
146
+ * @param bool $tillTar
147
+ * @param bool $clearInterm
148
  * @return string Path to file
149
  */
150
  public function unpack($source, $destination='.', $tillTar=false, $clearInterm = true)
161
  $packed = rtrim($destination, DS) . DS . '~tmp-'. microtime(true) . $archivers[$i-1] . '.' . $archivers[$i-1];
162
  }
163
  $source = $this->_getArchiver($archivers[$i])->unpack($source, $packed);
164
+
 
 
165
  if ($clearInterm && $interimSource && $i >= 0) {
166
  unlink($interimSource);
167
  }
217
  }
218
  return false;
219
  }
220
+ }
221
 
 
lib/Mage/Archive/Abstract.php CHANGED
@@ -20,7 +20,7 @@
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
 
@@ -34,14 +34,16 @@
34
  class Mage_Archive_Abstract
35
  {
36
  /**
37
- * Write data to file. If file can't be opened,
38
  *
39
  * @param string $destination
40
  * @param string $data
41
  * @return boolean
 
42
  */
43
  protected function _writeFile($destination, $data)
44
  {
 
45
  if(false === file_put_contents($destination, $data)) {
46
  throw new Mage_Exception("Can't write to file: " . $destination);
47
  }
@@ -53,6 +55,7 @@ class Mage_Archive_Abstract
53
  *
54
  * @param string $source
55
  * @return string
 
56
  */
57
  protected function _readFile($source)
58
  {
@@ -70,7 +73,8 @@ class Mage_Archive_Abstract
70
  * Get file name from source (URI) without last extension.
71
  *
72
  * @param string $source
73
- * @return string
 
74
  */
75
  public function getFilename($source, $withExtension=false)
76
  {
@@ -80,5 +84,4 @@ class Mage_Archive_Abstract
80
  }
81
  return $file;
82
  }
83
-
84
- }
20
  *
21
  * @category Mage
22
  * @package Mage_Archive
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
34
  class Mage_Archive_Abstract
35
  {
36
  /**
37
+ * Write data to file. If file can't be opened - throw exception
38
  *
39
  * @param string $destination
40
  * @param string $data
41
  * @return boolean
42
+ * @throws Mage_Exception
43
  */
44
  protected function _writeFile($destination, $data)
45
  {
46
+ $destination = trim($destination);
47
  if(false === file_put_contents($destination, $data)) {
48
  throw new Mage_Exception("Can't write to file: " . $destination);
49
  }
55
  *
56
  * @param string $source
57
  * @return string
58
+ * @throws Mage_Exception
59
  */
60
  protected function _readFile($source)
61
  {
73
  * Get file name from source (URI) without last extension.
74
  *
75
  * @param string $source
76
+ * @param bool $withExtension
77
+ * @return mixed|string
78
  */
79
  public function getFilename($source, $withExtension=false)
80
  {
84
  }
85
  return $file;
86
  }
87
+ }
 
lib/Mage/Archive/Bz.php CHANGED
@@ -20,7 +20,7 @@
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
 
@@ -43,9 +43,19 @@ class Mage_Archive_Bz extends Mage_Archive_Abstract implements Mage_Archive_Inte
43
  */
44
  public function pack($source, $destination)
45
  {
46
- $data = $this->_readFile($source);
47
- $bzData = bzcompress($data, 9);
48
- $this->_writeFile($destination, $bzData);
 
 
 
 
 
 
 
 
 
 
49
  return $destination;
50
  }
51
 
@@ -58,22 +68,22 @@ class Mage_Archive_Bz extends Mage_Archive_Abstract implements Mage_Archive_Inte
58
  */
59
  public function unpack($source, $destination)
60
  {
61
- $data = '';
62
- $bzPointer = bzopen($source, 'r' );
63
- if (empty($bzPointer)) {
64
- throw new Exception('Can\'t open BZ archive : ' . $source);
65
- }
66
- while (!feof($bzPointer)) {
67
- $data .= bzread($bzPointer, 131072);
68
- }
69
- bzclose($bzPointer);
70
  if (is_dir($destination)) {
71
  $file = $this->getFilename($source);
72
  $destination = $destination . $file;
73
  }
74
- echo $destination;
75
- $this->_writeFile($destination, $data);
 
 
 
 
 
 
 
 
 
76
  return $destination;
77
  }
78
 
79
- }
20
  *
21
  * @category Mage
22
  * @package Mage_Archive
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
43
  */
44
  public function pack($source, $destination)
45
  {
46
+ $fileReader = new Mage_Archive_Helper_File($source);
47
+ $fileReader->open('r');
48
+
49
+ $archiveWriter = new Mage_Archive_Helper_File_Bz($destination);
50
+ $archiveWriter->open('w');
51
+
52
+ while (!$fileReader->eof()) {
53
+ $archiveWriter->write($fileReader->read());
54
+ }
55
+
56
+ $fileReader->close();
57
+ $archiveWriter->close();
58
+
59
  return $destination;
60
  }
61
 
68
  */
69
  public function unpack($source, $destination)
70
  {
 
 
 
 
 
 
 
 
 
71
  if (is_dir($destination)) {
72
  $file = $this->getFilename($source);
73
  $destination = $destination . $file;
74
  }
75
+
76
+ $archiveReader = new Mage_Archive_Helper_File_Bz($source);
77
+ $archiveReader->open('r');
78
+
79
+ $fileWriter = new Mage_Archive_Helper_File($destination);
80
+ $fileWriter->open('w');
81
+
82
+ while (!$archiveReader->eof()) {
83
+ $fileWriter->write($archiveReader->read());
84
+ }
85
+
86
  return $destination;
87
  }
88
 
89
+ }
lib/Mage/Archive/Gz.php CHANGED
@@ -20,7 +20,7 @@
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
 
@@ -42,9 +42,19 @@ class Mage_Archive_Gz extends Mage_Archive_Abstract implements Mage_Archive_Inte
42
  */
43
  public function pack($source, $destination)
44
  {
45
- $data = $this->_readFile($source);
46
- $gzData = gzencode($data, 9);
47
- $this->_writeFile($destination, $gzData);
 
 
 
 
 
 
 
 
 
 
48
  return $destination;
49
  }
50
 
@@ -57,21 +67,21 @@ class Mage_Archive_Gz extends Mage_Archive_Abstract implements Mage_Archive_Inte
57
  */
58
  public function unpack($source, $destination)
59
  {
60
- $gzPointer = gzopen($source, 'r' );
61
- if (empty($gzPointer)) {
62
- throw new Mage_Exception('Can\'t open GZ archive : ' . $source);
63
- }
64
- $data = '';
65
- while (!gzeof($gzPointer)) {
66
- $data .= gzread($gzPointer, 131072);
67
- }
68
- gzclose($gzPointer);
69
  if (is_dir($destination)) {
70
  $file = $this->getFilename($source);
71
  $destination = $destination . $file;
72
  }
73
- $this->_writeFile($destination, $data);
 
 
 
 
 
 
 
 
 
 
74
  return $destination;
75
  }
76
-
77
- }
20
  *
21
  * @category Mage
22
  * @package Mage_Archive
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
42
  */
43
  public function pack($source, $destination)
44
  {
45
+ $fileReader = new Mage_Archive_Helper_File($source);
46
+ $fileReader->open('r');
47
+
48
+ $archiveWriter = new Mage_Archive_Helper_File_Gz($destination);
49
+ $archiveWriter->open('wb9');
50
+
51
+ while (!$fileReader->eof()) {
52
+ $archiveWriter->write($fileReader->read());
53
+ }
54
+
55
+ $fileReader->close();
56
+ $archiveWriter->close();
57
+
58
  return $destination;
59
  }
60
 
67
  */
68
  public function unpack($source, $destination)
69
  {
 
 
 
 
 
 
 
 
 
70
  if (is_dir($destination)) {
71
  $file = $this->getFilename($source);
72
  $destination = $destination . $file;
73
  }
74
+
75
+ $archiveReader = new Mage_Archive_Helper_File_Gz($source);
76
+ $archiveReader->open('r');
77
+
78
+ $fileWriter = new Mage_Archive_Helper_File($destination);
79
+ $fileWriter->open('w');
80
+
81
+ while (!$archiveReader->eof()) {
82
+ $fileWriter->write($archiveReader->read());
83
+ }
84
+
85
  return $destination;
86
  }
87
+ }
 
lib/Mage/Archive/Helper/File.php ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Helper class that simplifies files stream reading and writing
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Helper_File
35
+ {
36
+ /**
37
+ * Full path to directory where file located
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_fileLocation;
42
+
43
+ /**
44
+ * File name
45
+ *
46
+ * @var string
47
+ */
48
+ protected $_fileName;
49
+
50
+ /**
51
+ * Full path (directory + filename) to file
52
+ *
53
+ * @var string
54
+ */
55
+ protected $_filePath;
56
+
57
+ /**
58
+ * File permissions that will be set if file opened in write mode
59
+ *
60
+ * @var int
61
+ */
62
+ protected $_chmod;
63
+
64
+ /**
65
+ * File handler
66
+ *
67
+ * @var pointer
68
+ */
69
+ protected $_fileHandler;
70
+
71
+ /**
72
+ * Set file path via constructor
73
+ *
74
+ * @param string $filePath
75
+ */
76
+ public function __construct($filePath)
77
+ {
78
+ $pathInfo = pathinfo($filePath);
79
+
80
+ $this->_filePath = $filePath;
81
+ $this->_fileLocation = isset($pathInfo['dirname']) ? $pathInfo['dirname'] : '';
82
+ $this->_fileName = isset($pathInfo['basename']) ? $pathInfo['basename'] : '';
83
+ }
84
+
85
+ /**
86
+ * Close file if it's not closed before object destruction
87
+ */
88
+ public function __destruct()
89
+ {
90
+ if ($this->_fileHandler) {
91
+ $this->_close();
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Open file
97
+ *
98
+ * @param string $mode
99
+ * @param int $chmod
100
+ * @throws Mage_Exception
101
+ */
102
+ public function open($mode = 'w+', $chmod = 0666)
103
+ {
104
+ if ($this->_isWritableMode($mode)) {
105
+ if (!is_writable($this->_fileLocation)) {
106
+ throw new Mage_Exception('Permission denied to write to ' . $this->_fileLocation);
107
+ }
108
+
109
+ if (is_file($this->_filePath) && !is_writable($this->_filePath)) {
110
+ throw new Mage_Exception("Can't open file " . $this->_fileName . " for writing. Permission denied.");
111
+ }
112
+ }
113
+
114
+ if ($this->_isReadableMode($mode) && (!is_file($this->_filePath) || !is_readable($this->_filePath))) {
115
+ if (!is_file($this->_filePath)) {
116
+ throw new Mage_Exception('File ' . $this->_filePath . ' does not exist');
117
+ }
118
+
119
+ if (!is_readable($this->_filePath)) {
120
+ throw new Mage_Exception('Permission denied to read file ' . $this->_filePath);
121
+ }
122
+ }
123
+
124
+ $this->_open($mode);
125
+
126
+ $this->_chmod = $chmod;
127
+ }
128
+
129
+ /**
130
+ * Write data to file
131
+ *
132
+ * @param string $data
133
+ */
134
+ public function write($data)
135
+ {
136
+ $this->_checkFileOpened();
137
+ $this->_write($data);
138
+ }
139
+
140
+ /**
141
+ * Read data from file
142
+ *
143
+ * @param int $length
144
+ * @return string|boolean
145
+ */
146
+ public function read($length = 4096)
147
+ {
148
+ $data = false;
149
+ $this->_checkFileOpened();
150
+ if ($length > 0) {
151
+ $data = $this->_read($length);
152
+ }
153
+
154
+ return $data;
155
+ }
156
+
157
+ /**
158
+ * Check whether end of file reached
159
+ *
160
+ * @return boolean
161
+ */
162
+ public function eof()
163
+ {
164
+ $this->_checkFileOpened();
165
+ return $this->_eof();
166
+ }
167
+
168
+ /**
169
+ * Close file
170
+ */
171
+ public function close()
172
+ {
173
+ $this->_checkFileOpened();
174
+ $this->_close();
175
+ $this->_fileHandler = false;
176
+ @chmod($this->_filePath, $this->_chmod);
177
+ }
178
+
179
+ /**
180
+ * Implementation of file opening
181
+ *
182
+ * @param string $mode
183
+ * @throws Mage_Exception
184
+ */
185
+ protected function _open($mode)
186
+ {
187
+ $this->_fileHandler = @fopen($this->_filePath, $mode);
188
+
189
+ if (false === $this->_fileHandler) {
190
+ throw new Mage_Exception('Failed to open file ' . $this->_filePath);
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Implementation of writing data to file
196
+ *
197
+ * @param string $data
198
+ * @throws Mage_Exception
199
+ */
200
+ protected function _write($data)
201
+ {
202
+ $result = @fwrite($this->_fileHandler, $data);
203
+
204
+ if (false === $result) {
205
+ throw new Mage_Exception('Failed to write data to ' . $this->_filePath);
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Implementation of file reading
211
+ *
212
+ * @param int $length
213
+ * @throws Mage_Exception
214
+ */
215
+ protected function _read($length)
216
+ {
217
+ $result = fread($this->_fileHandler, $length);
218
+
219
+ if (false === $result) {
220
+ throw new Mage_Exception('Failed to read data from ' . $this->_filePath);
221
+ }
222
+
223
+ return $result;
224
+ }
225
+
226
+ /**
227
+ * Implementation of EOF indicator
228
+ *
229
+ * @return boolean
230
+ */
231
+ protected function _eof()
232
+ {
233
+ return feof($this->_fileHandler);
234
+ }
235
+
236
+ /**
237
+ * Implementation of file closing
238
+ */
239
+ protected function _close()
240
+ {
241
+ fclose($this->_fileHandler);
242
+ }
243
+
244
+ /**
245
+ * Check whether requested mode is writable mode
246
+ *
247
+ * @param string $mode
248
+ */
249
+ protected function _isWritableMode($mode)
250
+ {
251
+ return preg_match('/(^[waxc])|(\+$)/', $mode);
252
+ }
253
+
254
+ /**
255
+ * Check whether requested mode is readable mode
256
+ *
257
+ * @param string $mode
258
+ */
259
+ protected function _isReadableMode($mode) {
260
+ return !$this->_isWritableMode($mode);
261
+ }
262
+
263
+ /**
264
+ * Check whether file is opened
265
+ *
266
+ * @throws Mage_Exception
267
+ */
268
+ protected function _checkFileOpened()
269
+ {
270
+ if (!$this->_fileHandler) {
271
+ throw new Mage_Exception('File not opened');
272
+ }
273
+ }
274
+ }
lib/Mage/Archive/Helper/File/Bz.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Helper class that simplifies bz2 files stream reading and writing
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Helper_File_Bz extends Mage_Archive_Helper_File
35
+ {
36
+ /**
37
+ * Open bz archive file
38
+ *
39
+ * @throws Mage_Exception
40
+ * @param string $mode
41
+ */
42
+ protected function _open($mode)
43
+ {
44
+ $this->_fileHandler = @bzopen($this->_filePath, $mode);
45
+
46
+ if (false === $this->_fileHandler) {
47
+ throw new Mage_Exception('Failed to open file ' . $this->_filePath);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Write data to bz archive
53
+ *
54
+ * @throws Mage_Exception
55
+ * @param $data
56
+ */
57
+ protected function _write($data)
58
+ {
59
+ $result = @bzwrite($this->_fileHandler, $data);
60
+
61
+ if (false === $result) {
62
+ throw new Mage_Exception('Failed to write data to ' . $this->_filePath);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Read data from bz archive
68
+ *
69
+ * @throws Mage_Exception
70
+ * @param int $length
71
+ * @return string
72
+ */
73
+ protected function _read($length)
74
+ {
75
+ $data = bzread($this->_fileHandler, $length);
76
+
77
+ if (false === $data) {
78
+ throw new Mage_Exception('Failed to read data from ' . $this->_filePath);
79
+ }
80
+
81
+ return $data;
82
+ }
83
+
84
+ /**
85
+ * Close bz archive
86
+ */
87
+ protected function _close()
88
+ {
89
+ bzclose($this->_fileHandler);
90
+ }
91
+ }
92
+
lib/Mage/Archive/Helper/File/Gz.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Helper class that simplifies gz files stream reading and writing
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Helper_File_Gz extends Mage_Archive_Helper_File
35
+ {
36
+ /**
37
+ * @see Mage_Archive_Helper_File::_open()
38
+ */
39
+ protected function _open($mode)
40
+ {
41
+ $this->_fileHandler = @gzopen($this->_filePath, $mode);
42
+
43
+ if (false === $this->_fileHandler) {
44
+ throw new Mage_Exception('Failed to open file ' . $this->_filePath);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * @see Mage_Archive_Helper_File::_write()
50
+ */
51
+ protected function _write($data)
52
+ {
53
+ $result = @gzwrite($this->_fileHandler, $data);
54
+
55
+ if (empty($result) && !empty($data)) {
56
+ throw new Mage_Exception('Failed to write data to ' . $this->_filePath);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @see Mage_Archive_Helper_File::_read()
62
+ */
63
+ protected function _read($length)
64
+ {
65
+ return gzread($this->_fileHandler, $length);
66
+ }
67
+
68
+ /**
69
+ * @see Mage_Archive_Helper_File::_eof()
70
+ */
71
+ protected function _eof()
72
+ {
73
+ return gzeof($this->_fileHandler);
74
+ }
75
+
76
+ /**
77
+ * @see Mage_Archive_Helper_File::_close()
78
+ */
79
+ protected function _close()
80
+ {
81
+ gzclose($this->_fileHandler);
82
+ }
83
+ }
lib/Mage/Archive/Interface.php CHANGED
@@ -20,7 +20,7 @@
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
 
@@ -50,4 +50,4 @@ interface Mage_Archive_Interface
50
  * @return string
51
  */
52
  public function unpack($source, $destination);
53
- }
20
  *
21
  * @category Mage
22
  * @package Mage_Archive
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
50
  * @return string
51
  */
52
  public function unpack($source, $destination);
53
+ }
lib/Mage/Archive/Tar.php CHANGED
@@ -20,7 +20,7 @@
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
 
@@ -34,9 +34,11 @@
34
  class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Interface
35
  {
36
  /**
37
- * Constant is used for parse tar's header.
 
 
38
  */
39
- const FORMAT_PARSE_HEADER = 'a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12closer';
40
 
41
  /**
42
  * Keep file or directory for packing.
@@ -60,6 +62,122 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
60
  */
61
  protected $_skipRoot;
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  /**
64
  * Set option that define ability skip first catalog level.
65
  *
@@ -80,7 +198,19 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
80
  */
81
  protected function _setCurrentFile($file)
82
  {
83
- $this->_currentFile = $file .((is_dir($file) && substr($file, -1)!=DS)?DS:'');
 
 
 
 
 
 
 
 
 
 
 
 
84
  return $this;
85
  }
86
 
@@ -124,6 +254,7 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
124
  * Walk through directory and add to tar file or directory.
125
  * Result is packed string on TAR format.
126
  *
 
127
  * @param boolean $skipRoot
128
  * @return string
129
  */
@@ -154,10 +285,74 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
154
  return $tarData;
155
  }
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  /**
158
  * Compose header for current file in TAR format.
159
  * If length of file's name greater 100 characters,
160
- * method breaks header to two pieces. First conatins
161
  * header and data with long name. Second contain only header.
162
  *
163
  * @param boolean $long
@@ -178,14 +373,16 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
178
  }
179
  $header = array();
180
  $header['100-name'] = $long?'././@LongLink':substr($nameFile, 0, 100);
181
- $header['8-mode'] = $long?' ':str_pad(substr(sprintf("%07o", $infoFile['mode']),-4), 6, '0', STR_PAD_LEFT);
 
182
  $header['8-uid'] = $long || $infoFile['uid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['uid']);
183
  $header['8-gid'] = $long || $infoFile['gid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['gid']);
184
- $header['12-size'] = $long?sprintf("%011o", strlen($nameFile)):sprintf("%011o", is_dir($file) ? 0 : filesize($file));
 
185
  $header['12-mtime'] = $long?'00000000000':sprintf("%011o", $infoFile['mtime']);
186
  $header['8-check'] = sprintf('% 8s', '');
187
- $header['1-type'] = $long?'L':(is_link($file) ? 2 : is_dir ($file) ? 5 : 0);
188
- $header['100-symlink'] = is_link($file) == 2 ? readlink($item) : '';
189
  $header['6-magic'] = 'ustar ';
190
  $header['2-version'] = ' ';
191
  $a=function_exists('posix_getpwuid')?posix_getpwuid (fileowner($file)):array('name'=>'');
@@ -219,38 +416,63 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
219
  *
220
  * @param string $destination path to file is unpacked
221
  * @return array list of files
 
222
  */
223
  protected function _unpackCurrentTar($destination)
224
  {
225
- $file = $this->_getCurrentFile();
226
- $pointer = fopen($file, 'r');
227
- if (empty($pointer)) {
228
- throw new Mage_Exception('Can\'t open file: ' . $file);
229
- }
230
  $list = array();
231
- while (!feof($pointer)) {
232
- $header = $this->_parseHeader($pointer);
233
- if ($header) {
234
- $currentFile = $destination . $header['name'];
235
- if ($header['type']=='5' && @mkdir($currentFile, 0777, true)) {
236
- $list[] = $currentFile . DS;
237
- } elseif (in_array($header['type'], array("0",chr(0), ''))) {
238
- $dirname = dirname($currentFile);
239
- if(!file_exists($dirname)) {
240
- @mkdir($dirname, 0777, true);
 
 
 
 
 
 
 
 
241
  }
242
- $this->_writeFile($currentFile, $header['data']);
243
- $list[] = $currentFile;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
245
  }
246
  }
247
- fclose($pointer);
248
  return $list;
249
  }
250
 
251
  /**
252
  * Get header from TAR string and unpacked it by format.
253
  *
 
254
  * @param resource $pointer
255
  * @return string
256
  */
@@ -262,10 +484,9 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
262
  return false;
263
  }
264
 
265
- $fmt = self::FORMAT_PARSE_HEADER;
266
  $header = unpack ($fmt, $firstLine);
267
 
268
-
269
  $header['mode']=$header['mode']+0;
270
  $header['uid']=octdec($header['uid']);
271
  $header['gid']=octdec($header['gid']);
@@ -284,7 +505,7 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
284
  }
285
 
286
  $isUstar = 'ustar' == strtolower(substr($header['magic'], 0, 5));
287
-
288
  $checksumOk = $header['checksum'] == $checksum;
289
  if (isset($header['name']) && $checksumOk) {
290
  if ($header['name'] == '././@LongLink' && $header['type'] == 'L') {
@@ -304,6 +525,90 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
304
  return false;
305
  }
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  /**
308
  * Pack file to TAR (Tape Archiver).
309
  *
@@ -312,14 +617,18 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
312
  * @param boolean $skipRoot
313
  * @return string
314
  */
315
- public function pack($source, $destination, $skipRoot=false)
316
  {
317
  $this->_setSkipRoot($skipRoot);
318
  $source = realpath($source);
319
  $tarData = $this->_setCurrentPath($source)
320
- ->_setCurrentFile($source)
321
- ->_packToTar($skipRoot);
322
- $this->_writeFile($destination, $tarData);
 
 
 
 
323
  return $destination;
324
  }
325
 
@@ -332,13 +641,13 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
332
  */
333
  public function unpack($source, $destination)
334
  {
335
- $tempFile = $destination . DS . '~tmp-'.microtime(true).'.tar';
336
- $data = $this->_readFile($source);
337
- $this->_writeFile($tempFile, $data);
338
- $this->_setCurrentFile($tempFile)
339
- ->_setCurrentPath($tempFile)
340
- ->_unpackCurrentTar($destination);
341
- unlink($tempFile);
342
  return $destination;
343
  }
344
 
@@ -352,21 +661,28 @@ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Int
352
  */
353
  public function extract($file, $source, $destination)
354
  {
355
- $pointer = fopen($source, 'r');
356
- if (empty($pointer)) {
357
- throw new Mage_Exception('Can\'t open file: '.$source);
358
- }
359
- $list = array();
360
  $extractedFile = '';
361
- while (!feof($pointer)) {
362
- $header = $this->_parseHeader($pointer);
 
363
  if ($header['name'] == $file) {
364
  $extractedFile = $destination . basename($header['name']);
365
- $this->_writeFile($extractedFile, $header['data']);
366
  break;
367
  }
 
 
 
 
 
 
368
  }
369
- fclose($pointer);
 
370
  return $extractedFile;
371
  }
372
  }
20
  *
21
  * @category Mage
22
  * @package Mage_Archive
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
34
  class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Interface
35
  {
36
  /**
37
+ * Tar block size
38
+ *
39
+ * @const int
40
  */
41
+ const TAR_BLOCK_SIZE = 512;
42
 
43
  /**
44
  * Keep file or directory for packing.
62
  */
63
  protected $_skipRoot;
64
 
65
+ /**
66
+ * Tarball data writer
67
+ *
68
+ * @var Mage_Archive_Helper_File
69
+ */
70
+ protected $_writer;
71
+
72
+ /**
73
+ * Tarball data reader
74
+ *
75
+ * @var Mage_Archive_Helper_File
76
+ */
77
+ protected $_reader;
78
+
79
+ /**
80
+ * Path to file where tarball should be placed
81
+ *
82
+ * @var string
83
+ */
84
+ protected $_destinationFilePath;
85
+
86
+ /**
87
+ * Initialize tarball writer
88
+ *
89
+ * @return Mage_Archive_Tar
90
+ */
91
+ protected function _initWriter()
92
+ {
93
+ $this->_writer = new Mage_Archive_Helper_File($this->_destinationFilePath);
94
+ $this->_writer->open('w');
95
+
96
+ return $this;
97
+ }
98
+
99
+ /**
100
+ * Returns string that is used for tar's header parsing
101
+ *
102
+ * @return string
103
+ */
104
+ protected static final function _getFormatParseHeader()
105
+ {
106
+ return 'a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2version/'
107
+ . 'a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12closer';
108
+ }
109
+
110
+ /**
111
+ * Destroy tarball writer
112
+ *
113
+ * @return Mage_Archive_Tar
114
+ */
115
+ protected function _destroyWriter()
116
+ {
117
+ if ($this->_writer instanceof Mage_Archive_Helper_File) {
118
+ $this->_writer->close();
119
+ $this->_writer = null;
120
+ }
121
+
122
+ return $this;
123
+ }
124
+
125
+ /**
126
+ * Get tarball writer
127
+ *
128
+ * @return Mage_Archive_Helper_File
129
+ */
130
+ protected function _getWriter()
131
+ {
132
+ if (!$this->_writer) {
133
+ $this->_initWriter();
134
+ }
135
+
136
+ return $this->_writer;
137
+ }
138
+
139
+ /**
140
+ * Initialize tarball reader
141
+ *
142
+ * @return Mage_Archive_Tar
143
+ */
144
+ protected function _initReader()
145
+ {
146
+ $this->_reader = new Mage_Archive_Helper_File($this->_getCurrentFile());
147
+ $this->_reader->open('r');
148
+
149
+ return $this;
150
+ }
151
+
152
+ /**
153
+ * Destroy tarball reader
154
+ *
155
+ * @return Mage_Archive_Tar
156
+ */
157
+ protected function _destroyReader()
158
+ {
159
+ if ($this->_reader instanceof Mage_Archive_Helper_File) {
160
+ $this->_reader->close();
161
+ $this->_reader = null;
162
+ }
163
+
164
+ return $this;
165
+ }
166
+
167
+ /**
168
+ * Get tarball reader
169
+ *
170
+ * @return Mage_Archive_Helper_File
171
+ */
172
+ protected function _getReader()
173
+ {
174
+ if (!$this->_reader) {
175
+ $this->_initReader();
176
+ }
177
+
178
+ return $this->_reader;
179
+ }
180
+
181
  /**
182
  * Set option that define ability skip first catalog level.
183
  *
198
  */
199
  protected function _setCurrentFile($file)
200
  {
201
+ $this->_currentFile = $file .((!is_link($file) && is_dir($file) && substr($file, -1) != DS) ? DS : '');
202
+ return $this;
203
+ }
204
+
205
+ /**
206
+ * Set path to file where tarball should be placed
207
+ *
208
+ * @param string $destinationFilePath
209
+ * @return Mage_Archive_Tar
210
+ */
211
+ protected function _setDestinationFilePath($destinationFilePath)
212
+ {
213
+ $this->_destinationFilePath = $destinationFilePath;
214
  return $this;
215
  }
216
 
254
  * Walk through directory and add to tar file or directory.
255
  * Result is packed string on TAR format.
256
  *
257
+ * @deprecated after 1.7.0.0
258
  * @param boolean $skipRoot
259
  * @return string
260
  */
285
  return $tarData;
286
  }
287
 
288
+ /**
289
+ * Recursively walk through file tree and create tarball
290
+ *
291
+ * @param boolean $skipRoot
292
+ * @param boolean $finalize
293
+ * @throws Mage_Exception
294
+ */
295
+ protected function _createTar($skipRoot = false, $finalize = false)
296
+ {
297
+ if (!$skipRoot) {
298
+ $this->_packAndWriteCurrentFile();
299
+ }
300
+
301
+ $file = $this->_getCurrentFile();
302
+
303
+ if (is_dir($file)) {
304
+ $dirFiles = scandir($file);
305
+
306
+ if (false === $dirFiles) {
307
+ throw new Mage_Exception('Can\'t scan dir: ' . $file);
308
+ }
309
+
310
+ array_shift($dirFiles); /* remove './'*/
311
+ array_shift($dirFiles); /* remove '../'*/
312
+
313
+ foreach ($dirFiles as $item) {
314
+ $this->_setCurrentFile($file . $item)->_createTar();
315
+ }
316
+ }
317
+
318
+ if ($finalize) {
319
+ $this->_getWriter()->write(str_repeat("\0", self::TAR_BLOCK_SIZE * 12));
320
+ }
321
+ }
322
+
323
+ /**
324
+ * Write current file to tarball
325
+ */
326
+ protected function _packAndWriteCurrentFile()
327
+ {
328
+ $archiveWriter = $this->_getWriter();
329
+ $archiveWriter->write($this->_composeHeader());
330
+
331
+ $currentFile = $this->_getCurrentFile();
332
+
333
+ $fileSize = 0;
334
+
335
+ if (is_file($currentFile) && !is_link($currentFile)) {
336
+ $fileReader = new Mage_Archive_Helper_File($currentFile);
337
+ $fileReader->open('r');
338
+
339
+ while (!$fileReader->eof()) {
340
+ $archiveWriter->write($fileReader->read());
341
+ }
342
+
343
+ $fileReader->close();
344
+
345
+ $fileSize = filesize($currentFile);
346
+ }
347
+
348
+ $appendZerosCount = (self::TAR_BLOCK_SIZE - $fileSize % self::TAR_BLOCK_SIZE) % self::TAR_BLOCK_SIZE;
349
+ $archiveWriter->write(str_repeat("\0", $appendZerosCount));
350
+ }
351
+
352
  /**
353
  * Compose header for current file in TAR format.
354
  * If length of file's name greater 100 characters,
355
+ * method breaks header into two pieces. First contains
356
  * header and data with long name. Second contain only header.
357
  *
358
  * @param boolean $long
373
  }
374
  $header = array();
375
  $header['100-name'] = $long?'././@LongLink':substr($nameFile, 0, 100);
376
+ $header['8-mode'] = $long ? ' '
377
+ : str_pad(substr(sprintf("%07o", $infoFile['mode']),-4), 6, '0', STR_PAD_LEFT);
378
  $header['8-uid'] = $long || $infoFile['uid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['uid']);
379
  $header['8-gid'] = $long || $infoFile['gid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['gid']);
380
+ $header['12-size'] = $long ? sprintf("%011o", strlen($nameFile)) : sprintf("%011o", is_dir($file)
381
+ ? 0 : filesize($file));
382
  $header['12-mtime'] = $long?'00000000000':sprintf("%011o", $infoFile['mtime']);
383
  $header['8-check'] = sprintf('% 8s', '');
384
+ $header['1-type'] = $long ? 'L' : (is_link($file) ? 2 : (is_dir($file) ? 5 : 0));
385
+ $header['100-symlink'] = is_link($file) ? readlink($file) : '';
386
  $header['6-magic'] = 'ustar ';
387
  $header['2-version'] = ' ';
388
  $a=function_exists('posix_getpwuid')?posix_getpwuid (fileowner($file)):array('name'=>'');
416
  *
417
  * @param string $destination path to file is unpacked
418
  * @return array list of files
419
+ * @throws Mage_Exception
420
  */
421
  protected function _unpackCurrentTar($destination)
422
  {
423
+ $archiveReader = $this->_getReader();
 
 
 
 
424
  $list = array();
425
+
426
+ while (!$archiveReader->eof()) {
427
+ $header = $this->_extractFileHeader();
428
+
429
+ if (!$header) {
430
+ continue;
431
+ }
432
+
433
+ $currentFile = $destination . $header['name'];
434
+ $dirname = dirname($currentFile);
435
+
436
+ if (in_array($header['type'], array("0",chr(0), ''))) {
437
+
438
+ if(!file_exists($dirname)) {
439
+ $mkdirResult = @mkdir($dirname, 0777, true);
440
+
441
+ if (false === $mkdirResult) {
442
+ throw new Mage_Exception('Failed to create directory ' . $dirname);
443
  }
444
+ }
445
+
446
+ $this->_extractAndWriteFile($header, $currentFile);
447
+ $list[] = $currentFile;
448
+
449
+ } elseif ($header['type'] == '5') {
450
+
451
+ if(!file_exists($dirname)) {
452
+ $mkdirResult = @mkdir($currentFile, $header['mode'], true);
453
+
454
+ if (false === $mkdirResult) {
455
+ throw new Mage_Exception('Failed to create directory ' . $currentFile);
456
+ }
457
+ }
458
+ $list[] = $currentFile . DS;
459
+ } elseif ($header['type'] == '2') {
460
+
461
+ $symlinkResult = @symlink($header['symlink'], $currentFile);
462
+
463
+ if (false === $symlinkResult) {
464
+ throw new Mage_Exception('Failed to create symlink ' . $currentFile . ' to ' . $header['symlink']);
465
  }
466
  }
467
  }
468
+
469
  return $list;
470
  }
471
 
472
  /**
473
  * Get header from TAR string and unpacked it by format.
474
  *
475
+ * @deprecated after 1.7.0.0
476
  * @param resource $pointer
477
  * @return string
478
  */
484
  return false;
485
  }
486
 
487
+ $fmt = self::_getFormatParseHeader();
488
  $header = unpack ($fmt, $firstLine);
489
 
 
490
  $header['mode']=$header['mode']+0;
491
  $header['uid']=octdec($header['uid']);
492
  $header['gid']=octdec($header['gid']);
505
  }
506
 
507
  $isUstar = 'ustar' == strtolower(substr($header['magic'], 0, 5));
508
+
509
  $checksumOk = $header['checksum'] == $checksum;
510
  if (isset($header['name']) && $checksumOk) {
511
  if ($header['name'] == '././@LongLink' && $header['type'] == 'L') {
525
  return false;
526
  }
527
 
528
+ /**
529
+ * Read and decode file header information from tarball
530
+ *
531
+ * @return array|boolean
532
+ */
533
+ protected function _extractFileHeader()
534
+ {
535
+ $archiveReader = $this->_getReader();
536
+
537
+ $headerBlock = $archiveReader->read(self::TAR_BLOCK_SIZE);
538
+
539
+ if (strlen($headerBlock) < self::TAR_BLOCK_SIZE) {
540
+ return false;
541
+ }
542
+
543
+ $header = unpack(self::_getFormatParseHeader(), $headerBlock);
544
+
545
+ $header['mode'] = octdec($header['mode']);
546
+ $header['uid'] = octdec($header['uid']);
547
+ $header['gid'] = octdec($header['gid']);
548
+ $header['size'] = octdec($header['size']);
549
+ $header['mtime'] = octdec($header['mtime']);
550
+ $header['checksum'] = octdec($header['checksum']);
551
+
552
+ if ($header['type'] == "5") {
553
+ $header['size'] = 0;
554
+ }
555
+
556
+ $checksum = 0;
557
+ $headerBlock = substr_replace($headerBlock, ' ', 148, 8);
558
+
559
+ for ($i = 0; $i < 512; $i++) {
560
+ $checksum += ord(substr($headerBlock, $i, 1));
561
+ }
562
+
563
+ $isUstar = 'ustar' == strtolower(substr($header['magic'], 0, 5));
564
+
565
+ $checksumOk = $header['checksum'] == $checksum;
566
+ if (isset($header['name']) && $checksumOk) {
567
+
568
+ if (!($header['name'] == '././@LongLink' && $header['type'] == 'L')) {
569
+ return $header;
570
+ }
571
+
572
+ $realNameBlockSize = floor(($header['size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE)
573
+ * self::TAR_BLOCK_SIZE;
574
+ $realNameBlock = $archiveReader->read($realNameBlockSize);
575
+ $realName = substr($realNameBlock, 0, $header['size']);
576
+
577
+ $headerMain = $this->_extractFileHeader();
578
+ $headerMain['name'] = $realName;
579
+ return $headerMain;
580
+ }
581
+
582
+ return false;
583
+ }
584
+
585
+ /**
586
+ * Extract next file from tarball by its $header information and save it to $destination
587
+ *
588
+ * @param array $fileHeader
589
+ * @param string $destination
590
+ */
591
+ protected function _extractAndWriteFile($fileHeader, $destination)
592
+ {
593
+ $fileWriter = new Mage_Archive_Helper_File($destination);
594
+ $fileWriter->open('w', $fileHeader['mode']);
595
+
596
+ $archiveReader = $this->_getReader();
597
+
598
+ $filesize = $fileHeader['size'];
599
+ $bytesExtracted = 0;
600
+
601
+ while ($filesize > $bytesExtracted && !$archiveReader->eof()) {
602
+ $block = $archiveReader->read(self::TAR_BLOCK_SIZE);
603
+ $nonExtractedBytesCount = $filesize - $bytesExtracted;
604
+
605
+ $data = substr($block, 0, $nonExtractedBytesCount);
606
+ $fileWriter->write($data);
607
+
608
+ $bytesExtracted += strlen($block);
609
+ }
610
+ }
611
+
612
  /**
613
  * Pack file to TAR (Tape Archiver).
614
  *
617
  * @param boolean $skipRoot
618
  * @return string
619
  */
620
+ public function pack($source, $destination, $skipRoot = false)
621
  {
622
  $this->_setSkipRoot($skipRoot);
623
  $source = realpath($source);
624
  $tarData = $this->_setCurrentPath($source)
625
+ ->_setDestinationFilePath($destination)
626
+ ->_setCurrentFile($source);
627
+
628
+ $this->_initWriter();
629
+ $this->_createTar($skipRoot, true);
630
+ $this->_destroyWriter();
631
+
632
  return $destination;
633
  }
634
 
641
  */
642
  public function unpack($source, $destination)
643
  {
644
+ $this->_setCurrentFile($source)
645
+ ->_setCurrentPath($source);
646
+
647
+ $this->_initReader();
648
+ $this->_unpackCurrentTar($destination);
649
+ $this->_destroyReader();
650
+
651
  return $destination;
652
  }
653
 
661
  */
662
  public function extract($file, $source, $destination)
663
  {
664
+ $this->_setCurrentFile($source);
665
+ $this->_initReader();
666
+
667
+ $archiveReader = $this->_getReader();
 
668
  $extractedFile = '';
669
+
670
+ while (!$archiveReader->eof()) {
671
+ $header = $this->_extractFileHeader();
672
  if ($header['name'] == $file) {
673
  $extractedFile = $destination . basename($header['name']);
674
+ $this->_extractAndWriteFile($header, $extractedFile);
675
  break;
676
  }
677
+
678
+ if ($header['type'] != 5){
679
+ $skipBytes = floor(($header['size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE)
680
+ * self::TAR_BLOCK_SIZE;
681
+ $archiveReader->read($skipBytes);
682
+ }
683
  }
684
+
685
+ $this->_destroyReader();
686
  return $extractedFile;
687
  }
688
  }
lib/Mage/Backup.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup
35
+ {
36
+ /**
37
+ * List of supported a backup types
38
+ *
39
+ * @var array
40
+ */
41
+ static protected $_allowedBackupTypes = array('db', 'snapshot', 'filesystem', 'media', 'nomedia');
42
+
43
+ /**
44
+ * get Backup Instance By File Name
45
+ *
46
+ * @param string $type
47
+ * @return Mage_Backup_Interface
48
+ */
49
+ static public function getBackupInstance($type)
50
+ {
51
+ $class = 'Mage_Backup_' . ucfirst($type);
52
+
53
+ if (!in_array($type, self::$_allowedBackupTypes) || !class_exists($class, true)){
54
+ throw new Mage_Exception('Current implementation not supported this type (' . $type . ') of backup.');
55
+ }
56
+
57
+ return new $class();
58
+ }
59
+ }
lib/Mage/Backup/Abstract.php ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ abstract class Mage_Backup_Abstract implements Mage_Backup_Interface
35
+ {
36
+ /**
37
+ * Backup name
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_name;
42
+
43
+ /**
44
+ * Backup creation date
45
+ *
46
+ * @var int
47
+ */
48
+ protected $_time;
49
+
50
+ /**
51
+ * Backup file extension
52
+ *
53
+ * @var string
54
+ */
55
+ protected $_backupExtension;
56
+
57
+ /**
58
+ * Resource model
59
+ *
60
+ * @var object
61
+ */
62
+ protected $_resourceModel;
63
+
64
+ /**
65
+ * Magento's root directory
66
+ *
67
+ * @var string
68
+ */
69
+ protected $_rootDir;
70
+
71
+ /**
72
+ * Path to directory where backups stored
73
+ *
74
+ * @var string
75
+ */
76
+ protected $_backupsDir;
77
+
78
+ /**
79
+ * Is last operation completed successfully
80
+ *
81
+ * @var bool
82
+ */
83
+ protected $_lastOperationSucceed = false;
84
+
85
+ /**
86
+ * Last failed operation error message
87
+ *
88
+ * @var string
89
+ */
90
+ protected $_lastErrorMessage;
91
+
92
+
93
+ /**
94
+ * Set Backup Extension
95
+ *
96
+ * @param string $backupExtension
97
+ * @return Mage_Backup_Interface
98
+ */
99
+ public function setBackupExtension($backupExtension)
100
+ {
101
+ $this->_backupExtension = $backupExtension;
102
+ return $this;
103
+ }
104
+
105
+ /**
106
+ * Get Backup Extension
107
+ *
108
+ * @return string
109
+ */
110
+ public function getBackupExtension()
111
+ {
112
+ return $this->_backupExtension;
113
+ }
114
+
115
+ /**
116
+ * Set Resource Model
117
+ *
118
+ * @param object $resourceModel
119
+ * @return Mage_Backup_Interface
120
+ */
121
+ public function setResourceModel($resourceModel)
122
+ {
123
+ $this->_resourceModel = $resourceModel;
124
+ return $this;
125
+ }
126
+
127
+ /**
128
+ * Get Resource Model
129
+ *
130
+ * @return object
131
+ */
132
+ public function getResourceModel()
133
+ {
134
+ return $this->_resourceModel;
135
+ }
136
+
137
+ /**
138
+ * Set Time
139
+ *
140
+ * @param int $time
141
+ * @return Mage_Backup_Interface
142
+ */
143
+ public function setTime($time)
144
+ {
145
+ $this->_time = $time;
146
+ return $this;
147
+ }
148
+
149
+ /**
150
+ * Get Time
151
+ *
152
+ * @return int
153
+ */
154
+ public function getTime()
155
+ {
156
+ return $this->_time;
157
+ }
158
+
159
+ /**
160
+ * Set root directory of Magento installation
161
+ *
162
+ * @param string $rootDir
163
+ * @throws Mage_Exception
164
+ * @return Mage_Backup_Interface
165
+ */
166
+ public function setRootDir($rootDir)
167
+ {
168
+ if (!is_dir($rootDir)) {
169
+ throw new Mage_Exception('Bad root directory');
170
+ }
171
+
172
+ $this->_rootDir = $rootDir;
173
+ return $this;
174
+ }
175
+
176
+ /**
177
+ * Get Magento's root directory
178
+ * @return string
179
+ */
180
+ public function getRootDir()
181
+ {
182
+ return $this->_rootDir;
183
+ }
184
+
185
+ /**
186
+ * Set path to directory where backups stored
187
+ *
188
+ * @param string $backupsDir
189
+ * @return Mage_Backup_Interface
190
+ */
191
+ public function setBackupsDir($backupsDir)
192
+ {
193
+ $this->_backupsDir = $backupsDir;
194
+ return $this;
195
+ }
196
+
197
+ /**
198
+ * Get path to directory where backups stored
199
+ *
200
+ * @return string
201
+ */
202
+ public function getBackupsDir()
203
+ {
204
+ return $this->_backupsDir;
205
+ }
206
+
207
+ /**
208
+ * Get path to backup
209
+ *
210
+ * @return string
211
+ */
212
+ public function getBackupPath()
213
+ {
214
+ return $this->getBackupsDir() . DS . $this->getBackupFilename();
215
+ }
216
+
217
+ /**
218
+ * Get backup file name
219
+ *
220
+ * @return string
221
+ */
222
+ public function getBackupFilename()
223
+ {
224
+ $filename = $this->getTime() . '_' . $this->getType();
225
+
226
+ $name = $this->getName();
227
+
228
+ if (!empty($name)) {
229
+ $filename .= '_' . $name;
230
+ }
231
+
232
+ $filename .= '.' . $this->getBackupExtension();
233
+
234
+ return $filename;
235
+ }
236
+
237
+ /**
238
+ * Check whether last operation completed successfully
239
+ *
240
+ * @return bool
241
+ */
242
+ public function getIsSuccess()
243
+ {
244
+ return $this->_lastOperationSucceed;
245
+ }
246
+
247
+ /**
248
+ * Get last error message
249
+ *
250
+ * @return string
251
+ */
252
+ public function getErrorMessage()
253
+ {
254
+ return $this->_lastErrorMessage;
255
+ }
256
+
257
+ /**
258
+ * Set error message
259
+ *
260
+ * @param string $errorMessage
261
+ * @return string
262
+ */
263
+ public function setErrorMessage($errorMessage)
264
+ {
265
+ $this->_lastErrorMessage = $errorMessage;
266
+ }
267
+
268
+ /**
269
+ * Set backup name
270
+ *
271
+ * @param string $name
272
+ * @param bool $applyFilter
273
+ * @return Mage_Backup_Interface
274
+ */
275
+ public function setName($name, $applyFilter = true)
276
+ {
277
+ if ($applyFilter) {
278
+ $name = $this->_filterName($name);
279
+ }
280
+ $this->_name = $name;
281
+ return $this;
282
+ }
283
+
284
+ /**
285
+ * Get backup name
286
+ *
287
+ * @return string
288
+ */
289
+ public function getName()
290
+ {
291
+ return $this->_name;
292
+ }
293
+
294
+ /**
295
+ * Get backup display name
296
+ *
297
+ * @return string
298
+ */
299
+ public function getDisplayName()
300
+ {
301
+ return str_replace('_', ' ', $this->_name);
302
+ }
303
+
304
+ /**
305
+ * Removes disallowed characters and replaces spaces with underscores
306
+ *
307
+ * @param string $name
308
+ * @return string
309
+ */
310
+ protected function _filterName($name)
311
+ {
312
+ $name = trim(preg_replace('/[^\da-zA-Z ]/', '', $name));
313
+ $name = preg_replace('/\s{2,}/', ' ', $name);
314
+ $name = str_replace(' ', '_', $name);
315
+
316
+ return $name;
317
+ }
318
+ }
lib/Mage/Backup/Archive/Tar.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Extended version of Mage_Archive_Tar that supports filtering
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Archive_Tar extends Mage_Archive_Tar
35
+ {
36
+ /**
37
+ * Filenames or filename parts that are used for filtering files
38
+ *
39
+ * @var array()
40
+ */
41
+ protected $_skipFiles = array();
42
+
43
+ /**
44
+ * Overridden Mage_Archive_Tar::_createTar method that does the same actions as it's parent but filters
45
+ * files using Mage_Backup_Filesystem_Iterator_Filter
46
+ *
47
+ * @see Mage_Archive_Tar::_createTar()
48
+ * @param bool $skipRoot
49
+ * @param bool $finalize
50
+ */
51
+ protected function _createTar($skipRoot = false, $finalize = false)
52
+ {
53
+ $path = $this->_getCurrentFile();
54
+
55
+ $filesystemIterator = new RecursiveIteratorIterator(
56
+ new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST
57
+ );
58
+
59
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $this->_skipFiles);
60
+
61
+ foreach ($iterator as $item) {
62
+ $this->_setCurrentFile($item->getPathname());
63
+ $this->_packAndWriteCurrentFile();
64
+ }
65
+
66
+ if ($finalize) {
67
+ $this->_getWriter()->write(str_repeat("\0", self::TAR_BLOCK_SIZE * 12));
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Set files that shouldn't be added to tarball
73
+ *
74
+ * @param array $skipFiles
75
+ * @return Mage_Backup_Archive_Tar
76
+ */
77
+ public function setSkipFiles(array $skipFiles)
78
+ {
79
+ $this->_skipFiles = $skipFiles;
80
+ return $this;
81
+ }
82
+ }
lib/Mage/Backup/Db.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with database backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Db extends Mage_Backup_Abstract
35
+ {
36
+ /**
37
+ * Implements Rollback functionality for Db
38
+ *
39
+ * @return bool
40
+ */
41
+ public function rollback()
42
+ {
43
+ set_time_limit(0);
44
+ ignore_user_abort(true);
45
+
46
+ $this->_lastOperationSucceed = false;
47
+
48
+ $archiveManager = new Mage_Archive();
49
+ $source = $archiveManager->unpack($this->getBackupPath(), $this->getBackupsDir());
50
+
51
+ $file = new Mage_Backup_Filesystem_Iterator_File($source);
52
+ foreach ($file as $statement) {
53
+ $this->getResourceModel()->runCommand($statement);
54
+ }
55
+ @unlink($source);
56
+
57
+ $this->_lastOperationSucceed = true;
58
+
59
+ return true;
60
+ }
61
+
62
+ /**
63
+ * Checks whether the line is last in sql command
64
+ *
65
+ * @param $line
66
+ * @return bool
67
+ */
68
+ protected function _isLineLastInCommand($line)
69
+ {
70
+ $cleanLine = trim($line);
71
+ $lineLength = strlen($cleanLine);
72
+
73
+ $returnResult = false;
74
+ if ($lineLength > 0){
75
+ $lastSymbolIndex = $lineLength-1;
76
+ if ($cleanLine[$lastSymbolIndex] == ';'){
77
+ $returnResult = true;
78
+ }
79
+ }
80
+
81
+ return $returnResult;
82
+ }
83
+
84
+ /**
85
+ * Implements Create Backup functionality for Db
86
+ *
87
+ * @return bool
88
+ */
89
+ public function create()
90
+ {
91
+ set_time_limit(0);
92
+ ignore_user_abort(true);
93
+
94
+ $this->_lastOperationSucceed = false;
95
+
96
+ $backup = Mage::getModel('backup/backup')
97
+ ->setTime($this->getTime())
98
+ ->setType($this->getType())
99
+ ->setPath($this->getBackupsDir())
100
+ ->setName($this->getName());
101
+
102
+ $backupDb = Mage::getModel('backup/db');
103
+ $backupDb->createBackup($backup);
104
+
105
+ $this->_lastOperationSucceed = true;
106
+
107
+ return true;
108
+ }
109
+
110
+ /**
111
+ * Get Backup Type
112
+ *
113
+ * @return string
114
+ */
115
+ public function getType()
116
+ {
117
+ return 'db';
118
+ }
119
+ }
lib/Mage/Backup/Exception.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception extends Mage_Exception
35
+ {
36
+ }
lib/Mage/Backup/Exception/CantLoadSnapshot.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_CantLoadSnapshot extends Mage_Backup_Exception
35
+ {
36
+ }
lib/Mage/Backup/Exception/FtpConnectionFailed.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_FtpConnectionFailed extends Mage_Backup_Exception
35
+ {
36
+ }
lib/Mage/Backup/Exception/FtpValidationFailed.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_FtpValidationFailed extends Mage_Backup_Exception
35
+ {
36
+ }
lib/Mage/Backup/Exception/NotEnoughFreeSpace.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_NotEnoughFreeSpace extends Mage_Backup_Exception
35
+ {
36
+ }
lib/Mage/Backup/Exception/NotEnoughPermissions.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_NotEnoughPermissions extends Mage_Backup_Exception
35
+ {
36
+ }
lib/Mage/Backup/Filesystem.php ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with filesystem backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem extends Mage_Backup_Abstract
35
+ {
36
+ /**
37
+ * Paths that ignored when creating or rolling back snapshot
38
+ *
39
+ * @var array
40
+ */
41
+ protected $_ignorePaths = array();
42
+
43
+ /**
44
+ * Whether use ftp account for rollback procedure
45
+ *
46
+ * @var bool
47
+ */
48
+ protected $_useFtp = false;
49
+
50
+ /**
51
+ * Ftp host
52
+ *
53
+ * @var string
54
+ */
55
+ protected $_ftpHost;
56
+
57
+ /**
58
+ * Ftp username
59
+ *
60
+ * @var string
61
+ */
62
+ protected $_ftpUser;
63
+
64
+ /**
65
+ * Password to ftp account
66
+ *
67
+ * @var string
68
+ */
69
+ protected $_ftpPass;
70
+
71
+ /**
72
+ * Ftp path to Magento installation
73
+ *
74
+ * @var string
75
+ */
76
+ protected $_ftpPath;
77
+
78
+ /**
79
+ * Implementation Rollback functionality for Filesystem
80
+ *
81
+ * @throws Mage_Exception
82
+ * @return bool
83
+ */
84
+ public function rollback()
85
+ {
86
+ $this->_lastOperationSucceed = false;
87
+
88
+ set_time_limit(0);
89
+ ignore_user_abort(true);
90
+
91
+ $rollbackWorker = $this->_useFtp ? new Mage_Backup_Filesystem_Rollback_Ftp($this)
92
+ : new Mage_Backup_Filesystem_Rollback_Fs($this);
93
+ $rollbackWorker->run();
94
+
95
+ $this->_lastOperationSucceed = true;
96
+ }
97
+
98
+ /**
99
+ * Implementation Create Backup functionality for Filesystem
100
+ *
101
+ * @throws Mage_Exception
102
+ * @return boolean
103
+ */
104
+ public function create()
105
+ {
106
+ set_time_limit(0);
107
+ ignore_user_abort(true);
108
+
109
+ $this->_lastOperationSucceed = false;
110
+
111
+ $this->_checkBackupsDir();
112
+
113
+ $fsHelper = new Mage_Backup_Filesystem_Helper();
114
+
115
+ $filesInfo = $fsHelper->getInfo(
116
+ $this->getRootDir(),
117
+ Mage_Backup_Filesystem_Helper::INFO_READABLE | Mage_Backup_Filesystem_Helper::INFO_SIZE,
118
+ $this->getIgnorePaths()
119
+ );
120
+
121
+ if (!$filesInfo['readable']) {
122
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Not enough permissions to read files for backup');
123
+ }
124
+
125
+ $freeSpace = disk_free_space($this->getBackupsDir());
126
+
127
+ if (2 * $filesInfo['size'] > $freeSpace) {
128
+ throw new Mage_Backup_Exception_NotEnoughFreeSpace('Not enough free space to create backup');
129
+ }
130
+
131
+ $tarTmpPath = $this->_getTarTmpPath();
132
+
133
+ $tarPacker = new Mage_Backup_Archive_Tar();
134
+ $tarPacker->setSkipFiles($this->getIgnorePaths())
135
+ ->pack($this->getRootDir(), $tarTmpPath, true);
136
+
137
+ if (!is_file($tarTmpPath) || filesize($tarTmpPath) == 0) {
138
+ throw new Mage_Exception('Failed to create backup');
139
+ }
140
+
141
+ $backupPath = $this->getBackupPath();
142
+
143
+ $gzPacker = new Mage_Archive_Gz();
144
+ $gzPacker->pack($tarTmpPath, $backupPath);
145
+
146
+ if (!is_file($backupPath) || filesize($backupPath) == 0) {
147
+ throw new Mage_Exception('Failed to create backup');
148
+ }
149
+
150
+ @unlink($tarTmpPath);
151
+
152
+ $this->_lastOperationSucceed = true;
153
+ }
154
+
155
+ /**
156
+ * Force class to use ftp for rollback procedure
157
+ *
158
+ * @param string $host
159
+ * @param string $username
160
+ * @param string $password
161
+ * @param string $path
162
+ * @return Mage_Backup_Filesystem
163
+ */
164
+ public function setUseFtp($host, $username, $password, $path)
165
+ {
166
+ $this->_useFtp = true;
167
+ $this->_ftpHost = $host;
168
+ $this->_ftpUser = $username;
169
+ $this->_ftpPass = $password;
170
+ $this->_ftpPath = $path;
171
+ return $this;
172
+ }
173
+
174
+ /**
175
+ * Get backup type
176
+ *
177
+ * @see Mage_Backup_Interface::getType()
178
+ * @return string
179
+ */
180
+ public function getType()
181
+ {
182
+ return 'filesystem';
183
+ }
184
+
185
+ /**
186
+ * Add path that should be ignoring when creating or rolling back backup
187
+ *
188
+ * @param string|array $paths
189
+ * @return Mage_Backup_Filesystem
190
+ */
191
+ public function addIgnorePaths($paths)
192
+ {
193
+ if (is_string($paths)) {
194
+ if (!in_array($paths, $this->_ignorePaths)) {
195
+ $this->_ignorePaths[] = $paths;
196
+ }
197
+ }
198
+ else if (is_array($paths)) {
199
+ foreach ($paths as $path) {
200
+ $this->addIgnorePaths($path);
201
+ }
202
+ }
203
+
204
+ return $this;
205
+ }
206
+
207
+ /**
208
+ * Get paths that should be ignored while creating or rolling back backup procedure
209
+ *
210
+ * @return array
211
+ */
212
+ public function getIgnorePaths()
213
+ {
214
+ return $this->_ignorePaths;
215
+ }
216
+
217
+ /**
218
+ * Set directory where backups saved and add it to ignore paths
219
+ *
220
+ * @see Mage_Backup_Abstract::setBackupsDir()
221
+ * @param string $backupsDir
222
+ * @return Mage_Backup_Filesystem
223
+ */
224
+ public function setBackupsDir($backupsDir)
225
+ {
226
+ parent::setBackupsDir($backupsDir);
227
+ $this->addIgnorePaths($backupsDir);
228
+ return $this;
229
+ }
230
+
231
+ /**
232
+ * getter for $_ftpPath variable
233
+ *
234
+ * @return string
235
+ */
236
+ public function getFtpPath()
237
+ {
238
+ return $this->_ftpPath;
239
+ }
240
+
241
+ /**
242
+ * Get ftp connection string
243
+ *
244
+ * @return string
245
+ */
246
+ public function getFtpConnectString()
247
+ {
248
+ return 'ftp://' . $this->_ftpUser . ':' . $this->_ftpPass . '@' . $this->_ftpHost . $this->_ftpPath;
249
+ }
250
+
251
+ /**
252
+ * Check backups directory existance and whether it's writeable
253
+ *
254
+ * @throws Mage_Exception
255
+ */
256
+ protected function _checkBackupsDir()
257
+ {
258
+ $backupsDir = $this->getBackupsDir();
259
+
260
+ if (!is_dir($backupsDir)) {
261
+ $backupsDirParentDirectory = basename($backupsDir);
262
+
263
+ if (!is_writeable($backupsDirParentDirectory)) {
264
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Cant create backups directory');
265
+ }
266
+
267
+ mkdir($backupsDir);
268
+ chmod($backupsDir, 0777);
269
+ }
270
+
271
+ if (!is_writable($backupsDir)) {
272
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Backups directory is not writeable');
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Generate tmp name for tarball
278
+ */
279
+ protected function _getTarTmpPath()
280
+ {
281
+ $tmpName = '~tmp-'. microtime(true) . '.tar';
282
+ return $this->getBackupsDir() . DS . $tmpName;
283
+ }
284
+ }
lib/Mage/Backup/Filesystem/Helper.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Filesystem helper for Mage_Backup library
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Helper
35
+ {
36
+ /**
37
+ * Constant can be used in getInfo() function as second parameter.
38
+ * Check whether directory and all files/sub directories are writable
39
+ *
40
+ * @const int
41
+ */
42
+ const INFO_WRITABLE = 1;
43
+
44
+ /**
45
+ * Constant can be used in getInfo() function as second parameter.
46
+ * Check whether directory and all files/sub directories are readable
47
+ *
48
+ * @const int
49
+ */
50
+ const INFO_READABLE = 2;
51
+
52
+ /**
53
+ * Constant can be used in getInfo() function as second parameter.
54
+ * Get directory size
55
+ *
56
+ * @const int
57
+ */
58
+ const INFO_SIZE = 4;
59
+
60
+ /**
61
+ * Constant can be used in getInfo() function as second parameter.
62
+ * Combination of INFO_WRITABLE, INFO_READABLE, INFO_SIZE
63
+ *
64
+ * @const int
65
+ */
66
+ const INFO_ALL = 7;
67
+
68
+ /**
69
+ * Recursively delete $path
70
+ *
71
+ * @param string $path
72
+ * @param array $skipPaths
73
+ * @param bool $removeRoot
74
+ * @throws Mage_Exception
75
+ */
76
+ public function rm($path, $skipPaths = array(), $removeRoot = false)
77
+ {
78
+ $filesystemIterator = new RecursiveIteratorIterator(
79
+ new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST
80
+ );
81
+
82
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $skipPaths);
83
+
84
+ foreach ($iterator as $item) {
85
+ $item->isDir() ? @rmdir($item->__toString()) : @unlink($item->__toString());
86
+ }
87
+
88
+ if ($removeRoot && is_dir($path)) {
89
+ @rmdir($path);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Get information (readable, writable, size) about $path
95
+ *
96
+ * @param string $path
97
+ * @param int $infoOptions
98
+ * @param array $skipFiles
99
+ */
100
+ public function getInfo($path, $infoOptions = self::INFO_ALL, $skipFiles = array())
101
+ {
102
+ $info = array();
103
+ if ($infoOptions & self::INFO_READABLE) {
104
+ $info['readable'] = true;
105
+ }
106
+
107
+ if ($infoOptions & self::INFO_WRITABLE) {
108
+ $info['writable'] = true;
109
+ }
110
+
111
+ if ($infoOptions & self::INFO_SIZE) {
112
+ $info['size'] = 0;
113
+ }
114
+
115
+ $filesystemIterator = new RecursiveIteratorIterator(
116
+ new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST
117
+ );
118
+
119
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $skipFiles);
120
+
121
+ foreach ($iterator as $item) {
122
+ if (($infoOptions & self::INFO_WRITABLE) && !$item->isWritable()) {
123
+ $info['writable'] = false;
124
+ }
125
+
126
+ if (($infoOptions & self::INFO_READABLE) && !$item->isReadable()) {
127
+ $info['readable'] = false;
128
+ }
129
+
130
+ if ($infoOptions & self::INFO_SIZE && !$item->isDir()) {
131
+ $info['size'] += $item->getSize();
132
+ }
133
+ }
134
+
135
+ return $info;
136
+ }
137
+ }
lib/Mage/Backup/Filesystem/Iterator/File.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ /**
29
+ * File lines iterator
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Backup
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Mage_Backup_Filesystem_Iterator_File extends SplFileObject
36
+ {
37
+ /**
38
+ * The statement that was last read during iteration
39
+ *
40
+ * @var string
41
+ */
42
+ protected $_currentStatement = '';
43
+
44
+ /**
45
+ * Return current sql statement
46
+ *
47
+ * @return string
48
+ */
49
+ public function current()
50
+ {
51
+ return $this->_currentStatement;
52
+ }
53
+
54
+ /**
55
+ * Iterate to next sql statement in file
56
+ */
57
+ public function next()
58
+ {
59
+ $this->_currentStatement = '';
60
+ while (!$this->eof()) {
61
+ $line = $this->fgets();
62
+ if (strlen(trim($line))) {
63
+ $this->_currentStatement .= $line;
64
+ if ($this->_isLineLastInCommand($line)) {
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Return to first statement
73
+ */
74
+ public function rewind()
75
+ {
76
+ parent::rewind();
77
+ $this->next();
78
+ }
79
+
80
+ /**
81
+ * Check whether provided string is comment
82
+ *
83
+ * @param string $line
84
+ * @return bool
85
+ */
86
+ protected function _isComment($line)
87
+ {
88
+ return $line[0] == '#' || substr($line, 0, 2) == '--';
89
+ }
90
+
91
+ /**
92
+ * Check is line a last in sql command
93
+ *
94
+ * @param string $line
95
+ * @return bool
96
+ */
97
+ protected function _isLineLastInCommand($line)
98
+ {
99
+ $cleanLine = trim($line);
100
+ $lineLength = strlen($cleanLine);
101
+
102
+ $returnResult = false;
103
+ if ($lineLength > 0) {
104
+ $lastSymbolIndex = $lineLength - 1;
105
+ if ($cleanLine[$lastSymbolIndex] == ';') {
106
+ $returnResult = true;
107
+ }
108
+ }
109
+
110
+ return $returnResult;
111
+ }
112
+ }
lib/Mage/Backup/Filesystem/Iterator/Filter.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Filter Iterator
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Iterator_Filter extends FilterIterator
35
+ {
36
+ /**
37
+ * Array that is used for filtering
38
+ *
39
+ * @var array
40
+ */
41
+ protected $_filters;
42
+
43
+ /**
44
+ * Constructor
45
+ *
46
+ * @param Iterator $iterator
47
+ * @param array $filters list of files to skip
48
+ */
49
+ public function __construct(Iterator $iterator, array $filters)
50
+ {
51
+ parent::__construct($iterator);
52
+ $this->_filters = $filters;
53
+ }
54
+
55
+ /**
56
+ * Check whether the current element of the iterator is acceptable
57
+ *
58
+ * @return bool
59
+ */
60
+ public function accept()
61
+ {
62
+ $current = $this->current()->__toString();
63
+ $currentFilename = $this->current()->getFilename();
64
+
65
+ if ($currentFilename == '.' || $currentFilename == '..') {
66
+ return false;
67
+ }
68
+
69
+ foreach ($this->_filters as $filter) {
70
+ if (false !== strpos($current, $filter)) {
71
+ return false;
72
+ }
73
+ }
74
+
75
+ return true;
76
+ }
77
+ }
lib/Mage/Backup/Filesystem/Rollback/Abstract.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Filesystem rollback workers abstract class
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ abstract class Mage_Backup_Filesystem_Rollback_Abstract
35
+ {
36
+ /**
37
+ * Snapshot object
38
+ *
39
+ * @var Mage_Backup_Filesystem
40
+ */
41
+ protected $_snapshot;
42
+
43
+ /**
44
+ * Default worker constructor
45
+ *
46
+ * @param Mage_Backup_Filesystem $snapshotObject
47
+ */
48
+ public function __construct(Mage_Backup_Filesystem $snapshotObject)
49
+ {
50
+ $this->_snapshot = $snapshotObject;
51
+ }
52
+
53
+ /**
54
+ * Main worker's function that makes files rollback
55
+ */
56
+ abstract public function run();
57
+ }
lib/Mage/Backup/Filesystem/Rollback/Fs.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Rollback worker for rolling back via local filesystem
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Rollback_Fs extends Mage_Backup_Filesystem_Rollback_Abstract
35
+ {
36
+ /**
37
+ * Files rollback implementation via local filesystem
38
+ *
39
+ * @see Mage_Backup_Filesystem_Rollback_Abstract::run()
40
+ * @throws Mage_Exception
41
+ */
42
+ public function run()
43
+ {
44
+ $snapshotPath = $this->_snapshot->getBackupPath();
45
+
46
+ if (!is_file($snapshotPath) || !is_readable($snapshotPath)) {
47
+ throw new Mage_Backup_Exception_CantLoadSnapshot('Cant load snapshot archive');
48
+ }
49
+
50
+ $fsHelper = new Mage_Backup_Filesystem_Helper();
51
+
52
+ $filesInfo = $fsHelper->getInfo(
53
+ $this->_snapshot->getRootDir(),
54
+ Mage_Backup_Filesystem_Helper::INFO_WRITABLE,
55
+ $this->_snapshot->getIgnorePaths()
56
+ );
57
+
58
+ if (!$filesInfo['writable']) {
59
+ throw new Mage_Backup_Exception_NotEnoughPermissions(
60
+ 'Unable to make rollback because not all files are writable'
61
+ );
62
+ }
63
+
64
+ $archiver = new Mage_Archive();
65
+
66
+ /**
67
+ * we need these fake initializations because all magento's files in filesystem will be deleted and autoloader
68
+ * wont be able to load classes that we need for unpacking
69
+ */
70
+ new Mage_Archive_Tar();
71
+ new Mage_Archive_Gz();
72
+ new Mage_Archive_Helper_File('');
73
+ new Mage_Archive_Helper_File_Gz('');
74
+
75
+ $fsHelper->rm($this->_snapshot->getRootDir(), $this->_snapshot->getIgnorePaths());
76
+ $archiver->unpack($snapshotPath, $this->_snapshot->getRootDir());
77
+ }
78
+ }
lib/Mage/Backup/Filesystem/Rollback/Ftp.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Rollback worker for rolling back via ftp
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Rollback_Ftp extends Mage_Backup_Filesystem_Rollback_Abstract
35
+ {
36
+ /**
37
+ * Ftp client
38
+ *
39
+ * @var Mage_System_Ftp
40
+ */
41
+ protected $_ftpClient;
42
+
43
+ /**
44
+ * Files rollback implementation via ftp
45
+ *
46
+ * @see Mage_Backup_Filesystem_Rollback_Abstract::run()
47
+ * @throws Mage_Exception
48
+ */
49
+ public function run()
50
+ {
51
+ $snapshotPath = $this->_snapshot->getBackupPath();
52
+
53
+ if (!is_file($snapshotPath) || !is_readable($snapshotPath)) {
54
+ throw new Mage_Backup_Exception_CantLoadSnapshot('Cant load snapshot archive');
55
+ }
56
+
57
+ $this->_initFtpClient();
58
+ $this->_validateFtp();
59
+
60
+ $tmpDir = $this->_createTmpDir();
61
+ $this->_unpackSnapshot($tmpDir);
62
+
63
+ $fsHelper = new Mage_Backup_Filesystem_Helper();
64
+
65
+ $this->_cleanupFtp();
66
+ $this->_uploadBackupToFtp($tmpDir);
67
+
68
+ $fsHelper->rm($tmpDir, array(), true);
69
+ }
70
+
71
+ /**
72
+ * Initialize ftp client and connect to ftp
73
+ *
74
+ * @throws Mage_Backup_Exception_FtpConnectionFailed
75
+ */
76
+ protected function _initFtpClient()
77
+ {
78
+ try {
79
+ $this->_ftpClient = new Mage_System_Ftp();
80
+ $this->_ftpClient->connect($this->_snapshot->getFtpConnectString());
81
+ } catch (Exception $e) {
82
+ throw new Mage_Backup_Exception_FtpConnectionFailed($e->getMessage());
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Perform ftp validation. Check whether ftp account provided points to current magento installation
88
+ *
89
+ * @throws Mage_Exception
90
+ */
91
+ protected function _validateFtp()
92
+ {
93
+ $validationFilename = '~validation-' . microtime(true) . '.tmp';
94
+ $validationFilePath = $this->_snapshot->getBackupsDir() . DS . $validationFilename;
95
+
96
+ $fh = @fopen($validationFilePath, 'w');
97
+ @fclose($fh);
98
+
99
+ if (!is_file($validationFilePath)) {
100
+ throw new Mage_Exception('Unable to validate ftp account');
101
+ }
102
+
103
+ $rootDir = $this->_snapshot->getRootDir();
104
+ $ftpPath = $this->_snapshot->getFtpPath() . DS . str_replace($rootDir, '', $validationFilePath);
105
+
106
+ $fileExistsOnFtp = $this->_ftpClient->fileExists($ftpPath);
107
+ @unlink($validationFilePath);
108
+
109
+ if (!$fileExistsOnFtp) {
110
+ throw new Mage_Backup_Exception_FtpValidationFailed('Failed to validate ftp account');
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Unpack snapshot
116
+ *
117
+ * @param string $tmpDir
118
+ */
119
+ protected function _unpackSnapshot($tmpDir)
120
+ {
121
+ $snapshotPath = $this->_snapshot->getBackupPath();
122
+
123
+ $archiver = new Mage_Archive();
124
+ $archiver->unpack($snapshotPath, $tmpDir);
125
+ }
126
+
127
+ /**
128
+ * @throws Mage_Exception
129
+ * @return string
130
+ */
131
+ protected function _createTmpDir()
132
+ {
133
+ $tmpDir = $this->_snapshot->getBackupsDir() . DS . '~tmp-' . microtime(true);
134
+
135
+ $result = @mkdir($tmpDir);
136
+
137
+ if (false === $result) {
138
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Failed to create directory ' . $tmpDir);
139
+ }
140
+
141
+ return $tmpDir;
142
+ }
143
+
144
+ /**
145
+ * Delete magento and all files from ftp
146
+ */
147
+ protected function _cleanupFtp()
148
+ {
149
+ $rootDir = $this->_snapshot->getRootDir();
150
+
151
+ $filesystemIterator = new RecursiveIteratorIterator(
152
+ new RecursiveDirectoryIterator($rootDir), RecursiveIteratorIterator::CHILD_FIRST
153
+ );
154
+
155
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $this->_snapshot->getIgnorePaths());
156
+
157
+ foreach ($iterator as $item) {
158
+ $ftpPath = $this->_snapshot->getFtpPath() . DS . str_replace($rootDir, '', $item->__toString());
159
+ $ftpPath = str_replace(DS, '/', $ftpPath);
160
+
161
+ $this->_ftpClient->delete($ftpPath);
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Perform files rollback
167
+ *
168
+ * @param string $tmpDir
169
+ * @throws Mage_Exception
170
+ */
171
+ protected function _uploadBackupToFtp($tmpDir)
172
+ {
173
+ $filesystemIterator = new RecursiveIteratorIterator(
174
+ new RecursiveDirectoryIterator($tmpDir), RecursiveIteratorIterator::SELF_FIRST
175
+ );
176
+
177
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $this->_snapshot->getIgnorePaths());
178
+
179
+ foreach ($filesystemIterator as $item) {
180
+ $ftpPath = $this->_snapshot->getFtpPath() . DS . str_replace($tmpDir, '', $item->__toString());
181
+ $ftpPath = str_replace(DS, '/', $ftpPath);
182
+
183
+ if ($item->isLink()) {
184
+ continue;
185
+ }
186
+
187
+ if ($item->isDir()) {
188
+ $this->_ftpClient->mkdirRecursive($ftpPath);
189
+ } else {
190
+ $result = $this->_ftpClient->put($ftpPath, $item->__toString());
191
+ if (false === $result) {
192
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Failed to upload file '
193
+ . $item->__toString() . ' to ftp');
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
lib/Mage/Backup/Interface.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Interface for work with archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ interface Mage_Backup_Interface
35
+ {
36
+ /**
37
+ * Create Backup
38
+ *
39
+ * @return boolean
40
+ */
41
+ public function create();
42
+
43
+ /**
44
+ * Rollback Backup
45
+ *
46
+ * @return boolean
47
+ */
48
+ public function rollback();
49
+
50
+ /**
51
+ * Set Backup Extension
52
+ *
53
+ * @param string $backupExtension
54
+ * @return Mage_Backup_Interface
55
+ */
56
+ public function setBackupExtension($backupExtension);
57
+
58
+ /**
59
+ * Set Resource Model
60
+ *
61
+ * @param object $resourceModel
62
+ * @return Mage_Backup_Interface
63
+ */
64
+ public function setResourceModel($resourceModel);
65
+
66
+ /**
67
+ * Set Time
68
+ *
69
+ * @param int $time
70
+ * @return Mage_Backup_Interface
71
+ */
72
+ public function setTime($time);
73
+
74
+ /**
75
+ * Get Backup Type
76
+ *
77
+ * @return string
78
+ */
79
+ public function getType();
80
+
81
+ /**
82
+ * Set path to directory where backups stored
83
+ *
84
+ * @param string $backupsDir
85
+ * @return Mage_Backup_Interface
86
+ */
87
+ public function setBackupsDir($backupsDir);
88
+ }
lib/Mage/Backup/Media.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work media folder and database backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Media extends Mage_Backup_Snapshot
35
+ {
36
+ /**
37
+ * Implementation Rollback functionality for Snapshot
38
+ *
39
+ * @throws Mage_Exception
40
+ * @return bool
41
+ */
42
+ public function rollback()
43
+ {
44
+ $this->_prepareIgnoreList();
45
+ return parent::rollback();
46
+ }
47
+
48
+ /**
49
+ * Implementation Create Backup functionality for Snapshot
50
+ *
51
+ * @throws Mage_Exception
52
+ * @return bool
53
+ */
54
+ public function create()
55
+ {
56
+ $this->_prepareIgnoreList();
57
+ return parent::create();
58
+ }
59
+
60
+ /**
61
+ * Overlap getType
62
+ *
63
+ * @return string
64
+ * @see Mage_Backup_Interface::getType()
65
+ */
66
+ public function getType()
67
+ {
68
+ return 'media';
69
+ }
70
+
71
+ /**
72
+ * Add all folders and files except media and db backup to ignore list
73
+ *
74
+ * @return Mage_Backup_Media
75
+ */
76
+ protected function _prepareIgnoreList()
77
+ {
78
+ $iterator = new DirectoryIterator($this->getRootDir());
79
+
80
+ foreach ($iterator as $item) {
81
+ $filename = $item->getFilename();
82
+ if (!in_array($filename, array('media', 'var'))) {
83
+ $this->addIgnorePaths($item->getPathname());
84
+ }
85
+ }
86
+
87
+ $iterator = new DirectoryIterator($this->getRootDir() . DS . 'var');
88
+ $dbBackupFilename = $this->_getDbBackupManager()->getBackupFilename();
89
+
90
+ foreach ($iterator as $item) {
91
+ $filename = $item->getFilename();
92
+ if ($filename != $dbBackupFilename) {
93
+ $this->addIgnorePaths($item->getPathname());
94
+ }
95
+ }
96
+
97
+ return $this;
98
+ }
99
+ }
lib/Mage/Backup/Nomedia.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work system backup that excludes media folder
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Nomedia extends Mage_Backup_Snapshot
35
+ {
36
+ /**
37
+ * Implementation Rollback functionality for Snapshot
38
+ *
39
+ * @throws Mage_Exception
40
+ * @return bool
41
+ */
42
+ public function rollback()
43
+ {
44
+ $this->_prepareIgnoreList();
45
+ return parent::rollback();
46
+ }
47
+
48
+ /**
49
+ * Implementation Create Backup functionality for Snapshot
50
+ *
51
+ * @throws Mage_Exception
52
+ * @return bool
53
+ */
54
+ public function create()
55
+ {
56
+ $this->_prepareIgnoreList();
57
+ return parent::create();
58
+ }
59
+
60
+ /**
61
+ * Overlap getType
62
+ *
63
+ * @return string
64
+ * @see Mage_Backup_Interface::getType()
65
+ */
66
+ public function getType()
67
+ {
68
+ return 'nomedia';
69
+ }
70
+
71
+ /**
72
+ * Add media folder to ignore list
73
+ *
74
+ * @return Mage_Backup_Media
75
+ */
76
+ protected function _prepareIgnoreList()
77
+ {
78
+ $this->addIgnorePaths($this->getRootDir() . DS . 'media');
79
+
80
+ return $this;
81
+ }
82
+ }
lib/Mage/Backup/Snapshot.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with full filesystem and database backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Snapshot extends Mage_Backup_Filesystem
35
+ {
36
+ /**
37
+ * Database backup manager
38
+ *
39
+ * @var Mage_Backup_Db
40
+ */
41
+ protected $_dbBackupManager;
42
+
43
+ /**
44
+ * Implementation Rollback functionality for Snapshot
45
+ *
46
+ * @throws Mage_Exception
47
+ * @return bool
48
+ */
49
+ public function rollback()
50
+ {
51
+ $result = parent::rollback();
52
+
53
+ $this->_lastOperationSucceed = false;
54
+
55
+ try {
56
+ $this->_getDbBackupManager()->rollback();
57
+ } catch (Exception $e) {
58
+ $this->_removeDbBackup();
59
+ throw $e;
60
+ }
61
+
62
+ $this->_removeDbBackup();
63
+ $this->_lastOperationSucceed = true;
64
+
65
+ return $result;
66
+ }
67
+
68
+ /**
69
+ * Implementation Create Backup functionality for Snapshot
70
+ *
71
+ * @throws Mage_Exception
72
+ * @return bool
73
+ */
74
+ public function create()
75
+ {
76
+ $this->_getDbBackupManager()->create();
77
+
78
+ try {
79
+ $result = parent::create();
80
+ } catch (Exception $e) {
81
+ $this->_removeDbBackup();
82
+ throw $e;
83
+ }
84
+
85
+ $this->_lastOperationSucceed = false;
86
+ $this->_removeDbBackup();
87
+ $this->_lastOperationSucceed = true;
88
+
89
+ return $result;
90
+ }
91
+
92
+ /**
93
+ * Overlap getType
94
+ *
95
+ * @return string
96
+ * @see Mage_Backup_Interface::getType()
97
+ */
98
+ public function getType()
99
+ {
100
+ return 'snapshot';
101
+ }
102
+
103
+ /**
104
+ * Create Db Instance
105
+ *
106
+ * @return Mage_Backup_Interface
107
+ */
108
+ protected function _createDbBackupInstance()
109
+ {
110
+ return Mage_Backup::getBackupInstance(Mage_Backup_Helper_Data::TYPE_DB)
111
+ ->setBackupExtension(Mage::helper('backup')->getExtensionByType(Mage_Backup_Helper_Data::TYPE_DB))
112
+ ->setTime($this->getTime())
113
+ ->setBackupsDir(Mage::getBaseDir("var"))
114
+ ->setResourceModel($this->getResourceModel());
115
+ }
116
+
117
+ /**
118
+ * Get database backup manager
119
+ *
120
+ * @return Mage_Backup_Db
121
+ */
122
+ protected function _getDbBackupManager()
123
+ {
124
+ if (is_null($this->_dbBackupManager)) {
125
+ $this->_dbBackupManager = $this->_createDbBackupInstance();
126
+ }
127
+
128
+ return $this->_dbBackupManager;
129
+ }
130
+
131
+ /**
132
+ * Remove Db backup after added it to the snapshot
133
+ *
134
+ * @return Mage_Backup_Snapshot
135
+ */
136
+ protected function _removeDbBackup(){
137
+ @unlink($this->_getDbBackupManager()->getBackupPath());
138
+ return $this;
139
+ }
140
+ }
lib/Mage/Connect/Ftp.php CHANGED
@@ -31,464 +31,6 @@
31
  * @package Mage_Connect
32
  * @author Magento Core Team <core@magentocommerce.com>
33
  */
34
- class Mage_Connect_Ftp
35
  {
36
-
37
- /**
38
- * Connection object
39
- * @var resource
40
- */
41
- protected $_conn = false;
42
-
43
- public function __construct()
44
- {
45
-
46
- }
47
-
48
- /**
49
- * Check connected, throw exception if not
50
- * @throws Exception
51
- * @return void
52
- */
53
- protected function checkConnected()
54
- {
55
- if(!$this->_conn) {
56
- throw new Exception(__CLASS__." - no connection established with server");
57
- }
58
- }
59
-
60
- /**
61
- * ftp_mkdir wrapper
62
- * @param stin$name
63
- * @return unknown_type
64
- */
65
- public function mdkir($name)
66
- {
67
- $this->checkConnected();
68
- return @ftp_mkdir($this->_conn, $name);
69
- }
70
-
71
-
72
-
73
- /**
74
- * Make dir recursive
75
- * @param string $path
76
- * @param int $mode
77
- */
78
- public function mkdirRecursive($path, $mode = 0777)
79
- {
80
- $this->checkConnected();
81
- $dir = split("/", $path);
82
- $path= "";
83
- $ret = true;
84
- for ($i=0; $i < count($dir); $i++) {
85
- $path .= "/" .$dir[$i];
86
- if(!@ftp_chdir($this->_conn, $path)) {
87
- @ftp_chdir($this->_conn,"/");
88
- if(!@ftp_mkdir($this->_conn,$path)) {
89
- $ret=false;
90
- break;
91
- } else {
92
- @ftp_chmod($this->_conn, $mode, $path);
93
- }
94
- }
95
- }
96
- return $ret;
97
- }
98
-
99
-
100
- /**
101
- * Try to login to server
102
- * @param string $login
103
- * @param string $password
104
- * @throws Exception on invalid login credentials
105
- * @return bool
106
- */
107
- public function login($login = "anonymous", $password = "test@gmail.com")
108
- {
109
- $this->checkConnected();
110
- $res = @ftp_login($this->_conn, $login, $password);
111
- if(!$res) {
112
- throw new Exception("Invalid login credentials");
113
- }
114
- return $res;
115
- }
116
-
117
- /**
118
- * Validate connection string
119
- * @param string $string
120
- * @throws Exception
121
- * @return string
122
- */
123
- public function validateConnectionString($string)
124
- {
125
- $data = @parse_url($string);
126
- if(false === $data) {
127
- throw new Exception("Connection string invalid: '{$string}'");
128
- }
129
- if($data['scheme'] != 'ftp') {
130
- throw new Exception("Support for scheme unsupported: '{$data['scheme']}'");
131
- }
132
- return $data;
133
- }
134
-
135
- /**
136
- * Connect to server using connect string
137
- * Connection string: ftp://user:pass@server:port/path
138
- * user,pass,port,path are optional parts
139
- * @param string $string
140
- *
141
- * @param $timeout
142
- * @return unknown_type
143
- */
144
- public function connect($string, $timeout = 900)
145
- {
146
- $params = $this->validateConnectionString($string);
147
- $port = isset($params['port']) ? intval($params['port']) : 21;
148
-
149
- $this->_conn = ftp_connect($params['host'], $port, $timeout);
150
-
151
- if(!$this->_conn) {
152
- throw new Exception("Cannot connect to host: {$params['host']}");
153
- }
154
- if(isset($params['user']) && isset($params['pass'])) {
155
- $this->login($params['user'], $params['pass']);
156
- } else {
157
- $this->login();
158
- }
159
- if(isset($params['path'])) {
160
- if(!$this->chdir($params['path'])) {
161
- throw new Exception ("Cannot chdir after login to: {$params['path']}");
162
- }
163
- }
164
- }
165
-
166
- /**
167
- * ftp_fput wrapper
168
- * @param string $remoteFile
169
- * @param resource $handle
170
- * @param int $mode FTP_BINARY | FTP_ASCII
171
- * @param int $startPos
172
- * @return bool
173
- */
174
-
175
- public function fput($remoteFile, $handle, $mode = FTP_BINARY, $startPos = 0)
176
- {
177
- $this->checkConnected();
178
- return @ftp_fput($this->_conn, $remoteFile, $handle, $mode, $startPos);
179
- }
180
-
181
- /**
182
- * ftp_put wrapper
183
- * @param string $remoteFile
184
- * @param string $localFile
185
- * @param int $mode FTP_BINARY | FTP_ASCII
186
- * @param int $startPos
187
- * @return bool
188
- */
189
- public function put($remoteFile, $localFile, $mode = FTP_BINARY, $startPos = 0)
190
- {
191
- $this->checkConnected();
192
- return ftp_put($this->_conn, $remoteFile, $localFile, $mode, $startPos);
193
- }
194
-
195
-
196
- /**
197
- * Get current working directory
198
- * @return mixed
199
- */
200
- public function getcwd()
201
- {
202
- $d = $this->raw("pwd");
203
- $data = explode(" ", $d[0], 3);
204
- if(empty($data[1])) {
205
- return false;
206
- }
207
- if(intval($data[0]) != 257) {
208
- return false;
209
- }
210
- $out = trim($data[1], '"');
211
- if($out !== "/") {
212
- $out = rtrim($out, "/");
213
- }
214
- return $out;
215
- }
216
-
217
- /**
218
- * ftp_raw wrapper
219
- * @param string $cmd
220
- * @return mixed
221
- */
222
- public function raw($cmd)
223
- {
224
- $this->checkConnected();
225
- return @ftp_raw($this->_conn, $cmd);
226
- }
227
-
228
-
229
- /**
230
- * Upload local file to remote
231
- *
232
- * Can be used for relative and absoulte remote paths
233
- * Relative: use chdir before calling this
234
- *
235
- * @param srting $remote
236
- * @param string $local
237
- * @param int $dirMode
238
- * @param int $ftpMode
239
- * @return unknown_type
240
- */
241
- public function upload($remote, $local, $dirMode = 0777, $ftpMode = FTP_BINARY)
242
- {
243
- $this->checkConnected();
244
-
245
- if(!file_exists($local)) {
246
- throw new Exception("Local file doesn't exist: {$localFile}");
247
- }
248
- if(!is_readable($local)) {
249
- throw new Exception("Local file is not readable: {$localFile}");
250
- }
251
- if(is_dir($local)) {
252
- throw new Exception("Directory given instead of file: {$localFile}");
253
- }
254
-
255
- $globalPathMode = substr($remote, 0, 1) == "/";
256
- $dirname = dirname($remote);
257
- $cwd = $this->getcwd();
258
- if(false === $cwd) {
259
- throw new Exception("Server returns something awful on PWD command");
260
- }
261
-
262
- if(!$globalPathMode) {
263
- $dirname = $cwd."/".$dirname;
264
- $remote = $cwd."/".$remote;
265
- }
266
- $res = $this->mkdirRecursive($dirname, $dirMode);
267
- $this->chdir($cwd);
268
-
269
- if(!$res) {
270
- return false;
271
- }
272
- return $this->put($remote, $local, $ftpMode);
273
- }
274
-
275
- /**
276
- * Download remote file to local machine
277
- * @param string $remote
278
- * @param string $local
279
- * @param int $ftpMode FTP_BINARY|FTP_ASCII
280
- * @return bool
281
- */
282
- public function download($remote, $local, $ftpMode = FTP_BINARY)
283
- {
284
- $this->checkConnected();
285
- return $this->get($local, $remote, $ftpMode);
286
- }
287
-
288
-
289
- /**
290
- * ftp_pasv wrapper
291
- * @param bool $pasv
292
- * @return bool
293
- */
294
- public function pasv($pasv)
295
- {
296
- $this->checkConnected();
297
- return @ftp_pasv($this->_conn, (bool) $pasv);
298
- }
299
-
300
- /**
301
- * Close FTP connection
302
- * @return void
303
- */
304
- public function close()
305
- {
306
- if($this->_conn) {
307
- @ftp_close($this->_conn);
308
- }
309
- }
310
-
311
- /**
312
- * ftp_chmod wrapper
313
- * @param $mode
314
- * @param $remoteFile
315
- * @return bool
316
- */
317
- public function chmod($mode, $remoteFile)
318
- {
319
- $this->checkConnected();
320
- return @ftp_chmod($this->_conn, $mode, $remoteFile);
321
- }
322
-
323
- /**
324
- * ftp_chdir wrapper
325
- * @param string $dir
326
- * @return bool
327
- */
328
- public function chdir($dir)
329
- {
330
- $this->checkConnected();
331
- return @ftp_chdir($this->_conn, $dir);
332
- }
333
-
334
- /**
335
- * ftp_cdup wrapper
336
- * @return bool
337
- */
338
- public function cdup()
339
- {
340
- $this->checkConnected();
341
- return @ftp_cdup($this->_conn);
342
- }
343
-
344
- /**
345
- * ftp_get wrapper
346
- * @param string $localFile
347
- * @param string $remoteFile
348
- * @param int $fileMode FTP_BINARY | FTP_ASCII
349
- * @param int $resumeOffset
350
- * @return bool
351
- */
352
- public function get($localFile, $remoteFile, $fileMode = FTP_BINARY, $resumeOffset = 0)
353
- {
354
- $remoteFile = $this->correctFilePath($remoteFile);
355
- $this->checkConnected();
356
- return @ftp_get($this->_conn, $localFile, $remoteFile, $fileMode, $resumeOffset);
357
- }
358
-
359
- /**
360
- * ftp_nlist wrapper
361
- * @param string $dir
362
- * @return bool
363
- */
364
- public function nlist($dir = "/")
365
- {
366
- $this->checkConnected();
367
- $dir = $this->correctFilePath($dir);
368
- return @ftp_nlist($this->_conn, $dir);
369
- }
370
-
371
- /**
372
- * ftp_rawlist wrapper
373
- * @param string $dir
374
- * @param bool $recursive
375
- * @return mixed
376
- */
377
- public function rawlist( $dir = "/", $recursive = false )
378
- {
379
- $this->checkConnected();
380
- $dir = $this->correctFilePath($dir);
381
- return @ftp_rawlist($this->_conn, $dir, $recursive);
382
- }
383
-
384
-
385
- /**
386
- * Convert byte count to float KB/MB format
387
- * @param int $bytes
388
- * @return string
389
- */
390
- public static function byteconvert($bytes)
391
- {
392
- $symbol = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
393
- $exp = floor( log($bytes) / log(1024) );
394
- return sprintf( '%.2f ' . $symbol[ $exp ], ($bytes / pow(1024, floor($exp))) );
395
- }
396
-
397
- /**
398
- * Chmod string "-rwxrwxrwx" to "777" converter
399
- * @param string $chmod
400
- * @return string
401
- */
402
- public static function chmodnum($chmod)
403
- {
404
- $trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
405
- $chmod = substr(strtr($chmod, $trans), 1);
406
- $array = str_split($chmod, 3);
407
- return array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
408
- }
409
-
410
-
411
- public function fileExists($path, $excludeIfIsDir = true)
412
- {
413
- $path = $this->correctFilePath($path);
414
- $globalPathMode = substr($path, 0, 1) == "/";
415
-
416
- $file = basename($path);
417
- $dir = $globalPathMode ? dirname($path) : $this->getcwd()."/".$path;
418
- $data = $this->ls($dir);
419
- foreach($data as $row) {
420
- if($file == $row['name']) {
421
- if($excludeIfIsDir && $row['dir']) {
422
- continue;
423
- }
424
- return true;
425
- }
426
- }
427
- return false;
428
- }
429
-
430
-
431
- /**
432
- * Get directory contents in PHP array
433
- * @param string $dir
434
- * @param bool $recursive
435
- * @return array
436
- */
437
- public function ls($dir = "/", $recursive = false)
438
- {
439
- $dir= $this->correctFilePath($dir);
440
- $rawfiles = (array) $this->rawlist($dir, $recursive);
441
- $structure = array();
442
- $arraypointer = &$structure;
443
- foreach ($rawfiles as $rawfile) {
444
- if ($rawfile[0] == '/') {
445
- $paths = array_slice(explode('/', str_replace(':', '', $rawfile)), 1);
446
- $arraypointer = &$structure;
447
- foreach ($paths as $path) {
448
- foreach ($arraypointer as $i => $file) {
449
- if ($file['name'] == $path) {
450
- $arraypointer = &$arraypointer[ $i ]['children'];
451
- break;
452
- }
453
- }
454
- }
455
- } elseif(!empty($rawfile)) {
456
- $info = preg_split("/[\s]+/", $rawfile, 9);
457
- $arraypointer[] = array(
458
- 'name' => $info[8],
459
- 'dir' => $info[0]{0} == 'd',
460
- 'size' => (int) $info[4],
461
- 'chmod' => self::chmodnum($info[0]),
462
- 'rawdata' => $info,
463
- 'raw' => $rawfile
464
- );
465
- }
466
- }
467
- return $structure;
468
- }
469
-
470
-
471
- /**
472
- * Correct file path
473
- * @param $str
474
- * @return string
475
- */
476
- public function correctFilePath($str)
477
- {
478
- $str = str_replace("\\", "/", $str);
479
- $str = preg_replace("/^.\//", "", $str);
480
- return $str;
481
- }
482
-
483
- public function delete($file)
484
- {
485
- $this->checkConnected();
486
- $file = $this->correctFilePath($file);
487
- return @ftp_delete($this->_conn, $file);
488
- }
489
-
490
-
491
-
492
-
493
-
494
- }
31
  * @package Mage_Connect
32
  * @author Magento Core Team <core@magentocommerce.com>
33
  */
34
+ class Mage_Connect_Ftp extends Mage_System_Ftp
35
  {
36
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/Mage/Connect/Packager.php CHANGED
@@ -34,14 +34,11 @@
34
 
35
  class Mage_Connect_Packager
36
  {
37
-
38
  /**
39
  * Constructor
40
- * @param Mage_connect_Config $config
41
  */
42
  public function __construct()
43
  {
44
-
45
  }
46
 
47
  /**
@@ -340,7 +337,7 @@ class Mage_Connect_Packager
340
  * @param string/array $channels
341
  * @param Mage_Connect_Singleconfig $cacheObject
342
  * @param Mage_Connect_Rest $restObj optional
343
- * @param bool $checkConflicts
344
  * @return array
345
  */
346
  public function getUpgradesList($channels, $cacheObject, $configObj, $restObj = null, $checkConflicts = false)
@@ -449,10 +446,10 @@ class Mage_Connect_Packager
449
 
450
  //print "Processing outer: {$keyOuter} \n";
451
  $hash[$keyOuter] = array (
452
- 'name' => $package,
453
- 'channel' => $chanName,
454
- 'version' => $version,
455
- 'packages' => $dependencies,
456
  );
457
 
458
  if($withDepsRecursive) {
@@ -473,7 +470,6 @@ class Mage_Connect_Packager
473
  }
474
 
475
  } catch (Exception $e) {
476
- //$this->_failed[] = array('name'=>$package, 'channel'=>$chanName, 'max'=>$versionMax, 'min'=>$versionMin, 'reason'=>$e->getMessage());
477
  }
478
 
479
  $level--;
@@ -496,9 +492,9 @@ class Mage_Connect_Packager
496
  * @param mixed $versionMin
497
  * @return mixed
498
  */
499
- public function getDependenciesList( $chanName, $package, $cache, $config, $versionMax = false, $versionMin = false, $withDepsRecursive = true, $forceRemote = false)
500
- {
501
-
502
  static $level = 0;
503
  static $_depsHash = array();
504
  static $_deps = array();
@@ -530,12 +526,12 @@ class Mage_Connect_Packager
530
 
531
  //print "Processing outer: {$keyOuter} \n";
532
  $_depsHash[$keyOuter] = array (
533
- 'name' => $package,
534
- 'channel' => $chanName,
535
- 'downloaded_version' => $version,
536
- 'min' => $versionMin,
537
- 'max' => $versionMax,
538
- 'packages' => $dependencies,
539
  );
540
 
541
  if($withDepsRecursive) {
@@ -580,7 +576,13 @@ class Mage_Connect_Packager
580
  if(!$cache->hasVersionRangeIntersect($pMin,$pMax, $hasMin, $hasMax)) {
581
  $reason = "Detected {$pName} conflict of versions: {$hasMin}-{$hasMax} and {$pMin}-{$pMax}";
582
  unset($_depsHash[$keyInner]);
583
- $_failed[] = array('name'=>$pName, 'channel'=>$pChannel, 'max'=>$pMax, 'min'=>$pMin, 'reason'=>$reason);
 
 
 
 
 
 
584
  continue;
585
  }
586
  $newMaxIsLess = version_compare($pMax, $hasMax, "<");
@@ -594,24 +596,27 @@ class Mage_Connect_Packager
594
  }
595
  }
596
  } catch (Exception $e) {
597
- $_failed[] = array('name'=>$package, 'channel'=>$chanName, 'max'=>$versionMax, 'min'=>$versionMin, 'reason'=>$e->getMessage());
 
 
 
 
 
 
598
  }
599
-
600
-
601
  $level--;
602
  if($level == 0) {
603
  $out = $this->processDepsHash($_depsHash);
604
- $deps = $_deps;
605
  $failed = $_failed;
606
  $_depsHash = array();
607
  $_deps = array();
608
- $_failed = array();
609
- return array('deps' => $deps, 'result' => $out, 'failed'=> $failed);
610
  }
611
-
612
  }
613
 
614
-
615
  /**
616
  * Process dependencies hash
617
  * Makes topological sorting and gives operation order list
@@ -658,5 +663,4 @@ class Mage_Connect_Packager
658
  unset($graph, $nodes);
659
  return $out;
660
  }
661
-
662
- }
34
 
35
  class Mage_Connect_Packager
36
  {
 
37
  /**
38
  * Constructor
 
39
  */
40
  public function __construct()
41
  {
 
42
  }
43
 
44
  /**
337
  * @param string/array $channels
338
  * @param Mage_Connect_Singleconfig $cacheObject
339
  * @param Mage_Connect_Rest $restObj optional
340
+ * @param bool $checkConflicts
341
  * @return array
342
  */
343
  public function getUpgradesList($channels, $cacheObject, $configObj, $restObj = null, $checkConflicts = false)
446
 
447
  //print "Processing outer: {$keyOuter} \n";
448
  $hash[$keyOuter] = array (
449
+ 'name' => $package,
450
+ 'channel' => $chanName,
451
+ 'version' => $version,
452
+ 'packages' => $dependencies,
453
  );
454
 
455
  if($withDepsRecursive) {
470
  }
471
 
472
  } catch (Exception $e) {
 
473
  }
474
 
475
  $level--;
492
  * @param mixed $versionMin
493
  * @return mixed
494
  */
495
+ public function getDependenciesList($chanName, $package, $cache, $config, $versionMax = false, $versionMin = false,
496
+ $withDepsRecursive = true, $forceRemote = false
497
+ ) {
498
  static $level = 0;
499
  static $_depsHash = array();
500
  static $_deps = array();
526
 
527
  //print "Processing outer: {$keyOuter} \n";
528
  $_depsHash[$keyOuter] = array (
529
+ 'name' => $package,
530
+ 'channel' => $chanName,
531
+ 'downloaded_version' => $version,
532
+ 'min' => $versionMin,
533
+ 'max' => $versionMax,
534
+ 'packages' => $dependencies,
535
  );
536
 
537
  if($withDepsRecursive) {
576
  if(!$cache->hasVersionRangeIntersect($pMin,$pMax, $hasMin, $hasMax)) {
577
  $reason = "Detected {$pName} conflict of versions: {$hasMin}-{$hasMax} and {$pMin}-{$pMax}";
578
  unset($_depsHash[$keyInner]);
579
+ $_failed[] = array(
580
+ 'name' => $pName,
581
+ 'channel' => $pChannel,
582
+ 'max' => $pMax,
583
+ 'min' => $pMin,
584
+ 'reason' => $reason
585
+ );
586
  continue;
587
  }
588
  $newMaxIsLess = version_compare($pMax, $hasMax, "<");
596
  }
597
  }
598
  } catch (Exception $e) {
599
+ $_failed[] = array(
600
+ 'name' => $package,
601
+ 'channel' => $chanName,
602
+ 'max' => $versionMax,
603
+ 'min' => $versionMin,
604
+ 'reason' => $e->getMessage()
605
+ );
606
  }
607
+
 
608
  $level--;
609
  if($level == 0) {
610
  $out = $this->processDepsHash($_depsHash);
611
+ $deps = $_deps;
612
  $failed = $_failed;
613
  $_depsHash = array();
614
  $_deps = array();
615
+ $_failed = array();
616
+ return array('deps' => $deps, 'result' => $out, 'failed'=> $failed);
617
  }
 
618
  }
619
 
 
620
  /**
621
  * Process dependencies hash
622
  * Makes topological sorting and gives operation order list
663
  unset($graph, $nodes);
664
  return $out;
665
  }
666
+ }
 
lib/Mage/Exception.php CHANGED
@@ -20,7 +20,7 @@
20
  *
21
  * @category Mage
22
  * @package Mage
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
 
@@ -32,4 +32,5 @@
32
  * @author Magento Core Team <core@magentocommerce.com>
33
  */
34
  class Mage_Exception extends Exception
35
- {}
 
20
  *
21
  * @category Mage
22
  * @package Mage
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
  */
26
 
32
  * @author Magento Core Team <core@magentocommerce.com>
33
  */
34
  class Mage_Exception extends Exception
35
+ {
36
+ }
lib/Mage/System/Args.php CHANGED
@@ -19,7 +19,7 @@
19
  * needs please refer to http://www.magentocommerce.com for more information.
20
  *
21
  * @category Mage
22
- * @package Mage_Connect
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
  */
@@ -59,7 +59,7 @@ class Mage_System_Args
59
  {
60
  $this->flags = array();
61
  $this->filtered = array();
62
-
63
  if(false === $source) {
64
  $argv = $GLOBALS['argv'];
65
  array_shift($argv);
@@ -89,7 +89,7 @@ class Mage_System_Args
89
  }
90
  elseif(strlen($str) == 2 && $str[0] == '-') // -a
91
  {
92
- $this->flags[$str[1]] = true;
93
  if(isset($argv[$i + 1]) && preg_match('/^--?.+/', $argv[$i + 1]) == 0) {
94
  $this->flags[$str[1]] = $argv[$i + 1];
95
  $argv[$i + 1] = null;
@@ -99,4 +99,4 @@ class Mage_System_Args
99
  }
100
  }
101
  }
102
- }
19
  * needs please refer to http://www.magentocommerce.com for more information.
20
  *
21
  * @category Mage
22
+ * @package Mage_System
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
  */
59
  {
60
  $this->flags = array();
61
  $this->filtered = array();
62
+
63
  if(false === $source) {
64
  $argv = $GLOBALS['argv'];
65
  array_shift($argv);
89
  }
90
  elseif(strlen($str) == 2 && $str[0] == '-') // -a
91
  {
92
+ $this->flags[$str[1]] = true;
93
  if(isset($argv[$i + 1]) && preg_match('/^--?.+/', $argv[$i + 1]) == 0) {
94
  $this->flags[$str[1]] = $argv[$i + 1];
95
  $argv[$i + 1] = null;
99
  }
100
  }
101
  }
102
+ }
lib/Mage/System/Dirs.php CHANGED
@@ -79,4 +79,4 @@ class Mage_System_Dirs
79
  }
80
 
81
  }
82
- }
79
  }
80
 
81
  }
82
+ }
lib/Mage/System/Ftp.php ADDED
@@ -0,0 +1,509 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_System
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
+ /**
28
+ * Class to work with remote FTP server
29
+ *
30
+ * @category Mage
31
+ * @package Mage_System
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_System_Ftp
35
+ {
36
+
37
+ /**
38
+ * Connection object
39
+ *
40
+ * @var resource
41
+ */
42
+ protected $_conn = false;
43
+
44
+ /**
45
+ * Check connected, throw exception if not
46
+ *
47
+ * @throws Exception
48
+ * @return void
49
+ */
50
+ protected function checkConnected()
51
+ {
52
+ if(!$this->_conn) {
53
+ throw new Exception(__CLASS__." - no connection established with server");
54
+ }
55
+ }
56
+
57
+ /**
58
+ * ftp_mkdir wrapper
59
+ *
60
+ * @param stin$name
61
+ * @return unknown_type
62
+ */
63
+ public function mdkir($name)
64
+ {
65
+ $this->checkConnected();
66
+ return @ftp_mkdir($this->_conn, $name);
67
+ }
68
+
69
+ /**
70
+ * Make dir recursive
71
+ *
72
+ * @param string $path
73
+ * @param int $mode
74
+ * @return bool
75
+ */
76
+ public function mkdirRecursive($path, $mode = 0777)
77
+ {
78
+ $this->checkConnected();
79
+ $dir = explode("/", $path);
80
+ $path= "";
81
+ $ret = true;
82
+ for ($i=0; $i < count($dir); $i++) {
83
+ $path .= "/" .$dir[$i];
84
+ if(!@ftp_chdir($this->_conn, $path)) {
85
+ @ftp_chdir($this->_conn,"/");
86
+ if(!@ftp_mkdir($this->_conn,$path)) {
87
+ $ret=false;
88
+ break;
89
+ } else {
90
+ @ftp_chmod($this->_conn, $mode, $path);
91
+ }
92
+ }
93
+ }
94
+ return $ret;
95
+ }
96
+
97
+ /**
98
+ * Try to login to server
99
+ *
100
+ * @param string $login
101
+ * @param string $password
102
+ * @throws Exception on invalid login credentials
103
+ * @return bool
104
+ */
105
+ public function login($login = "anonymous", $password = "test@gmail.com")
106
+ {
107
+ $this->checkConnected();
108
+ $res = @ftp_login($this->_conn, $login, $password);
109
+ if(!$res) {
110
+ throw new Exception("Invalid login credentials");
111
+ }
112
+ return $res;
113
+ }
114
+
115
+ /**
116
+ * Validate connection string
117
+ *
118
+ * @param string $string
119
+ * @throws Exception
120
+ * @return string
121
+ */
122
+ public function validateConnectionString($string)
123
+ {
124
+ $data = @parse_url($string);
125
+ if(false === $data) {
126
+ throw new Exception("Connection string invalid: '{$string}'");
127
+ }
128
+ if($data['scheme'] != 'ftp') {
129
+ throw new Exception("Support for scheme unsupported: '{$data['scheme']}'");
130
+ }
131
+ return $data;
132
+ }
133
+
134
+ /**
135
+ * Connect to server using connect string
136
+ * Connection string: ftp://user:pass@server:port/path
137
+ * user,pass,port,path are optional parts
138
+ *
139
+ * @param string $string
140
+ * @param int $timeout
141
+ */
142
+ public function connect($string, $timeout = 900)
143
+ {
144
+ $params = $this->validateConnectionString($string);
145
+ $port = isset($params['port']) ? intval($params['port']) : 21;
146
+
147
+ $this->_conn = ftp_connect($params['host'], $port, $timeout);
148
+
149
+ if(!$this->_conn) {
150
+ throw new Exception("Cannot connect to host: {$params['host']}");
151
+ }
152
+ if(isset($params['user']) && isset($params['pass'])) {
153
+ $this->login($params['user'], $params['pass']);
154
+ } else {
155
+ $this->login();
156
+ }
157
+ if(isset($params['path'])) {
158
+ if(!$this->chdir($params['path'])) {
159
+ throw new Exception ("Cannot chdir after login to: {$params['path']}");
160
+ }
161
+ }
162
+ }
163
+
164
+ /**
165
+ * ftp_fput wrapper
166
+ *
167
+ * @param string $remoteFile
168
+ * @param resource $handle
169
+ * @param int $mode FTP_BINARY | FTP_ASCII
170
+ * @param int $startPos
171
+ * @return bool
172
+ */
173
+ public function fput($remoteFile, $handle, $mode = FTP_BINARY, $startPos = 0)
174
+ {
175
+ $this->checkConnected();
176
+ return @ftp_fput($this->_conn, $remoteFile, $handle, $mode, $startPos);
177
+ }
178
+
179
+ /**
180
+ * ftp_put wrapper
181
+ *
182
+ * @param string $remoteFile
183
+ * @param string $localFile
184
+ * @param int $mode FTP_BINARY | FTP_ASCII
185
+ * @param int $startPos
186
+ * @return bool
187
+ */
188
+ public function put($remoteFile, $localFile, $mode = FTP_BINARY, $startPos = 0)
189
+ {
190
+ $this->checkConnected();
191
+ return ftp_put($this->_conn, $remoteFile, $localFile, $mode, $startPos);
192
+ }
193
+
194
+ /**
195
+ * Get current working directory
196
+ *
197
+ * @return mixed
198
+ */
199
+ public function getcwd()
200
+ {
201
+ $d = $this->raw("pwd");
202
+ $data = explode(" ", $d[0], 3);
203
+ if(empty($data[1])) {
204
+ return false;
205
+ }
206
+ if(intval($data[0]) != 257) {
207
+ return false;
208
+ }
209
+ $out = trim($data[1], '"');
210
+ if($out !== "/") {
211
+ $out = rtrim($out, "/");
212
+ }
213
+ return $out;
214
+ }
215
+
216
+ /**
217
+ * ftp_raw wrapper
218
+ *
219
+ * @param string $cmd
220
+ * @return mixed
221
+ */
222
+ public function raw($cmd)
223
+ {
224
+ $this->checkConnected();
225
+ return @ftp_raw($this->_conn, $cmd);
226
+ }
227
+
228
+ /**
229
+ * Upload local file to remote
230
+ *
231
+ * Can be used for relative and absoulte remote paths
232
+ * Relative: use chdir before calling this
233
+ *
234
+ * @param srting $remote
235
+ * @param string $local
236
+ * @param int $dirMode
237
+ * @param int $ftpMode
238
+ * @return unknown_type
239
+ */
240
+ public function upload($remote, $local, $dirMode = 0777, $ftpMode = FTP_BINARY)
241
+ {
242
+ $this->checkConnected();
243
+
244
+ if(!file_exists($local)) {
245
+ throw new Exception("Local file doesn't exist: {$localFile}");
246
+ }
247
+ if(!is_readable($local)) {
248
+ throw new Exception("Local file is not readable: {$localFile}");
249
+ }
250
+ if(is_dir($local)) {
251
+ throw new Exception("Directory given instead of file: {$localFile}");
252
+ }
253
+
254
+ $globalPathMode = substr($remote, 0, 1) == "/";
255
+ $dirname = dirname($remote);
256
+ $cwd = $this->getcwd();
257
+ if(false === $cwd) {
258
+ throw new Exception("Server returns something awful on PWD command");
259
+ }
260
+
261
+ if(!$globalPathMode) {
262
+ $dirname = $cwd."/".$dirname;
263
+ $remote = $cwd."/".$remote;
264
+ }
265
+ $res = $this->mkdirRecursive($dirname, $dirMode);
266
+ $this->chdir($cwd);
267
+
268
+ if(!$res) {
269
+ return false;
270
+ }
271
+ return $this->put($remote, $local, $ftpMode);
272
+ }
273
+
274
+ /**
275
+ * Download remote file to local machine
276
+ *
277
+ * @param string $remote
278
+ * @param string $local
279
+ * @param int $ftpMode FTP_BINARY|FTP_ASCII
280
+ * @return bool
281
+ */
282
+ public function download($remote, $local, $ftpMode = FTP_BINARY)
283
+ {
284
+ $this->checkConnected();
285
+ return $this->get($local, $remote, $ftpMode);
286
+ }
287
+
288
+ /**
289
+ * ftp_pasv wrapper
290
+ *
291
+ * @param bool $pasv
292
+ * @return bool
293
+ */
294
+ public function pasv($pasv)
295
+ {
296
+ $this->checkConnected();
297
+ return @ftp_pasv($this->_conn, (bool) $pasv);
298
+ }
299
+
300
+ /**
301
+ * Close FTP connection
302
+ *
303
+ * @return void
304
+ */
305
+ public function close()
306
+ {
307
+ if($this->_conn) {
308
+ @ftp_close($this->_conn);
309
+ }
310
+ }
311
+
312
+ /**
313
+ * ftp_chmod wrapper
314
+ *
315
+ * @param $mode
316
+ * @param $remoteFile
317
+ * @return bool
318
+ */
319
+ public function chmod($mode, $remoteFile)
320
+ {
321
+ $this->checkConnected();
322
+ return @ftp_chmod($this->_conn, $mode, $remoteFile);
323
+ }
324
+
325
+ /**
326
+ * ftp_chdir wrapper
327
+ *
328
+ * @param string $dir
329
+ * @return bool
330
+ */
331
+ public function chdir($dir)
332
+ {
333
+ $this->checkConnected();
334
+ return @ftp_chdir($this->_conn, $dir);
335
+ }
336
+
337
+ /**
338
+ * ftp_cdup wrapper
339
+ *
340
+ * @return bool
341
+ */
342
+ public function cdup()
343
+ {
344
+ $this->checkConnected();
345
+ return @ftp_cdup($this->_conn);
346
+ }
347
+
348
+ /**
349
+ * ftp_get wrapper
350
+ *
351
+ * @param string $localFile
352
+ * @param string $remoteFile
353
+ * @param int $fileMode FTP_BINARY | FTP_ASCII
354
+ * @param int $resumeOffset
355
+ * @return bool
356
+ */
357
+ public function get($localFile, $remoteFile, $fileMode = FTP_BINARY, $resumeOffset = 0)
358
+ {
359
+ $remoteFile = $this->correctFilePath($remoteFile);
360
+ $this->checkConnected();
361
+ return @ftp_get($this->_conn, $localFile, $remoteFile, $fileMode, $resumeOffset);
362
+ }
363
+
364
+ /**
365
+ * ftp_nlist wrapper
366
+ *
367
+ * @param string $dir
368
+ * @return bool
369
+ */
370
+ public function nlist($dir = "/")
371
+ {
372
+ $this->checkConnected();
373
+ $dir = $this->correctFilePath($dir);
374
+ return @ftp_nlist($this->_conn, $dir);
375
+ }
376
+
377
+ /**
378
+ * ftp_rawlist wrapper
379
+ *
380
+ * @param string $dir
381
+ * @param bool $recursive
382
+ * @return mixed
383
+ */
384
+ public function rawlist( $dir = "/", $recursive = false )
385
+ {
386
+ $this->checkConnected();
387
+ $dir = $this->correctFilePath($dir);
388
+ return @ftp_rawlist($this->_conn, $dir, $recursive);
389
+ }
390
+
391
+ /**
392
+ * Convert byte count to float KB/MB format
393
+ *
394
+ * @param int $bytes
395
+ * @return string
396
+ */
397
+ public static function byteconvert($bytes)
398
+ {
399
+ $symbol = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
400
+ $exp = floor( log($bytes) / log(1024) );
401
+ return sprintf( '%.2f ' . $symbol[ $exp ], ($bytes / pow(1024, floor($exp))) );
402
+ }
403
+
404
+ /**
405
+ * Chmod string "-rwxrwxrwx" to "777" converter
406
+ *
407
+ * @param string $chmod
408
+ * @return string
409
+ */
410
+ public static function chmodnum($chmod)
411
+ {
412
+ $trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
413
+ $chmod = substr(strtr($chmod, $trans), 1);
414
+ $array = str_split($chmod, 3);
415
+ return array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
416
+ }
417
+
418
+ /**
419
+ * Check whether file exists
420
+ *
421
+ * @param string $path
422
+ * @param bool $excludeIfIsDir
423
+ * @return bool
424
+ */
425
+ public function fileExists($path, $excludeIfIsDir = true)
426
+ {
427
+ $path = $this->correctFilePath($path);
428
+ $globalPathMode = substr($path, 0, 1) == "/";
429
+
430
+ $file = basename($path);
431
+ $dir = $globalPathMode ? dirname($path) : $this->getcwd()."/".$path;
432
+ $data = $this->ls($dir);
433
+ foreach($data as $row) {
434
+ if($file == $row['name']) {
435
+ if($excludeIfIsDir && $row['dir']) {
436
+ continue;
437
+ }
438
+ return true;
439
+ }
440
+ }
441
+ return false;
442
+ }
443
+
444
+ /**
445
+ * Get directory contents in PHP array
446
+ *
447
+ * @param string $dir
448
+ * @param bool $recursive
449
+ * @return array
450
+ */
451
+ public function ls($dir = "/", $recursive = false)
452
+ {
453
+ $dir= $this->correctFilePath($dir);
454
+ $rawfiles = (array) $this->rawlist($dir, $recursive);
455
+ $structure = array();
456
+ $arraypointer = &$structure;
457
+ foreach ($rawfiles as $rawfile) {
458
+ if ($rawfile[0] == '/') {
459
+ $paths = array_slice(explode('/', str_replace(':', '', $rawfile)), 1);
460
+ $arraypointer = &$structure;
461
+ foreach ($paths as $path) {
462
+ foreach ($arraypointer as $i => $file) {
463
+ if ($file['name'] == $path) {
464
+ $arraypointer = &$arraypointer[ $i ]['children'];
465
+ break;
466
+ }
467
+ }
468
+ }
469
+ } elseif(!empty($rawfile)) {
470
+ $info = preg_split("/[\s]+/", $rawfile, 9);
471
+ $arraypointer[] = array(
472
+ 'name' => $info[8],
473
+ 'dir' => $info[0]{0} == 'd',
474
+ 'size' => (int) $info[4],
475
+ 'chmod' => self::chmodnum($info[0]),
476
+ 'rawdata' => $info,
477
+ 'raw' => $rawfile
478
+ );
479
+ }
480
+ }
481
+ return $structure;
482
+ }
483
+
484
+ /**
485
+ * Correct file path
486
+ *
487
+ * @param string $str
488
+ * @return string
489
+ */
490
+ public function correctFilePath($str)
491
+ {
492
+ $str = str_replace("\\", "/", $str);
493
+ $str = preg_replace("/^.\//", "", $str);
494
+ return $str;
495
+ }
496
+
497
+ /**
498
+ * Delete file
499
+ *
500
+ * @param string $file
501
+ * @return bool
502
+ */
503
+ public function delete($file)
504
+ {
505
+ $this->checkConnected();
506
+ $file = $this->correctFilePath($file);
507
+ return @ftp_delete($this->_conn, $file);
508
+ }
509
+ }
package.xml CHANGED
@@ -1,18 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Lib_Mage</name>
4
- <version>1.6.1.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Mage Library</summary>
10
  <description>Mage Library</description>
11
- <notes>1.6.1.0</notes>
12
  <authors><author><name>Magento Core Team</name><user>core</user><email>core@magentocommerce.com</email></author></authors>
13
- <date>2011-10-19</date>
14
- <time>11:50:03</time>
15
- <contents><target name="magelib"><dir name="Mage"><dir name="Archive"><file name="Abstract.php" hash="facb355053858f94439409d8657757ff"/><file name="Bz.php" hash="bce512d3062f936f1a8c12bf5c408b64"/><file name="Gz.php" hash="0dca1839014c71886a8a93186bb993d0"/><file name="Interface.php" hash="ef441008981545b886dcab6f386a6882"/><file name="Tar.php" hash="9f09ed124af89b683897246503ea9832"/></dir><file name="Archive.php" hash="f7745fb5794efd8e0a2adaef4a3f6f12"/><dir name="Autoload"><file name="Simple.php" hash="0112e880807596fbe8822be12314f14f"/></dir><dir name="Connect"><dir name="Channel"><file name="Generator.php" hash="a1f115e909680bca8c1b1f0940244b13"/><file name="Parser.php" hash="ec2e7380ec4bca81de2795f96975e778"/><file name="VO.php" hash="870a1b9b28d85dd72b2b1e2529dca354"/></dir><dir name="Command"><file name="Channels.php" hash="12f730285615329cba0b570385009837"/><file name="Channels_Header.php" hash="934366a4daa1ebe87b25cb9dfa061798"/><file name="Config.php" hash="5091776f35732d8b0ff12c8ff3561c69"/><file name="Config_Header.php" hash="119a103ed71b326993756961b6c7c2a0"/><file name="Install.php" hash="2f7227a1f4003d6ce6edec4a0ce02e0f"/><file name="Install_Header.php" hash="71f0b6bad2f745235352d181bcc66645"/><file name="Package.php" hash="b36bdc6a3c0f6bc9d7766a37c046a481"/><file name="Package_Header.php" hash="dc3840a95f89ef844df40c585582815d"/><file name="Registry.php" hash="f9fde28940ff38dbc336335d575a295d"/><file name="Registry_Header.php" hash="559edbac0f3d267c8ca289e526b940d1"/><file name="Remote.php" hash="6f959617993d58aec974d578921b6212"/><file name="Remote_Header.php" hash="4b56cd683710de6c81241f902570ba25"/></dir><file name="Command.php" hash="0d474da0956a292aa83e88da4975c527"/><file name="Config.php" hash="511f752123ccc6c148a6a308fc3f81b2"/><file name="Converter.php" hash="1cde84613c6079050bb3824aba3b380d"/><dir name="Frontend"><file name="CLI.php" hash="86e6631d9345d5bf9d15148cfdace3bf"/></dir><file name="Frontend.php" hash="0a97c590fdc9844b225638d631315d35"/><file name="Ftp.php" hash="095b9ad01ea60418b1667732cb374d95"/><dir name="Loader"><file name="Ftp.php" hash="0ca46737d25bf0eb321414f2d8b7ced0"/></dir><file name="Loader.php" hash="009d6f986d5ff406f7e94d2b395f6e25"/><dir name="Package"><file name="Extension.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Hotfix.php" hash="850bd23783a77dbf6f50b4f169c2c7b3"/><file name="Maintainer.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Reader.php" hash="ca384e066ac21168e0a7aebc5da869c1"/><file name="Target.php" hash="351af5965f7870d3f4e960d402805b17"/><file name="VO.php" hash="9ffbdff9210474b68db7caddf9a5fe5a"/><file name="Writer.php" hash="431f107ab2ffd1977f74a94ae16481d1"/></dir><file name="Package.php" hash="bf5af87c29959f229de7b69d1d94f1e0"/><file name="Packager.php" hash="37df01e250a103684b37a6f0b71b3128"/><dir name="Repository"><file name="Abstract.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><dir name="Channel"><file name="Abstract.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Commercial.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Community.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Core.php" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><file name="Channel.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Local.php" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><file name="Repository.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Rest.php" hash="ba2d2365fc989274940e1fdff6476875"/><file name="Singleconfig.php" hash="975c04d57cbce24327e84a93d9f5443e"/><dir name="Structures"><file name="Graph.php" hash="b85283fd2af6fd54fb748cb6ea933842"/><file name="Node.php" hash="26a7e4041c3d2fd93bfdc3c692c85ede"/></dir><file name="Validator.php" hash="3ac1b21ec703073d5dd9b5dda3471fe8"/></dir><dir name="DB"><file name="Exception.php" hash="e0b55d77af8e215135ef223f593832ad"/><file name="Mysqli.php" hash="5057ea65f441bbb00c7e55298e9252a4"/></dir><file name="Exception.php" hash="9bf1aefdb7fd166d25889f36707997dc"/><dir name="HTTP"><dir name="Client"><file name="Curl.php" hash="f537a9879781ec3fe2748677bee43737"/><file name="Socket.php" hash="7a889fed729d92eba849d6fdfa32d7d6"/></dir><file name="Client.php" hash="7072f9366680bc5ebc1c447700193cb4"/><file name="IClient.php" hash="88a4a88a31a05a2154d430d7b4308ff6"/></dir><dir name="System"><file name="Args.php" hash="8080a06707f4393b9155441ed4160f4a"/><file name="Dirs.php" hash="adc832887e04f359b2ec050b0b2e6d17"/></dir><dir name="Xml"><file name="Generator.php" hash="0ddc93b0c75885f67d049d0a38c630fa"/><file name="Parser.php" hash="b2bdc0880cd5bc2d82468ee075e783a2"/></dir></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Lib_Mage</name>
4
+ <version>1.7.0.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Mage Library</summary>
10
  <description>Mage Library</description>
11
+ <notes>1.7.0.0</notes>
12
  <authors><author><name>Magento Core Team</name><user>core</user><email>core@magentocommerce.com</email></author></authors>
13
+ <date>2012-04-23</date>
14
+ <time>13:47:58</time>
15
+ <contents><target name="magelib"><dir name="Mage"><dir name="Archive"><file name="Abstract.php" hash="6324215ec8ab3c55730c57976b7cd4f7"/><file name="Bz.php" hash="6485bb0cd67f6f5dfa11b8ba29e23d43"/><file name="Gz.php" hash="7f75dbebd125a0d4c27803d4ca4983f4"/><dir name="Helper"><dir name="File"><file name="Bz.php" hash="ec70e019f9031c2c2f16c9f910434352"/><file name="Gz.php" hash="84d1f376a78efa1898f888c854faf040"/></dir><file name="File.php" hash="8a0383c1b32cdbc8c53ba551c7814bda"/></dir><file name="Interface.php" hash="283914c36fdcf9851ec651149176fff7"/><file name="Tar.php" hash="63a72e6d9eefab1edce10451216b96d2"/></dir><file name="Archive.php" hash="1e0342bbcb89d417c7ee77ad3387938d"/><dir name="Autoload"><file name="Simple.php" hash="0112e880807596fbe8822be12314f14f"/></dir><dir name="Backup"><file name="Abstract.php" hash="4ab32913f5831b4e449486a5cf84d07e"/><dir name="Archive"><file name="Tar.php" hash="b6b2731bfa267b6b5fcb28d3f8f8cdbf"/></dir><file name="Db.php" hash="58001faa3a70a54441f45de8cb77aacb"/><dir name="Exception"><file name="CantLoadSnapshot.php" hash="67e47d7b54e466ebf0230810bec31158"/><file name="FtpConnectionFailed.php" hash="54cc1c76345d5fc601f7cf3af67151f6"/><file name="FtpValidationFailed.php" hash="51847fdeb1539094b9eca84b601ca241"/><file name="NotEnoughFreeSpace.php" hash="5a95f8877b4b8ca8936c0fc88a1a65ac"/><file name="NotEnoughPermissions.php" hash="b89a417fc74cc6b45371967c9c7a3e92"/></dir><file name="Exception.php" hash="b10632f40d57f0768f8d1058b0fd10fc"/><dir name="Filesystem"><file name="Helper.php" hash="0366375e211a2e4093f451db7793b3b0"/><dir name="Iterator"><file name="File.php" hash="0bfe672a2e72af47c777f7321b0752aa"/><file name="Filter.php" hash="f994e954d22007498e4078345aeadd20"/></dir><dir name="Rollback"><file name="Abstract.php" hash="90a2781c3c6443e08aeb3b6f1d21f97f"/><file name="Fs.php" hash="c76f9c2e09d37d4dcc785fab7d4e02b0"/><file name="Ftp.php" hash="ebea4f77dee7cc83444da16b7d51e397"/></dir></dir><file name="Filesystem.php" hash="8da3a28a9f90091105121dee17cfa142"/><file name="Interface.php" hash="5507294967fc6a5472aa82df60a1bf69"/><file name="Media.php" hash="fd2d608b2b5afaab2f33f67b5155e14b"/><file name="Nomedia.php" hash="da38dbea4586952e20d327b3af1347ae"/><file name="Snapshot.php" hash="2e4ce7ed1b78c4dbad25221abbb4aaf2"/></dir><file name="Backup.php" hash="56bf7a531ab332a0f10821e5d583afc4"/><dir name="Connect"><dir name="Channel"><file name="Generator.php" hash="a1f115e909680bca8c1b1f0940244b13"/><file name="Parser.php" hash="ec2e7380ec4bca81de2795f96975e778"/><file name="VO.php" hash="870a1b9b28d85dd72b2b1e2529dca354"/></dir><dir name="Command"><file name="Channels.php" hash="12f730285615329cba0b570385009837"/><file name="Channels_Header.php" hash="934366a4daa1ebe87b25cb9dfa061798"/><file name="Config.php" hash="5091776f35732d8b0ff12c8ff3561c69"/><file name="Config_Header.php" hash="119a103ed71b326993756961b6c7c2a0"/><file name="Install.php" hash="2f7227a1f4003d6ce6edec4a0ce02e0f"/><file name="Install_Header.php" hash="71f0b6bad2f745235352d181bcc66645"/><file name="Package.php" hash="b36bdc6a3c0f6bc9d7766a37c046a481"/><file name="Package_Header.php" hash="dc3840a95f89ef844df40c585582815d"/><file name="Registry.php" hash="f9fde28940ff38dbc336335d575a295d"/><file name="Registry_Header.php" hash="559edbac0f3d267c8ca289e526b940d1"/><file name="Remote.php" hash="6f959617993d58aec974d578921b6212"/><file name="Remote_Header.php" hash="4b56cd683710de6c81241f902570ba25"/></dir><file name="Command.php" hash="0d474da0956a292aa83e88da4975c527"/><file name="Config.php" hash="511f752123ccc6c148a6a308fc3f81b2"/><file name="Converter.php" hash="1cde84613c6079050bb3824aba3b380d"/><dir name="Frontend"><file name="CLI.php" hash="86e6631d9345d5bf9d15148cfdace3bf"/></dir><file name="Frontend.php" hash="0a97c590fdc9844b225638d631315d35"/><file name="Ftp.php" hash="2b87de89c19712ae22756b11c763e137"/><dir name="Loader"><file name="Ftp.php" hash="0ca46737d25bf0eb321414f2d8b7ced0"/></dir><file name="Loader.php" hash="009d6f986d5ff406f7e94d2b395f6e25"/><dir name="Package"><file name="Extension.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Hotfix.php" hash="850bd23783a77dbf6f50b4f169c2c7b3"/><file name="Maintainer.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Reader.php" hash="ca384e066ac21168e0a7aebc5da869c1"/><file name="Target.php" hash="351af5965f7870d3f4e960d402805b17"/><file name="VO.php" hash="9ffbdff9210474b68db7caddf9a5fe5a"/><file name="Writer.php" hash="431f107ab2ffd1977f74a94ae16481d1"/></dir><file name="Package.php" hash="bf5af87c29959f229de7b69d1d94f1e0"/><file name="Packager.php" hash="42efcb63cc3b9dbbc5e8eb98b2d8d08e"/><dir name="Repository"><file name="Abstract.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><dir name="Channel"><file name="Abstract.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Commercial.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Community.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Core.php" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><file name="Channel.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Local.php" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><file name="Repository.php" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="Rest.php" hash="ba2d2365fc989274940e1fdff6476875"/><file name="Singleconfig.php" hash="975c04d57cbce24327e84a93d9f5443e"/><dir name="Structures"><file name="Graph.php" hash="b85283fd2af6fd54fb748cb6ea933842"/><file name="Node.php" hash="26a7e4041c3d2fd93bfdc3c692c85ede"/></dir><file name="Validator.php" hash="3ac1b21ec703073d5dd9b5dda3471fe8"/></dir><dir name="DB"><file name="Exception.php" hash="e0b55d77af8e215135ef223f593832ad"/><file name="Mysqli.php" hash="5057ea65f441bbb00c7e55298e9252a4"/></dir><file name="Exception.php" hash="807f6335110c3d6fa0cf5072e2be7892"/><dir name="HTTP"><dir name="Client"><file name="Curl.php" hash="f537a9879781ec3fe2748677bee43737"/><file name="Socket.php" hash="7a889fed729d92eba849d6fdfa32d7d6"/></dir><file name="Client.php" hash="7072f9366680bc5ebc1c447700193cb4"/><file name="IClient.php" hash="88a4a88a31a05a2154d430d7b4308ff6"/></dir><dir name="System"><file name="Args.php" hash="46467e1069edf432030d14dd59fa73df"/><file name="Dirs.php" hash="4edad790aedfbd404df28af9d2f2bea6"/><file name="Ftp.php" hash="6fc28c56dde7613be3da7b9f766caa51"/></dir><dir name="Xml"><file name="Generator.php" hash="0ddc93b0c75885f67d049d0a38c630fa"/><file name="Parser.php" hash="b2bdc0880cd5bc2d82468ee075e783a2"/></dir></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>