Version Description
- Added new archiver library for alternative backup method
- Backup algorithm optimized
Download this release
Release Info
Developer | robosoft |
Plugin | Gallery – Photo Gallery and Images Gallery |
Version | 2.6.9 |
Comparing to | |
See all releases |
Code changes from version 2.6.8 to 2.6.9
- includes/extensions/zip/Core/AbstractException.php +14 -0
- includes/extensions/zip/Core/AbstractZipArchive.php +1046 -0
- includes/extensions/zip/Core/ZipUtils.php +125 -0
- includes/extensions/zip/Core/index.html +0 -0
- includes/extensions/zip/Exception/BufferNotEmpty.php +46 -0
- includes/extensions/zip/Exception/HeaderPositionError.php +52 -0
- includes/extensions/zip/Exception/HeadersSent.php +52 -0
- includes/extensions/zip/Exception/IncompatiblePhpVersion.php +54 -0
- includes/extensions/zip/Exception/InvalidPhpConfiguration.php +58 -0
- includes/extensions/zip/Exception/LengthMismatch.php +51 -0
- includes/extensions/zip/Exception/index.html +0 -0
- includes/extensions/zip/File/Zip.php +348 -0
- includes/extensions/zip/File/index.html +0 -0
- includes/extensions/zip/Listener/ZipArchiveListener.php +71 -0
- includes/extensions/zip/Listener/index.html +0 -0
- includes/extensions/zip/Stream/ZipStream.php +204 -0
- includes/extensions/zip/Stream/index.html +0 -0
- includes/extensions/zip/index.html +0 -0
- readme.txt +9 -1
- robogallery.php +5 -5
includes/extensions/zip/Core/AbstractException.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as a proxy for all \PHPZip\Zip\Exception classes.
|
7 |
+
* It is empty for now, but properties can be added in the future without
|
8 |
+
* breaking any code.
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace PHPZip\Zip\Core;
|
13 |
+
|
14 |
+
abstract class AbstractException extends \Exception {}
|
includes/extensions/zip/Core/AbstractZipArchive.php
ADDED
@@ -0,0 +1,1046 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author A. Grandt <php@grandt.com>
|
5 |
+
* @author Greg Kappatos
|
6 |
+
*
|
7 |
+
* This class serves as an abstract superclass for zip archives.
|
8 |
+
*
|
9 |
+
*/
|
10 |
+
|
11 |
+
namespace PHPZip\Zip\Core;
|
12 |
+
|
13 |
+
use com\grandt\BinStringStatic;
|
14 |
+
use PHPZip\Zip\Listener\ZipArchiveListener as ZipArchiveListener;
|
15 |
+
use PHPZip\Zip\Exception\IncompatiblePhpVersion as IncompatiblePhpVersionException;
|
16 |
+
use PHPZip\Zip\Exception\InvalidPhpConfiguration as InvalidPhpConfigurationException;
|
17 |
+
use PHPZip\Zip\Exception\HeadersSent as HeadersSentException;
|
18 |
+
use PHPZip\Zip\Exception\BufferNotEmpty as BufferNotEmptyException;
|
19 |
+
use PHPZip\Zip\Exception\LengthMismatch as LengthMismatchException;
|
20 |
+
use ZipMerge\Zip\Core\AbstractZipWriter;
|
21 |
+
use ZipMerge\Zip\Core\Header\ZipFileEntry;
|
22 |
+
use ZipMerge\Zip\Stream\ZipMerge;
|
23 |
+
|
24 |
+
|
25 |
+
abstract class AbstractZipArchive extends AbstractZipWriter {
|
26 |
+
const APP_NAME = 'PHPZip';
|
27 |
+
const VERSION = "2.0.8";
|
28 |
+
const MIN_PHP_VERSION = 5.3; // for namespaces
|
29 |
+
|
30 |
+
const CONTENT_TYPE = 'application/zip';
|
31 |
+
|
32 |
+
const NULL_BYTE = "\x00";
|
33 |
+
const NULL_WORD = "\x00\x00"; // Two nul bytes, used often enough.
|
34 |
+
const NULL_DWORD = "\x00\x00\x00\x00";
|
35 |
+
|
36 |
+
const ZIP_CENTRAL_FILE_HEADER = "PK\x01\x02"; // Central file header signature
|
37 |
+
const ZIP_LOCAL_FILE_HEADER = "PK\x03\x04"; // Local file header signature
|
38 |
+
const ZIP_LOCAL_DATA_DESCRIPTOR = "PK\x07\x08"; // Local Header, data descriptor
|
39 |
+
const ZIP_END_OF_CENTRAL_DIRECTORY = "PK\x05\x06"; // End of Central directory record
|
40 |
+
|
41 |
+
const HEADER_UNIX_TYPE_1 = 'UX'; // \x55\x58 or 0x5855 It has been replaced by the extended-timestamp extra block 'UT' (0x5455) and the Unix type 2 extra block 'Ux' (0x7855).
|
42 |
+
const HEADER_UNIX_TYPE_2 = 'Ux'; // \x55\x78 or 0x7855
|
43 |
+
const HEADER_UNIX_TYPE_3 = 'ux'; // \x75\x78 or 0x7875
|
44 |
+
const HEADER_EXTENDED_TIMESTAMP = 'UT'; // \x55\x54 or 0x5455
|
45 |
+
const HEADER_UNICODE_PATH = 'up'; // \x75\x70 or 0x7075
|
46 |
+
const HEADER_UNICODE_COMMENT = 'uc'; // \x75\x63 or 0x6375
|
47 |
+
|
48 |
+
const EXT_FILE_ATTR_DIR = 010173200020; // Permission 755 drwxr-xr-x = (((S_IFDIR | 0755) << 16) | S_DOS_D);
|
49 |
+
const EXT_FILE_ATTR_FILE = 020151000040; // Permission 644 -rw-r--r-- = (((S_IFREG | 0644) << 16) | S_DOS_A);
|
50 |
+
|
51 |
+
const ATTR_VERSION_TO_EXTRACT = "\x14\x00"; // Version needed to extract = 20 (File is compressed using Deflate compression)
|
52 |
+
const ATTR_MADE_BY_VERSION = "\x1E\x03"; // Made By Version
|
53 |
+
|
54 |
+
const DEFAULT_GZ_TYPE = "\x08\x00"; // Compression type 8 = deflate
|
55 |
+
const DEFAULT_GP_FLAGS = self::NULL_WORD; // General Purpose bit flags for compression type 8 it is: 0=Normal, 1=Maximum, 2=Fast, 3=super fast compression.
|
56 |
+
|
57 |
+
const DEFAULT_GZ_TYPE_STORED = self::NULL_WORD; // Compression type 0 = stored
|
58 |
+
const DEFAULT_GP_FLAGS_STORED = self::NULL_WORD; // Compression type 0 = stored
|
59 |
+
|
60 |
+
// UID 1000, GID 0
|
61 |
+
const EXTRA_FIELD_NEW_UNIX_GUID = "ux\x0B\x00\x01\x04\xE8\x03\x00\x00\x04\x00\x00\x00\x00"; // \x75\x78 3rd gen Unis GUID
|
62 |
+
const EXTRA_FIELD_NEW_UNIX_GUID_CD = "ux\x00\x00"; // \x75\x78 3rd gen Unis GUID CD record version must have length 0.
|
63 |
+
|
64 |
+
protected $zipComment = null;
|
65 |
+
protected $cdRec = array(); // central directory
|
66 |
+
protected $offset = 0;
|
67 |
+
protected $isFinalized = false;
|
68 |
+
protected $addExtraField = true;
|
69 |
+
|
70 |
+
protected $streamChunkSize = 0;
|
71 |
+
protected $streamFilePath = null;
|
72 |
+
protected $streamTimestamp = null;
|
73 |
+
protected $streamFileComment = null;
|
74 |
+
protected $streamFile = null;
|
75 |
+
protected $streamData = null;
|
76 |
+
protected $streamFileLength = 0;
|
77 |
+
protected $streamExtFileAttr = null;
|
78 |
+
|
79 |
+
/**
|
80 |
+
* A custom temporary folder, or a callable that returns a custom temporary file.
|
81 |
+
* @var string|callable
|
82 |
+
*/
|
83 |
+
public static $temp = null;
|
84 |
+
|
85 |
+
private $_listeners = array();
|
86 |
+
private $_phpConfigurationWatch = array(
|
87 |
+
// 'mbstring.func_overload' => '0' // throw an exception if setting in php.ini is not '0'
|
88 |
+
);
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Constructor.
|
92 |
+
*
|
93 |
+
* @author A. Grandt <php@grandt.com>
|
94 |
+
* @author Greg Kappatos
|
95 |
+
*
|
96 |
+
* @param boolean $streamChunkSize Size of each chunk
|
97 |
+
*
|
98 |
+
* @throws \PHPZip\Zip\Exception\InvalidPhpConfiguration In case of errors
|
99 |
+
*/
|
100 |
+
protected function __construct($streamChunkSize) {
|
101 |
+
$this->streamChunkSize = $streamChunkSize;
|
102 |
+
|
103 |
+
if (count($this->_phpConfigurationWatch) > 0) {
|
104 |
+
foreach ($this->_phpConfigurationWatch as $k => $v) {
|
105 |
+
$s = (string)$v;
|
106 |
+
if (@ini_get($k) !== $s) {
|
107 |
+
$this->_throwException(new InvalidPhpConfigurationException(array(
|
108 |
+
'setting' => $k,
|
109 |
+
'expected' => $s,
|
110 |
+
)));
|
111 |
+
break; // technically not needed.
|
112 |
+
}
|
113 |
+
}
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Extra fields on the Zip directory records are Unix time codes needed for compatibility on the default Mac zip archive tool.
|
119 |
+
* These are enabled as default, as they do no harm elsewhere and only add 26 bytes per file added.
|
120 |
+
*
|
121 |
+
* @author A. Grandt <php@grandt.com>
|
122 |
+
*
|
123 |
+
* @param bool $setExtraField true (default) will enable adding of extra fields, anything else will disable it.
|
124 |
+
*/
|
125 |
+
public function setExtraField($setExtraField = true) {
|
126 |
+
$this->addExtraField = ($setExtraField === true);
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Set Zip archive comment.
|
131 |
+
*
|
132 |
+
* @author A. Grandt <php@grandt.com>
|
133 |
+
*
|
134 |
+
* @param string $newComment New comment. null to clear.
|
135 |
+
*
|
136 |
+
* @return bool $success
|
137 |
+
*/
|
138 |
+
public function setComment($newComment = null) {
|
139 |
+
if ($this->isFinalized) {
|
140 |
+
return false;
|
141 |
+
}
|
142 |
+
|
143 |
+
$this->zipComment = $newComment;
|
144 |
+
|
145 |
+
return true;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Add an empty directory entry to the zip archive.
|
150 |
+
* Basically this is only used if an empty directory is added.
|
151 |
+
*
|
152 |
+
* @author A. Grandt <php@grandt.com>
|
153 |
+
* @author Greg Kappatos
|
154 |
+
*
|
155 |
+
* @param string $directoryPath Directory Path and name to be added to the archive.
|
156 |
+
* @param int $timestamp (Optional) Timestamp for the added directory, if omitted or set to 0, the current time will be used.
|
157 |
+
* @param string $fileComment (Optional) Comment to be added to the archive for this directory. To use $fileComment, $timestamp must be given.
|
158 |
+
* @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
|
159 |
+
*
|
160 |
+
* @return bool $success
|
161 |
+
*/
|
162 |
+
public function addDirectory($directoryPath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_DIR) {
|
163 |
+
// TODO: get rid of magic numbers.
|
164 |
+
$result = false;
|
165 |
+
|
166 |
+
if (!$this->isFinalized) {
|
167 |
+
$directoryPath = str_replace("\\", '/', $directoryPath);
|
168 |
+
$directoryPath = rtrim($directoryPath, '/');
|
169 |
+
|
170 |
+
if (BinStringStatic::_strlen($directoryPath) > 0) {
|
171 |
+
$this->buildZipEntry($directoryPath.'/',
|
172 |
+
$fileComment,
|
173 |
+
self::DEFAULT_GZ_TYPE_STORED,
|
174 |
+
self::DEFAULT_GP_FLAGS_STORED,
|
175 |
+
$timestamp,
|
176 |
+
"\x00\x00\x00\x00",
|
177 |
+
0, 0, $extFileAttr);
|
178 |
+
$result = true;
|
179 |
+
}
|
180 |
+
}
|
181 |
+
return $result;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Add a file to the archive at the specified location and file name.
|
186 |
+
*
|
187 |
+
* @author A. Grandt <php@grandt.com>
|
188 |
+
* @author Greg Kappatos
|
189 |
+
*
|
190 |
+
* @param string $data File data.
|
191 |
+
* @param string $filePath File path and name to be used in the archive.
|
192 |
+
* @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
|
193 |
+
* @param string $fileComment (Optional) Comment to be added to the archive for this file. To use $fileComment, $timestamp must be given.
|
194 |
+
* @param bool $compress (Optional) Compress file, if set to false the file will only be stored. Default true.
|
195 |
+
* @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
|
196 |
+
*
|
197 |
+
* @return bool $success
|
198 |
+
*/
|
199 |
+
public function addFile($data, $filePath, $timestamp = 0, $fileComment = null, $compress = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
|
200 |
+
if ($this->isFinalized) {
|
201 |
+
return false;
|
202 |
+
}
|
203 |
+
|
204 |
+
if (is_resource($data) && get_resource_type($data) === 'stream') {
|
205 |
+
$this->addLargeFile($data, $filePath, $timestamp, $fileComment, $extFileAttr);
|
206 |
+
return false;
|
207 |
+
}
|
208 |
+
|
209 |
+
$gzData = '';
|
210 |
+
$gzType = self::DEFAULT_GZ_TYPE;
|
211 |
+
$gpFlags = self::DEFAULT_GP_FLAGS;
|
212 |
+
$dataLength = BinStringStatic::_strlen($data);
|
213 |
+
$fileCRC32 = pack("V", crc32($data));
|
214 |
+
$gzLength = $dataLength;
|
215 |
+
|
216 |
+
if ($compress) {
|
217 |
+
$gzTmp = gzcompress($data);
|
218 |
+
// gzcompress adds a 2 byte header and 4 byte Adler-32 CRC at the end, which we can't use.
|
219 |
+
$gzData = substr($gzTmp, 2, -4);
|
220 |
+
// The 2 byte header does contain useful data,
|
221 |
+
// though in this case the 2 parameters we'd be interested in will
|
222 |
+
// always be 8 for compression type, and 2 for General purpose flag.
|
223 |
+
$gzLength = BinStringStatic::_strlen($gzData);
|
224 |
+
}
|
225 |
+
|
226 |
+
if ($gzLength >= $dataLength) {
|
227 |
+
$gzLength = $dataLength;
|
228 |
+
$gzData = $data;
|
229 |
+
|
230 |
+
$gzType = self::DEFAULT_GZ_TYPE_STORED;
|
231 |
+
$gpFlags = self::DEFAULT_GP_FLAGS_STORED;
|
232 |
+
}
|
233 |
+
|
234 |
+
$this->onBeginAddFile(array(
|
235 |
+
'gzLength' => $gzLength,
|
236 |
+
));
|
237 |
+
|
238 |
+
$this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr);
|
239 |
+
|
240 |
+
$this->onEndAddFile(array(
|
241 |
+
'gzData' => $gzData,
|
242 |
+
));
|
243 |
+
|
244 |
+
$this->_notifyListeners(null, array(
|
245 |
+
'data' => $data,
|
246 |
+
));
|
247 |
+
|
248 |
+
return true;
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Add the content to a directory.
|
253 |
+
*
|
254 |
+
* @author Adam Schmalhofer <Adam.Schmalhofer@gmx.de>
|
255 |
+
* @author A. Grandt <php@grandt.com>
|
256 |
+
*
|
257 |
+
* @param string $realPath Path on the file system.
|
258 |
+
* @param string $zipPath File path and name to be used in the archive.
|
259 |
+
* @param bool $recursive Add content recursively, default is true.
|
260 |
+
* @param bool $followSymlinks Follow and add symbolic links, if they are accessible, default is true.
|
261 |
+
* @param array &$addedFiles Reference to the added files, this is used to prevent duplicates, default is an empty array.
|
262 |
+
* If you start the function by parsing an array, the array will be populated with the $realPath
|
263 |
+
* and $zipPath kay/value pairs added to the archive by the function.
|
264 |
+
* @param bool $overrideFilePermissions Force the use of the file/dir permissions set in the $extDirAttr
|
265 |
+
* and $extFileAttr parameters.
|
266 |
+
* @param int $extDirAttr Permissions for directories.
|
267 |
+
* @param int $extFileAttr Permissions for files.
|
268 |
+
*/
|
269 |
+
public function addDirectoryContent($realPath, $zipPath, $recursive = true, $followSymlinks = true, &$addedFiles = array(),
|
270 |
+
$overrideFilePermissions = false, $extDirAttr = self::EXT_FILE_ATTR_DIR, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
|
271 |
+
if (file_exists($realPath) && !isset($addedFiles[realpath($realPath)])) {
|
272 |
+
if (is_dir($realPath)) {
|
273 |
+
$this->addDirectory(
|
274 |
+
$zipPath,
|
275 |
+
0,
|
276 |
+
null,
|
277 |
+
$overrideFilePermissions ? $extDirAttr : ZipUtils::getFileExtAttr($realPath)
|
278 |
+
);
|
279 |
+
}
|
280 |
+
|
281 |
+
$addedFiles[realpath($realPath)] = $zipPath;
|
282 |
+
|
283 |
+
$iter = new \DirectoryIterator($realPath);
|
284 |
+
|
285 |
+
foreach ($iter as $file) {
|
286 |
+
/* @var $file \DirectoryIterator */
|
287 |
+
if ($file->isDot()) {
|
288 |
+
continue;
|
289 |
+
}
|
290 |
+
|
291 |
+
$newRealPath = $file->getPathname();
|
292 |
+
$newZipPath = \RelativePath::pathJoin($zipPath, $file->getFilename());
|
293 |
+
|
294 |
+
if (file_exists($newRealPath) && ($followSymlinks || !is_link($newRealPath))) {
|
295 |
+
if ($file->isFile()) {
|
296 |
+
$addedFiles[realpath($newRealPath)] = $newZipPath;
|
297 |
+
$this->addLargeFile(
|
298 |
+
$newRealPath,
|
299 |
+
$newZipPath,
|
300 |
+
0,
|
301 |
+
null,
|
302 |
+
$overrideFilePermissions ? $extFileAttr : ZipUtils::getFileExtAttr($newRealPath)
|
303 |
+
);
|
304 |
+
} else if ($recursive) {
|
305 |
+
$this->addDirectoryContent(
|
306 |
+
$newRealPath,
|
307 |
+
$newZipPath,
|
308 |
+
$recursive,
|
309 |
+
$followSymlinks,
|
310 |
+
$addedFiles,
|
311 |
+
$overrideFilePermissions,
|
312 |
+
$extDirAttr,
|
313 |
+
$extFileAttr
|
314 |
+
);
|
315 |
+
} else {
|
316 |
+
$this->addDirectory(
|
317 |
+
$zipPath,
|
318 |
+
0,
|
319 |
+
null,
|
320 |
+
$overrideFilePermissions ? $extDirAttr : ZipUtils::getFileExtAttr($newRealPath)
|
321 |
+
);
|
322 |
+
}
|
323 |
+
}
|
324 |
+
}
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Append the contents of an existing zip file to the current, WITHOUT re-compressing the data within it.
|
330 |
+
*
|
331 |
+
* @param string $file the path to the zip file to be added.
|
332 |
+
* @param string $subPath place the contents in the $subPath sub-folder, default is '', and places the
|
333 |
+
* content in the root of the new zip file.
|
334 |
+
*/
|
335 |
+
public function appendZip($file, $subPath = '') {
|
336 |
+
$zipMerge = new ZipMerge(null);
|
337 |
+
$zipMerge->appendZip($file, $subPath, $this);
|
338 |
+
$files = $zipMerge->finalize();
|
339 |
+
|
340 |
+
/* @var $files array */
|
341 |
+
foreach ($files as $fileEntry) {
|
342 |
+
/* @var $fileEntry ZipFileEntry */
|
343 |
+
$fileEntry->offset = $this->offset;
|
344 |
+
$this->cdRec[] = $fileEntry->getCentralDirectoryHeader();
|
345 |
+
$this->offset += BinStringStatic::_strlen( $fileEntry->getLocalHeader()) + $fileEntry->gzLength;
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Add a file to the archive at the specified location and file name.
|
351 |
+
*
|
352 |
+
* @author A. Grandt <php@grandt.com>
|
353 |
+
* @author Greg Kappatos
|
354 |
+
*
|
355 |
+
* @param string $dataFile File name/path.
|
356 |
+
* @param string $filePath File path and name to be used in the archive.
|
357 |
+
* @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
|
358 |
+
* @param string $fileComment (Optional) Comment to be added to the archive for this file. To use $fileComment, $timestamp must be given.
|
359 |
+
* @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
|
360 |
+
*
|
361 |
+
* @return bool $success
|
362 |
+
*/
|
363 |
+
public function addLargeFile($dataFile, $filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
|
364 |
+
$result = false;
|
365 |
+
|
366 |
+
if (!$this->isFinalized) {
|
367 |
+
|
368 |
+
if (is_string($dataFile) && is_file($dataFile)) {
|
369 |
+
$this->processFile($dataFile, $filePath, $timestamp, $fileComment, $extFileAttr);
|
370 |
+
} else if (is_resource($dataFile) && get_resource_type($dataFile) == "stream") {
|
371 |
+
$fh = $dataFile;
|
372 |
+
$this->openStream($filePath, $timestamp, $fileComment, $extFileAttr);
|
373 |
+
|
374 |
+
while (!feof($fh)) {
|
375 |
+
$this->addStreamData(fread($fh, $this->streamChunkSize));
|
376 |
+
}
|
377 |
+
$this->closeStream();
|
378 |
+
}
|
379 |
+
$result = true;
|
380 |
+
}
|
381 |
+
|
382 |
+
$this->_notifyListeners(null, array(
|
383 |
+
'file' => $dataFile,
|
384 |
+
'result' => $result,
|
385 |
+
));
|
386 |
+
|
387 |
+
return $result;
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Create a stream to be used for large entries.
|
392 |
+
*
|
393 |
+
* @author A. Grandt <php@grandt.com>
|
394 |
+
* @author Greg Kappatos
|
395 |
+
*
|
396 |
+
* @param string $filePath File path and name to be used in the archive.
|
397 |
+
* @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
|
398 |
+
* @param string $fileComment (Optional) Comment to be added to the archive for this file. To use $fileComment, $timestamp must be given.
|
399 |
+
* @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
|
400 |
+
*
|
401 |
+
* @throws \PHPZip\Zip\Exception\IncompatiblePhpVersion Throws an exception in case of errors
|
402 |
+
*
|
403 |
+
* @return bool $success
|
404 |
+
*/
|
405 |
+
public function openStream($filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
|
406 |
+
|
407 |
+
$result = false;
|
408 |
+
|
409 |
+
if (!function_exists('sys_get_temp_dir')) {
|
410 |
+
$this->_throwException(new IncompatiblePhpVersionException(array(
|
411 |
+
'appName' => self::APP_NAME,
|
412 |
+
'appVersion' => self::VERSION,
|
413 |
+
'minVersion' => self::MIN_PHP_VERSION,
|
414 |
+
)));
|
415 |
+
}
|
416 |
+
|
417 |
+
if (!$this->isFinalized) {
|
418 |
+
$this->onOpenStream();
|
419 |
+
|
420 |
+
if (BinStringStatic::_strlen($this->streamFilePath) > 0) {
|
421 |
+
$this->closeStream();
|
422 |
+
}
|
423 |
+
|
424 |
+
$this->streamFile = self::getTemporaryFile();
|
425 |
+
$this->streamData = fopen($this->streamFile, "wb");
|
426 |
+
$this->streamFilePath = $filePath;
|
427 |
+
$this->streamTimestamp = $timestamp;
|
428 |
+
$this->streamFileComment = $fileComment;
|
429 |
+
$this->streamFileLength = 0;
|
430 |
+
$this->streamExtFileAttr = $extFileAttr;
|
431 |
+
|
432 |
+
$result = true;
|
433 |
+
}
|
434 |
+
|
435 |
+
$this->_notifyListeners(null, array(
|
436 |
+
'file' => $this->streamFile,
|
437 |
+
'result' => $result,
|
438 |
+
));
|
439 |
+
|
440 |
+
return $result;
|
441 |
+
}
|
442 |
+
|
443 |
+
/**
|
444 |
+
* Add data to the open stream.
|
445 |
+
*
|
446 |
+
* @author A. Grandt <php@grandt.com>
|
447 |
+
* @author Greg Kappatos
|
448 |
+
*
|
449 |
+
* @param string $data
|
450 |
+
*
|
451 |
+
* @throws LengthMismatchException Throws an exception in case of errors
|
452 |
+
*
|
453 |
+
* @return mixed length in bytes added or false if the archive is finalized or there are no open stream.
|
454 |
+
*/
|
455 |
+
public function addStreamData($data) {
|
456 |
+
if ($this->isFinalized || BinStringStatic::_strlen($this->streamFilePath) == 0) {
|
457 |
+
return false;
|
458 |
+
}
|
459 |
+
|
460 |
+
$dataLength = BinStringStatic::_strlen($data);
|
461 |
+
$length = fwrite($this->streamData, $data, $dataLength);
|
462 |
+
|
463 |
+
if ($length != $dataLength) {
|
464 |
+
$this->_throwException(new LengthMismatchException(array(
|
465 |
+
'expected' => BinStringStatic::_strlen($data),
|
466 |
+
'written' => (!$length ? 'NONE!' : $length),
|
467 |
+
)));
|
468 |
+
}
|
469 |
+
|
470 |
+
$this->streamFileLength += $length;
|
471 |
+
|
472 |
+
return $length;
|
473 |
+
}
|
474 |
+
|
475 |
+
/**
|
476 |
+
* Close the current stream.
|
477 |
+
*
|
478 |
+
* @author A. Grandt <php@grandt.com>
|
479 |
+
*
|
480 |
+
* @return bool $success
|
481 |
+
*/
|
482 |
+
public function closeStream() {
|
483 |
+
if ($this->isFinalized || BinStringStatic::_strlen($this->streamFilePath) == 0) {
|
484 |
+
return false;
|
485 |
+
}
|
486 |
+
|
487 |
+
fflush($this->streamData);
|
488 |
+
fclose($this->streamData);
|
489 |
+
|
490 |
+
$this->processFile(
|
491 |
+
$this->streamFile,
|
492 |
+
$this->streamFilePath,
|
493 |
+
$this->streamTimestamp,
|
494 |
+
$this->streamFileComment,
|
495 |
+
$this->streamExtFileAttr
|
496 |
+
);
|
497 |
+
|
498 |
+
$this->streamData = null;
|
499 |
+
$this->streamFilePath = null;
|
500 |
+
$this->streamTimestamp = null;
|
501 |
+
$this->streamFileComment = null;
|
502 |
+
$this->streamFileLength = 0;
|
503 |
+
$this->streamExtFileAttr = null;
|
504 |
+
|
505 |
+
// Windows is a little slow at times, so a millisecond later, we can unlink this.
|
506 |
+
unlink($this->streamFile);
|
507 |
+
$this->streamFile = null;
|
508 |
+
|
509 |
+
return true;
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Process the current file.
|
514 |
+
*
|
515 |
+
* @author A. Grandt <php@grandt.com>
|
516 |
+
* @author Greg Kappatos
|
517 |
+
*
|
518 |
+
* @param string $dataFile
|
519 |
+
* @param string $filePath
|
520 |
+
* @param int $timestamp
|
521 |
+
* @param string $fileComment
|
522 |
+
* @param int $extFileAttr
|
523 |
+
*
|
524 |
+
* @return bool $success
|
525 |
+
*/
|
526 |
+
protected function processFile($dataFile, $filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
|
527 |
+
|
528 |
+
// TODO: change the magic numbers below to constants.
|
529 |
+
|
530 |
+
if ($this->isFinalized) {
|
531 |
+
return false;
|
532 |
+
}
|
533 |
+
|
534 |
+
$tempZip = self::getTemporaryFile();
|
535 |
+
|
536 |
+
$zip = new \ZipArchive;
|
537 |
+
$rv = $zip->open($tempZip, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
538 |
+
|
539 |
+
if ($rv === true) { // open returns true if successful, however one of the error values is 1, which will also read as true.
|
540 |
+
$zip->addFile($dataFile, 'file');
|
541 |
+
$zip->close();
|
542 |
+
} else {
|
543 |
+
// TODO: An error occurred reading the ZipArchive temp file (Seen on Windows installations)
|
544 |
+
}
|
545 |
+
|
546 |
+
$handle = fopen($tempZip, "rb");
|
547 |
+
$stats = fstat($handle);
|
548 |
+
$eof = $stats['size']-72; // set EOF to the position of the end of the zip data, before the CD record.
|
549 |
+
// Should probably use 34+gzLength instead.
|
550 |
+
|
551 |
+
fseek($handle, 6); // Skip Zip local file header and version
|
552 |
+
|
553 |
+
$gpFlags = fread($handle, 2);
|
554 |
+
$gzType = fread($handle, 2);
|
555 |
+
fread($handle, 4); // Skip DOS Time and Date
|
556 |
+
$fileCRC32 = fread($handle, 4);
|
557 |
+
|
558 |
+
$v = unpack("Vval", fread($handle, 4));
|
559 |
+
$gzLength = $v['val'];
|
560 |
+
|
561 |
+
$v = unpack("Vval", fread($handle, 4));
|
562 |
+
$dataLength = $v['val'];
|
563 |
+
|
564 |
+
$this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr);
|
565 |
+
|
566 |
+
$pos = 34;
|
567 |
+
fseek($handle, $pos); // Position pointer at the start of the actual zip data.
|
568 |
+
|
569 |
+
while (!feof($handle) && $pos < $eof) {
|
570 |
+
$len = $this->streamChunkSize;
|
571 |
+
|
572 |
+
if ($pos + $this->streamChunkSize > $eof) {
|
573 |
+
$len = $eof - $pos;
|
574 |
+
}
|
575 |
+
$data = fread($handle, $len);
|
576 |
+
$pos += $len;
|
577 |
+
|
578 |
+
$this->onProcessFile(array(
|
579 |
+
'data' => $data,
|
580 |
+
));
|
581 |
+
}
|
582 |
+
|
583 |
+
fclose($handle);
|
584 |
+
unlink($tempZip);
|
585 |
+
|
586 |
+
$this->_notifyListeners(null, array(
|
587 |
+
'file' => $dataFile,
|
588 |
+
));
|
589 |
+
|
590 |
+
return true;
|
591 |
+
}
|
592 |
+
|
593 |
+
/**
|
594 |
+
* Build the Zip file structures
|
595 |
+
*
|
596 |
+
* @author A. Grandt <php@grandt.com>
|
597 |
+
* @author Greg Kappatos
|
598 |
+
*
|
599 |
+
* @param string $filePath
|
600 |
+
* @param string $fileComment
|
601 |
+
* @param string $gpFlags
|
602 |
+
* @param string $gzType
|
603 |
+
* @param int $timestamp
|
604 |
+
* @param string $fileCRC32
|
605 |
+
* @param int $gzLength
|
606 |
+
* @param int $dataLength
|
607 |
+
* @param int $extFileAttr Use self::EXT_FILE_ATTR_FILE for files, self::EXT_FILE_ATTR_DIR for Directories.
|
608 |
+
*/
|
609 |
+
protected function buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr) {
|
610 |
+
$filePath = str_replace("\\", "/", $filePath);
|
611 |
+
$fileCommentLength = (empty($fileComment) ? 0 : BinStringStatic::_strlen($fileComment));
|
612 |
+
$timestamp = (int)$timestamp;
|
613 |
+
$timestamp = ($timestamp == 0 ? time() : $timestamp);
|
614 |
+
|
615 |
+
$dosTime = ZipUtils::getDosTime($timestamp);
|
616 |
+
$tsPack = pack("V", $timestamp);
|
617 |
+
|
618 |
+
if (!isset($gpFlags) || BinStringStatic::_strlen($gpFlags) != 2) {
|
619 |
+
$gpFlags = self::DEFAULT_GP_FLAGS;
|
620 |
+
}
|
621 |
+
|
622 |
+
$isFileUTF8 = mb_check_encoding($filePath, "UTF-8") && !mb_check_encoding($filePath, "ASCII");
|
623 |
+
$isCommentUTF8 = !empty($fileComment) && mb_check_encoding($fileComment, "UTF-8") && !mb_check_encoding($fileComment, "ASCII");
|
624 |
+
|
625 |
+
$locExField = "";
|
626 |
+
$cenExField = "";
|
627 |
+
|
628 |
+
if ($this->addExtraField) {
|
629 |
+
$locExField .= self::HEADER_EXTENDED_TIMESTAMP . "\x09\x00\x03"
|
630 |
+
. $tsPack . $tsPack
|
631 |
+
. self::EXTRA_FIELD_NEW_UNIX_GUID;
|
632 |
+
$cenExField .= self::HEADER_EXTENDED_TIMESTAMP . "\x05\x00\x03"
|
633 |
+
. $tsPack
|
634 |
+
. self::EXTRA_FIELD_NEW_UNIX_GUID_CD;
|
635 |
+
}
|
636 |
+
|
637 |
+
if ($isFileUTF8 || $isCommentUTF8) {
|
638 |
+
$flag = 0;
|
639 |
+
$gpFlagsV = unpack("vflags", $gpFlags);
|
640 |
+
if (isset($gpFlagsV['flags'])) {
|
641 |
+
$flag = $gpFlagsV['flags'];
|
642 |
+
}
|
643 |
+
$gpFlags = pack("v", $flag | (1 << 11));
|
644 |
+
|
645 |
+
if ($isFileUTF8) {
|
646 |
+
$utfExField = self::HEADER_UNICODE_PATH // utf8 encoded File path extra field
|
647 |
+
. pack ("v", (5 + BinStringStatic::_strlen($filePath)))
|
648 |
+
. "\x01"
|
649 |
+
. pack("V", crc32($filePath))
|
650 |
+
. $filePath;
|
651 |
+
|
652 |
+
$locExField .= $utfExField;
|
653 |
+
$cenExField .= $utfExField;
|
654 |
+
}
|
655 |
+
if ($isCommentUTF8) {
|
656 |
+
$cenExField .= self::HEADER_UNICODE_COMMENT // utf8 encoded file comment extra field
|
657 |
+
. pack ("v", (5 + BinStringStatic::_strlen($fileComment)))
|
658 |
+
. "\x01"
|
659 |
+
. pack("V", crc32($fileComment))
|
660 |
+
. $fileComment;
|
661 |
+
}
|
662 |
+
}
|
663 |
+
|
664 |
+
$header = $gpFlags . $gzType . $dosTime. $fileCRC32
|
665 |
+
. pack("VVv", $gzLength, $dataLength, BinStringStatic::_strlen($filePath)); // File name length
|
666 |
+
|
667 |
+
$zipEntry = self::ZIP_LOCAL_FILE_HEADER
|
668 |
+
. self::ATTR_VERSION_TO_EXTRACT
|
669 |
+
. $header
|
670 |
+
. pack("v", BinStringStatic::_strlen($locExField)) // Extra field length
|
671 |
+
. $filePath // FileName
|
672 |
+
. $locExField; // Extra fields
|
673 |
+
|
674 |
+
$this->onBuildZipEntry(array(
|
675 |
+
'zipEntry' => $zipEntry,
|
676 |
+
));
|
677 |
+
|
678 |
+
$cdEntry = self::ZIP_CENTRAL_FILE_HEADER
|
679 |
+
. self::ATTR_MADE_BY_VERSION
|
680 |
+
. ($dataLength === 0 ? "\x0A\x00" : self::ATTR_VERSION_TO_EXTRACT)
|
681 |
+
. $header
|
682 |
+
. pack("v", BinStringStatic::_strlen($cenExField)) // Extra field length
|
683 |
+
. pack("v", $fileCommentLength) // File comment length
|
684 |
+
. self::NULL_WORD // Disk number start
|
685 |
+
. self::NULL_WORD // internal file attributes
|
686 |
+
. pack("V", $extFileAttr) // External file attributes
|
687 |
+
. pack("V", $this->offset) // Relative offset of local header
|
688 |
+
. $filePath // FileName
|
689 |
+
. $cenExField; // Extra fields
|
690 |
+
|
691 |
+
if (!empty($fileComment)) {
|
692 |
+
$cdEntry .= $fileComment; // Comment
|
693 |
+
}
|
694 |
+
|
695 |
+
$this->cdRec[] = $cdEntry;
|
696 |
+
$this->offset += BinStringStatic::_strlen($zipEntry) + $gzLength;
|
697 |
+
|
698 |
+
$this->_notifyListeners(null, array(
|
699 |
+
'file' => $zipEntry,
|
700 |
+
));
|
701 |
+
}
|
702 |
+
|
703 |
+
/**
|
704 |
+
* Build the base standard response headers, and ensure the content can be streamed.
|
705 |
+
*
|
706 |
+
* @author A. Grandt <php@grandt.com>
|
707 |
+
* @author Greg Kappatos
|
708 |
+
*
|
709 |
+
* @param String $fileName The name of the Zip archive, in ISO-8859-1 (or ASCII) encoding, ie. "archive.zip". Optional, defaults to null, which means that no ISO-8859-1 encoded file name will be specified.
|
710 |
+
* @param String $contentType Content mime type. Optional, defaults to "application/zip".
|
711 |
+
* @param String $utf8FileName The name of the Zip archive, in UTF-8 encoding. Optional, defaults to null, which means that no UTF-8 encoded file name will be specified.
|
712 |
+
* @param bool $inline Use Content-Disposition with "inline" instead of "attached". Optional, defaults to false.
|
713 |
+
*
|
714 |
+
* @throws \PHPZip\Zip\Exception\IncompatiblePhpVersion, BufferNotEmpty, HeadersSent In case of errors
|
715 |
+
*
|
716 |
+
* @return bool Always returns true (for backward compatibility).
|
717 |
+
*/
|
718 |
+
public function buildResponseHeader($fileName = null, $contentType = self::CONTENT_TYPE, $utf8FileName = null, $inline = false) {
|
719 |
+
$ob = null;
|
720 |
+
$headerFile = null;
|
721 |
+
$headerLine = null;
|
722 |
+
$zlibConfig = 'zlib.output_compression';
|
723 |
+
|
724 |
+
$this->onBeginBuildResponseHeader();
|
725 |
+
|
726 |
+
if (!function_exists('sys_get_temp_dir')) {
|
727 |
+
$this->_throwException(new IncompatiblePhpVersionException(array(
|
728 |
+
'appName' => self::APP_NAME,
|
729 |
+
'appVersion' => self::VERSION,
|
730 |
+
'minVersion' => self::MIN_PHP_VERSION,
|
731 |
+
)));
|
732 |
+
}
|
733 |
+
|
734 |
+
$ob = ob_get_contents();
|
735 |
+
if ($ob !== false && BinStringStatic::_strlen($ob)) {
|
736 |
+
$this->_throwException(new BufferNotEmptyException(array(
|
737 |
+
'outputBuffer' => $ob,
|
738 |
+
'fileName' => $fileName,
|
739 |
+
)));
|
740 |
+
}
|
741 |
+
|
742 |
+
if (headers_sent($headerFile, $headerLine)) {
|
743 |
+
$this->_throwException(new HeadersSentException(array(
|
744 |
+
'headerFile' => $headerFile,
|
745 |
+
'headerLine' => $headerLine,
|
746 |
+
'fileName' => $fileName,
|
747 |
+
)));
|
748 |
+
}
|
749 |
+
|
750 |
+
if (@ini_get($zlibConfig)) {
|
751 |
+
@ini_set($zlibConfig, 'Off');
|
752 |
+
}
|
753 |
+
|
754 |
+
$cd = 'Content-Disposition: ' . ($inline ? 'inline' : 'attachment');
|
755 |
+
|
756 |
+
if ($fileName) {
|
757 |
+
$cd .= '; filename="' . $fileName . '"';
|
758 |
+
}
|
759 |
+
|
760 |
+
if ($utf8FileName) {
|
761 |
+
$cd .= "; filename*=UTF-8''" . rawurlencode($utf8FileName);
|
762 |
+
}
|
763 |
+
|
764 |
+
header('Pragma: public');
|
765 |
+
header('Last-Modified: ' . gmdate('D, d M Y H:i:s T'));
|
766 |
+
header('Expires: 0');
|
767 |
+
header('Accept-Ranges: bytes');
|
768 |
+
header('Content-Type: ' . $contentType);
|
769 |
+
header($cd);
|
770 |
+
|
771 |
+
$this->onEndBuildResponseHeader();
|
772 |
+
|
773 |
+
$this->_notifyListeners(null, array(
|
774 |
+
'file' => $fileName,
|
775 |
+
'utf8FileName' => $utf8FileName,
|
776 |
+
'contentType' => $contentType,
|
777 |
+
));
|
778 |
+
|
779 |
+
return true;
|
780 |
+
}
|
781 |
+
|
782 |
+
/**
|
783 |
+
* Close the archive.
|
784 |
+
* A closed archive can no longer have new files added to it.
|
785 |
+
*
|
786 |
+
* @author A. Grandt <php@grandt.com>
|
787 |
+
*
|
788 |
+
* @return bool Success
|
789 |
+
*/
|
790 |
+
public function finalize() {
|
791 |
+
if (!$this->isFinalized) {
|
792 |
+
if (BinStringStatic::_strlen($this->streamFilePath) > 0) {
|
793 |
+
$this->closeStream();
|
794 |
+
}
|
795 |
+
|
796 |
+
$cd = implode("", $this->cdRec);
|
797 |
+
|
798 |
+
$cdRecSize = pack("v", sizeof($this->cdRec));
|
799 |
+
$cdRec = $cd . self::ZIP_END_OF_CENTRAL_DIRECTORY
|
800 |
+
. self::NULL_DWORD // really two words, used for split archives: #ofThisDisk . #ofDiskWithCD. Both 0.
|
801 |
+
. $cdRecSize . $cdRecSize
|
802 |
+
. pack("VV", BinStringStatic::_strlen($cd), $this->offset);
|
803 |
+
|
804 |
+
if (!empty($this->zipComment)) {
|
805 |
+
$cdRec .= pack("v", BinStringStatic::_strlen($this->zipComment))
|
806 |
+
. $this->zipComment;
|
807 |
+
} else {
|
808 |
+
$cdRec .= self::NULL_WORD;
|
809 |
+
}
|
810 |
+
|
811 |
+
$this->zipWrite($cdRec);
|
812 |
+
$this->zipFlushBuffer();
|
813 |
+
|
814 |
+
$this->isFinalized = true;
|
815 |
+
$this->cdRec = null;
|
816 |
+
|
817 |
+
return true;
|
818 |
+
}
|
819 |
+
|
820 |
+
return false;
|
821 |
+
}
|
822 |
+
|
823 |
+
/**
|
824 |
+
* Check PHP version.
|
825 |
+
*
|
826 |
+
* @author A. Grandt <php@grandt.com>
|
827 |
+
*/
|
828 |
+
public function checkVersion() {
|
829 |
+
if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION, '<') || !function_exists('sys_get_temp_dir') ) {
|
830 |
+
die ("ERROR: " . self::APP_NAME . " " . self::VERSION . " requires PHP version " . self::MIN_PHP_VERSION . " or above.");
|
831 |
+
}
|
832 |
+
}
|
833 |
+
|
834 |
+
/*
|
835 |
+
* ************************************************************************
|
836 |
+
* Abstract methods.
|
837 |
+
* ************************************************************************
|
838 |
+
*/
|
839 |
+
|
840 |
+
/**
|
841 |
+
* Called when specialised action is needed
|
842 |
+
* while building a zip entry.
|
843 |
+
*
|
844 |
+
* @author A. Grandt <php@grandt.com>
|
845 |
+
* @author Greg Kappatos
|
846 |
+
*
|
847 |
+
* @param array $params Array that contains zipEntry.
|
848 |
+
*/
|
849 |
+
abstract protected function onBuildZipEntry(array $params);
|
850 |
+
|
851 |
+
/**
|
852 |
+
* Called when specialised action is needed
|
853 |
+
* at the start of adding a file to the archive.
|
854 |
+
*
|
855 |
+
* @author A. Grandt <php@grandt.com>
|
856 |
+
* @author Greg Kappatos
|
857 |
+
*
|
858 |
+
* @param array $params Array that contains gzLength.
|
859 |
+
*/
|
860 |
+
abstract protected function onBeginAddFile(array $params);
|
861 |
+
|
862 |
+
/**
|
863 |
+
* Called when specialised action is needed
|
864 |
+
* at the end of adding a file to the archive.
|
865 |
+
*
|
866 |
+
* @author A. Grandt <php@grandt.com>
|
867 |
+
* @author Greg Kappatos
|
868 |
+
*
|
869 |
+
* @param array $params Array that contains gzData.
|
870 |
+
*/
|
871 |
+
abstract protected function onEndAddFile(array $params);
|
872 |
+
|
873 |
+
/**
|
874 |
+
* Called when specialised action is needed
|
875 |
+
* at the start of sending the zip file|stream
|
876 |
+
* response headers.
|
877 |
+
*
|
878 |
+
* @author A. Grandt <php@grandt.com>
|
879 |
+
* @author Greg Kappatos
|
880 |
+
*/
|
881 |
+
abstract protected function onBeginBuildResponseHeader();
|
882 |
+
|
883 |
+
/**
|
884 |
+
* Called when specialised action is needed
|
885 |
+
* at the end of sending the zip file|stream
|
886 |
+
* response headers.
|
887 |
+
*
|
888 |
+
* @author A. Grandt <php@grandt.com>
|
889 |
+
* @author Greg Kappatos
|
890 |
+
*/
|
891 |
+
abstract protected function onEndBuildResponseHeader();
|
892 |
+
|
893 |
+
/**
|
894 |
+
* Called when specialised action is needed
|
895 |
+
* while opening a file|stream.
|
896 |
+
*
|
897 |
+
* @author A. Grandt <php@grandt.com>
|
898 |
+
* @author Greg Kappatos
|
899 |
+
*/
|
900 |
+
abstract protected function onOpenStream();
|
901 |
+
|
902 |
+
/**
|
903 |
+
* Called when specialised action is needed
|
904 |
+
* while processing a file.
|
905 |
+
*
|
906 |
+
* @author A. Grandt <php@grandt.com>
|
907 |
+
* @author Greg Kappatos
|
908 |
+
*
|
909 |
+
* @param array $params Array that contains data.
|
910 |
+
*/
|
911 |
+
abstract protected function onProcessFile(array $params);
|
912 |
+
|
913 |
+
/**
|
914 |
+
* Verify if the memory buffer is about to be exceeded.
|
915 |
+
*
|
916 |
+
* @author A. Grandt <php@grandt.com>
|
917 |
+
*
|
918 |
+
* @param int $gzLength length of the pending data.
|
919 |
+
*/
|
920 |
+
abstract public function zipVerifyMemBuffer($gzLength);
|
921 |
+
|
922 |
+
/**
|
923 |
+
*
|
924 |
+
* @author A. Grandt <php@grandt.com>
|
925 |
+
*
|
926 |
+
* @param string $data
|
927 |
+
*/
|
928 |
+
//abstract public function zipWrite($data);
|
929 |
+
|
930 |
+
/**
|
931 |
+
* Flush Zip Data stored in memory, to a temp file.
|
932 |
+
*
|
933 |
+
* @author A. Grandt <php@grandt.com>
|
934 |
+
*
|
935 |
+
*/
|
936 |
+
abstract public function zipFlush();
|
937 |
+
|
938 |
+
/**
|
939 |
+
*
|
940 |
+
* @author A. Grandt <php@grandt.com>
|
941 |
+
*
|
942 |
+
*/
|
943 |
+
abstract public function zipFlushBuffer();
|
944 |
+
|
945 |
+
/*
|
946 |
+
* ************************************************************************
|
947 |
+
* Listener methods.
|
948 |
+
* ************************************************************************
|
949 |
+
*/
|
950 |
+
|
951 |
+
/**
|
952 |
+
* Listen to events fired by this class.
|
953 |
+
*
|
954 |
+
* @author Greg Kappatos
|
955 |
+
*
|
956 |
+
* @param ZipArchiveListener $listener Class that implements the ZipArchiveListener interface.
|
957 |
+
*/
|
958 |
+
public function addListener(ZipArchiveListener $listener) {
|
959 |
+
$this->_listeners[] = $listener;
|
960 |
+
}
|
961 |
+
|
962 |
+
/**
|
963 |
+
* Stop listening to events fired by this class.
|
964 |
+
*
|
965 |
+
* @author Greg Kappatos
|
966 |
+
*
|
967 |
+
* @param ZipArchiveListener $listener Class that implements the ZipArchiveListener interface.
|
968 |
+
*/
|
969 |
+
public function removeListener(ZipArchiveListener $listener) {
|
970 |
+
$key = array_search($listener, $this->_listeners);
|
971 |
+
|
972 |
+
if ($key !== false) {
|
973 |
+
unset($this->_listeners[$key]);
|
974 |
+
}
|
975 |
+
}
|
976 |
+
|
977 |
+
/**
|
978 |
+
* Helper method to fire appropriate event.
|
979 |
+
*
|
980 |
+
* @author Greg Kappatos
|
981 |
+
*
|
982 |
+
* @param string|null $method (Optional) The name of the event to fire. If this is null, then the calling method is used.
|
983 |
+
* @param array $data Method parameters passed as an array.
|
984 |
+
*/
|
985 |
+
private function _notifyListeners($method = null, array $data = array()) {
|
986 |
+
if (is_null($method)) {
|
987 |
+
$backtrace = debug_backtrace();
|
988 |
+
if (sizeof($backtrace) > 0) {
|
989 |
+
$trace = $backtrace[1];
|
990 |
+
$method = 'on' . ucwords($trace['function']);
|
991 |
+
}
|
992 |
+
}
|
993 |
+
|
994 |
+
foreach ($this->_listeners as $listener) {
|
995 |
+
if (count($data) > 0) {
|
996 |
+
$listener->$method($data);
|
997 |
+
} else {
|
998 |
+
$listener->$method();
|
999 |
+
}
|
1000 |
+
}
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
/**
|
1004 |
+
* Helper method to fire OnException event for listeners and then throw the appropriate exception.
|
1005 |
+
*
|
1006 |
+
* @author Greg Kappatos
|
1007 |
+
*
|
1008 |
+
* @param AbstractException $exception Whatever exception needs to be thrown.
|
1009 |
+
*
|
1010 |
+
* @throws AbstractException $exception
|
1011 |
+
*/
|
1012 |
+
private function _throwException(AbstractException $exception) {
|
1013 |
+
$this->_notifyListeners('onException', array(
|
1014 |
+
'exception' => $exception,
|
1015 |
+
));
|
1016 |
+
|
1017 |
+
throw $exception;
|
1018 |
+
}
|
1019 |
+
|
1020 |
+
/*
|
1021 |
+
* ************************************************************************
|
1022 |
+
* Static methods/
|
1023 |
+
* ************************************************************************
|
1024 |
+
*/
|
1025 |
+
|
1026 |
+
/**
|
1027 |
+
*
|
1028 |
+
* @author A. Grandt <php@grandt.com>
|
1029 |
+
* @author Greg Kappatos
|
1030 |
+
*
|
1031 |
+
* @return string The full path to a temporary file.
|
1032 |
+
*/
|
1033 |
+
public static function getTemporaryFile() {
|
1034 |
+
if (is_callable(self::$temp)) {
|
1035 |
+
$file = @call_user_func(self::$temp);
|
1036 |
+
|
1037 |
+
if (is_string($file) && BinStringStatic::_strlen($file) && is_writable($file)) {
|
1038 |
+
return $file;
|
1039 |
+
}
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
$dir = (is_string(self::$temp) && BinStringStatic::_strlen(self::$temp)) ? self::$temp : sys_get_temp_dir();
|
1043 |
+
|
1044 |
+
return tempnam($dir, __NAMESPACE__);
|
1045 |
+
}
|
1046 |
+
}
|
includes/extensions/zip/Core/ZipUtils.php
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace PHPZip\Zip\Core;
|
3 |
+
|
4 |
+
use com\grandt\BinStringStatic;
|
5 |
+
|
6 |
+
class ZipUtils {
|
7 |
+
// Unix file types
|
8 |
+
const S_IFIFO = 0010000; // named pipe (fifo)
|
9 |
+
const S_IFCHR = 0020000; // character special
|
10 |
+
const S_IFDIR = 0040000; // directory
|
11 |
+
const S_IFBLK = 0060000; // block special
|
12 |
+
const S_IFREG = 0100000; // regular
|
13 |
+
const S_IFLNK = 0120000; // symbolic link
|
14 |
+
const S_IFSOCK = 0140000; // socket
|
15 |
+
|
16 |
+
// setuid/setgid/sticky bits, the same as for chmod:
|
17 |
+
const S_ISUID = 0004000; // set user id on execution
|
18 |
+
const S_ISGID = 0002000; // set group id on execution
|
19 |
+
const S_ISTXT = 0001000; // sticky bit
|
20 |
+
|
21 |
+
// And of course, the other 12 bits are for the permissions, the same as for chmod:
|
22 |
+
// When adding these up, you can also just write the permissions as a single octal number
|
23 |
+
// ie. 0755. The leading 0 specifies octal notation.
|
24 |
+
const S_IRWXU = 0000700; // RWX mask for owner
|
25 |
+
const S_IRUSR = 0000400; // R for owner
|
26 |
+
const S_IWUSR = 0000200; // W for owner
|
27 |
+
const S_IXUSR = 0000100; // X for owner
|
28 |
+
const S_IRWXG = 0000070; // RWX mask for group
|
29 |
+
const S_IRGRP = 0000040; // R for group
|
30 |
+
const S_IWGRP = 0000020; // W for group
|
31 |
+
const S_IXGRP = 0000010; // X for group
|
32 |
+
const S_IRWXO = 0000007; // RWX mask for other
|
33 |
+
const S_IROTH = 0000004; // R for other
|
34 |
+
const S_IWOTH = 0000002; // W for other
|
35 |
+
const S_IXOTH = 0000001; // X for other
|
36 |
+
const S_ISVTX = 0001000; // save swapped text even after use
|
37 |
+
|
38 |
+
// File type, sticky and permissions are added up, and shifted 16 bits left BEFORE adding the DOS flags.
|
39 |
+
// DOS file type flags, we really only use the S_DOS_D flag.
|
40 |
+
const S_DOS_A = 0000040; // DOS flag for Archive
|
41 |
+
const S_DOS_D = 0000020; // DOS flag for Directory
|
42 |
+
const S_DOS_V = 0000010; // DOS flag for Volume
|
43 |
+
const S_DOS_S = 0000004; // DOS flag for System
|
44 |
+
const S_DOS_H = 0000002; // DOS flag for Hidden
|
45 |
+
const S_DOS_R = 0000001; // DOS flag for Read Only
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Calculate the 2 byte dos time used in the zip entries.
|
49 |
+
*
|
50 |
+
* @author A. Grandt <php@grandt.com>
|
51 |
+
*
|
52 |
+
* @param int $timestamp
|
53 |
+
*
|
54 |
+
* @return string 2-byte encoded DOS Date
|
55 |
+
*/
|
56 |
+
public static function getDosTime($timestamp = 0) {
|
57 |
+
$timestamp = (int)$timestamp;
|
58 |
+
$oldTZ = @date_default_timezone_get();
|
59 |
+
date_default_timezone_set('UTC');
|
60 |
+
|
61 |
+
$date = ($timestamp == 0 ? getdate() : getdate($timestamp));
|
62 |
+
date_default_timezone_set($oldTZ);
|
63 |
+
|
64 |
+
if ($date["year"] >= 1980) { // Dos dates start on 1 Jan 1980
|
65 |
+
return pack("V", (($date["mday"] + ($date["mon"] << 5) + (($date["year"] - 1980) << 9)) << 16) |
|
66 |
+
(($date["seconds"] >> 1) + ($date["minutes"] << 5) + ($date["hours"] << 11)));
|
67 |
+
}
|
68 |
+
return "\x00\x00\x00\x00";
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Create the file permissions for a file or directory, for use in the extFileAttr parameters.
|
73 |
+
*
|
74 |
+
* @author A. Grandt <php@grandt.com>
|
75 |
+
*
|
76 |
+
* @param int $owner Unix permissions for owner (octal from 00 to 07)
|
77 |
+
* @param int $group Unix permissions for group (octal from 00 to 07)
|
78 |
+
* @param int $other Unix permissions for others (octal from 00 to 07)
|
79 |
+
* @param bool $isFile
|
80 |
+
*
|
81 |
+
* @return string EXTERNAL_REF field.
|
82 |
+
*/
|
83 |
+
public static function generateExtAttr($owner = 07, $group = 05, $other = 05, $isFile = true) {
|
84 |
+
$fp = $isFile ? self::S_IFREG : self::S_IFDIR;
|
85 |
+
$fp |= (($owner & 07) << 6) | (($group & 07) << 3) | ($other & 07);
|
86 |
+
|
87 |
+
return ($fp << 16) | ($isFile ? self::S_DOS_A : self::S_DOS_D);
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Get the file permissions for a file or directory, for use in the extFileAttr parameters.
|
92 |
+
*
|
93 |
+
* @author A. Grandt <php@grandt.com>
|
94 |
+
*
|
95 |
+
* @param string $filename
|
96 |
+
*
|
97 |
+
* @return string|bool external ref field, or false if the file is not found.
|
98 |
+
*/
|
99 |
+
public static function getFileExtAttr($filename) {
|
100 |
+
if (file_exists($filename)) {
|
101 |
+
$fp = fileperms($filename) << 16;
|
102 |
+
return $fp | (is_dir($filename) ? self::S_DOS_D : self::S_DOS_A);
|
103 |
+
}
|
104 |
+
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
|
108 |
+
public static function testBit($data, $bit) {
|
109 |
+
$bv = 1 << $bit;
|
110 |
+
return ($data & $bv) == $bv;
|
111 |
+
}
|
112 |
+
|
113 |
+
public static function setBit(&$data, $bit, $value = true) {
|
114 |
+
if ($value) {
|
115 |
+
$data |= (1 << $bit);
|
116 |
+
} else {
|
117 |
+
self::clrBit($data, $bit);
|
118 |
+
}
|
119 |
+
|
120 |
+
}
|
121 |
+
|
122 |
+
public static function clrBit(&$data, $bit) {
|
123 |
+
$data &= ~(1 << $bit);
|
124 |
+
}
|
125 |
+
}
|
includes/extensions/zip/Core/index.html
ADDED
File without changes
|
includes/extensions/zip/Exception/BufferNotEmpty.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as a concrete exception.
|
7 |
+
* It will be thrown if the output buffer contains data while
|
8 |
+
* trying to perform any operations with this library.
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace PHPZip\Zip\Exception;
|
13 |
+
|
14 |
+
use PHPZip\Zip\Core\AbstractException;
|
15 |
+
|
16 |
+
class BufferNotEmpty extends AbstractException {
|
17 |
+
|
18 |
+
private $_outputBuffer = null;
|
19 |
+
private $_fileName = null;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Constructor
|
23 |
+
*
|
24 |
+
* @author A. Grandt <php@grandt.com>
|
25 |
+
* @author Greg Kappatos
|
26 |
+
*
|
27 |
+
* @param array $config Configuration array containing outputBuffer and fileName
|
28 |
+
*/
|
29 |
+
public function __construct(array $config){
|
30 |
+
$this->_outputBuffer = $config['outputBuffer'];
|
31 |
+
$this->_fileName = isset($config['fileName']) ? $config['fileName'] : null;
|
32 |
+
|
33 |
+
$message = is_null($this->_fileName) ? '' : "Unable to send '{$this->_fileName}'. ";
|
34 |
+
$message .= "Output buffer contains the following text (typically warning or errors):\n{$this->_outputBuffer}";
|
35 |
+
|
36 |
+
parent::__construct($message);
|
37 |
+
}
|
38 |
+
|
39 |
+
public function getOutputBuffer(){
|
40 |
+
return $this->_outputBuffer;
|
41 |
+
}
|
42 |
+
|
43 |
+
public function getFileName(){
|
44 |
+
return $this->_fileName;
|
45 |
+
}
|
46 |
+
}
|
includes/extensions/zip/Exception/HeaderPositionError.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as a concrete exception.
|
7 |
+
* It will be thrown if the output length of fwrite() does not match
|
8 |
+
* the input length. So far, this only occurs in Core\AbstractZipArchive::addStreamData()
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace PHPZip\Zip\Exception;
|
13 |
+
|
14 |
+
use PHPZip\Zip\Core\AbstractException;
|
15 |
+
|
16 |
+
class HeaderPositionError extends AbstractException {
|
17 |
+
|
18 |
+
private $_expected = null;
|
19 |
+
private $_actual = null;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Constructor
|
23 |
+
*
|
24 |
+
* @author A. Grandt <php@grandt.com>
|
25 |
+
* @author Greg Kappatos
|
26 |
+
*
|
27 |
+
* @param array $config Configuration array containing expected and written
|
28 |
+
*/
|
29 |
+
public function __construct(array $config){
|
30 |
+
$this->_expected = (string)$config['expected'];
|
31 |
+
$this->_actual = (string)$config['actual'];
|
32 |
+
|
33 |
+
$message = sprintf(
|
34 |
+
'%s %s %s %s %s',
|
35 |
+
(string)($this->_actual - $this->_expected),
|
36 |
+
' extra bytes before header. Expected pos ',
|
37 |
+
$this->_expected,
|
38 |
+
' but found the header at ',
|
39 |
+
$this->_actual
|
40 |
+
);
|
41 |
+
|
42 |
+
parent::__construct($message);
|
43 |
+
}
|
44 |
+
|
45 |
+
public function getExpected(){
|
46 |
+
return $this->_expected;
|
47 |
+
}
|
48 |
+
|
49 |
+
public function getActual(){
|
50 |
+
return $this->_actual;
|
51 |
+
}
|
52 |
+
}
|
includes/extensions/zip/Exception/HeadersSent.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as a concrete exception.
|
7 |
+
* It will be thrown if any headers have been sent, or if any
|
8 |
+
* output has been printed or echoed.
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace PHPZip\Zip\Exception;
|
13 |
+
|
14 |
+
use PHPZip\Zip\Core\AbstractException;
|
15 |
+
|
16 |
+
class HeadersSent extends AbstractException {
|
17 |
+
|
18 |
+
private $_headerFile = null;
|
19 |
+
private $_headerLine = null;
|
20 |
+
private $_fileName = null;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Constructor
|
24 |
+
*
|
25 |
+
* @author A. Grandt <php@grandt.com>
|
26 |
+
* @author Greg Kappatos
|
27 |
+
*
|
28 |
+
* @param array $config Configuration array containing headerFile, headerLine and fileName
|
29 |
+
*/
|
30 |
+
public function __construct(array $config){
|
31 |
+
$this->_headerFile = $config['headerFile'];
|
32 |
+
$this->_headerLine = $config['headerLine'];
|
33 |
+
$this->_fileName = isset($config['fileName']) ? $config['fileName'] : null;
|
34 |
+
|
35 |
+
$message = is_null($this->_fileName) ? '' : "Unable to send '{$this->_fileName}'. ";
|
36 |
+
$message .= "Headers have already been sent from '{$this->_headerFile}' in line {$this->_headerLine}";
|
37 |
+
|
38 |
+
parent::__construct($message);
|
39 |
+
}
|
40 |
+
|
41 |
+
public function getHeaderFile(){
|
42 |
+
return $this->_headerFile;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function getHeaderLine(){
|
46 |
+
return $this->_headerLine;
|
47 |
+
}
|
48 |
+
|
49 |
+
public function getFileName(){
|
50 |
+
return $this->_fileName;
|
51 |
+
}
|
52 |
+
}
|
includes/extensions/zip/Exception/IncompatiblePhpVersion.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as a concrete exception.
|
7 |
+
* It will be thrown if the current PHP version is below the minimum
|
8 |
+
* required version.
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace PHPZip\Zip\Exception;
|
13 |
+
|
14 |
+
use PHPZip\Zip\Core\AbstractException;
|
15 |
+
|
16 |
+
class IncompatiblePhpVersion extends AbstractException {
|
17 |
+
|
18 |
+
private $_minVersion = null;
|
19 |
+
private $_currentVersion = null;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Constructor
|
23 |
+
*
|
24 |
+
* @author A. Grandt <php@grandt.com>
|
25 |
+
* @author Greg Kappatos
|
26 |
+
*
|
27 |
+
* @param array $config Configuration array containing appName, appVersion and minVersion (PHP)
|
28 |
+
*/
|
29 |
+
public function __construct(array $config){
|
30 |
+
$this->_minVersion = (string)$config['minVersion'];
|
31 |
+
$this->_currentVersion = (string)phpversion();
|
32 |
+
|
33 |
+
$message = sprintf(
|
34 |
+
'%s %s %s %s %s (%s %s).',
|
35 |
+
$config['appName'],
|
36 |
+
(string)$config['appVersion'],
|
37 |
+
'requires PHP version',
|
38 |
+
$this->_minVersion,
|
39 |
+
'or above',
|
40 |
+
$this->_currentVersion,
|
41 |
+
'detected'
|
42 |
+
);
|
43 |
+
|
44 |
+
parent::__construct($message);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function getMinVersion(){
|
48 |
+
return $this->_minVersion;
|
49 |
+
}
|
50 |
+
|
51 |
+
public function getCurrentVersion(){
|
52 |
+
return $this->_currentVersion;
|
53 |
+
}
|
54 |
+
}
|
includes/extensions/zip/Exception/InvalidPhpConfiguration.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as a concrete exception.
|
7 |
+
* It will be thrown if an invalid setting is detected in php.ini
|
8 |
+
* that will prevent this library from operating properly.
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace PHPZip\Zip\Exception;
|
13 |
+
|
14 |
+
use PHPZip\Zip\Core\AbstractException;
|
15 |
+
|
16 |
+
class InvalidPhpConfiguration extends AbstractException {
|
17 |
+
|
18 |
+
private $_setting = null;
|
19 |
+
private $_expected = null;
|
20 |
+
private $_actual = null;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Constructor
|
24 |
+
*
|
25 |
+
* @author Greg Kappatos
|
26 |
+
*
|
27 |
+
* @param array $config Configuration array containing php.ini settings: setting and expected (value)
|
28 |
+
*/
|
29 |
+
public function __construct(array $config){
|
30 |
+
$this->_setting = $config['setting'];
|
31 |
+
$this->_expected = $config['expected'];
|
32 |
+
$this->_actual = (string)@ini_get($this->_setting);
|
33 |
+
|
34 |
+
$message = sprintf(
|
35 |
+
'%s %s "%s" %s %s %s',
|
36 |
+
'Invalid PHP Configuration: ',
|
37 |
+
$this->_setting,
|
38 |
+
$this->_actual,
|
39 |
+
'Please change this setting to',
|
40 |
+
$this->_expected,
|
41 |
+
'to continue.'
|
42 |
+
);
|
43 |
+
|
44 |
+
parent::__construct($message);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function getSetting(){
|
48 |
+
return $this->_setting;
|
49 |
+
}
|
50 |
+
|
51 |
+
public function getExpected(){
|
52 |
+
return $this->_expected;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function getActual(){
|
56 |
+
return $this->_actual;
|
57 |
+
}
|
58 |
+
}
|
includes/extensions/zip/Exception/LengthMismatch.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as a concrete exception.
|
7 |
+
* It will be thrown if the output length of fwrite() does not match
|
8 |
+
* the input length. So far, this only occurs in Core\AbstractZipArchive::addStreamData()
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace PHPZip\Zip\Exception;
|
13 |
+
|
14 |
+
use PHPZip\Zip\Core\AbstractException;
|
15 |
+
|
16 |
+
class LengthMismatch extends AbstractException {
|
17 |
+
|
18 |
+
private $_expected = null;
|
19 |
+
private $_written = null;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Constructor
|
23 |
+
*
|
24 |
+
* @author A. Grandt <php@grandt.com>
|
25 |
+
* @author Greg Kappatos
|
26 |
+
*
|
27 |
+
* @param array $config Configuration array containing expected and written
|
28 |
+
*/
|
29 |
+
public function __construct(array $config){
|
30 |
+
$this->_expected = (string)$config['expected'];
|
31 |
+
$this->_written = (string)$config['written'];
|
32 |
+
|
33 |
+
$message = sprintf(
|
34 |
+
'%s %s %s %s',
|
35 |
+
'Length Mismatch Error: Expected',
|
36 |
+
$this->_expected,
|
37 |
+
'bytes, wrote',
|
38 |
+
$this->_written
|
39 |
+
);
|
40 |
+
|
41 |
+
parent::__construct($message);
|
42 |
+
}
|
43 |
+
|
44 |
+
public function getExpected(){
|
45 |
+
return $this->_expected;
|
46 |
+
}
|
47 |
+
|
48 |
+
public function getWritten(){
|
49 |
+
return $this->_written;
|
50 |
+
}
|
51 |
+
}
|
includes/extensions/zip/Exception/index.html
ADDED
File without changes
|
includes/extensions/zip/File/Zip.php
ADDED
@@ -0,0 +1,348 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author A. Grandt <php@grandt.com>
|
5 |
+
* @author Greg Kappatos
|
6 |
+
*
|
7 |
+
* This class serves as a concrete zip file archive.
|
8 |
+
*
|
9 |
+
*/
|
10 |
+
|
11 |
+
namespace PHPZip\Zip\File;
|
12 |
+
|
13 |
+
use com\grandt\BinStringStatic;
|
14 |
+
use PHPZip\Zip\Core\AbstractZipArchive;
|
15 |
+
|
16 |
+
class Zip extends AbstractZipArchive {
|
17 |
+
|
18 |
+
const MEMORY_THRESHOLD = 1048576; // 1 MB - Auto create temp file if the zip data exceeds this
|
19 |
+
const STREAM_CHUNK_SIZE = 65536; // 64 KB
|
20 |
+
|
21 |
+
private $_zipData = null;
|
22 |
+
private $_zipFile = null;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Constructor.
|
26 |
+
*
|
27 |
+
* @author A. Grandt <php@grandt.com>
|
28 |
+
* @author Greg Kappatos
|
29 |
+
*
|
30 |
+
* @param boolean $useZipFile Write temp zip data to tempFile? Default FALSE
|
31 |
+
*
|
32 |
+
* @throws \PHPZip\Zip\Exception\InvalidPhpConfiguration In case of errors
|
33 |
+
*/
|
34 |
+
public function __construct($useZipFile = false) {
|
35 |
+
parent::__construct(self::STREAM_CHUNK_SIZE);
|
36 |
+
|
37 |
+
if ($useZipFile) {
|
38 |
+
$this->_zipFile = tmpfile();
|
39 |
+
} else {
|
40 |
+
$this->_zipData = '';
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Destructor.
|
46 |
+
* Perform clean up actions.
|
47 |
+
*
|
48 |
+
* @author A. Grandt <php@grandt.com>
|
49 |
+
*/
|
50 |
+
public function __destruct() {
|
51 |
+
if (is_resource($this->_zipFile)) {
|
52 |
+
fclose($this->_zipFile);
|
53 |
+
}
|
54 |
+
|
55 |
+
$this->_zipData = null;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Set zip file to write zip data to.
|
60 |
+
* This will cause all present and future data written to this class to be written to this file.
|
61 |
+
* This can be used at any time, even after the Zip Archive have been finalized. Any previous file will be closed.
|
62 |
+
* Warning: If the given file already exists, it will be overwritten.
|
63 |
+
*
|
64 |
+
* @author A. Grandt <php@grandt.com>
|
65 |
+
*
|
66 |
+
* @param string $fileName
|
67 |
+
*
|
68 |
+
* @return bool Success
|
69 |
+
*/
|
70 |
+
public function setZipFile($fileName) {
|
71 |
+
if (is_file($fileName)) {
|
72 |
+
unlink($fileName);
|
73 |
+
}
|
74 |
+
|
75 |
+
$fd = fopen($fileName, "x+b");
|
76 |
+
|
77 |
+
if (is_resource($this->_zipFile)) {
|
78 |
+
rewind($this->_zipFile);
|
79 |
+
|
80 |
+
while (!feof($this->_zipFile)) {
|
81 |
+
fwrite($fd, fread($this->_zipFile, $this->streamChunkSize));
|
82 |
+
}
|
83 |
+
|
84 |
+
fclose($this->_zipFile);
|
85 |
+
} else {
|
86 |
+
fwrite($fd, $this->_zipData);
|
87 |
+
$this->_zipData = null;
|
88 |
+
}
|
89 |
+
|
90 |
+
$this->_zipFile = $fd;
|
91 |
+
return true;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Alias for setZipFile
|
96 |
+
*
|
97 |
+
* @param $fileName
|
98 |
+
*
|
99 |
+
* @return bool
|
100 |
+
*/
|
101 |
+
public function saveZipFile($fileName) {
|
102 |
+
return $this->setZipFile($fileName);
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Get the handle resource for the archive zip file.
|
107 |
+
* If the zip haven't been finalized yet, this will cause it to become finalized
|
108 |
+
*
|
109 |
+
* @author A. Grandt <php@grandt.com>
|
110 |
+
*
|
111 |
+
* @return resource zip file handle
|
112 |
+
*/
|
113 |
+
public function getZipFile() {
|
114 |
+
if (!$this->isFinalized) {
|
115 |
+
$this->finalize();
|
116 |
+
}
|
117 |
+
|
118 |
+
$this->zipFlush();
|
119 |
+
rewind($this->_zipFile);
|
120 |
+
return $this->_zipFile;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Send the archive as a zip download
|
125 |
+
*
|
126 |
+
* @author A. Grandt <php@grandt.com>
|
127 |
+
*
|
128 |
+
* @param String $fileName The name of the Zip archive, in ISO-8859-1 (or ASCII) encoding,
|
129 |
+
* ie. "archive.zip". Optional, defaults to null, which means that
|
130 |
+
* no ISO-8859-1 encoded file name will be specified.
|
131 |
+
* @param String $contentType Content mime type. Optional, defaults to "application/zip".
|
132 |
+
* @param String $utf8FileName The name of the Zip archive, in UTF-8 encoding. Optional, defaults
|
133 |
+
* to null, which means that no UTF-8 encoded file name will be specified.
|
134 |
+
* @param bool $inline Use Content-Disposition with "inline" instead of "attachment". Optional, defaults to false.
|
135 |
+
*
|
136 |
+
* @return bool $success
|
137 |
+
*/
|
138 |
+
public function sendZip($fileName = null, $contentType = self::CONTENT_TYPE, $utf8FileName = null, $inline = false) {
|
139 |
+
if (!$this->isFinalized) {
|
140 |
+
$this->finalize();
|
141 |
+
}
|
142 |
+
|
143 |
+
if ($this->buildResponseHeader($fileName, $contentType, $utf8FileName, $inline)) {
|
144 |
+
return true;
|
145 |
+
}
|
146 |
+
return false;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Get the zip file contents
|
151 |
+
* If the zip haven't been finalized yet, this will cause it to become finalized
|
152 |
+
*
|
153 |
+
* @author A. Grandt <php@grandt.com>
|
154 |
+
* @author Greg Kappatos
|
155 |
+
*
|
156 |
+
* @return string zip data
|
157 |
+
*/
|
158 |
+
public function getZipData() {
|
159 |
+
$result = null;
|
160 |
+
|
161 |
+
if (!$this->isFinalized) {
|
162 |
+
$this->finalize();
|
163 |
+
}
|
164 |
+
|
165 |
+
if (!is_resource($this->_zipFile)) {
|
166 |
+
$result = $this->_zipData;
|
167 |
+
} else {
|
168 |
+
rewind($this->_zipFile);
|
169 |
+
$stat = fstat($this->_zipFile);
|
170 |
+
$result = fread($this->_zipFile, $stat['size']);
|
171 |
+
}
|
172 |
+
|
173 |
+
return $result;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Return the current size of the archive
|
178 |
+
*
|
179 |
+
* @author A. Grandt <php@grandt.com>
|
180 |
+
*
|
181 |
+
* @return int Size of the archive
|
182 |
+
*/
|
183 |
+
public function getArchiveSize() {
|
184 |
+
if (!is_resource($this->_zipFile)) {
|
185 |
+
return BinStringStatic::_strlen($this->_zipData);
|
186 |
+
}
|
187 |
+
|
188 |
+
$stat = fstat($this->_zipFile);
|
189 |
+
return $stat['size'];
|
190 |
+
}
|
191 |
+
|
192 |
+
/*
|
193 |
+
* ************************************************************************
|
194 |
+
* Superclass callbacks.
|
195 |
+
* ************************************************************************
|
196 |
+
*/
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Called by superclass when specialised action is needed
|
200 |
+
* while building a zip entry.
|
201 |
+
*
|
202 |
+
* @author A. Grandt <php@grandt.com>
|
203 |
+
* @author Greg Kappatos
|
204 |
+
*
|
205 |
+
* @param array $params Array that contains zipEntry.
|
206 |
+
*/
|
207 |
+
public function onBuildZipEntry(array $params) {
|
208 |
+
$this->zipWrite($params['zipEntry']);
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Called by superclass when specialised action is needed
|
213 |
+
* at the start of adding a file to the archive.
|
214 |
+
*
|
215 |
+
* @author A. Grandt <php@grandt.com>
|
216 |
+
* @author Greg Kappatos
|
217 |
+
*
|
218 |
+
* @param array $params Array that contains gzLength.
|
219 |
+
*/
|
220 |
+
public function onBeginAddFile(array $params) {
|
221 |
+
if (!is_resource($this->_zipFile) && ($this->offset + $params['gzLength']) > self::MEMORY_THRESHOLD) {
|
222 |
+
$this->zipFlush();
|
223 |
+
}
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Called by superclass when specialised action is needed
|
228 |
+
* at the end of adding a file to the archive.
|
229 |
+
*
|
230 |
+
* @author A. Grandt <php@grandt.com>
|
231 |
+
* @author Greg Kappatos
|
232 |
+
*
|
233 |
+
* @param array $params Array that contains gzData.
|
234 |
+
*/
|
235 |
+
public function onEndAddFile(array $params) {
|
236 |
+
$this->zipWrite($params['gzData']);
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Called by superclass when specialised action is needed
|
241 |
+
* at the start of sending the zip file response header.
|
242 |
+
*
|
243 |
+
* @author A. Grandt <php@grandt.com>
|
244 |
+
* @author Greg Kappatos
|
245 |
+
*/
|
246 |
+
public function onBeginBuildResponseHeader() {
|
247 |
+
if (!$this->isFinalized) {
|
248 |
+
$this->finalize();
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Called by superclass when specialised action is needed
|
254 |
+
* at the end of sending the zip file response header.
|
255 |
+
*
|
256 |
+
* @author A. Grandt <php@grandt.com>
|
257 |
+
* @author Greg Kappatos
|
258 |
+
*/
|
259 |
+
public function onEndBuildResponseHeader() {
|
260 |
+
header('Connection: close');
|
261 |
+
header('Content-Length: ' . $this->getArchiveSize());
|
262 |
+
|
263 |
+
if (!is_resource($this->_zipFile)) {
|
264 |
+
echo $this->_zipData;
|
265 |
+
} else {
|
266 |
+
rewind($this->_zipFile);
|
267 |
+
|
268 |
+
while (!feof($this->_zipFile)) {
|
269 |
+
echo fread($this->_zipFile, $this->streamChunkSize);
|
270 |
+
}
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Called by superclass when specialised action is needed
|
276 |
+
* while opening a stream.
|
277 |
+
*
|
278 |
+
* @author A. Grandt <php@grandt.com>
|
279 |
+
* @author Greg Kappatos
|
280 |
+
*/
|
281 |
+
public function onOpenStream() {
|
282 |
+
$this->zipFlush();
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Called by superclass when specialised action is needed
|
287 |
+
* while processing a file.
|
288 |
+
*
|
289 |
+
* @author A. Grandt <php@grandt.com>
|
290 |
+
* @author Greg Kappatos
|
291 |
+
*
|
292 |
+
* @param array $params Array that contains data.
|
293 |
+
*/
|
294 |
+
public function onProcessFile(array $params) {
|
295 |
+
$this->zipWrite($params['data']);
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Verify if the memory buffer is about to be exceeded.
|
300 |
+
*
|
301 |
+
* @author A. Grandt <php@grandt.com>
|
302 |
+
*
|
303 |
+
* @param int $gzLength length of the pending data.
|
304 |
+
*/
|
305 |
+
public function zipVerifyMemBuffer($gzLength) {
|
306 |
+
if (!is_resource($this->_zipFile) && ($this->offset + $gzLength) > self::MEMORY_THRESHOLD) {
|
307 |
+
$this->zipFlush();
|
308 |
+
}
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
*
|
313 |
+
* @author A. Grandt <php@grandt.com>
|
314 |
+
*
|
315 |
+
* @param string $data
|
316 |
+
*/
|
317 |
+
public function zipWrite($data) {
|
318 |
+
if (!is_resource($this->_zipFile)) {
|
319 |
+
$this->_zipData .= $data;
|
320 |
+
} else {
|
321 |
+
fwrite($this->_zipFile, $data);
|
322 |
+
fflush($this->_zipFile);
|
323 |
+
}
|
324 |
+
}
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Flush Zip Data stored in memory, to a temp file.
|
328 |
+
*
|
329 |
+
* @author A. Grandt <php@grandt.com>
|
330 |
+
*
|
331 |
+
*/
|
332 |
+
public function zipFlush() {
|
333 |
+
if (!is_resource($this->_zipFile)) {
|
334 |
+
$this->_zipFile = tmpfile();
|
335 |
+
fwrite($this->_zipFile, $this->_zipData);
|
336 |
+
$this->_zipData = null;
|
337 |
+
}
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
*
|
342 |
+
* @author A. Grandt <php@grandt.com>
|
343 |
+
*
|
344 |
+
*/
|
345 |
+
public function zipFlushBuffer() {
|
346 |
+
// Does nothing.
|
347 |
+
}
|
348 |
+
}
|
includes/extensions/zip/File/index.html
ADDED
File without changes
|
includes/extensions/zip/Listener/ZipArchiveListener.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author Greg Kappatos
|
5 |
+
*
|
6 |
+
* This class serves as an observer/listener which can be implemented
|
7 |
+
* by any other class who is interested in the PHPZip events.
|
8 |
+
* Simply implement the methods and call Stream\ZipStream or
|
9 |
+
* File\Zip::addListener($this) from inside your class.
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace PHPZip\Zip\Listener;
|
14 |
+
|
15 |
+
interface ZipArchiveListener {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Event fired after a zip entry has been successfully built.
|
19 |
+
*
|
20 |
+
* @author Greg Kappatos
|
21 |
+
*
|
22 |
+
* @param array $params Array that contains file (zipEntry).
|
23 |
+
*/
|
24 |
+
public function onBuildZipEntry(array $params);
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Event fired after a stream has been successfully opened.
|
28 |
+
*
|
29 |
+
* @author Greg Kappatos
|
30 |
+
*
|
31 |
+
* @param array $params Array that contains file (zipEntry).
|
32 |
+
*/
|
33 |
+
public function onOpenStream(array $params);
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Event fired after a file has been successfully added to archive.
|
37 |
+
*
|
38 |
+
* @author Greg Kappatos
|
39 |
+
*
|
40 |
+
* @param array $params Array that contains file (zipEntry).
|
41 |
+
*/
|
42 |
+
public function onAddFile(array $params);
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Event fired after a large file has been successfully added to archive.
|
46 |
+
*
|
47 |
+
* @author Greg Kappatos
|
48 |
+
*
|
49 |
+
* @param array $params Array that contains file (zipEntry).
|
50 |
+
*/
|
51 |
+
public function onAddLargeFile(array $params);
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Event fired after a zip archive has been sent.
|
55 |
+
*
|
56 |
+
* @author Greg Kappatos
|
57 |
+
*
|
58 |
+
* @param array $params Array that contains file (zipEntry).
|
59 |
+
*/
|
60 |
+
public function onSendZip(array $params);
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Event fired before a subclass of \PHPZip\Zip\Core\AbstractException is thrown.
|
64 |
+
*
|
65 |
+
* @author Greg Kappatos
|
66 |
+
*
|
67 |
+
* @param array $params Array that contains file (zipEntry).
|
68 |
+
*/
|
69 |
+
public function onException(array $params);
|
70 |
+
|
71 |
+
}
|
includes/extensions/zip/Listener/index.html
ADDED
File without changes
|
includes/extensions/zip/Stream/ZipStream.php
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @author A. Grandt <php@grandt.com>
|
5 |
+
* @author Greg Kappatos
|
6 |
+
*
|
7 |
+
* This class serves as a concrete zip stream archive.
|
8 |
+
*
|
9 |
+
*/
|
10 |
+
|
11 |
+
namespace PHPZip\Zip\Stream;
|
12 |
+
|
13 |
+
use PHPZip\Zip\Core\AbstractZipArchive;
|
14 |
+
|
15 |
+
class ZipStream extends AbstractZipArchive {
|
16 |
+
|
17 |
+
const STREAM_CHUNK_SIZE = 16384; // 16 KB
|
18 |
+
private $maxStreamBufferLength = 1048576;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Constructor.
|
22 |
+
*
|
23 |
+
* @author A. Grandt <php@grandt.com>
|
24 |
+
* @author Greg Kappatos
|
25 |
+
*
|
26 |
+
* @param String $fileName The name of the Zip archive, in ISO-8859-1 (or ASCII) encoding, ie. "archive.zip". Optional, defaults to NULL, which means that no ISO-8859-1 encoded file name will be specified.
|
27 |
+
* @param String $contentType Content mime type. Optional, defaults to "application/zip".
|
28 |
+
* @param String $utf8FileName The name of the Zip archive, in UTF-8 encoding. Optional, defaults to NULL, which means that no UTF-8 encoded file name will be specified.
|
29 |
+
* @param bool $inline Use Content-Disposition with "inline" instead of "attached". Optional, defaults to FALSE.
|
30 |
+
*
|
31 |
+
* @throws \PHPZip\Zip\Exception\BufferNotEmpty, HeadersSent, IncompatiblePhpVersion, InvalidPhpConfiguration In case of errors
|
32 |
+
*/
|
33 |
+
public function __construct($fileName = '', $contentType = self::CONTENT_TYPE, $utf8FileName = null, $inline = false) {
|
34 |
+
parent::__construct(self::STREAM_CHUNK_SIZE);
|
35 |
+
$this->buildResponseHeader($fileName, $contentType, $utf8FileName, $inline);
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Destructor.
|
40 |
+
* Perform clean up actions.
|
41 |
+
* Please note that frameworks are absolutely prohibited from sending ANYTHING to the output after the Zip is sent.
|
42 |
+
*
|
43 |
+
* @author A. Grandt <php@grandt.com>
|
44 |
+
*/
|
45 |
+
public function __destruct(){
|
46 |
+
$this->isFinalized = true;
|
47 |
+
$this->cdRec = null;
|
48 |
+
}
|
49 |
+
|
50 |
+
/*
|
51 |
+
* ************************************************************************
|
52 |
+
* Superclass callbacks.
|
53 |
+
* ************************************************************************
|
54 |
+
*/
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Called by superclass when specialised action is needed
|
58 |
+
* while building a zip entry.
|
59 |
+
*
|
60 |
+
* @author A. Grandt <php@grandt.com>
|
61 |
+
* @author Greg Kappatos
|
62 |
+
*
|
63 |
+
* @param array $params Array that contains zipEntry.
|
64 |
+
*/
|
65 |
+
public function onBuildZipEntry(array $params){
|
66 |
+
print($params['zipEntry']);
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Called by superclass when specialised action is needed
|
71 |
+
* at the start of adding a file to the archive.
|
72 |
+
*
|
73 |
+
* @author A. Grandt <php@grandt.com>
|
74 |
+
* @author Greg Kappatos
|
75 |
+
*
|
76 |
+
* @param array $params Array that contains gzLength.
|
77 |
+
*/
|
78 |
+
public function onBeginAddFile(array $params){
|
79 |
+
// Do nothing.
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Called by superclass when specialised action is needed
|
84 |
+
* at the end of adding a file to the archive.
|
85 |
+
*
|
86 |
+
* @author A. Grandt <php@grandt.com>
|
87 |
+
* @author Greg Kappatos
|
88 |
+
*
|
89 |
+
* @param array $params Array that contains gzData.
|
90 |
+
*/
|
91 |
+
public function onEndAddFile(array $params){
|
92 |
+
print($params['gzData']);
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Called by superclass when specialised action is needed
|
97 |
+
* at the start of sending the zip stream response header.
|
98 |
+
*
|
99 |
+
* @author A. Grandt <php@grandt.com>
|
100 |
+
* @author Greg Kappatos
|
101 |
+
*/
|
102 |
+
public function onBeginBuildResponseHeader(){
|
103 |
+
// Do nothing.
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Called by superclass when specialised action is needed
|
108 |
+
* at the end of sending the zip stream response header.
|
109 |
+
*
|
110 |
+
* @author A. Grandt <php@grandt.com>
|
111 |
+
* @author Greg Kappatos
|
112 |
+
*/
|
113 |
+
public function onEndBuildResponseHeader(){
|
114 |
+
//header("Connection: Keep-Alive");
|
115 |
+
$this->zipFlushBuffer();
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Called by superclass when specialised action is needed
|
120 |
+
* while opening a stream.
|
121 |
+
*
|
122 |
+
* @author A. Grandt <php@grandt.com>
|
123 |
+
* @author Greg Kappatos
|
124 |
+
*/
|
125 |
+
public function onOpenStream(){
|
126 |
+
// Do nothing.
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Called by superclass when specialised action is needed
|
131 |
+
* while processing a file.
|
132 |
+
*
|
133 |
+
* @author A. Grandt <php@grandt.com>
|
134 |
+
* @author Greg Kappatos
|
135 |
+
*
|
136 |
+
* @param array $params Array that contains data.
|
137 |
+
*/
|
138 |
+
public function onProcessFile(array $params){
|
139 |
+
print($params['data']);
|
140 |
+
$this->zipFlushBuffer();
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Verify if the memory buffer is about to be exceeded.
|
145 |
+
*
|
146 |
+
* @author A. Grandt <php@grandt.com>
|
147 |
+
*
|
148 |
+
* @param int $gzLength length of the pending data.
|
149 |
+
*/
|
150 |
+
public function zipVerifyMemBuffer($gzLength) {
|
151 |
+
if (ob_get_length() !== FALSE && ob_get_length() > $this->maxStreamBufferLength) {
|
152 |
+
|
153 |
+
ob_flush();
|
154 |
+
|
155 |
+
while (ob_get_length() > $this->maxStreamBufferLength) {
|
156 |
+
usleep(500000);
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
*
|
163 |
+
* @author A. Grandt <php@grandt.com>
|
164 |
+
*
|
165 |
+
* @param string $data
|
166 |
+
*/
|
167 |
+
public function zipWrite($data) {
|
168 |
+
print($data);
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Flush Zip Data stored in memory, to a temp file.
|
173 |
+
*
|
174 |
+
* @author A. Grandt <php@grandt.com>
|
175 |
+
*
|
176 |
+
*/
|
177 |
+
public function zipFlush() {
|
178 |
+
// Does nothing.
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
*
|
183 |
+
* @author A. Grandt <php@grandt.com>
|
184 |
+
*
|
185 |
+
*/
|
186 |
+
public function zipFlushBuffer() {
|
187 |
+
flush();
|
188 |
+
$this->zipVerifyMemBuffer(0);
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* @return int
|
193 |
+
*/
|
194 |
+
public function getMaxStreamBufferLength() {
|
195 |
+
return $this->maxStreamBufferLength;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* @param int $maxStreamBufferLength
|
200 |
+
*/
|
201 |
+
public function setMaxStreamBufferLength($maxStreamBufferLength) {
|
202 |
+
$this->maxStreamBufferLength = $maxStreamBufferLength;
|
203 |
+
}
|
204 |
+
}
|
includes/extensions/zip/Stream/index.html
ADDED
File without changes
|
includes/extensions/zip/index.html
ADDED
File without changes
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: http://robosoft.co/robogallery
|
|
4 |
Tags: gallery, photo gallery, images gallery, gallery images, responsive gallery, categories gallery, Polaroid gallery, gallery lightbox, portfolio gallery, video gallery, Gallery Plugin, Robo Gallery
|
5 |
Requires at least: 3.3
|
6 |
Tested up to: 4.7
|
7 |
-
Stable tag: 2.6.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
@@ -254,6 +254,10 @@ If any problem occurs, please contact us.
|
|
254 |
|
255 |
== Changelog ==
|
256 |
|
|
|
|
|
|
|
|
|
257 |
= 2.6.8 =
|
258 |
* Front end seo code optimization, changed alt in lightbox functionality
|
259 |
|
@@ -361,6 +365,10 @@ If any problem occurs, please contact us.
|
|
361 |
|
362 |
== Upgrade Notice ==
|
363 |
|
|
|
|
|
|
|
|
|
364 |
= 2.6.8 =
|
365 |
Front end seo code optimization, changed alt in lightbox functionality
|
366 |
|
4 |
Tags: gallery, photo gallery, images gallery, gallery images, responsive gallery, categories gallery, Polaroid gallery, gallery lightbox, portfolio gallery, video gallery, Gallery Plugin, Robo Gallery
|
5 |
Requires at least: 3.3
|
6 |
Tested up to: 4.7
|
7 |
+
Stable tag: 2.6.9
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
254 |
|
255 |
== Changelog ==
|
256 |
|
257 |
+
= 2.6.9 =
|
258 |
+
* Added new archiver library for alternative backup method
|
259 |
+
* Backup algorithm optimized
|
260 |
+
|
261 |
= 2.6.8 =
|
262 |
* Front end seo code optimization, changed alt in lightbox functionality
|
263 |
|
365 |
|
366 |
== Upgrade Notice ==
|
367 |
|
368 |
+
= 2.6.9 =
|
369 |
+
Added new archiver library for alternative backup method
|
370 |
+
Backup algorithm optimized
|
371 |
+
|
372 |
= 2.6.8 =
|
373 |
Front end seo code optimization, changed alt in lightbox functionality
|
374 |
|
robogallery.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/*
|
3 |
Plugin Name: Robo Gallery
|
4 |
Description: Gallery modes photo gallery, images gallery, video gallery, Polaroid gallery, gallery lighbox, portfolio gallery, responsive gallery
|
5 |
-
Version: 2.6.
|
6 |
Author: RoboSoft
|
7 |
Plugin URI: http://robosoft.co/gallery
|
8 |
Author URI: http://robosoft.co/gallery
|
@@ -15,13 +15,13 @@ if(!defined('WPINC'))die;
|
|
15 |
if(!defined("ABSPATH"))exit;
|
16 |
|
17 |
define("ROBO_GALLERY", 1);
|
18 |
-
define("ROBO_GALLERY_VERSION", '2.6.
|
19 |
|
20 |
if( !defined("ROBO_GALLERY_PATH") ) define("ROBO_GALLERY_PATH", plugin_dir_path( __FILE__ ));
|
21 |
|
22 |
-
define("ROBO_GALLERY_SPECIAL",
|
23 |
-
define("ROBO_GALLERY_EVENT_DATE", '
|
24 |
-
define("ROBO_GALLERY_EVENT_HOUR",
|
25 |
|
26 |
add_action( 'plugins_loaded', 'rbs_gallery_load_textdomain' );
|
27 |
function rbs_gallery_load_textdomain() {
|
2 |
/*
|
3 |
Plugin Name: Robo Gallery
|
4 |
Description: Gallery modes photo gallery, images gallery, video gallery, Polaroid gallery, gallery lighbox, portfolio gallery, responsive gallery
|
5 |
+
Version: 2.6.9
|
6 |
Author: RoboSoft
|
7 |
Plugin URI: http://robosoft.co/gallery
|
8 |
Author URI: http://robosoft.co/gallery
|
15 |
if(!defined("ABSPATH"))exit;
|
16 |
|
17 |
define("ROBO_GALLERY", 1);
|
18 |
+
define("ROBO_GALLERY_VERSION", '2.6.9');
|
19 |
|
20 |
if( !defined("ROBO_GALLERY_PATH") ) define("ROBO_GALLERY_PATH", plugin_dir_path( __FILE__ ));
|
21 |
|
22 |
+
define("ROBO_GALLERY_SPECIAL", 0);
|
23 |
+
define("ROBO_GALLERY_EVENT_DATE", '2016-12-08');
|
24 |
+
define("ROBO_GALLERY_EVENT_HOUR", 20);
|
25 |
|
26 |
add_action( 'plugins_loaded', 'rbs_gallery_load_textdomain' );
|
27 |
function rbs_gallery_load_textdomain() {
|