Version Description
Download this release
Release Info
Developer | cory@lamle.org |
Plugin | Duplicator – WordPress Migration Plugin |
Version | 1.4.5 |
Comparing to | |
See all releases |
Code changes from version 1.4.4 to 1.4.5
- assets/css/style.css +1 -1
- assets/img/logo-pro-32.png +0 -0
- classes/class.db.php +35 -28
- classes/class.logging.php +538 -538
- classes/class.password.php +1 -1
- classes/package/class.pack.archive.zip.php +237 -237
- classes/package/class.pack.database.php +13 -7
- classes/package/class.pack.php +23 -12
- classes/package/duparchive/class.pack.archive.duparchive.php +0 -57
- classes/utilities/class.u.php +859 -859
- ctrls/class.web.services.php +4 -4
- ctrls/ctrl.ui.php +165 -165
- deactivation.php +3 -3
- define.php +2 -2
- duplicator.php +1 -1
- installer/dup-installer/assets/inc.js.php +226 -226
- installer/dup-installer/classes/class.csrf.php +3 -3
- installer/dup-installer/classes/class.s3.func.php +2 -2
- installer/dup-installer/classes/utilities/class.u.html.php +1 -1
- installer/dup-installer/classes/utilities/class.u.notices.manager.php +1250 -1250
- installer/dup-installer/ctrls/classes/class.ctrl.extraction.php +604 -603
- installer/dup-installer/views/view.help.php +1 -1
- installer/dup-installer/views/view.s3.php +26 -12
- installer/dup-installer/views/view.s4.php +11 -6
- lib/snaplib/class.snaplib.u.util.php +1 -1
- readme.txt +1 -1
- views/packages/details/detail.php +94 -53
- views/packages/details/transfer.php +2 -2
- views/packages/main/packages.php +12 -8
- views/packages/main/s1.setup2.php +117 -74
- views/packages/main/s2.scan2.php +3 -3
- views/packages/main/s2.scan3.php +3 -3
- views/packages/main/s3.build.php +72 -67
- views/settings/import.php +0 -8
- views/settings/packages.php +1 -1
- views/settings/storage.php +12 -12
- views/tools/diagnostics/inc.settings.php +1 -1
- views/tools/diagnostics/logging.php +1 -1
assets/css/style.css
CHANGED
@@ -28,7 +28,7 @@ ul.category-tabs li {cursor:pointer}
|
|
28 |
|
29 |
/*BOXES:Expandable sections */
|
30 |
div.dup-box {padding:0px; display:block; background-color:#fff; border:1px solid #e5e5e5; box-shadow:0 1px 1px rgba(0,0,0,.04);}
|
31 |
-
div.dup-box-title {font-size:
|
32 |
div.dup-box-title:hover {color:#555;}
|
33 |
div.dup-box-arrow {text-decoration:none!important; float:right; width:27px; height:30px; font-size:16px; cursor:pointer; padding:1px 0 0 0; white-space:nowrap}
|
34 |
div.dup-box-panel {padding:10px 15px 10px 15px; border-top:1px solid #EEEEEE; margin:-1px 0 0 0;}
|
28 |
|
29 |
/*BOXES:Expandable sections */
|
30 |
div.dup-box {padding:0px; display:block; background-color:#fff; border:1px solid #e5e5e5; box-shadow:0 1px 1px rgba(0,0,0,.04);}
|
31 |
+
div.dup-box-title {font-size:20px; padding:12px 0 3px 12px; font-weight:bold; cursor:pointer; height:30px; margin:0; color:#000; }
|
32 |
div.dup-box-title:hover {color:#555;}
|
33 |
div.dup-box-arrow {text-decoration:none!important; float:right; width:27px; height:30px; font-size:16px; cursor:pointer; padding:1px 0 0 0; white-space:nowrap}
|
34 |
div.dup-box-panel {padding:10px 15px 10px 15px; border-top:1px solid #EEEEEE; margin:-1px 0 0 0;}
|
assets/img/logo-pro-32.png
DELETED
Binary file
|
classes/class.db.php
CHANGED
@@ -16,6 +16,8 @@ if (!defined('DUPLICATOR_VERSION')) exit;
|
|
16 |
|
17 |
class DUP_DB extends wpdb
|
18 |
{
|
|
|
|
|
19 |
public static $remove_placeholder_escape_exists = null;
|
20 |
|
21 |
public static function init()
|
@@ -176,36 +178,41 @@ class DUP_DB extends wpdb
|
|
176 |
}
|
177 |
|
178 |
/**
|
179 |
-
* Returns all collation types that are assigned to the tables in
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
*
|
|
|
185 |
*/
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
-
|
192 |
-
|
|
|
|
|
|
|
193 |
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
} catch (Exception $ex) {
|
206 |
-
return $collations;
|
207 |
-
}
|
208 |
-
}
|
209 |
|
210 |
/**
|
211 |
* Returns an escaped SQL string
|
@@ -231,7 +238,7 @@ class DUP_DB extends wpdb
|
|
231 |
|
232 |
/**
|
233 |
* this function escape sql string without add and remove remove_placeholder_escape
|
234 |
-
*
|
235 |
*
|
236 |
* @global type $wpdb
|
237 |
* @param mixed $sql
|
16 |
|
17 |
class DUP_DB extends wpdb
|
18 |
{
|
19 |
+
const MAX_TABLE_COUNT_IN_PACKET = 100;
|
20 |
+
|
21 |
public static $remove_placeholder_escape_exists = null;
|
22 |
|
23 |
public static function init()
|
178 |
}
|
179 |
|
180 |
/**
|
181 |
+
* Returns all collation types that are assigned to the tables and columns table in
|
182 |
+
* the current database. Each element in the array is unique
|
183 |
+
*
|
184 |
+
* @param array &$tablesToInclude A list of tables to include in the search.
|
185 |
+
* Parameter does not change in the function, is passed by reference only to avoid copying.
|
186 |
+
*
|
187 |
+
* @return array Returns an array with all the collation types being used
|
188 |
*/
|
189 |
+
public static function getTableCollationList(&$tablesToInclude)
|
190 |
+
{
|
191 |
+
global $wpdb;
|
192 |
+
static $collations = null;
|
193 |
+
if (is_null($collations)) {
|
194 |
+
$collations = array();
|
195 |
+
//use half the number of tables since we are using them twice
|
196 |
+
foreach (array_chunk($tablesToInclude, self::MAX_TABLE_COUNT_IN_PACKET) as $tablesChunk) {
|
197 |
+
$sqlTables = implode(",", array_map(array(__CLASS__, 'escValueToQueryString'), $tablesChunk));
|
198 |
|
199 |
+
//UNION is by default DISTINCT
|
200 |
+
$query = "SELECT `COLLATION_NAME` FROM `information_schema`.`columns` WHERE `COLLATION_NAME` IS NOT NULL AND `table_schema` = '{$wpdb->dbname}' "
|
201 |
+
. "AND `table_name` in (" . $sqlTables . ")"
|
202 |
+
. "UNION SELECT `TABLE_COLLATION` FROM `information_schema`.`tables` WHERE `TABLE_COLLATION` IS NOT NULL AND `table_schema` = '{$wpdb->dbname}' "
|
203 |
+
. "AND `table_name` in (" . $sqlTables . ")";
|
204 |
|
205 |
+
if (!$wpdb->query($query)) {
|
206 |
+
DUP_Log::Info("GET TABLE COLLATION ERROR: " . $wpdb->last_error);
|
207 |
+
continue;
|
208 |
+
}
|
209 |
+
|
210 |
+
$collations = array_unique(array_merge($collations, $wpdb->get_col()));
|
211 |
+
}
|
212 |
+
sort($collations);
|
213 |
+
}
|
214 |
+
return $collations;
|
215 |
+
}
|
|
|
|
|
|
|
|
|
216 |
|
217 |
/**
|
218 |
* Returns an escaped SQL string
|
238 |
|
239 |
/**
|
240 |
* this function escape sql string without add and remove remove_placeholder_escape
|
241 |
+
* doesn't work on array
|
242 |
*
|
243 |
* @global type $wpdb
|
244 |
* @param mixed $sql
|
classes/class.logging.php
CHANGED
@@ -1,538 +1,538 @@
|
|
1 |
-
<?php
|
2 |
-
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
-
// Exit if accessed directly
|
4 |
-
if (!defined('DUPLICATOR_VERSION')) exit;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Helper Class for logging
|
8 |
-
* @package Duplicator\classes
|
9 |
-
*/
|
10 |
-
abstract class Dup_ErrorBehavior
|
11 |
-
{
|
12 |
-
const LogOnly = 0;
|
13 |
-
const ThrowException = 1;
|
14 |
-
const Quit = 2;
|
15 |
-
}
|
16 |
-
|
17 |
-
class DUP_Log
|
18 |
-
{
|
19 |
-
/**
|
20 |
-
* The file handle used to write to the package log file
|
21 |
-
*/
|
22 |
-
private static $logFileHandle = null;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Get the setting which indicates if tracing is enabled
|
26 |
-
*/
|
27 |
-
private static $traceEnabled = false;
|
28 |
-
|
29 |
-
public static $profileLogs = null;
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Init this static object
|
33 |
-
*/
|
34 |
-
public static function Init()
|
35 |
-
{
|
36 |
-
self::$traceEnabled = (DUP_Settings::Get('trace_log_enabled') == 1);
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Open a log file connection for writing to the package log file
|
41 |
-
*
|
42 |
-
* @param string $nameHas The Name of the log file to create
|
43 |
-
*
|
44 |
-
* @return nul
|
45 |
-
*/
|
46 |
-
public static function Open($nameHash)
|
47 |
-
{
|
48 |
-
if (!isset($nameHash)) {
|
49 |
-
throw new Exception("A name value is required to open a file log.");
|
50 |
-
}
|
51 |
-
self::Close();
|
52 |
-
if ((self::$logFileHandle = @fopen(DUP_Settings::getSsdirPath()."/{$nameHash}.log", "a+")) === false) {
|
53 |
-
self::$logFileHandle = null;
|
54 |
-
return false;
|
55 |
-
} else {
|
56 |
-
/**
|
57 |
-
* By initializing the error_handler on opening the log, I am sure that when a package is processed, the handler is active.
|
58 |
-
*/
|
59 |
-
DUP_Handler::init_error_handler();
|
60 |
-
return true;
|
61 |
-
}
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Close the package log file connection if is opened
|
66 |
-
*
|
67 |
-
* @return bool Returns TRUE on success or FALSE on failure.
|
68 |
-
*/
|
69 |
-
public static function Close()
|
70 |
-
{
|
71 |
-
$result = true;
|
72 |
-
|
73 |
-
if (!is_null(self::$logFileHandle)) {
|
74 |
-
$result = @fclose(self::$logFileHandle);
|
75 |
-
self::$logFileHandle = null;
|
76 |
-
} else {
|
77 |
-
$result = true;
|
78 |
-
}
|
79 |
-
return $result;
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* General information send to the package log if opened
|
84 |
-
* @param string $msg The message to log
|
85 |
-
*
|
86 |
-
* REPLACE TO DEBUG: Memory consumption as script runs
|
87 |
-
* $results = DUP_Util::byteSize(memory_get_peak_usage(true)) . "\t" . $msg;
|
88 |
-
* @fwrite(self::$logFileHandle, "{$results} \n");
|
89 |
-
*
|
90 |
-
* @param string $msg The message to log
|
91 |
-
*
|
92 |
-
* @return null
|
93 |
-
*/
|
94 |
-
public static function Info($msg)
|
95 |
-
{
|
96 |
-
if (self::$traceEnabled) {
|
97 |
-
self::Trace($msg);
|
98 |
-
}
|
99 |
-
if (!is_null(self::$logFileHandle)) {
|
100 |
-
@fwrite(self::$logFileHandle, $msg."\n");
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
public static function print_r_info($val, $name = '')
|
105 |
-
{
|
106 |
-
$msg = empty($name) ? '' : 'VALUE '.$name.': ';
|
107 |
-
$msg .= print_r($val, true);
|
108 |
-
self::info($msg);
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Does the trace file exists
|
113 |
-
*
|
114 |
-
* @return bool Returns true if an active trace file exists
|
115 |
-
*/
|
116 |
-
public static function TraceFileExists()
|
117 |
-
{
|
118 |
-
$file_path = self::getTraceFilepath();
|
119 |
-
return file_exists($file_path);
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Gets the current file size of the active trace file
|
124 |
-
*
|
125 |
-
* @return string Returns a human readable file size of the active trace file
|
126 |
-
*/
|
127 |
-
public static function getTraceStatus()
|
128 |
-
{
|
129 |
-
$file_path = DUP_Log::getTraceFilepath();
|
130 |
-
$backup_path = DUP_Log::getBackupTraceFilepath();
|
131 |
-
|
132 |
-
if (file_exists($file_path)) {
|
133 |
-
|
134 |
-
$filesize = is_file($file_path) ? @filesize($file_path) : 0;
|
135 |
-
|
136 |
-
//Its possible mulitple trace log files exist due to size
|
137 |
-
if (is_file($backup_path)) {
|
138 |
-
$filesize += @filesize($backup_path);
|
139 |
-
}
|
140 |
-
|
141 |
-
$message = sprintf('%1$s', DUP_Util::byteSize($filesize));
|
142 |
-
} else {
|
143 |
-
$message = esc_html__('No Log', 'duplicator');
|
144 |
-
}
|
145 |
-
|
146 |
-
return $message;
|
147 |
-
}
|
148 |
-
|
149 |
-
// RSR TODO: Swap trace logic out for real trace later
|
150 |
-
public static function Trace($message, $calling_function_override = null)
|
151 |
-
{
|
152 |
-
|
153 |
-
if (self::$traceEnabled) {
|
154 |
-
$unique_id = sprintf("%08x", abs(crc32($_SERVER['REMOTE_ADDR'].$_SERVER['REQUEST_TIME'].$_SERVER['REMOTE_PORT'])));
|
155 |
-
|
156 |
-
if ($calling_function_override == null) {
|
157 |
-
$calling_function = DupLiteSnapLibUtil::getCallingFunctionName();
|
158 |
-
} else {
|
159 |
-
$calling_function = $calling_function_override;
|
160 |
-
}
|
161 |
-
|
162 |
-
if (is_object($message)) {
|
163 |
-
$ov = get_object_vars($message);
|
164 |
-
$message = print_r($ov, true);
|
165 |
-
} else if (is_array($message)) {
|
166 |
-
$message = print_r($message, true);
|
167 |
-
}
|
168 |
-
|
169 |
-
$logging_message = "{$unique_id}|{$calling_function} | {$message}";
|
170 |
-
$ticks = time() + ((int) get_option('gmt_offset') * 3600);
|
171 |
-
$formatted_time = date('d-m-H:i:s', $ticks);
|
172 |
-
$formatted_logging_message = "{$formatted_time}|DUP|{$logging_message} \r\n";
|
173 |
-
|
174 |
-
// Always write to error log - if they don't want the info they can turn off WordPress error logging or tracing
|
175 |
-
self::ErrLog($logging_message);
|
176 |
-
|
177 |
-
// Everything goes to the plugin log, whether it's part of package generation or not.
|
178 |
-
self::WriteToTrace($formatted_logging_message);
|
179 |
-
}
|
180 |
-
}
|
181 |
-
|
182 |
-
public static function print_r_trace($val, $name = '', $calling_function_override = null)
|
183 |
-
{
|
184 |
-
$msg = empty($name) ? '' : 'VALUE '.$name.': ';
|
185 |
-
$msg .= print_r($val, true);
|
186 |
-
self::trace($msg, $calling_function_override);
|
187 |
-
}
|
188 |
-
|
189 |
-
public static function errLog($message)
|
190 |
-
{
|
191 |
-
$message = 'DUP:'.$message;
|
192 |
-
error_log($message);
|
193 |
-
}
|
194 |
-
|
195 |
-
public static function TraceObject($msg, $o, $log_private_members = true)
|
196 |
-
{
|
197 |
-
if (self::$traceEnabled) {
|
198 |
-
if (!$log_private_members) {
|
199 |
-
$o = get_object_vars($o);
|
200 |
-
}
|
201 |
-
self::Trace($msg.':'.print_r($o, true));
|
202 |
-
}
|
203 |
-
}
|
204 |
-
|
205 |
-
public static function GetDefaultKey()
|
206 |
-
{
|
207 |
-
$auth_key = defined('AUTH_KEY') ? AUTH_KEY : 'atk';
|
208 |
-
$auth_key .= defined('DB_HOST') ? DB_HOST : 'dbh';
|
209 |
-
$auth_key .= defined('DB_NAME') ? DB_NAME : 'dbn';
|
210 |
-
$auth_key .= defined('DB_USER') ? DB_USER : 'dbu';
|
211 |
-
return hash('md5', $auth_key);
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Gets the current file size of the old trace file "1"
|
216 |
-
*
|
217 |
-
* @return string Returns a human readable file size of the active trace file
|
218 |
-
*/
|
219 |
-
public static function GetBackupTraceFilepath()
|
220 |
-
{
|
221 |
-
$default_key = self::getDefaultKey();
|
222 |
-
$backup_log_filename = "dup_$default_key.log1";
|
223 |
-
$backup_path = DUP_Settings::getSsdirPath()."/".$backup_log_filename;
|
224 |
-
return $backup_path;
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* Gets the active trace file path
|
229 |
-
*
|
230 |
-
* @return string Returns the full path to the active trace file (i.e. dup-pro_hash.log)
|
231 |
-
*/
|
232 |
-
public static function GetTraceFilepath()
|
233 |
-
{
|
234 |
-
$default_key = self::getDefaultKey();
|
235 |
-
$log_filename = "dup_$default_key.log";
|
236 |
-
$file_path = DUP_Settings::getSsdirPath()."/".$log_filename;
|
237 |
-
return $file_path;
|
238 |
-
}
|
239 |
-
|
240 |
-
/**
|
241 |
-
* Deletes the trace log and backup trace log files
|
242 |
-
*
|
243 |
-
* @return null
|
244 |
-
*/
|
245 |
-
public static function DeleteTraceLog()
|
246 |
-
{
|
247 |
-
$file_path = self::GetTraceFilepath();
|
248 |
-
$backup_path = self::GetBackupTraceFilepath();
|
249 |
-
self::trace("deleting $file_path");
|
250 |
-
@unlink($file_path);
|
251 |
-
self::trace("deleting $backup_path");
|
252 |
-
@unlink($backup_path);
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* Called when an error is detected and no further processing should occur
|
257 |
-
* @param string $msg The message to log
|
258 |
-
* @param string $detail Additional details to help resolve the issue if possible
|
259 |
-
* @param int $behavior
|
260 |
-
* @throws Exception
|
261 |
-
*/
|
262 |
-
public static function error($msg, $detail = '', $behavior = Dup_ErrorBehavior::Quit)
|
263 |
-
{
|
264 |
-
|
265 |
-
error_log($msg.' DETAIL:'.$detail);
|
266 |
-
$source = self::getStack(debug_backtrace());
|
267 |
-
|
268 |
-
$err_msg = "\n==================================================================================\n";
|
269 |
-
$err_msg .= "DUPLICATOR ERROR\n";
|
270 |
-
$err_msg .= "Please try again! If the error persists see the Duplicator 'Help' menu.\n";
|
271 |
-
$err_msg .= "---------------------------------------------------------------------------------\n";
|
272 |
-
$err_msg .= "MESSAGE:\n\t{$msg}\n";
|
273 |
-
if (strlen($detail)) {
|
274 |
-
$err_msg .= "DETAILS:\n\t{$detail}\n";
|
275 |
-
}
|
276 |
-
$err_msg .= "TRACE:\n{$source}";
|
277 |
-
$err_msg .= "==================================================================================\n\n";
|
278 |
-
@fwrite(self::$logFileHandle, "{$err_msg}");
|
279 |
-
|
280 |
-
switch ($behavior) {
|
281 |
-
|
282 |
-
case Dup_ErrorBehavior::ThrowException:
|
283 |
-
DUP_LOG::trace("throwing exception");
|
284 |
-
throw new Exception($msg);
|
285 |
-
break;
|
286 |
-
|
287 |
-
case Dup_ErrorBehavior::Quit:
|
288 |
-
DUP_LOG::trace("quitting");
|
289 |
-
die("DUPLICATOR ERROR: Please see the 'Package Log' file link below.");
|
290 |
-
break;
|
291 |
-
|
292 |
-
default:
|
293 |
-
// Nothing
|
294 |
-
}
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* The current stack trace of a PHP call
|
299 |
-
* @param $stacktrace The current debug stack
|
300 |
-
* @return string
|
301 |
-
*/
|
302 |
-
public static function getStack($stacktrace)
|
303 |
-
{
|
304 |
-
$output = "";
|
305 |
-
$i = 1;
|
306 |
-
foreach ($stacktrace as $node) {
|
307 |
-
$output .= "\t $i. ".basename($node['file'])." : ".$node['function']." (".$node['line'].")\n";
|
308 |
-
$i++;
|
309 |
-
}
|
310 |
-
return $output;
|
311 |
-
}
|
312 |
-
|
313 |
-
/**
|
314 |
-
* Manages writing the active or backup log based on the size setting
|
315 |
-
*
|
316 |
-
* @return null
|
317 |
-
*/
|
318 |
-
private static function WriteToTrace($formatted_logging_message)
|
319 |
-
{
|
320 |
-
$log_filepath = self::GetTraceFilepath();
|
321 |
-
|
322 |
-
if (@filesize($log_filepath) > DUPLICATOR_MAX_LOG_SIZE) {
|
323 |
-
$backup_log_filepath = self::GetBackupTraceFilepath();
|
324 |
-
|
325 |
-
if (file_exists($backup_log_filepath)) {
|
326 |
-
if (@unlink($backup_log_filepath) === false) {
|
327 |
-
self::errLog("Couldn't delete backup log $backup_log_filepath");
|
328 |
-
}
|
329 |
-
}
|
330 |
-
|
331 |
-
if (@rename($log_filepath, $backup_log_filepath) === false) {
|
332 |
-
self::errLog("Couldn't rename log $log_filepath to $backup_log_filepath");
|
333 |
-
}
|
334 |
-
}
|
335 |
-
|
336 |
-
if (@file_put_contents($log_filepath, $formatted_logging_message, FILE_APPEND) === false) {
|
337 |
-
// Not en error worth reporting
|
338 |
-
}
|
339 |
-
}
|
340 |
-
}
|
341 |
-
|
342 |
-
class DUP_Handler
|
343 |
-
{
|
344 |
-
const MODE_OFF = 0; // don't write in log
|
345 |
-
const MODE_LOG = 1; // write errors in log file
|
346 |
-
const MODE_VAR = 2; // put php errors in $varModeLog static var
|
347 |
-
const SHUTDOWN_TIMEOUT = 'tm';
|
348 |
-
|
349 |
-
/**
|
350 |
-
*
|
351 |
-
* @var bool
|
352 |
-
*/
|
353 |
-
private static $initialized = false;
|
354 |
-
|
355 |
-
/**
|
356 |
-
*
|
357 |
-
* @var array
|
358 |
-
*/
|
359 |
-
private static $shutdownReturns = array(
|
360 |
-
'tm' => 'timeout'
|
361 |
-
);
|
362 |
-
|
363 |
-
/**
|
364 |
-
*
|
365 |
-
* @var int
|
366 |
-
*/
|
367 |
-
private static $handlerMode = self::MODE_LOG;
|
368 |
-
|
369 |
-
/**
|
370 |
-
*
|
371 |
-
* @var bool // print code reference and errno at end of php error line [CODE:10|FILE:test.php|LINE:100]
|
372 |
-
*/
|
373 |
-
private static $codeReference = true;
|
374 |
-
|
375 |
-
/**
|
376 |
-
*
|
377 |
-
* @var bool // print prefix in php error line [PHP ERR][WARN] MSG: .....
|
378 |
-
*/
|
379 |
-
private static $errPrefix = true;
|
380 |
-
|
381 |
-
/**
|
382 |
-
*
|
383 |
-
* @var string // php errors in MODE_VAR
|
384 |
-
*/
|
385 |
-
private static $varModeLog = '';
|
386 |
-
|
387 |
-
/**
|
388 |
-
* This function only initializes the error handler the first time it is called
|
389 |
-
*/
|
390 |
-
public static function init_error_handler()
|
391 |
-
{
|
392 |
-
if (!self::$initialized) {
|
393 |
-
@set_error_handler(array(__CLASS__, 'error'));
|
394 |
-
@register_shutdown_function(array(__CLASS__, 'shutdown'));
|
395 |
-
self::$initialized = true;
|
396 |
-
}
|
397 |
-
}
|
398 |
-
|
399 |
-
/**
|
400 |
-
* Error handler
|
401 |
-
*
|
402 |
-
* @param integer $errno Error level
|
403 |
-
* @param string $errstr Error message
|
404 |
-
* @param string $errfile Error file
|
405 |
-
* @param integer $errline Error line
|
406 |
-
* @return void
|
407 |
-
*/
|
408 |
-
public static function error($errno, $errstr, $errfile, $errline)
|
409 |
-
{
|
410 |
-
switch (self::$handlerMode) {
|
411 |
-
case self::MODE_OFF:
|
412 |
-
if ($errno == E_ERROR) {
|
413 |
-
$log_message = self::getMessage($errno, $errstr, $errfile, $errline);
|
414 |
-
DUP_Log::error($log_message);
|
415 |
-
}
|
416 |
-
break;
|
417 |
-
case self::MODE_VAR:
|
418 |
-
self::$varModeLog .= self::getMessage($errno, $errstr, $errfile, $errline)."\n";
|
419 |
-
break;
|
420 |
-
case self::MODE_LOG:
|
421 |
-
default:
|
422 |
-
switch ($errno) {
|
423 |
-
case E_ERROR :
|
424 |
-
$log_message = self::getMessage($errno, $errstr, $errfile, $errline);
|
425 |
-
DUP_Log::error($log_message);
|
426 |
-
break;
|
427 |
-
case E_NOTICE :
|
428 |
-
case E_WARNING :
|
429 |
-
default :
|
430 |
-
$log_message = self::getMessage($errno, $errstr, $errfile, $errline);
|
431 |
-
DUP_Log::Info($log_message);
|
432 |
-
break;
|
433 |
-
}
|
434 |
-
}
|
435 |
-
}
|
436 |
-
|
437 |
-
private static function getMessage($errno, $errstr, $errfile, $errline)
|
438 |
-
{
|
439 |
-
$result = '';
|
440 |
-
|
441 |
-
if (self::$errPrefix) {
|
442 |
-
$result = '[PHP ERR]';
|
443 |
-
switch ($errno) {
|
444 |
-
case E_ERROR :
|
445 |
-
$result .= '[FATAL]';
|
446 |
-
break;
|
447 |
-
case E_WARNING :
|
448 |
-
$result .= '[WARN]';
|
449 |
-
break;
|
450 |
-
case E_NOTICE :
|
451 |
-
$result .= '[NOTICE]';
|
452 |
-
break;
|
453 |
-
default :
|
454 |
-
$result .= '[ISSUE]';
|
455 |
-
break;
|
456 |
-
}
|
457 |
-
$result .= ' MSG:';
|
458 |
-
}
|
459 |
-
|
460 |
-
$result .= $errstr;
|
461 |
-
|
462 |
-
if (self::$codeReference) {
|
463 |
-
$result .= ' [CODE:'.$errno.'|FILE:'.$errfile.'|LINE:'.$errline.']';
|
464 |
-
$result .= "\n".wp_debug_backtrace_summary();
|
465 |
-
}
|
466 |
-
|
467 |
-
return $result;
|
468 |
-
}
|
469 |
-
|
470 |
-
/**
|
471 |
-
* if setMode is called without params set as default
|
472 |
-
*
|
473 |
-
* @param int $mode
|
474 |
-
* @param bool $errPrefix // print prefix in php error line [PHP ERR][WARN] MSG: .....
|
475 |
-
* @param bool $codeReference // print code reference and errno at end of php error line [CODE:10|FILE:test.php|LINE:100]
|
476 |
-
*/
|
477 |
-
public static function setMode($mode = self::MODE_LOG, $errPrefix = true, $codeReference = true)
|
478 |
-
{
|
479 |
-
switch ($mode) {
|
480 |
-
case self::MODE_OFF:
|
481 |
-
case self::MODE_VAR:
|
482 |
-
self::$handlerMode = $mode;
|
483 |
-
break;
|
484 |
-
case self::MODE_LOG:
|
485 |
-
default:
|
486 |
-
self::$handlerMode = self::MODE_LOG;
|
487 |
-
}
|
488 |
-
|
489 |
-
self::$varModeLog = '';
|
490 |
-
self::$errPrefix = $errPrefix;
|
491 |
-
self::$codeReference = $codeReference;
|
492 |
-
}
|
493 |
-
|
494 |
-
/**
|
495 |
-
*
|
496 |
-
* @return string // return var log string in MODE_VAR
|
497 |
-
*/
|
498 |
-
public static function getVarLog()
|
499 |
-
{
|
500 |
-
return self::$varModeLog;
|
501 |
-
}
|
502 |
-
|
503 |
-
/**
|
504 |
-
*
|
505 |
-
* @return string // return var log string in MODE_VAR and clean var
|
506 |
-
*/
|
507 |
-
public static function getVarLogClean()
|
508 |
-
{
|
509 |
-
$result = self::$varModeLog;
|
510 |
-
self::$varModeLog = '';
|
511 |
-
return $result;
|
512 |
-
}
|
513 |
-
|
514 |
-
/**
|
515 |
-
*
|
516 |
-
* @param string $status // timeout
|
517 |
-
* @param string
|
518 |
-
*/
|
519 |
-
public static function setShutdownReturn($status, $str)
|
520 |
-
{
|
521 |
-
self::$shutdownReturns[$status] = $str;
|
522 |
-
}
|
523 |
-
|
524 |
-
/**
|
525 |
-
* Shutdown handler
|
526 |
-
*
|
527 |
-
* @return void
|
528 |
-
*/
|
529 |
-
public static function shutdown()
|
530 |
-
{
|
531 |
-
if (($error = error_get_last())) {
|
532 |
-
if (preg_match('/^Maximum execution time (?:.+) exceeded$/i', $error['message'])) {
|
533 |
-
echo self::$shutdownReturns[self::SHUTDOWN_TIMEOUT];
|
534 |
-
}
|
535 |
-
self::error($error['type'], $error['message'], $error['file'], $error['line']);
|
536 |
-
}
|
537 |
-
}
|
538 |
-
}
|
1 |
+
<?php
|
2 |
+
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
+
// Exit if accessed directly
|
4 |
+
if (!defined('DUPLICATOR_VERSION')) exit;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Helper Class for logging
|
8 |
+
* @package Duplicator\classes
|
9 |
+
*/
|
10 |
+
abstract class Dup_ErrorBehavior
|
11 |
+
{
|
12 |
+
const LogOnly = 0;
|
13 |
+
const ThrowException = 1;
|
14 |
+
const Quit = 2;
|
15 |
+
}
|
16 |
+
|
17 |
+
class DUP_Log
|
18 |
+
{
|
19 |
+
/**
|
20 |
+
* The file handle used to write to the package log file
|
21 |
+
*/
|
22 |
+
private static $logFileHandle = null;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Get the setting which indicates if tracing is enabled
|
26 |
+
*/
|
27 |
+
private static $traceEnabled = false;
|
28 |
+
|
29 |
+
public static $profileLogs = null;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Init this static object
|
33 |
+
*/
|
34 |
+
public static function Init()
|
35 |
+
{
|
36 |
+
self::$traceEnabled = (DUP_Settings::Get('trace_log_enabled') == 1);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Open a log file connection for writing to the package log file
|
41 |
+
*
|
42 |
+
* @param string $nameHas The Name of the log file to create
|
43 |
+
*
|
44 |
+
* @return nul
|
45 |
+
*/
|
46 |
+
public static function Open($nameHash)
|
47 |
+
{
|
48 |
+
if (!isset($nameHash)) {
|
49 |
+
throw new Exception("A name value is required to open a file log.");
|
50 |
+
}
|
51 |
+
self::Close();
|
52 |
+
if ((self::$logFileHandle = @fopen(DUP_Settings::getSsdirPath()."/{$nameHash}.log", "a+")) === false) {
|
53 |
+
self::$logFileHandle = null;
|
54 |
+
return false;
|
55 |
+
} else {
|
56 |
+
/**
|
57 |
+
* By initializing the error_handler on opening the log, I am sure that when a package is processed, the handler is active.
|
58 |
+
*/
|
59 |
+
DUP_Handler::init_error_handler();
|
60 |
+
return true;
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Close the package log file connection if is opened
|
66 |
+
*
|
67 |
+
* @return bool Returns TRUE on success or FALSE on failure.
|
68 |
+
*/
|
69 |
+
public static function Close()
|
70 |
+
{
|
71 |
+
$result = true;
|
72 |
+
|
73 |
+
if (!is_null(self::$logFileHandle)) {
|
74 |
+
$result = @fclose(self::$logFileHandle);
|
75 |
+
self::$logFileHandle = null;
|
76 |
+
} else {
|
77 |
+
$result = true;
|
78 |
+
}
|
79 |
+
return $result;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* General information send to the package log if opened
|
84 |
+
* @param string $msg The message to log
|
85 |
+
*
|
86 |
+
* REPLACE TO DEBUG: Memory consumption as script runs
|
87 |
+
* $results = DUP_Util::byteSize(memory_get_peak_usage(true)) . "\t" . $msg;
|
88 |
+
* @fwrite(self::$logFileHandle, "{$results} \n");
|
89 |
+
*
|
90 |
+
* @param string $msg The message to log
|
91 |
+
*
|
92 |
+
* @return null
|
93 |
+
*/
|
94 |
+
public static function Info($msg)
|
95 |
+
{
|
96 |
+
if (self::$traceEnabled) {
|
97 |
+
self::Trace($msg);
|
98 |
+
}
|
99 |
+
if (!is_null(self::$logFileHandle)) {
|
100 |
+
@fwrite(self::$logFileHandle, $msg."\n");
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
public static function print_r_info($val, $name = '')
|
105 |
+
{
|
106 |
+
$msg = empty($name) ? '' : 'VALUE '.$name.': ';
|
107 |
+
$msg .= print_r($val, true);
|
108 |
+
self::info($msg);
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Does the trace file exists
|
113 |
+
*
|
114 |
+
* @return bool Returns true if an active trace file exists
|
115 |
+
*/
|
116 |
+
public static function TraceFileExists()
|
117 |
+
{
|
118 |
+
$file_path = self::getTraceFilepath();
|
119 |
+
return file_exists($file_path);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Gets the current file size of the active trace file
|
124 |
+
*
|
125 |
+
* @return string Returns a human readable file size of the active trace file
|
126 |
+
*/
|
127 |
+
public static function getTraceStatus()
|
128 |
+
{
|
129 |
+
$file_path = DUP_Log::getTraceFilepath();
|
130 |
+
$backup_path = DUP_Log::getBackupTraceFilepath();
|
131 |
+
|
132 |
+
if (file_exists($file_path)) {
|
133 |
+
|
134 |
+
$filesize = is_file($file_path) ? @filesize($file_path) : 0;
|
135 |
+
|
136 |
+
//Its possible mulitple trace log files exist due to size
|
137 |
+
if (is_file($backup_path)) {
|
138 |
+
$filesize += @filesize($backup_path);
|
139 |
+
}
|
140 |
+
|
141 |
+
$message = sprintf('%1$s', DUP_Util::byteSize($filesize));
|
142 |
+
} else {
|
143 |
+
$message = esc_html__('No Log', 'duplicator');
|
144 |
+
}
|
145 |
+
|
146 |
+
return $message;
|
147 |
+
}
|
148 |
+
|
149 |
+
// RSR TODO: Swap trace logic out for real trace later
|
150 |
+
public static function Trace($message, $calling_function_override = null)
|
151 |
+
{
|
152 |
+
|
153 |
+
if (self::$traceEnabled) {
|
154 |
+
$unique_id = sprintf("%08x", abs(crc32($_SERVER['REMOTE_ADDR'].$_SERVER['REQUEST_TIME'].$_SERVER['REMOTE_PORT'])));
|
155 |
+
|
156 |
+
if ($calling_function_override == null) {
|
157 |
+
$calling_function = DupLiteSnapLibUtil::getCallingFunctionName();
|
158 |
+
} else {
|
159 |
+
$calling_function = $calling_function_override;
|
160 |
+
}
|
161 |
+
|
162 |
+
if (is_object($message)) {
|
163 |
+
$ov = get_object_vars($message);
|
164 |
+
$message = print_r($ov, true);
|
165 |
+
} else if (is_array($message)) {
|
166 |
+
$message = print_r($message, true);
|
167 |
+
}
|
168 |
+
|
169 |
+
$logging_message = "{$unique_id}|{$calling_function} | {$message}";
|
170 |
+
$ticks = time() + ((int) get_option('gmt_offset') * 3600);
|
171 |
+
$formatted_time = date('d-m-H:i:s', $ticks);
|
172 |
+
$formatted_logging_message = "{$formatted_time}|DUP|{$logging_message} \r\n";
|
173 |
+
|
174 |
+
// Always write to error log - if they don't want the info they can turn off WordPress error logging or tracing
|
175 |
+
self::ErrLog($logging_message);
|
176 |
+
|
177 |
+
// Everything goes to the plugin log, whether it's part of package generation or not.
|
178 |
+
self::WriteToTrace($formatted_logging_message);
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
public static function print_r_trace($val, $name = '', $calling_function_override = null)
|
183 |
+
{
|
184 |
+
$msg = empty($name) ? '' : 'VALUE '.$name.': ';
|
185 |
+
$msg .= print_r($val, true);
|
186 |
+
self::trace($msg, $calling_function_override);
|
187 |
+
}
|
188 |
+
|
189 |
+
public static function errLog($message)
|
190 |
+
{
|
191 |
+
$message = 'DUP:'.$message;
|
192 |
+
error_log($message);
|
193 |
+
}
|
194 |
+
|
195 |
+
public static function TraceObject($msg, $o, $log_private_members = true)
|
196 |
+
{
|
197 |
+
if (self::$traceEnabled) {
|
198 |
+
if (!$log_private_members) {
|
199 |
+
$o = get_object_vars($o);
|
200 |
+
}
|
201 |
+
self::Trace($msg.':'.print_r($o, true));
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
public static function GetDefaultKey()
|
206 |
+
{
|
207 |
+
$auth_key = defined('AUTH_KEY') ? AUTH_KEY : 'atk';
|
208 |
+
$auth_key .= defined('DB_HOST') ? DB_HOST : 'dbh';
|
209 |
+
$auth_key .= defined('DB_NAME') ? DB_NAME : 'dbn';
|
210 |
+
$auth_key .= defined('DB_USER') ? DB_USER : 'dbu';
|
211 |
+
return hash('md5', $auth_key);
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Gets the current file size of the old trace file "1"
|
216 |
+
*
|
217 |
+
* @return string Returns a human readable file size of the active trace file
|
218 |
+
*/
|
219 |
+
public static function GetBackupTraceFilepath()
|
220 |
+
{
|
221 |
+
$default_key = self::getDefaultKey();
|
222 |
+
$backup_log_filename = "dup_$default_key.log1";
|
223 |
+
$backup_path = DUP_Settings::getSsdirPath()."/".$backup_log_filename;
|
224 |
+
return $backup_path;
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Gets the active trace file path
|
229 |
+
*
|
230 |
+
* @return string Returns the full path to the active trace file (i.e. dup-pro_hash.log)
|
231 |
+
*/
|
232 |
+
public static function GetTraceFilepath()
|
233 |
+
{
|
234 |
+
$default_key = self::getDefaultKey();
|
235 |
+
$log_filename = "dup_$default_key.log";
|
236 |
+
$file_path = DUP_Settings::getSsdirPath()."/".$log_filename;
|
237 |
+
return $file_path;
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Deletes the trace log and backup trace log files
|
242 |
+
*
|
243 |
+
* @return null
|
244 |
+
*/
|
245 |
+
public static function DeleteTraceLog()
|
246 |
+
{
|
247 |
+
$file_path = self::GetTraceFilepath();
|
248 |
+
$backup_path = self::GetBackupTraceFilepath();
|
249 |
+
self::trace("deleting $file_path");
|
250 |
+
@unlink($file_path);
|
251 |
+
self::trace("deleting $backup_path");
|
252 |
+
@unlink($backup_path);
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Called when an error is detected and no further processing should occur
|
257 |
+
* @param string $msg The message to log
|
258 |
+
* @param string $detail Additional details to help resolve the issue if possible
|
259 |
+
* @param int $behavior
|
260 |
+
* @throws Exception
|
261 |
+
*/
|
262 |
+
public static function error($msg, $detail = '', $behavior = Dup_ErrorBehavior::Quit)
|
263 |
+
{
|
264 |
+
|
265 |
+
error_log($msg.' DETAIL:'.$detail);
|
266 |
+
$source = self::getStack(debug_backtrace());
|
267 |
+
|
268 |
+
$err_msg = "\n==================================================================================\n";
|
269 |
+
$err_msg .= "DUPLICATOR ERROR\n";
|
270 |
+
$err_msg .= "Please try again! If the error persists see the Duplicator 'Help' menu.\n";
|
271 |
+
$err_msg .= "---------------------------------------------------------------------------------\n";
|
272 |
+
$err_msg .= "MESSAGE:\n\t{$msg}\n";
|
273 |
+
if (strlen($detail)) {
|
274 |
+
$err_msg .= "DETAILS:\n\t{$detail}\n";
|
275 |
+
}
|
276 |
+
$err_msg .= "TRACE:\n{$source}";
|
277 |
+
$err_msg .= "==================================================================================\n\n";
|
278 |
+
@fwrite(self::$logFileHandle, "{$err_msg}");
|
279 |
+
|
280 |
+
switch ($behavior) {
|
281 |
+
|
282 |
+
case Dup_ErrorBehavior::ThrowException:
|
283 |
+
DUP_LOG::trace("throwing exception");
|
284 |
+
throw new Exception($msg);
|
285 |
+
break;
|
286 |
+
|
287 |
+
case Dup_ErrorBehavior::Quit:
|
288 |
+
DUP_LOG::trace("quitting");
|
289 |
+
die("DUPLICATOR ERROR: Please see the 'Package Log' file link below.");
|
290 |
+
break;
|
291 |
+
|
292 |
+
default:
|
293 |
+
// Nothing
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* The current stack trace of a PHP call
|
299 |
+
* @param $stacktrace The current debug stack
|
300 |
+
* @return string
|
301 |
+
*/
|
302 |
+
public static function getStack($stacktrace)
|
303 |
+
{
|
304 |
+
$output = "";
|
305 |
+
$i = 1;
|
306 |
+
foreach ($stacktrace as $node) {
|
307 |
+
$output .= "\t $i. ".basename($node['file'])." : ".$node['function']." (".$node['line'].")\n";
|
308 |
+
$i++;
|
309 |
+
}
|
310 |
+
return $output;
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Manages writing the active or backup log based on the size setting
|
315 |
+
*
|
316 |
+
* @return null
|
317 |
+
*/
|
318 |
+
private static function WriteToTrace($formatted_logging_message)
|
319 |
+
{
|
320 |
+
$log_filepath = self::GetTraceFilepath();
|
321 |
+
|
322 |
+
if (@filesize($log_filepath) > DUPLICATOR_MAX_LOG_SIZE) {
|
323 |
+
$backup_log_filepath = self::GetBackupTraceFilepath();
|
324 |
+
|
325 |
+
if (file_exists($backup_log_filepath)) {
|
326 |
+
if (@unlink($backup_log_filepath) === false) {
|
327 |
+
self::errLog("Couldn't delete backup log $backup_log_filepath");
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
if (@rename($log_filepath, $backup_log_filepath) === false) {
|
332 |
+
self::errLog("Couldn't rename log $log_filepath to $backup_log_filepath");
|
333 |
+
}
|
334 |
+
}
|
335 |
+
|
336 |
+
if (@file_put_contents($log_filepath, $formatted_logging_message, FILE_APPEND) === false) {
|
337 |
+
// Not en error worth reporting
|
338 |
+
}
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
class DUP_Handler
|
343 |
+
{
|
344 |
+
const MODE_OFF = 0; // don't write in log
|
345 |
+
const MODE_LOG = 1; // write errors in log file
|
346 |
+
const MODE_VAR = 2; // put php errors in $varModeLog static var
|
347 |
+
const SHUTDOWN_TIMEOUT = 'tm';
|
348 |
+
|
349 |
+
/**
|
350 |
+
*
|
351 |
+
* @var bool
|
352 |
+
*/
|
353 |
+
private static $initialized = false;
|
354 |
+
|
355 |
+
/**
|
356 |
+
*
|
357 |
+
* @var array
|
358 |
+
*/
|
359 |
+
private static $shutdownReturns = array(
|
360 |
+
'tm' => 'timeout'
|
361 |
+
);
|
362 |
+
|
363 |
+
/**
|
364 |
+
*
|
365 |
+
* @var int
|
366 |
+
*/
|
367 |
+
private static $handlerMode = self::MODE_LOG;
|
368 |
+
|
369 |
+
/**
|
370 |
+
*
|
371 |
+
* @var bool // print code reference and errno at end of php error line [CODE:10|FILE:test.php|LINE:100]
|
372 |
+
*/
|
373 |
+
private static $codeReference = true;
|
374 |
+
|
375 |
+
/**
|
376 |
+
*
|
377 |
+
* @var bool // print prefix in php error line [PHP ERR][WARN] MSG: .....
|
378 |
+
*/
|
379 |
+
private static $errPrefix = true;
|
380 |
+
|
381 |
+
/**
|
382 |
+
*
|
383 |
+
* @var string // php errors in MODE_VAR
|
384 |
+
*/
|
385 |
+
private static $varModeLog = '';
|
386 |
+
|
387 |
+
/**
|
388 |
+
* This function only initializes the error handler the first time it is called
|
389 |
+
*/
|
390 |
+
public static function init_error_handler()
|
391 |
+
{
|
392 |
+
if (!self::$initialized) {
|
393 |
+
@set_error_handler(array(__CLASS__, 'error'));
|
394 |
+
@register_shutdown_function(array(__CLASS__, 'shutdown'));
|
395 |
+
self::$initialized = true;
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
/**
|
400 |
+
* Error handler
|
401 |
+
*
|
402 |
+
* @param integer $errno Error level
|
403 |
+
* @param string $errstr Error message
|
404 |
+
* @param string $errfile Error file
|
405 |
+
* @param integer $errline Error line
|
406 |
+
* @return void
|
407 |
+
*/
|
408 |
+
public static function error($errno, $errstr, $errfile, $errline)
|
409 |
+
{
|
410 |
+
switch (self::$handlerMode) {
|
411 |
+
case self::MODE_OFF:
|
412 |
+
if ($errno == E_ERROR) {
|
413 |
+
$log_message = self::getMessage($errno, $errstr, $errfile, $errline);
|
414 |
+
DUP_Log::error($log_message);
|
415 |
+
}
|
416 |
+
break;
|
417 |
+
case self::MODE_VAR:
|
418 |
+
self::$varModeLog .= self::getMessage($errno, $errstr, $errfile, $errline)."\n";
|
419 |
+
break;
|
420 |
+
case self::MODE_LOG:
|
421 |
+
default:
|
422 |
+
switch ($errno) {
|
423 |
+
case E_ERROR :
|
424 |
+
$log_message = self::getMessage($errno, $errstr, $errfile, $errline);
|
425 |
+
DUP_Log::error($log_message);
|
426 |
+
break;
|
427 |
+
case E_NOTICE :
|
428 |
+
case E_WARNING :
|
429 |
+
default :
|
430 |
+
$log_message = self::getMessage($errno, $errstr, $errfile, $errline);
|
431 |
+
DUP_Log::Info($log_message);
|
432 |
+
break;
|
433 |
+
}
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
private static function getMessage($errno, $errstr, $errfile, $errline)
|
438 |
+
{
|
439 |
+
$result = '';
|
440 |
+
|
441 |
+
if (self::$errPrefix) {
|
442 |
+
$result = '[PHP ERR]';
|
443 |
+
switch ($errno) {
|
444 |
+
case E_ERROR :
|
445 |
+
$result .= '[FATAL]';
|
446 |
+
break;
|
447 |
+
case E_WARNING :
|
448 |
+
$result .= '[WARN]';
|
449 |
+
break;
|
450 |
+
case E_NOTICE :
|
451 |
+
$result .= '[NOTICE]';
|
452 |
+
break;
|
453 |
+
default :
|
454 |
+
$result .= '[ISSUE]';
|
455 |
+
break;
|
456 |
+
}
|
457 |
+
$result .= ' MSG:';
|
458 |
+
}
|
459 |
+
|
460 |
+
$result .= $errstr;
|
461 |
+
|
462 |
+
if (self::$codeReference) {
|
463 |
+
$result .= ' [CODE:'.$errno.'|FILE:'.$errfile.'|LINE:'.$errline.']';
|
464 |
+
$result .= "\n".wp_debug_backtrace_summary();
|
465 |
+
}
|
466 |
+
|
467 |
+
return $result;
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* if setMode is called without params set as default
|
472 |
+
*
|
473 |
+
* @param int $mode
|
474 |
+
* @param bool $errPrefix // print prefix in php error line [PHP ERR][WARN] MSG: .....
|
475 |
+
* @param bool $codeReference // print code reference and errno at end of php error line [CODE:10|FILE:test.php|LINE:100]
|
476 |
+
*/
|
477 |
+
public static function setMode($mode = self::MODE_LOG, $errPrefix = true, $codeReference = true)
|
478 |
+
{
|
479 |
+
switch ($mode) {
|
480 |
+
case self::MODE_OFF:
|
481 |
+
case self::MODE_VAR:
|
482 |
+
self::$handlerMode = $mode;
|
483 |
+
break;
|
484 |
+
case self::MODE_LOG:
|
485 |
+
default:
|
486 |
+
self::$handlerMode = self::MODE_LOG;
|
487 |
+
}
|
488 |
+
|
489 |
+
self::$varModeLog = '';
|
490 |
+
self::$errPrefix = $errPrefix;
|
491 |
+
self::$codeReference = $codeReference;
|
492 |
+
}
|
493 |
+
|
494 |
+
/**
|
495 |
+
*
|
496 |
+
* @return string // return var log string in MODE_VAR
|
497 |
+
*/
|
498 |
+
public static function getVarLog()
|
499 |
+
{
|
500 |
+
return self::$varModeLog;
|
501 |
+
}
|
502 |
+
|
503 |
+
/**
|
504 |
+
*
|
505 |
+
* @return string // return var log string in MODE_VAR and clean var
|
506 |
+
*/
|
507 |
+
public static function getVarLogClean()
|
508 |
+
{
|
509 |
+
$result = self::$varModeLog;
|
510 |
+
self::$varModeLog = '';
|
511 |
+
return $result;
|
512 |
+
}
|
513 |
+
|
514 |
+
/**
|
515 |
+
*
|
516 |
+
* @param string $status // timeout
|
517 |
+
* @param string
|
518 |
+
*/
|
519 |
+
public static function setShutdownReturn($status, $str)
|
520 |
+
{
|
521 |
+
self::$shutdownReturns[$status] = $str;
|
522 |
+
}
|
523 |
+
|
524 |
+
/**
|
525 |
+
* Shutdown handler
|
526 |
+
*
|
527 |
+
* @return void
|
528 |
+
*/
|
529 |
+
public static function shutdown()
|
530 |
+
{
|
531 |
+
if (($error = error_get_last())) {
|
532 |
+
if (preg_match('/^Maximum execution time (?:.+) exceeded$/i', $error['message'])) {
|
533 |
+
echo self::$shutdownReturns[self::SHUTDOWN_TIMEOUT];
|
534 |
+
}
|
535 |
+
self::error($error['type'], $error['message'], $error['file'], $error['line']);
|
536 |
+
}
|
537 |
+
}
|
538 |
+
}
|
classes/class.password.php
CHANGED
@@ -163,7 +163,7 @@ class DUP_PasswordHash
|
|
163 |
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
164 |
|
165 |
$output = '$2a$';
|
166 |
-
$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
|
167 |
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
|
168 |
$output .= '$';
|
169 |
|
163 |
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
164 |
|
165 |
$output = '$2a$';
|
166 |
+
$output .= chr(ord('0') + (int)($this->iteration_count_log2 / 10));
|
167 |
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
|
168 |
$output .= '$';
|
169 |
|
classes/package/class.pack.archive.zip.php
CHANGED
@@ -1,238 +1,238 @@
|
|
1 |
-
<?php
|
2 |
-
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
-
// Exit if accessed directly
|
4 |
-
if (! defined('DUPLICATOR_VERSION')) exit;
|
5 |
-
|
6 |
-
require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.archive.php');
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Creates a zip file using the built in PHP ZipArchive class
|
10 |
-
*/
|
11 |
-
class DUP_Zip extends DUP_Archive
|
12 |
-
{
|
13 |
-
//PRIVATE
|
14 |
-
private static $compressDir;
|
15 |
-
private static $countDirs = 0;
|
16 |
-
private static $countFiles = 0;
|
17 |
-
private static $sqlPath;
|
18 |
-
private static $zipPath;
|
19 |
-
private static $zipFileSize;
|
20 |
-
private static $zipArchive;
|
21 |
-
private static $limitItems = 0;
|
22 |
-
private static $networkFlush = false;
|
23 |
-
private static $scanReport;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Creates the zip file and adds the SQL file to the archive
|
27 |
-
*/
|
28 |
-
public static function create(DUP_Archive $archive, $buildProgress)
|
29 |
-
{
|
30 |
-
try {
|
31 |
-
$timerAllStart = DUP_Util::getMicrotime();
|
32 |
-
$package_zip_flush = DUP_Settings::Get('package_zip_flush');
|
33 |
-
|
34 |
-
self::$compressDir = rtrim(wp_normalize_path(DUP_Util::safePath($archive->PackDir)), '/');
|
35 |
-
self::$sqlPath = DUP_Settings::getSsdirTmpPath()."/{$archive->Package->Database->File}";
|
36 |
-
self::$zipPath = DUP_Settings::getSsdirTmpPath()."/{$archive->File}";
|
37 |
-
self::$zipArchive = new ZipArchive();
|
38 |
-
self::$networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
|
39 |
-
|
40 |
-
$filterDirs = empty($archive->FilterDirs) ? 'not set' : $archive->FilterDirs;
|
41 |
-
$filterExts = empty($archive->FilterExts) ? 'not set' : $archive->FilterExts;
|
42 |
-
$filterFiles = empty($archive->FilterFiles) ? 'not set' : $archive->FilterFiles;
|
43 |
-
$filterOn = ($archive->FilterOn) ? 'ON' : 'OFF';
|
44 |
-
$filterDirsFormat = rtrim(str_replace(';', "\n\t", $filterDirs));
|
45 |
-
$filterFilesFormat = rtrim(str_replace(';', "\n\t", $filterFiles));
|
46 |
-
$lastDirSuccess = self::$compressDir;
|
47 |
-
|
48 |
-
//LOAD SCAN REPORT
|
49 |
-
$json = file_get_contents(DUP_Settings::getSsdirTmpPath()."/{$archive->Package->NameHash}_scan.json");
|
50 |
-
self::$scanReport = json_decode($json);
|
51 |
-
|
52 |
-
DUP_Log::Info("\n********************************************************************************");
|
53 |
-
DUP_Log::Info("ARCHIVE (ZIP):");
|
54 |
-
DUP_Log::Info("********************************************************************************");
|
55 |
-
$isZipOpen = (self::$zipArchive->open(self::$zipPath, ZIPARCHIVE::CREATE) === TRUE);
|
56 |
-
if (!$isZipOpen) {
|
57 |
-
$error_message = "Cannot open zip file with PHP ZipArchive.";
|
58 |
-
$buildProgress->set_failed($error_message);
|
59 |
-
DUP_Log::error($error_message, "Path location [".self::$zipPath."]", Dup_ErrorBehavior::LogOnly);
|
60 |
-
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
61 |
-
return;
|
62 |
-
}
|
63 |
-
DUP_Log::Info("ARCHIVE DIR: ".self::$compressDir);
|
64 |
-
DUP_Log::Info("ARCHIVE FILE: ".basename(self::$zipPath));
|
65 |
-
DUP_Log::Info("FILTERS: *{$filterOn}*");
|
66 |
-
DUP_Log::Info("DIRS:\n\t{$filterDirsFormat}");
|
67 |
-
DUP_Log::Info("FILES:\n\t{$filterFilesFormat}");
|
68 |
-
DUP_Log::Info("EXTS: {$filterExts}");
|
69 |
-
|
70 |
-
DUP_Log::Info("----------------------------------------");
|
71 |
-
DUP_Log::Info("COMPRESSING");
|
72 |
-
DUP_Log::Info("SIZE:\t".self::$scanReport->ARC->Size);
|
73 |
-
DUP_Log::Info("STATS:\tDirs ".self::$scanReport->ARC->DirCount." | Files ".self::$scanReport->ARC->FileCount);
|
74 |
-
|
75 |
-
//ADD SQL
|
76 |
-
$sql_ark_file_path = $archive->Package->getSqlArkFilePath();
|
77 |
-
$isSQLInZip = self::$zipArchive->addFile(self::$sqlPath, $sql_ark_file_path);
|
78 |
-
|
79 |
-
if ($isSQLInZip) {
|
80 |
-
DUP_Log::Info("SQL ADDED: ".basename(self::$sqlPath));
|
81 |
-
} else {
|
82 |
-
$error_message = "Unable to add database.sql to archive.";
|
83 |
-
DUP_Log::error($error_message, "SQL File Path [".self::$sqlPath."]", Dup_ErrorBehavior::LogOnly);
|
84 |
-
$buildProgress->set_failed($error_message);
|
85 |
-
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
86 |
-
return;
|
87 |
-
}
|
88 |
-
self::$zipArchive->close();
|
89 |
-
self::$zipArchive->open(self::$zipPath, ZipArchive::CREATE);
|
90 |
-
|
91 |
-
//ZIP DIRECTORIES
|
92 |
-
$info = '';
|
93 |
-
foreach (self::$scanReport->ARC->Dirs as $dir) {
|
94 |
-
$emptyDir = $archive->getLocalDirPath($dir);
|
95 |
-
|
96 |
-
if (is_readable($dir) && self::$zipArchive->addEmptyDir($emptyDir)) {
|
97 |
-
self::$countDirs++;
|
98 |
-
$lastDirSuccess = $dir;
|
99 |
-
} else {
|
100 |
-
//Don't warn when dirtory is the root path
|
101 |
-
if (strcmp($dir, rtrim(self::$compressDir, '/')) != 0) {
|
102 |
-
$dir_path = strlen($dir) ? "[{$dir}]" : "[Read Error] - last successful read was: [{$lastDirSuccess}]";
|
103 |
-
$info .= "DIR: {$dir_path}\n";
|
104 |
-
}
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
//LOG Unreadable DIR info
|
109 |
-
if (strlen($info)) {
|
110 |
-
DUP_Log::Info("\nWARNING: Unable to zip directories:");
|
111 |
-
DUP_Log::Info($info);
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* count update for integrity check
|
116 |
-
*/
|
117 |
-
$sumItems = (self::$countDirs + self::$countFiles);
|
118 |
-
|
119 |
-
/* ZIP FILES: Network Flush
|
120 |
-
* This allows the process to not timeout on fcgi
|
121 |
-
* setups that need a response every X seconds */
|
122 |
-
$totalFileCount = count(self::$scanReport->ARC->Files);
|
123 |
-
$info = '';
|
124 |
-
if (self::$networkFlush) {
|
125 |
-
foreach (self::$scanReport->ARC->Files as $file) {
|
126 |
-
$file_size = @filesize($file);
|
127 |
-
$localFileName = $archive->getLocalFilePath($file);
|
128 |
-
|
129 |
-
if (is_readable($file)) {
|
130 |
-
if (defined('DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR') && DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR && $file_size < DUP_Constants::ZIP_STRING_LIMIT && self::$zipArchive->addFromString($localFileName, file_get_contents($file))) {
|
131 |
-
Dup_Log::Info("Adding {$file} to zip");
|
132 |
-
self::$limitItems++;
|
133 |
-
self::$countFiles++;
|
134 |
-
} elseif (self::$zipArchive->addFile($file, $localFileName)) {
|
135 |
-
Dup_Log::Info("Adding {$file} to zip");
|
136 |
-
self::$limitItems++;
|
137 |
-
self::$countFiles++;
|
138 |
-
} else {
|
139 |
-
$info .= "FILE: [{$file}]\n";
|
140 |
-
}
|
141 |
-
} else {
|
142 |
-
$info .= "FILE: [{$file}]\n";
|
143 |
-
}
|
144 |
-
//Trigger a flush to the web server after so many files have been loaded.
|
145 |
-
if (self::$limitItems > DUPLICATOR_ZIP_FLUSH_TRIGGER) {
|
146 |
-
self::$zipArchive->close();
|
147 |
-
self::$zipArchive->open(self::$zipPath);
|
148 |
-
self::$limitItems = 0;
|
149 |
-
DUP_Util::fcgiFlush();
|
150 |
-
DUP_Log::Info("Items archived [{$sumItems}] flushing response.");
|
151 |
-
}
|
152 |
-
|
153 |
-
if(self::$countFiles % 500 == 0) {
|
154 |
-
// Every so many files update the status so the UI can display
|
155 |
-
$archive->Package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::ARCSTART, DUP_PackageStatus::ARCVALIDATION, $totalFileCount, self::$countFiles);
|
156 |
-
$archive->Package->update();
|
157 |
-
}
|
158 |
-
}
|
159 |
-
}
|
160 |
-
//Normal
|
161 |
-
else {
|
162 |
-
foreach (self::$scanReport->ARC->Files as $file) {
|
163 |
-
$file_size = @filesize($file);
|
164 |
-
$localFileName = $archive->getLocalFilePath($file);
|
165 |
-
|
166 |
-
if (is_readable($file)) {
|
167 |
-
if (defined('DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR') && DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR && $file_size < DUP_Constants::ZIP_STRING_LIMIT && self::$zipArchive->addFromString($localFileName, file_get_contents($file))) {
|
168 |
-
self::$countFiles++;
|
169 |
-
} elseif (self::$zipArchive->addFile($file, $localFileName)) {
|
170 |
-
self::$countFiles++;
|
171 |
-
} else {
|
172 |
-
$info .= "FILE: [{$file}]\n";
|
173 |
-
}
|
174 |
-
} else {
|
175 |
-
$info .= "FILE: [{$file}]\n";
|
176 |
-
}
|
177 |
-
|
178 |
-
if(self::$countFiles % 500 == 0) {
|
179 |
-
// Every so many files update the status so the UI can display
|
180 |
-
$archive->Package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::ARCSTART, DUP_PackageStatus::ARCVALIDATION, $totalFileCount, self::$countFiles);
|
181 |
-
$archive->Package->update();
|
182 |
-
}
|
183 |
-
}
|
184 |
-
}
|
185 |
-
|
186 |
-
//LOG Unreadable FILE info
|
187 |
-
if (strlen($info)) {
|
188 |
-
DUP_Log::Info("\nWARNING: Unable to zip files:");
|
189 |
-
DUP_Log::Info($info);
|
190 |
-
unset($info);
|
191 |
-
}
|
192 |
-
|
193 |
-
DUP_Log::Info(print_r(self::$zipArchive, true));
|
194 |
-
|
195 |
-
/**
|
196 |
-
* count update for integrity check
|
197 |
-
*/
|
198 |
-
$archive->file_count = self::$countDirs + self::$countFiles;
|
199 |
-
DUP_Log::Info("FILE ADDED TO ZIP: ".$archive->file_count);
|
200 |
-
|
201 |
-
|
202 |
-
//--------------------------------
|
203 |
-
//LOG FINAL RESULTS
|
204 |
-
DUP_Util::fcgiFlush();
|
205 |
-
$zipCloseResult = self::$zipArchive->close();
|
206 |
-
if($zipCloseResult) {
|
207 |
-
DUP_Log::Info("COMPRESSION RESULT: '{$zipCloseResult}'");
|
208 |
-
} else {
|
209 |
-
$error_message = "ZipArchive close failure.";
|
210 |
-
DUP_Log::error($error_message,
|
211 |
-
"The ZipArchive engine is having issues zipping up the files on this server. For more details visit the FAQ\n"
|
212 |
-
. "I'm getting a ZipArchive close failure when building. How can I resolve this?\n"
|
213 |
-
. "[https://snapcreek.com/duplicator/docs/faqs-tech/#faq-package-165-q]",
|
214 |
-
Dup_ErrorBehavior::LogOnly);
|
215 |
-
$buildProgress->set_failed($error_message);
|
216 |
-
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
217 |
-
return;
|
218 |
-
}
|
219 |
-
|
220 |
-
$timerAllEnd = DUP_Util::getMicrotime();
|
221 |
-
$timerAllSum = DUP_Util::elapsedTime($timerAllEnd, $timerAllStart);
|
222 |
-
|
223 |
-
self::$zipFileSize = @filesize(self::$zipPath);
|
224 |
-
DUP_Log::Info("COMPRESSED SIZE: ".DUP_Util::byteSize(self::$zipFileSize));
|
225 |
-
DUP_Log::Info("ARCHIVE RUNTIME: {$timerAllSum}");
|
226 |
-
DUP_Log::Info("MEMORY STACK: ".DUP_Server::getPHPMemory());
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
} catch (Exception $e) {
|
231 |
-
$error_message = "Runtime error in class.pack.archive.zip.php constructor.";
|
232 |
-
DUP_Log::error($error_message, "Exception: {$e}", Dup_ErrorBehavior::LogOnly);
|
233 |
-
$buildProgress->set_failed($error_message);
|
234 |
-
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
235 |
-
return;
|
236 |
-
}
|
237 |
-
}
|
238 |
}
|
1 |
+
<?php
|
2 |
+
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
+
// Exit if accessed directly
|
4 |
+
if (! defined('DUPLICATOR_VERSION')) exit;
|
5 |
+
|
6 |
+
require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.archive.php');
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Creates a zip file using the built in PHP ZipArchive class
|
10 |
+
*/
|
11 |
+
class DUP_Zip extends DUP_Archive
|
12 |
+
{
|
13 |
+
//PRIVATE
|
14 |
+
private static $compressDir;
|
15 |
+
private static $countDirs = 0;
|
16 |
+
private static $countFiles = 0;
|
17 |
+
private static $sqlPath;
|
18 |
+
private static $zipPath;
|
19 |
+
private static $zipFileSize;
|
20 |
+
private static $zipArchive;
|
21 |
+
private static $limitItems = 0;
|
22 |
+
private static $networkFlush = false;
|
23 |
+
private static $scanReport;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Creates the zip file and adds the SQL file to the archive
|
27 |
+
*/
|
28 |
+
public static function create(DUP_Archive $archive, $buildProgress)
|
29 |
+
{
|
30 |
+
try {
|
31 |
+
$timerAllStart = DUP_Util::getMicrotime();
|
32 |
+
$package_zip_flush = DUP_Settings::Get('package_zip_flush');
|
33 |
+
|
34 |
+
self::$compressDir = rtrim(wp_normalize_path(DUP_Util::safePath($archive->PackDir)), '/');
|
35 |
+
self::$sqlPath = DUP_Settings::getSsdirTmpPath()."/{$archive->Package->Database->File}";
|
36 |
+
self::$zipPath = DUP_Settings::getSsdirTmpPath()."/{$archive->File}";
|
37 |
+
self::$zipArchive = new ZipArchive();
|
38 |
+
self::$networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
|
39 |
+
|
40 |
+
$filterDirs = empty($archive->FilterDirs) ? 'not set' : $archive->FilterDirs;
|
41 |
+
$filterExts = empty($archive->FilterExts) ? 'not set' : $archive->FilterExts;
|
42 |
+
$filterFiles = empty($archive->FilterFiles) ? 'not set' : $archive->FilterFiles;
|
43 |
+
$filterOn = ($archive->FilterOn) ? 'ON' : 'OFF';
|
44 |
+
$filterDirsFormat = rtrim(str_replace(';', "\n\t", $filterDirs));
|
45 |
+
$filterFilesFormat = rtrim(str_replace(';', "\n\t", $filterFiles));
|
46 |
+
$lastDirSuccess = self::$compressDir;
|
47 |
+
|
48 |
+
//LOAD SCAN REPORT
|
49 |
+
$json = file_get_contents(DUP_Settings::getSsdirTmpPath()."/{$archive->Package->NameHash}_scan.json");
|
50 |
+
self::$scanReport = json_decode($json);
|
51 |
+
|
52 |
+
DUP_Log::Info("\n********************************************************************************");
|
53 |
+
DUP_Log::Info("ARCHIVE (ZIP):");
|
54 |
+
DUP_Log::Info("********************************************************************************");
|
55 |
+
$isZipOpen = (self::$zipArchive->open(self::$zipPath, ZIPARCHIVE::CREATE) === TRUE);
|
56 |
+
if (!$isZipOpen) {
|
57 |
+
$error_message = "Cannot open zip file with PHP ZipArchive.";
|
58 |
+
$buildProgress->set_failed($error_message);
|
59 |
+
DUP_Log::error($error_message, "Path location [".self::$zipPath."]", Dup_ErrorBehavior::LogOnly);
|
60 |
+
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
DUP_Log::Info("ARCHIVE DIR: ".self::$compressDir);
|
64 |
+
DUP_Log::Info("ARCHIVE FILE: ".basename(self::$zipPath));
|
65 |
+
DUP_Log::Info("FILTERS: *{$filterOn}*");
|
66 |
+
DUP_Log::Info("DIRS:\n\t{$filterDirsFormat}");
|
67 |
+
DUP_Log::Info("FILES:\n\t{$filterFilesFormat}");
|
68 |
+
DUP_Log::Info("EXTS: {$filterExts}");
|
69 |
+
|
70 |
+
DUP_Log::Info("----------------------------------------");
|
71 |
+
DUP_Log::Info("COMPRESSING");
|
72 |
+
DUP_Log::Info("SIZE:\t".self::$scanReport->ARC->Size);
|
73 |
+
DUP_Log::Info("STATS:\tDirs ".self::$scanReport->ARC->DirCount." | Files ".self::$scanReport->ARC->FileCount);
|
74 |
+
|
75 |
+
//ADD SQL
|
76 |
+
$sql_ark_file_path = $archive->Package->getSqlArkFilePath();
|
77 |
+
$isSQLInZip = self::$zipArchive->addFile(self::$sqlPath, $sql_ark_file_path);
|
78 |
+
|
79 |
+
if ($isSQLInZip) {
|
80 |
+
DUP_Log::Info("SQL ADDED: ".basename(self::$sqlPath));
|
81 |
+
} else {
|
82 |
+
$error_message = "Unable to add database.sql to archive.";
|
83 |
+
DUP_Log::error($error_message, "SQL File Path [".self::$sqlPath."]", Dup_ErrorBehavior::LogOnly);
|
84 |
+
$buildProgress->set_failed($error_message);
|
85 |
+
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
86 |
+
return;
|
87 |
+
}
|
88 |
+
self::$zipArchive->close();
|
89 |
+
self::$zipArchive->open(self::$zipPath, ZipArchive::CREATE);
|
90 |
+
|
91 |
+
//ZIP DIRECTORIES
|
92 |
+
$info = '';
|
93 |
+
foreach (self::$scanReport->ARC->Dirs as $dir) {
|
94 |
+
$emptyDir = $archive->getLocalDirPath($dir);
|
95 |
+
|
96 |
+
if (is_readable($dir) && self::$zipArchive->addEmptyDir($emptyDir)) {
|
97 |
+
self::$countDirs++;
|
98 |
+
$lastDirSuccess = $dir;
|
99 |
+
} else {
|
100 |
+
//Don't warn when dirtory is the root path
|
101 |
+
if (strcmp($dir, rtrim(self::$compressDir, '/')) != 0) {
|
102 |
+
$dir_path = strlen($dir) ? "[{$dir}]" : "[Read Error] - last successful read was: [{$lastDirSuccess}]";
|
103 |
+
$info .= "DIR: {$dir_path}\n";
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
//LOG Unreadable DIR info
|
109 |
+
if (strlen($info)) {
|
110 |
+
DUP_Log::Info("\nWARNING: Unable to zip directories:");
|
111 |
+
DUP_Log::Info($info);
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* count update for integrity check
|
116 |
+
*/
|
117 |
+
$sumItems = (self::$countDirs + self::$countFiles);
|
118 |
+
|
119 |
+
/* ZIP FILES: Network Flush
|
120 |
+
* This allows the process to not timeout on fcgi
|
121 |
+
* setups that need a response every X seconds */
|
122 |
+
$totalFileCount = count(self::$scanReport->ARC->Files);
|
123 |
+
$info = '';
|
124 |
+
if (self::$networkFlush) {
|
125 |
+
foreach (self::$scanReport->ARC->Files as $file) {
|
126 |
+
$file_size = @filesize($file);
|
127 |
+
$localFileName = $archive->getLocalFilePath($file);
|
128 |
+
|
129 |
+
if (is_readable($file)) {
|
130 |
+
if (defined('DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR') && DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR && $file_size < DUP_Constants::ZIP_STRING_LIMIT && self::$zipArchive->addFromString($localFileName, file_get_contents($file))) {
|
131 |
+
Dup_Log::Info("Adding {$file} to zip");
|
132 |
+
self::$limitItems++;
|
133 |
+
self::$countFiles++;
|
134 |
+
} elseif (self::$zipArchive->addFile($file, $localFileName)) {
|
135 |
+
Dup_Log::Info("Adding {$file} to zip");
|
136 |
+
self::$limitItems++;
|
137 |
+
self::$countFiles++;
|
138 |
+
} else {
|
139 |
+
$info .= "FILE: [{$file}]\n";
|
140 |
+
}
|
141 |
+
} else {
|
142 |
+
$info .= "FILE: [{$file}]\n";
|
143 |
+
}
|
144 |
+
//Trigger a flush to the web server after so many files have been loaded.
|
145 |
+
if (self::$limitItems > DUPLICATOR_ZIP_FLUSH_TRIGGER) {
|
146 |
+
self::$zipArchive->close();
|
147 |
+
self::$zipArchive->open(self::$zipPath);
|
148 |
+
self::$limitItems = 0;
|
149 |
+
DUP_Util::fcgiFlush();
|
150 |
+
DUP_Log::Info("Items archived [{$sumItems}] flushing response.");
|
151 |
+
}
|
152 |
+
|
153 |
+
if(self::$countFiles % 500 == 0) {
|
154 |
+
// Every so many files update the status so the UI can display
|
155 |
+
$archive->Package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::ARCSTART, DUP_PackageStatus::ARCVALIDATION, $totalFileCount, self::$countFiles);
|
156 |
+
$archive->Package->update();
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
//Normal
|
161 |
+
else {
|
162 |
+
foreach (self::$scanReport->ARC->Files as $file) {
|
163 |
+
$file_size = @filesize($file);
|
164 |
+
$localFileName = $archive->getLocalFilePath($file);
|
165 |
+
|
166 |
+
if (is_readable($file)) {
|
167 |
+
if (defined('DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR') && DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR && $file_size < DUP_Constants::ZIP_STRING_LIMIT && self::$zipArchive->addFromString($localFileName, file_get_contents($file))) {
|
168 |
+
self::$countFiles++;
|
169 |
+
} elseif (self::$zipArchive->addFile($file, $localFileName)) {
|
170 |
+
self::$countFiles++;
|
171 |
+
} else {
|
172 |
+
$info .= "FILE: [{$file}]\n";
|
173 |
+
}
|
174 |
+
} else {
|
175 |
+
$info .= "FILE: [{$file}]\n";
|
176 |
+
}
|
177 |
+
|
178 |
+
if(self::$countFiles % 500 == 0) {
|
179 |
+
// Every so many files update the status so the UI can display
|
180 |
+
$archive->Package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::ARCSTART, DUP_PackageStatus::ARCVALIDATION, $totalFileCount, self::$countFiles);
|
181 |
+
$archive->Package->update();
|
182 |
+
}
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
//LOG Unreadable FILE info
|
187 |
+
if (strlen($info)) {
|
188 |
+
DUP_Log::Info("\nWARNING: Unable to zip files:");
|
189 |
+
DUP_Log::Info($info);
|
190 |
+
unset($info);
|
191 |
+
}
|
192 |
+
|
193 |
+
DUP_Log::Info(print_r(self::$zipArchive, true));
|
194 |
+
|
195 |
+
/**
|
196 |
+
* count update for integrity check
|
197 |
+
*/
|
198 |
+
$archive->file_count = self::$countDirs + self::$countFiles;
|
199 |
+
DUP_Log::Info("FILE ADDED TO ZIP: ".$archive->file_count);
|
200 |
+
|
201 |
+
|
202 |
+
//--------------------------------
|
203 |
+
//LOG FINAL RESULTS
|
204 |
+
DUP_Util::fcgiFlush();
|
205 |
+
$zipCloseResult = self::$zipArchive->close();
|
206 |
+
if($zipCloseResult) {
|
207 |
+
DUP_Log::Info("COMPRESSION RESULT: '{$zipCloseResult}'");
|
208 |
+
} else {
|
209 |
+
$error_message = "ZipArchive close failure.";
|
210 |
+
DUP_Log::error($error_message,
|
211 |
+
"The ZipArchive engine is having issues zipping up the files on this server. For more details visit the FAQ\n"
|
212 |
+
. "I'm getting a ZipArchive close failure when building. How can I resolve this?\n"
|
213 |
+
. "[https://snapcreek.com/duplicator/docs/faqs-tech/#faq-package-165-q]",
|
214 |
+
Dup_ErrorBehavior::LogOnly);
|
215 |
+
$buildProgress->set_failed($error_message);
|
216 |
+
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
217 |
+
return;
|
218 |
+
}
|
219 |
+
|
220 |
+
$timerAllEnd = DUP_Util::getMicrotime();
|
221 |
+
$timerAllSum = DUP_Util::elapsedTime($timerAllEnd, $timerAllStart);
|
222 |
+
|
223 |
+
self::$zipFileSize = @filesize(self::$zipPath);
|
224 |
+
DUP_Log::Info("COMPRESSED SIZE: ".DUP_Util::byteSize(self::$zipFileSize));
|
225 |
+
DUP_Log::Info("ARCHIVE RUNTIME: {$timerAllSum}");
|
226 |
+
DUP_Log::Info("MEMORY STACK: ".DUP_Server::getPHPMemory());
|
227 |
+
|
228 |
+
|
229 |
+
|
230 |
+
} catch (Exception $e) {
|
231 |
+
$error_message = "Runtime error in class.pack.archive.zip.php constructor.";
|
232 |
+
DUP_Log::error($error_message, "Exception: {$e}", Dup_ErrorBehavior::LogOnly);
|
233 |
+
$buildProgress->set_failed($error_message);
|
234 |
+
$archive->Package->setStatus(DUP_PackageStatus::ERROR);
|
235 |
+
return;
|
236 |
+
}
|
237 |
+
}
|
238 |
}
|
classes/package/class.pack.database.php
CHANGED
@@ -277,6 +277,7 @@ class DUP_Database
|
|
277 |
$tblSizeFound = 0;
|
278 |
|
279 |
//Grab Table Stats
|
|
|
280 |
foreach ($tables as $table) {
|
281 |
$tblBaseCount++;
|
282 |
$name = $table["Name"];
|
@@ -295,6 +296,7 @@ class DUP_Database
|
|
295 |
$info['TableList'][$name]['Rows'] = number_format($rows);
|
296 |
$info['TableList'][$name]['Size'] = DUP_Util::byteSize($size);
|
297 |
$info['TableList'][$name]['USize'] = $size;
|
|
|
298 |
$tblCount++;
|
299 |
|
300 |
//Table Uppercase
|
@@ -318,8 +320,7 @@ class DUP_Database
|
|
318 |
}
|
319 |
}
|
320 |
}
|
321 |
-
|
322 |
-
$this->setInfoObj();
|
323 |
$this->info->addTriggers();
|
324 |
|
325 |
$info['Status']['DB_Case'] = preg_match('/[A-Z]/', $wpdb->dbname) ? 'Warn' : 'Good';
|
@@ -346,18 +347,23 @@ class DUP_Database
|
|
346 |
return $info;
|
347 |
}
|
348 |
|
349 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
{
|
351 |
global $wpdb;
|
352 |
-
|
353 |
-
|
354 |
$this->info->buildMode = DUP_DB::getBuildMode();
|
355 |
$this->info->version = DUP_DB::getVersion();
|
356 |
$this->info->versionComment = DUP_DB::getVariable('version_comment');
|
357 |
$this->info->varLowerCaseTables = DUP_DB::getVariable('lower_case_table_names');
|
358 |
$this->info->name = $wpdb->dbname;
|
359 |
$this->info->isNameUpperCase = preg_match('/[A-Z]/', $wpdb->dbname) ? 1 : 0;
|
360 |
-
$this->info->collationList = DUP_DB::getTableCollationList($
|
361 |
}
|
362 |
|
363 |
/**
|
@@ -568,7 +574,7 @@ class DUP_Database
|
|
568 |
* 2 - Exception
|
569 |
*/
|
570 |
DUP_Log::Info('MYSQL DUMP ERROR '.print_r($mysqlResult, true));
|
571 |
-
DUP_Log::error(__('Shell mysql dump error. Change SQL
|
572 |
DUPLICATOR_DB_MYSQLDUMP_ERROR_CONTAINING_LINE_COUNT, DUPLICATOR_DB_MYSQLDUMP_ERROR_CHARS_IN_LINE_COUNT)), Dup_ErrorBehavior::ThrowException);
|
573 |
return false;
|
574 |
}
|
277 |
$tblSizeFound = 0;
|
278 |
|
279 |
//Grab Table Stats
|
280 |
+
$filteredTables = array();
|
281 |
foreach ($tables as $table) {
|
282 |
$tblBaseCount++;
|
283 |
$name = $table["Name"];
|
296 |
$info['TableList'][$name]['Rows'] = number_format($rows);
|
297 |
$info['TableList'][$name]['Size'] = DUP_Util::byteSize($size);
|
298 |
$info['TableList'][$name]['USize'] = $size;
|
299 |
+
$filteredTables[] = $name;
|
300 |
$tblCount++;
|
301 |
|
302 |
//Table Uppercase
|
320 |
}
|
321 |
}
|
322 |
}
|
323 |
+
$this->setInfoObj($filteredTables);
|
|
|
324 |
$this->info->addTriggers();
|
325 |
|
326 |
$info['Status']['DB_Case'] = preg_match('/[A-Z]/', $wpdb->dbname) ? 'Warn' : 'Good';
|
347 |
return $info;
|
348 |
}
|
349 |
|
350 |
+
/**
|
351 |
+
* @param array &$filteredTables Filtered names of tables to include in collation search.
|
352 |
+
* Parameter does not change in the function, is passed by reference only to avoid copying.
|
353 |
+
*
|
354 |
+
* @return void
|
355 |
+
*/
|
356 |
+
public function setInfoObj(&$filteredTables)
|
357 |
{
|
358 |
global $wpdb;
|
359 |
+
|
|
|
360 |
$this->info->buildMode = DUP_DB::getBuildMode();
|
361 |
$this->info->version = DUP_DB::getVersion();
|
362 |
$this->info->versionComment = DUP_DB::getVariable('version_comment');
|
363 |
$this->info->varLowerCaseTables = DUP_DB::getVariable('lower_case_table_names');
|
364 |
$this->info->name = $wpdb->dbname;
|
365 |
$this->info->isNameUpperCase = preg_match('/[A-Z]/', $wpdb->dbname) ? 1 : 0;
|
366 |
+
$this->info->collationList = DUP_DB::getTableCollationList($filteredTables);
|
367 |
}
|
368 |
|
369 |
/**
|
574 |
* 2 - Exception
|
575 |
*/
|
576 |
DUP_Log::Info('MYSQL DUMP ERROR '.print_r($mysqlResult, true));
|
577 |
+
DUP_Log::error(__('Shell mysql dump error. Change SQL Mode to the "PHP Code" in the Duplicator > Settings > Packages.', 'duplicator'), implode("\n", DupLiteSnapLibIOU::getLastLinesOfFile($this->tempDbPath,
|
578 |
DUPLICATOR_DB_MYSQLDUMP_ERROR_CONTAINING_LINE_COUNT, DUPLICATOR_DB_MYSQLDUMP_ERROR_CHARS_IN_LINE_COUNT)), Dup_ErrorBehavior::ThrowException);
|
579 |
return false;
|
580 |
}
|
classes/package/class.pack.php
CHANGED
@@ -1702,22 +1702,33 @@ class DUP_Package
|
|
1702 |
$files = DUP_Util::listFiles(DUP_Settings::getSsdirTmpPath());
|
1703 |
$newPath = DUP_Settings::getSsdirPath();
|
1704 |
|
1705 |
-
|
1706 |
-
|
1707 |
-
|
1708 |
-
|
1709 |
-
|
1710 |
-
|
|
|
|
|
|
|
|
|
1711 |
}
|
1712 |
-
|
1713 |
-
|
1714 |
-
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
|
|
|
|
1718 |
}
|
1719 |
}
|
|
|
|
|
|
|
|
|
1720 |
}
|
|
|
1721 |
}
|
1722 |
|
1723 |
|
1702 |
$files = DUP_Util::listFiles(DUP_Settings::getSsdirTmpPath());
|
1703 |
$newPath = DUP_Settings::getSsdirPath();
|
1704 |
|
1705 |
+
$filesToStore = array(
|
1706 |
+
$this->Installer->File,
|
1707 |
+
$this->Archive->File,
|
1708 |
+
);
|
1709 |
+
|
1710 |
+
foreach ($files as $file) {
|
1711 |
+
|
1712 |
+
$fileName = basename($file);
|
1713 |
+
if (!strstr($fileName, $this->NameHash)) {
|
1714 |
+
continue;
|
1715 |
}
|
1716 |
+
|
1717 |
+
if (in_array($fileName, $filesToStore)) {
|
1718 |
+
if (function_exists('rename')) {
|
1719 |
+
rename($file, "{$newPath}/{$fileName}");
|
1720 |
+
} elseif (function_exists('copy')) {
|
1721 |
+
copy($file, "{$newPath}/{$fileName}");
|
1722 |
+
} else {
|
1723 |
+
throw new Exception('PHP copy and rename functions not found! Contact hosting provider!');
|
1724 |
}
|
1725 |
}
|
1726 |
+
|
1727 |
+
if (file_exists($file)) {
|
1728 |
+
unlink($file);
|
1729 |
+
}
|
1730 |
}
|
1731 |
+
|
1732 |
}
|
1733 |
|
1734 |
|
classes/package/duparchive/class.pack.archive.duparchive.php
CHANGED
@@ -1,8 +1,6 @@
|
|
1 |
<?php
|
2 |
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
|
4 |
-
//require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.archive.php');
|
5 |
-
//require_once (DUPLICATOR_PLUGIN_PATH.'classes/utilities/class.u.php');
|
6 |
require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/duparchive/class.pack.archive.duparchive.state.expand.php');
|
7 |
require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/duparchive/class.pack.archive.duparchive.state.create.php');
|
8 |
require_once (DUPLICATOR_PLUGIN_PATH.'lib/dup_archive/classes/class.duparchive.loggerbase.php');
|
@@ -37,10 +35,8 @@ class DUP_DupArchive
|
|
37 |
DUP_LOG::trace("start");
|
38 |
try {
|
39 |
DUP_Log::Open($package->NameHash);
|
40 |
-
DUP_Log::trace("c2");
|
41 |
|
42 |
if ($buildProgress->retries > DUPLICATOR_MAX_BUILD_RETRIES) {
|
43 |
-
DUP_LOG::trace("c3");
|
44 |
$error_msg = __('Package build appears stuck so marking package as failed. Is the Max Worker Time set too high?.', 'duplicator');
|
45 |
DUP_Log::error(esc_html__('Build Failure', 'duplicator'), esc_html($error_msg), Dup_ErrorBehavior::LogOnly);
|
46 |
//$buildProgress->failed = true;
|
@@ -49,7 +45,6 @@ class DUP_DupArchive
|
|
49 |
;
|
50 |
return true;
|
51 |
} else {
|
52 |
-
DUP_LOG::trace("c4");
|
53 |
// If all goes well retries will be reset to 0 at the end of this function.
|
54 |
$buildProgress->retries++;
|
55 |
$package->update();
|
@@ -57,29 +52,21 @@ class DUP_DupArchive
|
|
57 |
|
58 |
$done = false;
|
59 |
|
60 |
-
DUP_LOG::trace("c5");
|
61 |
DupArchiveEngine::init(new DUP_DupArchive_Logger(), null, $archive);
|
62 |
-
|
63 |
-
DUP_LOG::trace("c6");
|
64 |
DUP_Package::safeTmpCleanup(true);
|
65 |
|
66 |
$compressDir = rtrim(DUP_Util::safePath($archive->PackDir), '/');
|
67 |
$sqlPath = DUP_Settings::getSsdirTmpPath()."/{$package->Database->File}";
|
68 |
$archivePath = DUP_Settings::getSsdirTmpPath()."/{$archive->File}";
|
69 |
$scanFilepath = DUP_Settings::getSsdirTmpPath()."/{$package->NameHash}_scan.json";
|
70 |
-
|
71 |
-
DUP_LOG::trace("c7");
|
72 |
$skipArchiveFinalization = false;
|
73 |
$json = '';
|
74 |
|
75 |
-
DUP_LOG::trace("c8");
|
76 |
if (file_exists($scanFilepath)) {
|
77 |
|
78 |
-
DUP_LOG::trace("c9");
|
79 |
$json = file_get_contents($scanFilepath);
|
80 |
|
81 |
if (empty($json)) {
|
82 |
-
DUP_LOG::trace("c10");
|
83 |
$errorText = __("Scan file $scanFilepath is empty!", 'duplicator');
|
84 |
$fixText = __("Click on \"Resolve This\" button to fix the JSON settings.", 'duplicator');
|
85 |
|
@@ -92,7 +79,6 @@ class DUP_DupArchive
|
|
92 |
return true;
|
93 |
}
|
94 |
} else {
|
95 |
-
DUP_LOG::trace("c11");
|
96 |
DUP_Log::trace("**** scan file $scanFilepath doesn't exist!!");
|
97 |
$errorMessage = sprintf(__("ERROR: Can't find Scanfile %s. Please ensure there no non-English characters in the package or schedule name.", 'duplicator'), $scanFilepath);
|
98 |
|
@@ -104,7 +90,6 @@ class DUP_DupArchive
|
|
104 |
return true;
|
105 |
}
|
106 |
|
107 |
-
DUP_LOG::trace("c12");
|
108 |
Dup_Log::TraceObject("buildprogress object", $buildProgress, false);
|
109 |
|
110 |
$scanReport = json_decode($json);
|
@@ -118,7 +103,6 @@ class DUP_DupArchive
|
|
118 |
$filterDirsFormat = rtrim(str_replace(';', "\n\t", $filterDirs));
|
119 |
$filterFilesFormat = rtrim(str_replace(';', "\n\t", $filterFiles));
|
120 |
|
121 |
-
DUP_LOG::trace("c13");
|
122 |
DUP_Log::info("\n********************************************************************************");
|
123 |
DUP_Log::info("ARCHIVE Type=DUP Mode=DupArchive");
|
124 |
DUP_Log::info("********************************************************************************");
|
@@ -128,7 +112,6 @@ class DUP_DupArchive
|
|
128 |
DUP_Log::Info("DIRS:\n\t{$filterDirsFormat}");
|
129 |
DUP_Log::Info("FILES:\n\t{$filterFilesFormat}");
|
130 |
DUP_Log::info("EXTS: {$filterExts}");
|
131 |
-
|
132 |
DUP_Log::info("----------------------------------------");
|
133 |
DUP_Log::info("COMPRESSING");
|
134 |
DUP_Log::info("SIZE:\t".$scanReport->ARC->Size);
|
@@ -138,7 +121,6 @@ class DUP_DupArchive
|
|
138 |
$error_message = 'Invalid Scan Report Detected';
|
139 |
|
140 |
DUP_Log::error($error_message, 'Invalid Scan Report Detected', Dup_ErrorBehavior::LogOnly);
|
141 |
-
//$buildProgress->failed = true;
|
142 |
$buildProgress->set_failed($error_message);
|
143 |
$package->setStatus(DUP_PackageStatus::ERROR);
|
144 |
return true;
|
@@ -153,33 +135,27 @@ class DUP_DupArchive
|
|
153 |
$error_message = 'Error adding database.sql to archive';
|
154 |
|
155 |
DUP_Log::error($error_message, $ex->getMessage(), Dup_ErrorBehavior::LogOnly);
|
156 |
-
//$buildProgress->failed = true;
|
157 |
$buildProgress->set_failed($error_message);
|
158 |
$package->setStatus(DUP_PackageStatus::ERROR);
|
159 |
return true;
|
160 |
}
|
161 |
|
162 |
$buildProgress->archive_started = true;
|
163 |
-
|
164 |
$buildProgress->retries = 0;
|
165 |
|
166 |
$createState = DUP_DupArchive_Create_State::createNew($archivePath, $compressDir, self::WorkerTimeInSec, true, true);
|
167 |
$createState->throttleDelayInUs = 0;
|
168 |
|
169 |
$createState->save();
|
170 |
-
|
171 |
$package->Update();
|
172 |
}
|
173 |
|
174 |
try {
|
175 |
-
|
176 |
-
DUP_LOG::trace("c14");
|
177 |
$createState = DUP_DupArchive_Create_State::get_instance();
|
178 |
|
179 |
if ($buildProgress->retries > 1) {
|
180 |
// Indicates it had problems before so move into robustness mode
|
181 |
$createState->isRobust = true;
|
182 |
-
|
183 |
$createState->save();
|
184 |
}
|
185 |
|
@@ -192,16 +168,12 @@ class DUP_DupArchive
|
|
192 |
$buildProgress->set_build_failures($createState->failures);
|
193 |
|
194 |
if ($createState->isCriticalFailurePresent()) {
|
195 |
-
|
196 |
throw new Exception($createState->getFailureSummary());
|
197 |
}
|
198 |
|
199 |
$totalFileCount = count($scanReport->ARC->Files);
|
200 |
-
|
201 |
$package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::ARCSTART, DUP_PackageStatus::ARCVALIDATION, $totalFileCount, $createState->currentFileIndex);
|
202 |
-
|
203 |
$buildProgress->retries = 0;
|
204 |
-
|
205 |
$createState->save();
|
206 |
|
207 |
DUP_LOG::TraceObject("Stored Create State", $createState);
|
@@ -215,7 +187,6 @@ class DUP_DupArchive
|
|
215 |
}
|
216 |
}
|
217 |
catch (Exception $ex) {
|
218 |
-
DUP_LOG::trace("c15");
|
219 |
$message = __('Problem adding items to archive.', 'duplicator').' '.$ex->getMessage();
|
220 |
|
221 |
DUP_Log::error(__('Problems adding items to archive.', 'duplicator'), $message, Dup_ErrorBehavior::LogOnly);
|
@@ -226,15 +197,11 @@ class DUP_DupArchive
|
|
226 |
return true;
|
227 |
}
|
228 |
|
229 |
-
DUP_LOG::trace("c16");
|
230 |
-
|
231 |
//-- Final Wrapup of the Archive
|
232 |
if ((!$skipArchiveFinalization) && ($createState->working == false)) {
|
233 |
|
234 |
DUP_LOG::Trace("Create state is not working and not skip archive finalization");
|
235 |
|
236 |
-
DUP_LOG::trace("c17");
|
237 |
-
|
238 |
if (!$buildProgress->installer_built) {
|
239 |
|
240 |
if ($package->Installer->build($package, false)) {
|
@@ -247,10 +214,6 @@ class DUP_DupArchive
|
|
247 |
return;
|
248 |
}
|
249 |
|
250 |
-
|
251 |
-
|
252 |
-
//rsr todo need this somewhere $package->buildCleanup();
|
253 |
-
|
254 |
DUP_Log::Trace("Installer has been built so running expand now");
|
255 |
|
256 |
$expandState = DUP_DupArchive_Expand_State::getInstance(true);
|
@@ -274,25 +237,19 @@ class DUP_DupArchive
|
|
274 |
DUP_LOG::traceObject("EXPAND STATE AFTER SAVE", $expandState);
|
275 |
} else {
|
276 |
|
277 |
-
DUP_LOG::trace("c18");
|
278 |
try {
|
279 |
|
280 |
$expandState = DUP_DupArchive_Expand_State::getInstance();
|
281 |
|
282 |
if ($buildProgress->retries > 1) {
|
283 |
-
|
284 |
// Indicates it had problems before so move into robustness mode
|
285 |
$expandState->isRobust = true;
|
286 |
-
|
287 |
$expandState->save();
|
288 |
}
|
289 |
|
290 |
DUP_Log::traceObject('Resumed validation expand state', $expandState);
|
291 |
-
|
292 |
DupArchiveEngine::expandArchive($expandState);
|
293 |
-
|
294 |
$buildProgress->set_validation_failures($expandState->failures);
|
295 |
-
|
296 |
$totalFileCount = count($scanReport->ARC->Files);
|
297 |
$archiveSize = @filesize($expandState->archivePath);
|
298 |
|
@@ -303,30 +260,21 @@ class DUP_DupArchive
|
|
303 |
}
|
304 |
catch (Exception $ex) {
|
305 |
DUP_Log::Trace('Exception:'.$ex->getMessage().':'.$ex->getTraceAsString());
|
306 |
-
//$buildProgress->failed = true;
|
307 |
$buildProgress->set_failed('Error validating archive');
|
308 |
$package->setStatus(DUP_PackageStatus::ERROR);
|
309 |
return true;
|
310 |
}
|
311 |
|
312 |
if ($expandState->isCriticalFailurePresent()) {
|
313 |
-
DUP_LOG::trace("c20");
|
314 |
// Fail immediately if critical failure present - even if havent completed processing the entire archive.
|
315 |
-
|
316 |
$error_message = __('Critical failure present in validation', 'duplicator');
|
317 |
-
|
318 |
DUP_Log::error($error_message, $expandState->getFailureSummary(), Dup_ErrorBehavior::LogOnly);
|
319 |
-
|
320 |
-
//$buildProgress->failed = true;
|
321 |
$buildProgress->set_failed($error_message);
|
322 |
return true;
|
323 |
} else if (!$expandState->working) {
|
324 |
-
DUP_LOG::trace("c21");
|
325 |
|
326 |
$buildProgress->archive_built = true;
|
327 |
$buildProgress->retries = 0;
|
328 |
-
|
329 |
-
// rsr todo is this required?
|
330 |
$package->update();
|
331 |
|
332 |
$timerAllEnd = DUP_Util::getMicrotime();
|
@@ -342,15 +290,10 @@ class DUP_DupArchive
|
|
342 |
DUP_Log::info("VALIDATION WARNINGS: ".$expandState->getFailureSummary(false, true));
|
343 |
|
344 |
$archive->file_count = $expandState->fileWriteCount + $expandState->directoryWriteCount;
|
345 |
-
|
346 |
$package->update();
|
347 |
-
|
348 |
-
DUP_LOG::trace("c22");
|
349 |
$done = true;
|
350 |
} else {
|
351 |
-
DUP_LOG::trace("c23");
|
352 |
$expandState->save();
|
353 |
-
DUP_LOG::trace("c24");
|
354 |
}
|
355 |
}
|
356 |
}
|
1 |
<?php
|
2 |
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
|
|
|
|
|
4 |
require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/duparchive/class.pack.archive.duparchive.state.expand.php');
|
5 |
require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/duparchive/class.pack.archive.duparchive.state.create.php');
|
6 |
require_once (DUPLICATOR_PLUGIN_PATH.'lib/dup_archive/classes/class.duparchive.loggerbase.php');
|
35 |
DUP_LOG::trace("start");
|
36 |
try {
|
37 |
DUP_Log::Open($package->NameHash);
|
|
|
38 |
|
39 |
if ($buildProgress->retries > DUPLICATOR_MAX_BUILD_RETRIES) {
|
|
|
40 |
$error_msg = __('Package build appears stuck so marking package as failed. Is the Max Worker Time set too high?.', 'duplicator');
|
41 |
DUP_Log::error(esc_html__('Build Failure', 'duplicator'), esc_html($error_msg), Dup_ErrorBehavior::LogOnly);
|
42 |
//$buildProgress->failed = true;
|
45 |
;
|
46 |
return true;
|
47 |
} else {
|
|
|
48 |
// If all goes well retries will be reset to 0 at the end of this function.
|
49 |
$buildProgress->retries++;
|
50 |
$package->update();
|
52 |
|
53 |
$done = false;
|
54 |
|
|
|
55 |
DupArchiveEngine::init(new DUP_DupArchive_Logger(), null, $archive);
|
|
|
|
|
56 |
DUP_Package::safeTmpCleanup(true);
|
57 |
|
58 |
$compressDir = rtrim(DUP_Util::safePath($archive->PackDir), '/');
|
59 |
$sqlPath = DUP_Settings::getSsdirTmpPath()."/{$package->Database->File}";
|
60 |
$archivePath = DUP_Settings::getSsdirTmpPath()."/{$archive->File}";
|
61 |
$scanFilepath = DUP_Settings::getSsdirTmpPath()."/{$package->NameHash}_scan.json";
|
|
|
|
|
62 |
$skipArchiveFinalization = false;
|
63 |
$json = '';
|
64 |
|
|
|
65 |
if (file_exists($scanFilepath)) {
|
66 |
|
|
|
67 |
$json = file_get_contents($scanFilepath);
|
68 |
|
69 |
if (empty($json)) {
|
|
|
70 |
$errorText = __("Scan file $scanFilepath is empty!", 'duplicator');
|
71 |
$fixText = __("Click on \"Resolve This\" button to fix the JSON settings.", 'duplicator');
|
72 |
|
79 |
return true;
|
80 |
}
|
81 |
} else {
|
|
|
82 |
DUP_Log::trace("**** scan file $scanFilepath doesn't exist!!");
|
83 |
$errorMessage = sprintf(__("ERROR: Can't find Scanfile %s. Please ensure there no non-English characters in the package or schedule name.", 'duplicator'), $scanFilepath);
|
84 |
|
90 |
return true;
|
91 |
}
|
92 |
|
|
|
93 |
Dup_Log::TraceObject("buildprogress object", $buildProgress, false);
|
94 |
|
95 |
$scanReport = json_decode($json);
|
103 |
$filterDirsFormat = rtrim(str_replace(';', "\n\t", $filterDirs));
|
104 |
$filterFilesFormat = rtrim(str_replace(';', "\n\t", $filterFiles));
|
105 |
|
|
|
106 |
DUP_Log::info("\n********************************************************************************");
|
107 |
DUP_Log::info("ARCHIVE Type=DUP Mode=DupArchive");
|
108 |
DUP_Log::info("********************************************************************************");
|
112 |
DUP_Log::Info("DIRS:\n\t{$filterDirsFormat}");
|
113 |
DUP_Log::Info("FILES:\n\t{$filterFilesFormat}");
|
114 |
DUP_Log::info("EXTS: {$filterExts}");
|
|
|
115 |
DUP_Log::info("----------------------------------------");
|
116 |
DUP_Log::info("COMPRESSING");
|
117 |
DUP_Log::info("SIZE:\t".$scanReport->ARC->Size);
|
121 |
$error_message = 'Invalid Scan Report Detected';
|
122 |
|
123 |
DUP_Log::error($error_message, 'Invalid Scan Report Detected', Dup_ErrorBehavior::LogOnly);
|
|
|
124 |
$buildProgress->set_failed($error_message);
|
125 |
$package->setStatus(DUP_PackageStatus::ERROR);
|
126 |
return true;
|
135 |
$error_message = 'Error adding database.sql to archive';
|
136 |
|
137 |
DUP_Log::error($error_message, $ex->getMessage(), Dup_ErrorBehavior::LogOnly);
|
|
|
138 |
$buildProgress->set_failed($error_message);
|
139 |
$package->setStatus(DUP_PackageStatus::ERROR);
|
140 |
return true;
|
141 |
}
|
142 |
|
143 |
$buildProgress->archive_started = true;
|
|
|
144 |
$buildProgress->retries = 0;
|
145 |
|
146 |
$createState = DUP_DupArchive_Create_State::createNew($archivePath, $compressDir, self::WorkerTimeInSec, true, true);
|
147 |
$createState->throttleDelayInUs = 0;
|
148 |
|
149 |
$createState->save();
|
|
|
150 |
$package->Update();
|
151 |
}
|
152 |
|
153 |
try {
|
|
|
|
|
154 |
$createState = DUP_DupArchive_Create_State::get_instance();
|
155 |
|
156 |
if ($buildProgress->retries > 1) {
|
157 |
// Indicates it had problems before so move into robustness mode
|
158 |
$createState->isRobust = true;
|
|
|
159 |
$createState->save();
|
160 |
}
|
161 |
|
168 |
$buildProgress->set_build_failures($createState->failures);
|
169 |
|
170 |
if ($createState->isCriticalFailurePresent()) {
|
|
|
171 |
throw new Exception($createState->getFailureSummary());
|
172 |
}
|
173 |
|
174 |
$totalFileCount = count($scanReport->ARC->Files);
|
|
|
175 |
$package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::ARCSTART, DUP_PackageStatus::ARCVALIDATION, $totalFileCount, $createState->currentFileIndex);
|
|
|
176 |
$buildProgress->retries = 0;
|
|
|
177 |
$createState->save();
|
178 |
|
179 |
DUP_LOG::TraceObject("Stored Create State", $createState);
|
187 |
}
|
188 |
}
|
189 |
catch (Exception $ex) {
|
|
|
190 |
$message = __('Problem adding items to archive.', 'duplicator').' '.$ex->getMessage();
|
191 |
|
192 |
DUP_Log::error(__('Problems adding items to archive.', 'duplicator'), $message, Dup_ErrorBehavior::LogOnly);
|
197 |
return true;
|
198 |
}
|
199 |
|
|
|
|
|
200 |
//-- Final Wrapup of the Archive
|
201 |
if ((!$skipArchiveFinalization) && ($createState->working == false)) {
|
202 |
|
203 |
DUP_LOG::Trace("Create state is not working and not skip archive finalization");
|
204 |
|
|
|
|
|
205 |
if (!$buildProgress->installer_built) {
|
206 |
|
207 |
if ($package->Installer->build($package, false)) {
|
214 |
return;
|
215 |
}
|
216 |
|
|
|
|
|
|
|
|
|
217 |
DUP_Log::Trace("Installer has been built so running expand now");
|
218 |
|
219 |
$expandState = DUP_DupArchive_Expand_State::getInstance(true);
|
237 |
DUP_LOG::traceObject("EXPAND STATE AFTER SAVE", $expandState);
|
238 |
} else {
|
239 |
|
|
|
240 |
try {
|
241 |
|
242 |
$expandState = DUP_DupArchive_Expand_State::getInstance();
|
243 |
|
244 |
if ($buildProgress->retries > 1) {
|
|
|
245 |
// Indicates it had problems before so move into robustness mode
|
246 |
$expandState->isRobust = true;
|
|
|
247 |
$expandState->save();
|
248 |
}
|
249 |
|
250 |
DUP_Log::traceObject('Resumed validation expand state', $expandState);
|
|
|
251 |
DupArchiveEngine::expandArchive($expandState);
|
|
|
252 |
$buildProgress->set_validation_failures($expandState->failures);
|
|
|
253 |
$totalFileCount = count($scanReport->ARC->Files);
|
254 |
$archiveSize = @filesize($expandState->archivePath);
|
255 |
|
260 |
}
|
261 |
catch (Exception $ex) {
|
262 |
DUP_Log::Trace('Exception:'.$ex->getMessage().':'.$ex->getTraceAsString());
|
|
|
263 |
$buildProgress->set_failed('Error validating archive');
|
264 |
$package->setStatus(DUP_PackageStatus::ERROR);
|
265 |
return true;
|
266 |
}
|
267 |
|
268 |
if ($expandState->isCriticalFailurePresent()) {
|
|
|
269 |
// Fail immediately if critical failure present - even if havent completed processing the entire archive.
|
|
|
270 |
$error_message = __('Critical failure present in validation', 'duplicator');
|
|
|
271 |
DUP_Log::error($error_message, $expandState->getFailureSummary(), Dup_ErrorBehavior::LogOnly);
|
|
|
|
|
272 |
$buildProgress->set_failed($error_message);
|
273 |
return true;
|
274 |
} else if (!$expandState->working) {
|
|
|
275 |
|
276 |
$buildProgress->archive_built = true;
|
277 |
$buildProgress->retries = 0;
|
|
|
|
|
278 |
$package->update();
|
279 |
|
280 |
$timerAllEnd = DUP_Util::getMicrotime();
|
290 |
DUP_Log::info("VALIDATION WARNINGS: ".$expandState->getFailureSummary(false, true));
|
291 |
|
292 |
$archive->file_count = $expandState->fileWriteCount + $expandState->directoryWriteCount;
|
|
|
293 |
$package->update();
|
|
|
|
|
294 |
$done = true;
|
295 |
} else {
|
|
|
296 |
$expandState->save();
|
|
|
297 |
}
|
298 |
}
|
299 |
}
|
classes/utilities/class.u.php
CHANGED
@@ -1,860 +1,860 @@
|
|
1 |
-
<?php
|
2 |
-
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Recursivly scans a directory and finds all sym-links and unreadable files
|
6 |
-
*
|
7 |
-
* Standard: PSR-2
|
8 |
-
* @link http://www.php-fig.org/psr/psr-2
|
9 |
-
*
|
10 |
-
* @package Duplicator
|
11 |
-
* @subpackage classes/utilities
|
12 |
-
* @copyright (c) 2017, Snapcreek LLC
|
13 |
-
*
|
14 |
-
* @todo Refactor out IO methods into class.io.php file
|
15 |
-
*/
|
16 |
-
class DUP_Util
|
17 |
-
{
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Is PHP 5.2.9 or better running
|
21 |
-
*/
|
22 |
-
public static $on_php_529_plus;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Is PHP 5.3 or better running
|
26 |
-
*/
|
27 |
-
public static $on_php_53_plus;
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Is PHP 5.4 or better running
|
31 |
-
*/
|
32 |
-
public static $on_php_54_plus;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Is PHP 7 or better running
|
36 |
-
*/
|
37 |
-
public static $PHP7_plus;
|
38 |
-
|
39 |
-
/**
|
40 |
-
* array of ini disable functions
|
41 |
-
*
|
42 |
-
* @var array
|
43 |
-
*/
|
44 |
-
private static $iniDisableFuncs = null;
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Initialized on load (see end of file)
|
48 |
-
*/
|
49 |
-
public static function init()
|
50 |
-
{
|
51 |
-
self::$on_php_529_plus = version_compare(PHP_VERSION, '5.2.9') >= 0;
|
52 |
-
self::$on_php_53_plus = version_compare(PHP_VERSION, '5.3.0') >= 0;
|
53 |
-
self::$on_php_54_plus = version_compare(PHP_VERSION, '5.4.0') >= 0;
|
54 |
-
self::$PHP7_plus = version_compare(PHP_VERSION, '7.0.0', '>=');
|
55 |
-
}
|
56 |
-
|
57 |
-
public static function getArchitectureString()
|
58 |
-
{
|
59 |
-
$php_int_size = PHP_INT_SIZE;
|
60 |
-
|
61 |
-
switch ($php_int_size) {
|
62 |
-
case 4:
|
63 |
-
return esc_html__('32-bit', 'duplicator');
|
64 |
-
break;
|
65 |
-
case 8:
|
66 |
-
return esc_html__('64-bit', 'duplicator');
|
67 |
-
break;
|
68 |
-
default:
|
69 |
-
return esc_html__('Unknown', 'duplicator');
|
70 |
-
}
|
71 |
-
}
|
72 |
-
|
73 |
-
public static function objectCopy($srcObject, $destObject, $skipMemberArray = null)
|
74 |
-
{
|
75 |
-
foreach ($srcObject as $member_name => $member_value) {
|
76 |
-
if (!is_object($member_value) && (($skipMemberArray == null) || !in_array($member_name, $skipMemberArray))) {
|
77 |
-
// Skipping all object members
|
78 |
-
$destObject->$member_name = $member_value;
|
79 |
-
}
|
80 |
-
}
|
81 |
-
}
|
82 |
-
|
83 |
-
public static function getWPCoreDirs()
|
84 |
-
{
|
85 |
-
$wp_core_dirs = array(get_home_path().'wp-admin', get_home_path().'wp-includes');
|
86 |
-
|
87 |
-
//if wp_content is overrided
|
88 |
-
$wp_path = get_home_path()."wp-content";
|
89 |
-
if (get_home_path().'wp-content' != WP_CONTENT_DIR) {
|
90 |
-
$wp_path = WP_CONTENT_DIR;
|
91 |
-
}
|
92 |
-
$wp_path = str_replace("\\", "/", $wp_path);
|
93 |
-
|
94 |
-
$wp_core_dirs[] = $wp_path;
|
95 |
-
$wp_core_dirs[] = $wp_path.'/plugins';
|
96 |
-
$wp_core_dirs[] = $wp_path.'/themes';
|
97 |
-
|
98 |
-
return $wp_core_dirs;
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* return absolute path for the files that are core directories
|
103 |
-
* @return string array
|
104 |
-
*/
|
105 |
-
public static function getWPCoreFiles()
|
106 |
-
{
|
107 |
-
$wp_cored_dirs = array(get_home_path().'wp-config.php');
|
108 |
-
return $wp_cored_dirs;
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Groups an array into arrays by a given key, or set of keys, shared between all array members.
|
113 |
-
*
|
114 |
-
* Based on {@author Jake Zatecky}'s {@link https://github.com/jakezatecky/array_group_by array_group_by()} function.
|
115 |
-
* This variant allows $key to be closures.
|
116 |
-
*
|
117 |
-
* @param array $array The array to have grouping performed on.
|
118 |
-
* @param mixed $key,... The key to group or split by. Can be a _string_, an _integer_, a _float_, or a _callable_.
|
119 |
-
* - If the key is a callback, it must return a valid key from the array.
|
120 |
-
* - If the key is _NULL_, the iterated element is skipped.
|
121 |
-
* - string|oink callback ( mixed $item )
|
122 |
-
*
|
123 |
-
* @return array|null Returns a multidimensional array or `null` if `$key` is invalid.
|
124 |
-
*/
|
125 |
-
public static function array_group_by(array $array, $key)
|
126 |
-
{
|
127 |
-
if (!is_string($key) && !is_int($key) && !is_float($key) && !is_callable($key)) {
|
128 |
-
trigger_error('array_group_by(): The key should be a string, an integer, or a callback', E_USER_ERROR);
|
129 |
-
return null;
|
130 |
-
}
|
131 |
-
$func = (!is_string($key) && is_callable($key) ? $key : null);
|
132 |
-
$_key = $key;
|
133 |
-
// Load the new array, splitting by the target key
|
134 |
-
$grouped = array();
|
135 |
-
foreach ($array as $value) {
|
136 |
-
$key = null;
|
137 |
-
if (is_callable($func)) {
|
138 |
-
$key = call_user_func($func, $value);
|
139 |
-
} elseif (is_object($value) && isset($value->{$_key})) {
|
140 |
-
$key = $value->{$_key};
|
141 |
-
} elseif (isset($value[$_key])) {
|
142 |
-
$key = $value[$_key];
|
143 |
-
}
|
144 |
-
if ($key === null) {
|
145 |
-
continue;
|
146 |
-
}
|
147 |
-
$grouped[$key][] = $value;
|
148 |
-
}
|
149 |
-
// Recursively build a nested grouping if more parameters are supplied
|
150 |
-
// Each grouped array value is grouped according to the next sequential key
|
151 |
-
if (func_num_args() > 2) {
|
152 |
-
$args = func_get_args();
|
153 |
-
foreach ($grouped as $key => $value) {
|
154 |
-
$params = array_merge(array($value), array_slice($args, 2, func_num_args()));
|
155 |
-
$grouped[$key] = call_user_func_array('DUP_Util::array_group_by', $params);
|
156 |
-
}
|
157 |
-
}
|
158 |
-
return $grouped;
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* PHP_SAPI for FCGI requires a data flush of at least 256
|
163 |
-
* bytes every 40 seconds or else it forces a script halt
|
164 |
-
*
|
165 |
-
* @return string A series of 256 space characters
|
166 |
-
*/
|
167 |
-
public static function fcgiFlush()
|
168 |
-
{
|
169 |
-
echo(str_repeat(' ', 300));
|
170 |
-
@flush();
|
171 |
-
@ob_flush();
|
172 |
-
}
|
173 |
-
|
174 |
-
public static function isWpDebug()
|
175 |
-
{
|
176 |
-
return defined('WP_DEBUG') && WP_DEBUG;
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Returns the last N lines of a file. Equivalent to tail command
|
181 |
-
*
|
182 |
-
* @param string $filepath The full path to the file to be tailed
|
183 |
-
* @param int $lines The number of lines to return with each tail call
|
184 |
-
*
|
185 |
-
* @return string The last N parts of the file
|
186 |
-
*/
|
187 |
-
public static function tailFile($filepath, $lines = 2)
|
188 |
-
{
|
189 |
-
// Open file
|
190 |
-
$f = @fopen($filepath, "rb");
|
191 |
-
if ($f === false)
|
192 |
-
return false;
|
193 |
-
|
194 |
-
// Sets buffer size
|
195 |
-
$buffer = 256;
|
196 |
-
|
197 |
-
// Jump to last character
|
198 |
-
fseek($f, -1, SEEK_END);
|
199 |
-
|
200 |
-
// Read it and adjust line number if necessary
|
201 |
-
// (Otherwise the result would be wrong if file doesn't end with a blank line)
|
202 |
-
if (fread($f, 1) != "\n")
|
203 |
-
$lines -= 1;
|
204 |
-
|
205 |
-
// Start reading
|
206 |
-
$output = '';
|
207 |
-
$chunk = '';
|
208 |
-
|
209 |
-
// While we would like more
|
210 |
-
while (ftell($f) > 0 && $lines >= 0) {
|
211 |
-
// Figure out how far back we should jump
|
212 |
-
$seek = min(ftell($f), $buffer);
|
213 |
-
// Do the jump (backwards, relative to where we are)
|
214 |
-
fseek($f, -$seek, SEEK_CUR);
|
215 |
-
// Read a chunk and prepend it to our output
|
216 |
-
$output = ($chunk = fread($f, $seek)).$output;
|
217 |
-
// Jump back to where we started reading
|
218 |
-
fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
|
219 |
-
// Decrease our line counter
|
220 |
-
$lines -= substr_count($chunk, "\n");
|
221 |
-
}
|
222 |
-
|
223 |
-
// While we have too many lines
|
224 |
-
// (Because of buffer size we might have read too many)
|
225 |
-
while ($lines++ < 0) {
|
226 |
-
// Find first newline and remove all text before that
|
227 |
-
$output = substr($output, strpos($output, "\n") + 1);
|
228 |
-
}
|
229 |
-
fclose($f);
|
230 |
-
return trim($output);
|
231 |
-
}
|
232 |
-
|
233 |
-
/**
|
234 |
-
* Display human readable byte sizes
|
235 |
-
*
|
236 |
-
* @param int $size The size in bytes
|
237 |
-
*
|
238 |
-
* @return string The size of bytes readable such as 100KB, 20MB, 1GB etc.
|
239 |
-
*/
|
240 |
-
public static function byteSize($size, $roundBy = 2)
|
241 |
-
{
|
242 |
-
try {
|
243 |
-
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
244 |
-
for ($i = 0; $size >= 1024 && $i < 4; $i++) {
|
245 |
-
$size /= 1024;
|
246 |
-
}
|
247 |
-
return round($size, $roundBy).$units[$i];
|
248 |
-
}
|
249 |
-
catch (Exception $e) {
|
250 |
-
return "n/a";
|
251 |
-
}
|
252 |
-
}
|
253 |
-
|
254 |
-
/**
|
255 |
-
* Makes path safe for any OS
|
256 |
-
* Paths should ALWAYS READ be "/"
|
257 |
-
* uni: /home/path/file.txt
|
258 |
-
* win: D:/home/path/file.txt
|
259 |
-
*
|
260 |
-
* @param string $path The path to make safe
|
261 |
-
*
|
262 |
-
* @return string A path with all slashes facing "/"
|
263 |
-
*/
|
264 |
-
public static function safePath($path)
|
265 |
-
{
|
266 |
-
return str_replace("\\", "/", $path);
|
267 |
-
}
|
268 |
-
|
269 |
-
/**
|
270 |
-
* Get current microtime as a float. Method is used for simple profiling
|
271 |
-
*
|
272 |
-
* @see elapsedTime
|
273 |
-
*
|
274 |
-
* @return string A float in the form "msec sec", where sec is the number of seconds since the Unix epoch
|
275 |
-
*/
|
276 |
-
public static function getMicrotime()
|
277 |
-
{
|
278 |
-
return microtime(true);
|
279 |
-
}
|
280 |
-
|
281 |
-
/**
|
282 |
-
* Append the value to the string if it doesn't already exist
|
283 |
-
*
|
284 |
-
* @param string $string The string to append to
|
285 |
-
* @param string $value The string to append to the $string
|
286 |
-
*
|
287 |
-
* @return string Returns the string with the $value appended once
|
288 |
-
*/
|
289 |
-
public static function appendOnce($string, $value)
|
290 |
-
{
|
291 |
-
return $string.(substr($string, -1) == $value ? '' : $value);
|
292 |
-
}
|
293 |
-
|
294 |
-
/**
|
295 |
-
* Return a string with the elapsed time
|
296 |
-
*
|
297 |
-
* @see getMicrotime()
|
298 |
-
*
|
299 |
-
* @param mixed number $end The final time in the sequence to measure
|
300 |
-
* @param mixed number $start The start time in the sequence to measure
|
301 |
-
*
|
302 |
-
* @return string The time elapsed from $start to $end
|
303 |
-
*/
|
304 |
-
public static function elapsedTime($end, $start)
|
305 |
-
{
|
306 |
-
return sprintf("%.2f sec.", abs($end - $start));
|
307 |
-
}
|
308 |
-
|
309 |
-
/**
|
310 |
-
* List all of the files of a path
|
311 |
-
*
|
312 |
-
* @param string $path The full path to a system directory
|
313 |
-
*
|
314 |
-
* @return array of all files in that path
|
315 |
-
*
|
316 |
-
* Notes:
|
317 |
-
* - Avoid using glob() as GLOB_BRACE is not an option on some operating systems
|
318 |
-
* - Pre PHP 5.3 DirectoryIterator will crash on unreadable files
|
319 |
-
* - Scandir will not crash on unreadable items, but will not return results
|
320 |
-
*/
|
321 |
-
public static function listFiles($path = '.')
|
322 |
-
{
|
323 |
-
try {
|
324 |
-
$files = array();
|
325 |
-
if ($dh = opendir($path)) {
|
326 |
-
while (($file = readdir($dh)) !== false) {
|
327 |
-
if ($file == '.' || $file == '..')
|
328 |
-
continue;
|
329 |
-
$full_file_path = trailingslashit($path).$file;
|
330 |
-
$files[] = str_replace("\\", '/', $full_file_path);
|
331 |
-
}
|
332 |
-
@closedir($dh);
|
333 |
-
}
|
334 |
-
return $files;
|
335 |
-
}
|
336 |
-
catch (Exception $exc) {
|
337 |
-
$result = array();
|
338 |
-
$files = @scandir($path);
|
339 |
-
if (is_array($files)) {
|
340 |
-
foreach ($files as $file) {
|
341 |
-
$result[] = str_replace("\\", '/', $path).$file;
|
342 |
-
}
|
343 |
-
}
|
344 |
-
return $result;
|
345 |
-
}
|
346 |
-
}
|
347 |
-
|
348 |
-
/**
|
349 |
-
* List all of the directories of a path
|
350 |
-
*
|
351 |
-
* @param string $path The full path to a system directory
|
352 |
-
*
|
353 |
-
* @return array of all dirs in the $path
|
354 |
-
*/
|
355 |
-
public static function listDirs($path = '.')
|
356 |
-
{
|
357 |
-
$dirs = array();
|
358 |
-
|
359 |
-
foreach (new DirectoryIterator($path) as $file) {
|
360 |
-
if ($file->isDir() && !$file->isDot()) {
|
361 |
-
$dirs[] = DUP_Util::safePath($file->getPathname());
|
362 |
-
}
|
363 |
-
}
|
364 |
-
return $dirs;
|
365 |
-
}
|
366 |
-
|
367 |
-
/**
|
368 |
-
* Does the directory have content
|
369 |
-
*
|
370 |
-
* @param string $path The full path to a system directory
|
371 |
-
*
|
372 |
-
* @return bool Returns true if directory is empty
|
373 |
-
*/
|
374 |
-
public static function isDirectoryEmpty($path)
|
375 |
-
{
|
376 |
-
if (!is_readable($path))
|
377 |
-
return NULL;
|
378 |
-
return (count(scandir($path)) == 2);
|
379 |
-
}
|
380 |
-
|
381 |
-
/**
|
382 |
-
* Size of the directory recursively in bytes
|
383 |
-
*
|
384 |
-
* @param string $path The full path to a system directory
|
385 |
-
*
|
386 |
-
* @return int Returns the size of the directory in bytes
|
387 |
-
*
|
388 |
-
*/
|
389 |
-
public static function getDirectorySize($path)
|
390 |
-
{
|
391 |
-
if (!file_exists($path))
|
392 |
-
return 0;
|
393 |
-
if (is_file($path))
|
394 |
-
return filesize($path);
|
395 |
-
|
396 |
-
$size = 0;
|
397 |
-
$list = glob($path."/*");
|
398 |
-
if (!empty($list)) {
|
399 |
-
foreach ($list as $file)
|
400 |
-
$size += self::getDirectorySize($file);
|
401 |
-
}
|
402 |
-
return $size;
|
403 |
-
}
|
404 |
-
|
405 |
-
/**
|
406 |
-
* Can shell_exec be called on this server
|
407 |
-
*
|
408 |
-
* @return bool Returns true if shell_exec can be called on server
|
409 |
-
*
|
410 |
-
*/
|
411 |
-
public static function hasShellExec()
|
412 |
-
{
|
413 |
-
$cmds = array('shell_exec', 'escapeshellarg', 'escapeshellcmd', 'extension_loaded');
|
414 |
-
|
415 |
-
//Function disabled at server level
|
416 |
-
if (array_intersect($cmds, array_map('trim', explode(',', @ini_get('disable_functions')))))
|
417 |
-
return apply_filters('duplicator_is_shellzip_available', false);
|
418 |
-
|
419 |
-
//Suhosin: http://www.hardened-php.net/suhosin/
|
420 |
-
//Will cause PHP to silently fail
|
421 |
-
if (extension_loaded('suhosin')) {
|
422 |
-
$suhosin_ini = @ini_get("suhosin.executor.func.blacklist");
|
423 |
-
if (array_intersect($cmds, array_map('trim', explode(',', $suhosin_ini))))
|
424 |
-
return apply_filters('duplicator_is_shellzip_available', false);
|
425 |
-
}
|
426 |
-
|
427 |
-
if (! function_exists('shell_exec')) {
|
428 |
-
return apply_filters('duplicator_is_shellzip_available', false);
|
429 |
-
}
|
430 |
-
|
431 |
-
// Can we issue a simple echo command?
|
432 |
-
if (!@shell_exec('echo duplicator'))
|
433 |
-
return apply_filters('duplicator_is_shellzip_available', false);
|
434 |
-
|
435 |
-
return apply_filters('duplicator_is_shellzip_available', true);
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* Is the server running Windows operating system
|
440 |
-
*
|
441 |
-
* @return bool Returns true if operating system is Windows
|
442 |
-
*
|
443 |
-
*/
|
444 |
-
public static function isWindows()
|
445 |
-
{
|
446 |
-
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
447 |
-
return true;
|
448 |
-
}
|
449 |
-
return false;
|
450 |
-
}
|
451 |
-
|
452 |
-
/**
|
453 |
-
* Wrap to prevent malware scanners from reporting false/positive
|
454 |
-
* Switched from our old method to avoid WordFence reporting a false positive
|
455 |
-
*
|
456 |
-
* @param string $string The string to decrypt i.e. base64_decode
|
457 |
-
*
|
458 |
-
* @return string Returns the string base64 decoded
|
459 |
-
*/
|
460 |
-
public static function installerUnscramble($string)
|
461 |
-
{
|
462 |
-
return base64_decode($string);
|
463 |
-
}
|
464 |
-
|
465 |
-
/**
|
466 |
-
* Wrap to prevent malware scanners from reporting false/positive
|
467 |
-
* Switched from our old method to avoid WordFence reporting a false positive
|
468 |
-
*
|
469 |
-
* @param string $string The string to decrypt i.e. base64_encode
|
470 |
-
*
|
471 |
-
* @return string Returns the string base64 encode
|
472 |
-
*/
|
473 |
-
public static function installerScramble($string)
|
474 |
-
{
|
475 |
-
return base64_encode($string);
|
476 |
-
}
|
477 |
-
const SECURE_ISSUE_DIE = 'die';
|
478 |
-
const SECURE_ISSUE_THROW = 'throw';
|
479 |
-
const SECURE_ISSUE_RETURN = 'return';
|
480 |
-
|
481 |
-
/**
|
482 |
-
* Does the current user have the capability
|
483 |
-
*
|
484 |
-
* @param type $permission
|
485 |
-
* @param type $exit // SECURE_ISSUE_DIE die script with die function
|
486 |
-
* SECURE_ISSUE_THROW throw an exception if fail
|
487 |
-
* SECURE_ISSUE_RETURN return false if fail
|
488 |
-
*
|
489 |
-
* @return boolean // return false is fail and $exit is SECURE_ISSUE_THROW
|
490 |
-
* // true if success
|
491 |
-
*
|
492 |
-
* @throws Exception // thow exception if $exit is SECURE_ISSUE_THROW
|
493 |
-
*/
|
494 |
-
public static function hasCapability($permission = 'read', $exit = self::SECURE_ISSUE_DIE)
|
495 |
-
{
|
496 |
-
$capability = apply_filters('wpfront_user_role_editor_duplicator_translate_capability', $permission);
|
497 |
-
|
498 |
-
if (!current_user_can($capability)) {
|
499 |
-
$exitMsg = __('You do not have sufficient permissions to access this page.', 'duplicator');
|
500 |
-
DUP_LOG::Trace('You do not have sufficient permissions to access this page. PERMISSION: '.$permission);
|
501 |
-
|
502 |
-
switch ($exit) {
|
503 |
-
case self::SECURE_ISSUE_THROW:
|
504 |
-
throw new Exception($exitMsg);
|
505 |
-
case self::SECURE_ISSUE_RETURN:
|
506 |
-
return false;
|
507 |
-
case self::SECURE_ISSUE_DIE:
|
508 |
-
default:
|
509 |
-
wp_die($exitMsg);
|
510 |
-
}
|
511 |
-
}
|
512 |
-
return true;
|
513 |
-
}
|
514 |
-
|
515 |
-
/**
|
516 |
-
* Gets the name of the owner of the current PHP script
|
517 |
-
*
|
518 |
-
* @return string The name of the owner of the current PHP script
|
519 |
-
*/
|
520 |
-
public static function getCurrentUser()
|
521 |
-
{
|
522 |
-
$unreadable = 'Undetectable';
|
523 |
-
if (function_exists('get_current_user') && is_callable('get_current_user')) {
|
524 |
-
$user = get_current_user();
|
525 |
-
return strlen($user) ? $user : $unreadable;
|
526 |
-
}
|
527 |
-
return $unreadable;
|
528 |
-
}
|
529 |
-
|
530 |
-
/**
|
531 |
-
* Gets the owner of the PHP process
|
532 |
-
*
|
533 |
-
* @return string Gets the owner of the PHP process
|
534 |
-
*/
|
535 |
-
public static function getProcessOwner()
|
536 |
-
{
|
537 |
-
$unreadable = 'Undetectable';
|
538 |
-
$user = '';
|
539 |
-
try {
|
540 |
-
if (function_exists('exec')) {
|
541 |
-
$user = @exec('whoami');
|
542 |
-
}
|
543 |
-
|
544 |
-
if (!strlen($user) && function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
|
545 |
-
$user = posix_getpwuid(posix_geteuid());
|
546 |
-
$user = $user['name'];
|
547 |
-
}
|
548 |
-
|
549 |
-
return strlen($user) ? $user : $unreadable;
|
550 |
-
}
|
551 |
-
catch (Exception $ex) {
|
552 |
-
return $unreadable;
|
553 |
-
}
|
554 |
-
}
|
555 |
-
|
556 |
-
/**
|
557 |
-
* Creates the snapshot directory if it doesn't already exist
|
558 |
-
*
|
559 |
-
* @return bool
|
560 |
-
*/
|
561 |
-
public static function initSnapshotDirectory()
|
562 |
-
{
|
563 |
-
$error = false;
|
564 |
-
|
565 |
-
$path_wproot = duplicator_get_abs_path();
|
566 |
-
$path_ssdir = DUP_Settings::getSsdirPath();
|
567 |
-
$path_plugin = DUP_Util::safePath(DUPLICATOR_PLUGIN_PATH);
|
568 |
-
|
569 |
-
if (!file_exists($path_ssdir)) {
|
570 |
-
$old_root_perm = @fileperms($path_wproot);
|
571 |
-
|
572 |
-
//--------------------------------
|
573 |
-
//CHMOD DIRECTORY ACCESS
|
574 |
-
//wordpress root directory
|
575 |
-
DupLiteSnapLibIOU::chmod($path_wproot, 'u+rwx');
|
576 |
-
|
577 |
-
//snapshot directory
|
578 |
-
if (DupLiteSnapLibIOU::dirWriteCheckOrMkdir($path_ssdir, 'u+rwx,go+rx') == false) {
|
579 |
-
$error = true;
|
580 |
-
}
|
581 |
-
|
582 |
-
// restore original root perms
|
583 |
-
DupLiteSnapLibIOU::chmod($path_wproot, $old_root_perm);
|
584 |
-
|
585 |
-
if ($error) {
|
586 |
-
return false;
|
587 |
-
}
|
588 |
-
}
|
589 |
-
|
590 |
-
DupLiteSnapLibIOU::chmod($path_ssdir, 'u+rwx,go+rx');
|
591 |
-
|
592 |
-
DupLiteSnapLibIOU::dirWriteCheckOrMkdir(DUP_Settings::getSsdirTmpPath(), 'u+rwx');
|
593 |
-
|
594 |
-
//plugins dir/files
|
595 |
-
DupLiteSnapLibIOU::dirWriteCheckOrMkdir($path_plugin.'files', 'u+rwx');
|
596 |
-
|
597 |
-
//--------------------------------
|
598 |
-
//FILE CREATION
|
599 |
-
//SSDIR: Create Index File
|
600 |
-
$fileName = $path_ssdir.'/index.php';
|
601 |
-
if (!file_exists($fileName)) {
|
602 |
-
$ssfile = @fopen($fileName, 'w');
|
603 |
-
@fwrite($ssfile,
|
604 |
-
'<?php error_reporting(0); if (stristr(php_sapi_name(), "fcgi")) { $url = "http://" . $_SERVER["HTTP_HOST"]; header("Location: {$url}/404.html");} else { header("HTTP/1.1 404 Not Found", true, 404);} exit(); ?>');
|
605 |
-
@fclose($ssfile);
|
606 |
-
}
|
607 |
-
|
608 |
-
//SSDIR: Create .htaccess
|
609 |
-
$storage_htaccess_off = DUP_Settings::Get('storage_htaccess_off');
|
610 |
-
$fileName = $path_ssdir.'/.htaccess';
|
611 |
-
if ($storage_htaccess_off) {
|
612 |
-
@unlink($fileName);
|
613 |
-
} else if (!file_exists($fileName)) {
|
614 |
-
$htfile = @fopen($fileName, 'w');
|
615 |
-
$htoutput = "Options -Indexes";
|
616 |
-
@fwrite($htfile, $htoutput);
|
617 |
-
@fclose($htfile);
|
618 |
-
}
|
619 |
-
|
620 |
-
//SSDIR: Robots.txt file
|
621 |
-
$fileName = $path_ssdir.'/robots.txt';
|
622 |
-
if (!file_exists($fileName)) {
|
623 |
-
$robotfile = @fopen($fileName, 'w');
|
624 |
-
@fwrite($robotfile,
|
625 |
-
"User-agent: * \n"
|
626 |
-
."Disallow: /".DUP_Settings::SSDIR_NAME_LEGACY."/\n"
|
627 |
-
."Disallow: /".DUP_Settings::SSDIR_NAME_NEW."/");
|
628 |
-
@fclose($robotfile);
|
629 |
-
}
|
630 |
-
|
631 |
-
return true;
|
632 |
-
}
|
633 |
-
|
634 |
-
/**
|
635 |
-
* Attempts to get the file zip path on a users system
|
636 |
-
*
|
637 |
-
* @return null
|
638 |
-
*/
|
639 |
-
public static function getZipPath()
|
640 |
-
{
|
641 |
-
$filepath = null;
|
642 |
-
|
643 |
-
if (self::hasShellExec()) {
|
644 |
-
if (shell_exec('hash zip 2>&1') == NULL) {
|
645 |
-
$filepath = 'zip';
|
646 |
-
} else {
|
647 |
-
$possible_paths = array(
|
648 |
-
'/usr/bin/zip',
|
649 |
-
'/opt/local/bin/zip'
|
650 |
-
//'C:/Program\ Files\ (x86)/GnuWin32/bin/zip.exe');
|
651 |
-
);
|
652 |
-
|
653 |
-
foreach ($possible_paths as $path) {
|
654 |
-
if (@file_exists($path)) {
|
655 |
-
$filepath = $path;
|
656 |
-
break;
|
657 |
-
}
|
658 |
-
}
|
659 |
-
}
|
660 |
-
}
|
661 |
-
|
662 |
-
return $filepath;
|
663 |
-
}
|
664 |
-
|
665 |
-
/**
|
666 |
-
* Is the server PHP 5.3 or better
|
667 |
-
*
|
668 |
-
* @return bool Returns true if the server PHP 5.3 or better
|
669 |
-
*/
|
670 |
-
public static function PHP53()
|
671 |
-
{
|
672 |
-
return version_compare(PHP_VERSION, '5.3.2', '>=');
|
673 |
-
}
|
674 |
-
|
675 |
-
/**
|
676 |
-
* Returns an array of the WordPress core tables.
|
677 |
-
*
|
678 |
-
* @return array Returns all WP core tables
|
679 |
-
*/
|
680 |
-
public static function getWPCoreTables()
|
681 |
-
{
|
682 |
-
global $wpdb;
|
683 |
-
$result = array();
|
684 |
-
foreach (self::getWPCoreTablesEnd() as $tend) {
|
685 |
-
$result[] = $wpdb->prefix.$tend;
|
686 |
-
}
|
687 |
-
return $result;
|
688 |
-
}
|
689 |
-
|
690 |
-
public static function getWPCoreTablesEnd()
|
691 |
-
{
|
692 |
-
return array(
|
693 |
-
'commentmeta',
|
694 |
-
'comments',
|
695 |
-
'links',
|
696 |
-
'options',
|
697 |
-
'postmeta',
|
698 |
-
'posts',
|
699 |
-
'term_relationships',
|
700 |
-
'term_taxonomy',
|
701 |
-
'termmeta',
|
702 |
-
'terms',
|
703 |
-
'usermeta',
|
704 |
-
'blogs',
|
705 |
-
'blog_versions',
|
706 |
-
'blogmeta',
|
707 |
-
'users',
|
708 |
-
'site',
|
709 |
-
'sitemeta',
|
710 |
-
'signups',
|
711 |
-
'registration_log',
|
712 |
-
'blog_versions');
|
713 |
-
}
|
714 |
-
|
715 |
-
public static function isWPCoreTable($table)
|
716 |
-
{
|
717 |
-
global $wpdb;
|
718 |
-
|
719 |
-
if (strpos($table, $wpdb->prefix) !== 0) {
|
720 |
-
return false;
|
721 |
-
}
|
722 |
-
|
723 |
-
$subTName = substr($table, strlen($wpdb->prefix));
|
724 |
-
$coreEnds = self::getWPCoreTablesEnd();
|
725 |
-
|
726 |
-
if (in_array($subTName, $coreEnds)) {
|
727 |
-
return true;
|
728 |
-
} else if (is_multisite()) {
|
729 |
-
$exTable = explode('_', $subTName);
|
730 |
-
if (count($exTable) >= 2 && is_numeric($exTable[0])) {
|
731 |
-
$tChekc = implode('_', array_slice($exTable, 1));
|
732 |
-
if (get_blog_details((int) $exTable[0], false) !== false && in_array($tChekc, $coreEnds)) {
|
733 |
-
return true;
|
734 |
-
}
|
735 |
-
}
|
736 |
-
}
|
737 |
-
|
738 |
-
return false;
|
739 |
-
}
|
740 |
-
|
741 |
-
public static function getWPBlogIdTable($table)
|
742 |
-
{
|
743 |
-
global $wpdb;
|
744 |
-
|
745 |
-
if (!is_multisite() || strpos($table, $wpdb->prefix) !== 0) {
|
746 |
-
return 0;
|
747 |
-
}
|
748 |
-
|
749 |
-
$subTName = substr($table, strlen($wpdb->prefix));
|
750 |
-
$exTable = explode('_', $subTName);
|
751 |
-
if (count($exTable) >= 2 && is_numeric($exTable[0]) && get_blog_details((int) $exTable[0], false) !== false) {
|
752 |
-
return (int) $exTable[0];
|
753 |
-
} else {
|
754 |
-
return 0;
|
755 |
-
}
|
756 |
-
}
|
757 |
-
|
758 |
-
/**
|
759 |
-
* Check given table is exist in real
|
760 |
-
*
|
761 |
-
* @param $table string Table name
|
762 |
-
* @return booleam
|
763 |
-
*/
|
764 |
-
public static function isTableExists($table)
|
765 |
-
{
|
766 |
-
// It will clear the $GLOBALS['wpdb']->last_error var
|
767 |
-
$GLOBALS['wpdb']->flush();
|
768 |
-
$sql = "SELECT 1 FROM `".esc_sql($table)."` LIMIT 1;";
|
769 |
-
$ret = $GLOBALS['wpdb']->get_var($sql);
|
770 |
-
if (empty($GLOBALS['wpdb']->last_error))
|
771 |
-
return true;
|
772 |
-
return false;
|
773 |
-
}
|
774 |
-
|
775 |
-
/**
|
776 |
-
* Finds if its a valid executable or not
|
777 |
-
*
|
778 |
-
* @param type $exe A non zero length executable path to find if that is executable or not.
|
779 |
-
* @param type $expectedValue expected value for the result
|
780 |
-
* @return boolean
|
781 |
-
*/
|
782 |
-
public static function isExecutable($cmd)
|
783 |
-
{
|
784 |
-
if (strlen($cmd) < 1)
|
785 |
-
return false;
|
786 |
-
|
787 |
-
if (@is_executable($cmd)) {
|
788 |
-
return true;
|
789 |
-
}
|
790 |
-
|
791 |
-
$output = shell_exec($cmd);
|
792 |
-
if (!is_null($output)) {
|
793 |
-
return true;
|
794 |
-
}
|
795 |
-
|
796 |
-
$output = shell_exec($cmd.' -?');
|
797 |
-
if (!is_null($output)) {
|
798 |
-
return true;
|
799 |
-
}
|
800 |
-
|
801 |
-
return false;
|
802 |
-
}
|
803 |
-
|
804 |
-
/**
|
805 |
-
* Display human readable byte sizes
|
806 |
-
*
|
807 |
-
* @param string $size The size in bytes
|
808 |
-
*
|
809 |
-
* @return string Human readable bytes such as 50MB, 1GB
|
810 |
-
*/
|
811 |
-
public static function readableByteSize($size)
|
812 |
-
{
|
813 |
-
try {
|
814 |
-
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
815 |
-
for ($i = 0; $size >= 1024 && $i < 4; $i++)
|
816 |
-
$size /= 1024;
|
817 |
-
return round($size, 2).$units[$i];
|
818 |
-
}
|
819 |
-
catch (Exception $e) {
|
820 |
-
return "n/a";
|
821 |
-
}
|
822 |
-
}
|
823 |
-
|
824 |
-
public static function getTablePrefix()
|
825 |
-
{
|
826 |
-
global $wpdb;
|
827 |
-
$tablePrefix = (is_multisite() && is_plugin_active_for_network('duplicator/duplicator.php')) ? $wpdb->base_prefix : $wpdb->prefix;
|
828 |
-
return $tablePrefix;
|
829 |
-
}
|
830 |
-
|
831 |
-
/**
|
832 |
-
* return ini disable functions array
|
833 |
-
*
|
834 |
-
* @return array
|
835 |
-
*/
|
836 |
-
public static function getIniDisableFuncs()
|
837 |
-
{
|
838 |
-
if (is_null(self::$iniDisableFuncs)) {
|
839 |
-
$tmpFuncs = ini_get('disable_functions');
|
840 |
-
$tmpFuncs = explode(',', $tmpFuncs);
|
841 |
-
self::$iniDisableFuncs = array();
|
842 |
-
foreach ($tmpFuncs as $cFunc) {
|
843 |
-
self::$iniDisableFuncs[] = trim($cFunc);
|
844 |
-
}
|
845 |
-
}
|
846 |
-
|
847 |
-
return self::$iniDisableFuncs;
|
848 |
-
}
|
849 |
-
|
850 |
-
/**
|
851 |
-
* Check if function exists and isn't in ini disable_functions
|
852 |
-
*
|
853 |
-
* @param string $function_name
|
854 |
-
* @return bool
|
855 |
-
*/
|
856 |
-
public static function isIniFunctionEnalbe($function_name)
|
857 |
-
{
|
858 |
-
return function_exists($function_name) && !in_array($function_name, self::getIniDisableFuncs());
|
859 |
-
}
|
860 |
}
|
1 |
+
<?php
|
2 |
+
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Recursivly scans a directory and finds all sym-links and unreadable files
|
6 |
+
*
|
7 |
+
* Standard: PSR-2
|
8 |
+
* @link http://www.php-fig.org/psr/psr-2
|
9 |
+
*
|
10 |
+
* @package Duplicator
|
11 |
+
* @subpackage classes/utilities
|
12 |
+
* @copyright (c) 2017, Snapcreek LLC
|
13 |
+
*
|
14 |
+
* @todo Refactor out IO methods into class.io.php file
|
15 |
+
*/
|
16 |
+
class DUP_Util
|
17 |
+
{
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Is PHP 5.2.9 or better running
|
21 |
+
*/
|
22 |
+
public static $on_php_529_plus;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Is PHP 5.3 or better running
|
26 |
+
*/
|
27 |
+
public static $on_php_53_plus;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Is PHP 5.4 or better running
|
31 |
+
*/
|
32 |
+
public static $on_php_54_plus;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Is PHP 7 or better running
|
36 |
+
*/
|
37 |
+
public static $PHP7_plus;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* array of ini disable functions
|
41 |
+
*
|
42 |
+
* @var array
|
43 |
+
*/
|
44 |
+
private static $iniDisableFuncs = null;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Initialized on load (see end of file)
|
48 |
+
*/
|
49 |
+
public static function init()
|
50 |
+
{
|
51 |
+
self::$on_php_529_plus = version_compare(PHP_VERSION, '5.2.9') >= 0;
|
52 |
+
self::$on_php_53_plus = version_compare(PHP_VERSION, '5.3.0') >= 0;
|
53 |
+
self::$on_php_54_plus = version_compare(PHP_VERSION, '5.4.0') >= 0;
|
54 |
+
self::$PHP7_plus = version_compare(PHP_VERSION, '7.0.0', '>=');
|
55 |
+
}
|
56 |
+
|
57 |
+
public static function getArchitectureString()
|
58 |
+
{
|
59 |
+
$php_int_size = PHP_INT_SIZE;
|
60 |
+
|
61 |
+
switch ($php_int_size) {
|
62 |
+
case 4:
|
63 |
+
return esc_html__('32-bit', 'duplicator');
|
64 |
+
break;
|
65 |
+
case 8:
|
66 |
+
return esc_html__('64-bit', 'duplicator');
|
67 |
+
break;
|
68 |
+
default:
|
69 |
+
return esc_html__('Unknown', 'duplicator');
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
public static function objectCopy($srcObject, $destObject, $skipMemberArray = null)
|
74 |
+
{
|
75 |
+
foreach ($srcObject as $member_name => $member_value) {
|
76 |
+
if (!is_object($member_value) && (($skipMemberArray == null) || !in_array($member_name, $skipMemberArray))) {
|
77 |
+
// Skipping all object members
|
78 |
+
$destObject->$member_name = $member_value;
|
79 |
+
}
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
public static function getWPCoreDirs()
|
84 |
+
{
|
85 |
+
$wp_core_dirs = array(get_home_path().'wp-admin', get_home_path().'wp-includes');
|
86 |
+
|
87 |
+
//if wp_content is overrided
|
88 |
+
$wp_path = get_home_path()."wp-content";
|
89 |
+
if (get_home_path().'wp-content' != WP_CONTENT_DIR) {
|
90 |
+
$wp_path = WP_CONTENT_DIR;
|
91 |
+
}
|
92 |
+
$wp_path = str_replace("\\", "/", $wp_path);
|
93 |
+
|
94 |
+
$wp_core_dirs[] = $wp_path;
|
95 |
+
$wp_core_dirs[] = $wp_path.'/plugins';
|
96 |
+
$wp_core_dirs[] = $wp_path.'/themes';
|
97 |
+
|
98 |
+
return $wp_core_dirs;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* return absolute path for the files that are core directories
|
103 |
+
* @return string array
|
104 |
+
*/
|
105 |
+
public static function getWPCoreFiles()
|
106 |
+
{
|
107 |
+
$wp_cored_dirs = array(get_home_path().'wp-config.php');
|
108 |
+
return $wp_cored_dirs;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Groups an array into arrays by a given key, or set of keys, shared between all array members.
|
113 |
+
*
|
114 |
+
* Based on {@author Jake Zatecky}'s {@link https://github.com/jakezatecky/array_group_by array_group_by()} function.
|
115 |
+
* This variant allows $key to be closures.
|
116 |
+
*
|
117 |
+
* @param array $array The array to have grouping performed on.
|
118 |
+
* @param mixed $key,... The key to group or split by. Can be a _string_, an _integer_, a _float_, or a _callable_.
|
119 |
+
* - If the key is a callback, it must return a valid key from the array.
|
120 |
+
* - If the key is _NULL_, the iterated element is skipped.
|
121 |
+
* - string|oink callback ( mixed $item )
|
122 |
+
*
|
123 |
+
* @return array|null Returns a multidimensional array or `null` if `$key` is invalid.
|
124 |
+
*/
|
125 |
+
public static function array_group_by(array $array, $key)
|
126 |
+
{
|
127 |
+
if (!is_string($key) && !is_int($key) && !is_float($key) && !is_callable($key)) {
|
128 |
+
trigger_error('array_group_by(): The key should be a string, an integer, or a callback', E_USER_ERROR);
|
129 |
+
return null;
|
130 |
+
}
|
131 |
+
$func = (!is_string($key) && is_callable($key) ? $key : null);
|
132 |
+
$_key = $key;
|
133 |
+
// Load the new array, splitting by the target key
|
134 |
+
$grouped = array();
|
135 |
+
foreach ($array as $value) {
|
136 |
+
$key = null;
|
137 |
+
if (is_callable($func)) {
|
138 |
+
$key = call_user_func($func, $value);
|
139 |
+
} elseif (is_object($value) && isset($value->{$_key})) {
|
140 |
+
$key = $value->{$_key};
|
141 |
+
} elseif (isset($value[$_key])) {
|
142 |
+
$key = $value[$_key];
|
143 |
+
}
|
144 |
+
if ($key === null) {
|
145 |
+
continue;
|
146 |
+
}
|
147 |
+
$grouped[$key][] = $value;
|
148 |
+
}
|
149 |
+
// Recursively build a nested grouping if more parameters are supplied
|
150 |
+
// Each grouped array value is grouped according to the next sequential key
|
151 |
+
if (func_num_args() > 2) {
|
152 |
+
$args = func_get_args();
|
153 |
+
foreach ($grouped as $key => $value) {
|
154 |
+
$params = array_merge(array($value), array_slice($args, 2, func_num_args()));
|
155 |
+
$grouped[$key] = call_user_func_array('DUP_Util::array_group_by', $params);
|
156 |
+
}
|
157 |
+
}
|
158 |
+
return $grouped;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* PHP_SAPI for FCGI requires a data flush of at least 256
|
163 |
+
* bytes every 40 seconds or else it forces a script halt
|
164 |
+
*
|
165 |
+
* @return string A series of 256 space characters
|
166 |
+
*/
|
167 |
+
public static function fcgiFlush()
|
168 |
+
{
|
169 |
+
echo(str_repeat(' ', 300));
|
170 |
+
@flush();
|
171 |
+
@ob_flush();
|
172 |
+
}
|
173 |
+
|
174 |
+
public static function isWpDebug()
|
175 |
+
{
|
176 |
+
return defined('WP_DEBUG') && WP_DEBUG;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Returns the last N lines of a file. Equivalent to tail command
|
181 |
+
*
|
182 |
+
* @param string $filepath The full path to the file to be tailed
|
183 |
+
* @param int $lines The number of lines to return with each tail call
|
184 |
+
*
|
185 |
+
* @return string The last N parts of the file
|
186 |
+
*/
|
187 |
+
public static function tailFile($filepath, $lines = 2)
|
188 |
+
{
|
189 |
+
// Open file
|
190 |
+
$f = @fopen($filepath, "rb");
|
191 |
+
if ($f === false)
|
192 |
+
return false;
|
193 |
+
|
194 |
+
// Sets buffer size
|
195 |
+
$buffer = 256;
|
196 |
+
|
197 |
+
// Jump to last character
|
198 |
+
fseek($f, -1, SEEK_END);
|
199 |
+
|
200 |
+
// Read it and adjust line number if necessary
|
201 |
+
// (Otherwise the result would be wrong if file doesn't end with a blank line)
|
202 |
+
if (fread($f, 1) != "\n")
|
203 |
+
$lines -= 1;
|
204 |
+
|
205 |
+
// Start reading
|
206 |
+
$output = '';
|
207 |
+
$chunk = '';
|
208 |
+
|
209 |
+
// While we would like more
|
210 |
+
while (ftell($f) > 0 && $lines >= 0) {
|
211 |
+
// Figure out how far back we should jump
|
212 |
+
$seek = min(ftell($f), $buffer);
|
213 |
+
// Do the jump (backwards, relative to where we are)
|
214 |
+
fseek($f, -$seek, SEEK_CUR);
|
215 |
+
// Read a chunk and prepend it to our output
|
216 |
+
$output = ($chunk = fread($f, $seek)).$output;
|
217 |
+
// Jump back to where we started reading
|
218 |
+
fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
|
219 |
+
// Decrease our line counter
|
220 |
+
$lines -= substr_count($chunk, "\n");
|
221 |
+
}
|
222 |
+
|
223 |
+
// While we have too many lines
|
224 |
+
// (Because of buffer size we might have read too many)
|
225 |
+
while ($lines++ < 0) {
|
226 |
+
// Find first newline and remove all text before that
|
227 |
+
$output = substr($output, strpos($output, "\n") + 1);
|
228 |
+
}
|
229 |
+
fclose($f);
|
230 |
+
return trim($output);
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Display human readable byte sizes
|
235 |
+
*
|
236 |
+
* @param int $size The size in bytes
|
237 |
+
*
|
238 |
+
* @return string The size of bytes readable such as 100KB, 20MB, 1GB etc.
|
239 |
+
*/
|
240 |
+
public static function byteSize($size, $roundBy = 2)
|
241 |
+
{
|
242 |
+
try {
|
243 |
+
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
244 |
+
for ($i = 0; $size >= 1024 && $i < 4; $i++) {
|
245 |
+
$size /= 1024;
|
246 |
+
}
|
247 |
+
return round($size, $roundBy).$units[$i];
|
248 |
+
}
|
249 |
+
catch (Exception $e) {
|
250 |
+
return "n/a";
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Makes path safe for any OS
|
256 |
+
* Paths should ALWAYS READ be "/"
|
257 |
+
* uni: /home/path/file.txt
|
258 |
+
* win: D:/home/path/file.txt
|
259 |
+
*
|
260 |
+
* @param string $path The path to make safe
|
261 |
+
*
|
262 |
+
* @return string A path with all slashes facing "/"
|
263 |
+
*/
|
264 |
+
public static function safePath($path)
|
265 |
+
{
|
266 |
+
return str_replace("\\", "/", $path);
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Get current microtime as a float. Method is used for simple profiling
|
271 |
+
*
|
272 |
+
* @see elapsedTime
|
273 |
+
*
|
274 |
+
* @return string A float in the form "msec sec", where sec is the number of seconds since the Unix epoch
|
275 |
+
*/
|
276 |
+
public static function getMicrotime()
|
277 |
+
{
|
278 |
+
return microtime(true);
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Append the value to the string if it doesn't already exist
|
283 |
+
*
|
284 |
+
* @param string $string The string to append to
|
285 |
+
* @param string $value The string to append to the $string
|
286 |
+
*
|
287 |
+
* @return string Returns the string with the $value appended once
|
288 |
+
*/
|
289 |
+
public static function appendOnce($string, $value)
|
290 |
+
{
|
291 |
+
return $string.(substr($string, -1) == $value ? '' : $value);
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Return a string with the elapsed time
|
296 |
+
*
|
297 |
+
* @see getMicrotime()
|
298 |
+
*
|
299 |
+
* @param mixed number $end The final time in the sequence to measure
|
300 |
+
* @param mixed number $start The start time in the sequence to measure
|
301 |
+
*
|
302 |
+
* @return string The time elapsed from $start to $end
|
303 |
+
*/
|
304 |
+
public static function elapsedTime($end, $start)
|
305 |
+
{
|
306 |
+
return sprintf("%.2f sec.", abs($end - $start));
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* List all of the files of a path
|
311 |
+
*
|
312 |
+
* @param string $path The full path to a system directory
|
313 |
+
*
|
314 |
+
* @return array of all files in that path
|
315 |
+
*
|
316 |
+
* Notes:
|
317 |
+
* - Avoid using glob() as GLOB_BRACE is not an option on some operating systems
|
318 |
+
* - Pre PHP 5.3 DirectoryIterator will crash on unreadable files
|
319 |
+
* - Scandir will not crash on unreadable items, but will not return results
|
320 |
+
*/
|
321 |
+
public static function listFiles($path = '.')
|
322 |
+
{
|
323 |
+
try {
|
324 |
+
$files = array();
|
325 |
+
if ($dh = opendir($path)) {
|
326 |
+
while (($file = readdir($dh)) !== false) {
|
327 |
+
if ($file == '.' || $file == '..')
|
328 |
+
continue;
|
329 |
+
$full_file_path = trailingslashit($path).$file;
|
330 |
+
$files[] = str_replace("\\", '/', $full_file_path);
|
331 |
+
}
|
332 |
+
@closedir($dh);
|
333 |
+
}
|
334 |
+
return $files;
|
335 |
+
}
|
336 |
+
catch (Exception $exc) {
|
337 |
+
$result = array();
|
338 |
+
$files = @scandir($path);
|
339 |
+
if (is_array($files)) {
|
340 |
+
foreach ($files as $file) {
|
341 |
+
$result[] = str_replace("\\", '/', $path).$file;
|
342 |
+
}
|
343 |
+
}
|
344 |
+
return $result;
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* List all of the directories of a path
|
350 |
+
*
|
351 |
+
* @param string $path The full path to a system directory
|
352 |
+
*
|
353 |
+
* @return array of all dirs in the $path
|
354 |
+
*/
|
355 |
+
public static function listDirs($path = '.')
|
356 |
+
{
|
357 |
+
$dirs = array();
|
358 |
+
|
359 |
+
foreach (new DirectoryIterator($path) as $file) {
|
360 |
+
if ($file->isDir() && !$file->isDot()) {
|
361 |
+
$dirs[] = DUP_Util::safePath($file->getPathname());
|
362 |
+
}
|
363 |
+
}
|
364 |
+
return $dirs;
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Does the directory have content
|
369 |
+
*
|
370 |
+
* @param string $path The full path to a system directory
|
371 |
+
*
|
372 |
+
* @return bool Returns true if directory is empty
|
373 |
+
*/
|
374 |
+
public static function isDirectoryEmpty($path)
|
375 |
+
{
|
376 |
+
if (!is_readable($path))
|
377 |
+
return NULL;
|
378 |
+
return (count(scandir($path)) == 2);
|
379 |
+
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Size of the directory recursively in bytes
|
383 |
+
*
|
384 |
+
* @param string $path The full path to a system directory
|
385 |
+
*
|
386 |
+
* @return int Returns the size of the directory in bytes
|
387 |
+
*
|
388 |
+
*/
|
389 |
+
public static function getDirectorySize($path)
|
390 |
+
{
|
391 |
+
if (!file_exists($path))
|
392 |
+
return 0;
|
393 |
+
if (is_file($path))
|
394 |
+
return filesize($path);
|
395 |
+
|
396 |
+
$size = 0;
|
397 |
+
$list = glob($path."/*");
|
398 |
+
if (!empty($list)) {
|
399 |
+
foreach ($list as $file)
|
400 |
+
$size += self::getDirectorySize($file);
|
401 |
+
}
|
402 |
+
return $size;
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Can shell_exec be called on this server
|
407 |
+
*
|
408 |
+
* @return bool Returns true if shell_exec can be called on server
|
409 |
+
*
|
410 |
+
*/
|
411 |
+
public static function hasShellExec()
|
412 |
+
{
|
413 |
+
$cmds = array('shell_exec', 'escapeshellarg', 'escapeshellcmd', 'extension_loaded');
|
414 |
+
|
415 |
+
//Function disabled at server level
|
416 |
+
if (array_intersect($cmds, array_map('trim', explode(',', @ini_get('disable_functions')))))
|
417 |
+
return apply_filters('duplicator_is_shellzip_available', false);
|
418 |
+
|
419 |
+
//Suhosin: http://www.hardened-php.net/suhosin/
|
420 |
+
//Will cause PHP to silently fail
|
421 |
+
if (extension_loaded('suhosin')) {
|
422 |
+
$suhosin_ini = @ini_get("suhosin.executor.func.blacklist");
|
423 |
+
if (array_intersect($cmds, array_map('trim', explode(',', $suhosin_ini))))
|
424 |
+
return apply_filters('duplicator_is_shellzip_available', false);
|
425 |
+
}
|
426 |
+
|
427 |
+
if (! function_exists('shell_exec')) {
|
428 |
+
return apply_filters('duplicator_is_shellzip_available', false);
|
429 |
+
}
|
430 |
+
|
431 |
+
// Can we issue a simple echo command?
|
432 |
+
if (!@shell_exec('echo duplicator'))
|
433 |
+
return apply_filters('duplicator_is_shellzip_available', false);
|
434 |
+
|
435 |
+
return apply_filters('duplicator_is_shellzip_available', true);
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Is the server running Windows operating system
|
440 |
+
*
|
441 |
+
* @return bool Returns true if operating system is Windows
|
442 |
+
*
|
443 |
+
*/
|
444 |
+
public static function isWindows()
|
445 |
+
{
|
446 |
+
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
447 |
+
return true;
|
448 |
+
}
|
449 |
+
return false;
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* Wrap to prevent malware scanners from reporting false/positive
|
454 |
+
* Switched from our old method to avoid WordFence reporting a false positive
|
455 |
+
*
|
456 |
+
* @param string $string The string to decrypt i.e. base64_decode
|
457 |
+
*
|
458 |
+
* @return string Returns the string base64 decoded
|
459 |
+
*/
|
460 |
+
public static function installerUnscramble($string)
|
461 |
+
{
|
462 |
+
return base64_decode($string);
|
463 |
+
}
|
464 |
+
|
465 |
+
/**
|
466 |
+
* Wrap to prevent malware scanners from reporting false/positive
|
467 |
+
* Switched from our old method to avoid WordFence reporting a false positive
|
468 |
+
*
|
469 |
+
* @param string $string The string to decrypt i.e. base64_encode
|
470 |
+
*
|
471 |
+
* @return string Returns the string base64 encode
|
472 |
+
*/
|
473 |
+
public static function installerScramble($string)
|
474 |
+
{
|
475 |
+
return base64_encode($string);
|
476 |
+
}
|
477 |
+
const SECURE_ISSUE_DIE = 'die';
|
478 |
+
const SECURE_ISSUE_THROW = 'throw';
|
479 |
+
const SECURE_ISSUE_RETURN = 'return';
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Does the current user have the capability
|
483 |
+
*
|
484 |
+
* @param type $permission
|
485 |
+
* @param type $exit // SECURE_ISSUE_DIE die script with die function
|
486 |
+
* SECURE_ISSUE_THROW throw an exception if fail
|
487 |
+
* SECURE_ISSUE_RETURN return false if fail
|
488 |
+
*
|
489 |
+
* @return boolean // return false is fail and $exit is SECURE_ISSUE_THROW
|
490 |
+
* // true if success
|
491 |
+
*
|
492 |
+
* @throws Exception // thow exception if $exit is SECURE_ISSUE_THROW
|
493 |
+
*/
|
494 |
+
public static function hasCapability($permission = 'read', $exit = self::SECURE_ISSUE_DIE)
|
495 |
+
{
|
496 |
+
$capability = apply_filters('wpfront_user_role_editor_duplicator_translate_capability', $permission);
|
497 |
+
|
498 |
+
if (!current_user_can($capability)) {
|
499 |
+
$exitMsg = __('You do not have sufficient permissions to access this page.', 'duplicator');
|
500 |
+
DUP_LOG::Trace('You do not have sufficient permissions to access this page. PERMISSION: '.$permission);
|
501 |
+
|
502 |
+
switch ($exit) {
|
503 |
+
case self::SECURE_ISSUE_THROW:
|
504 |
+
throw new Exception($exitMsg);
|
505 |
+
case self::SECURE_ISSUE_RETURN:
|
506 |
+
return false;
|
507 |
+
case self::SECURE_ISSUE_DIE:
|
508 |
+
default:
|
509 |
+
wp_die($exitMsg);
|
510 |
+
}
|
511 |
+
}
|
512 |
+
return true;
|
513 |
+
}
|
514 |
+
|
515 |
+
/**
|
516 |
+
* Gets the name of the owner of the current PHP script
|
517 |
+
*
|
518 |
+
* @return string The name of the owner of the current PHP script
|
519 |
+
*/
|
520 |
+
public static function getCurrentUser()
|
521 |
+
{
|
522 |
+
$unreadable = 'Undetectable';
|
523 |
+
if (function_exists('get_current_user') && is_callable('get_current_user')) {
|
524 |
+
$user = get_current_user();
|
525 |
+
return strlen($user) ? $user : $unreadable;
|
526 |
+
}
|
527 |
+
return $unreadable;
|
528 |
+
}
|
529 |
+
|
530 |
+
/**
|
531 |
+
* Gets the owner of the PHP process
|
532 |
+
*
|
533 |
+
* @return string Gets the owner of the PHP process
|
534 |
+
*/
|
535 |
+
public static function getProcessOwner()
|
536 |
+
{
|
537 |
+
$unreadable = 'Undetectable';
|
538 |
+
$user = '';
|
539 |
+
try {
|
540 |
+
if (function_exists('exec')) {
|
541 |
+
$user = @exec('whoami');
|
542 |
+
}
|
543 |
+
|
544 |
+
if (!strlen($user) && function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
|
545 |
+
$user = posix_getpwuid(posix_geteuid());
|
546 |
+
$user = $user['name'];
|
547 |
+
}
|
548 |
+
|
549 |
+
return strlen($user) ? $user : $unreadable;
|
550 |
+
}
|
551 |
+
catch (Exception $ex) {
|
552 |
+
return $unreadable;
|
553 |
+
}
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Creates the snapshot directory if it doesn't already exist
|
558 |
+
*
|
559 |
+
* @return bool
|
560 |
+
*/
|
561 |
+
public static function initSnapshotDirectory()
|
562 |
+
{
|
563 |
+
$error = false;
|
564 |
+
|
565 |
+
$path_wproot = duplicator_get_abs_path();
|
566 |
+
$path_ssdir = DUP_Settings::getSsdirPath();
|
567 |
+
$path_plugin = DUP_Util::safePath(DUPLICATOR_PLUGIN_PATH);
|
568 |
+
|
569 |
+
if (!file_exists($path_ssdir)) {
|
570 |
+
$old_root_perm = @fileperms($path_wproot);
|
571 |
+
|
572 |
+
//--------------------------------
|
573 |
+
//CHMOD DIRECTORY ACCESS
|
574 |
+
//wordpress root directory
|
575 |
+
DupLiteSnapLibIOU::chmod($path_wproot, 'u+rwx');
|
576 |
+
|
577 |
+
//snapshot directory
|
578 |
+
if (DupLiteSnapLibIOU::dirWriteCheckOrMkdir($path_ssdir, 'u+rwx,go+rx') == false) {
|
579 |
+
$error = true;
|
580 |
+
}
|
581 |
+
|
582 |
+
// restore original root perms
|
583 |
+
DupLiteSnapLibIOU::chmod($path_wproot, $old_root_perm);
|
584 |
+
|
585 |
+
if ($error) {
|
586 |
+
return false;
|
587 |
+
}
|
588 |
+
}
|
589 |
+
|
590 |
+
DupLiteSnapLibIOU::chmod($path_ssdir, 'u+rwx,go+rx');
|
591 |
+
|
592 |
+
DupLiteSnapLibIOU::dirWriteCheckOrMkdir(DUP_Settings::getSsdirTmpPath(), 'u+rwx');
|
593 |
+
|
594 |
+
//plugins dir/files
|
595 |
+
DupLiteSnapLibIOU::dirWriteCheckOrMkdir($path_plugin.'files', 'u+rwx');
|
596 |
+
|
597 |
+
//--------------------------------
|
598 |
+
//FILE CREATION
|
599 |
+
//SSDIR: Create Index File
|
600 |
+
$fileName = $path_ssdir.'/index.php';
|
601 |
+
if (!file_exists($fileName)) {
|
602 |
+
$ssfile = @fopen($fileName, 'w');
|
603 |
+
@fwrite($ssfile,
|
604 |
+
'<?php error_reporting(0); if (stristr(php_sapi_name(), "fcgi")) { $url = "http://" . $_SERVER["HTTP_HOST"]; header("Location: {$url}/404.html");} else { header("HTTP/1.1 404 Not Found", true, 404);} exit(); ?>');
|
605 |
+
@fclose($ssfile);
|
606 |
+
}
|
607 |
+
|
608 |
+
//SSDIR: Create .htaccess
|
609 |
+
$storage_htaccess_off = DUP_Settings::Get('storage_htaccess_off');
|
610 |
+
$fileName = $path_ssdir.'/.htaccess';
|
611 |
+
if ($storage_htaccess_off) {
|
612 |
+
@unlink($fileName);
|
613 |
+
} else if (!file_exists($fileName)) {
|
614 |
+
$htfile = @fopen($fileName, 'w');
|
615 |
+
$htoutput = "Options -Indexes";
|
616 |
+
@fwrite($htfile, $htoutput);
|
617 |
+
@fclose($htfile);
|
618 |
+
}
|
619 |
+
|
620 |
+
//SSDIR: Robots.txt file
|
621 |
+
$fileName = $path_ssdir.'/robots.txt';
|
622 |
+
if (!file_exists($fileName)) {
|
623 |
+
$robotfile = @fopen($fileName, 'w');
|
624 |
+
@fwrite($robotfile,
|
625 |
+
"User-agent: * \n"
|
626 |
+
."Disallow: /".DUP_Settings::SSDIR_NAME_LEGACY."/\n"
|
627 |
+
."Disallow: /".DUP_Settings::SSDIR_NAME_NEW."/");
|
628 |
+
@fclose($robotfile);
|
629 |
+
}
|
630 |
+
|
631 |
+
return true;
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Attempts to get the file zip path on a users system
|
636 |
+
*
|
637 |
+
* @return null
|
638 |
+
*/
|
639 |
+
public static function getZipPath()
|
640 |
+
{
|
641 |
+
$filepath = null;
|
642 |
+
|
643 |
+
if (self::hasShellExec()) {
|
644 |
+
if (shell_exec('hash zip 2>&1') == NULL) {
|
645 |
+
$filepath = 'zip';
|
646 |
+
} else {
|
647 |
+
$possible_paths = array(
|
648 |
+
'/usr/bin/zip',
|
649 |
+
'/opt/local/bin/zip'
|
650 |
+
//'C:/Program\ Files\ (x86)/GnuWin32/bin/zip.exe');
|
651 |
+
);
|
652 |
+
|
653 |
+
foreach ($possible_paths as $path) {
|
654 |
+
if (@file_exists($path)) {
|
655 |
+
$filepath = $path;
|
656 |
+
break;
|
657 |
+
}
|
658 |
+
}
|
659 |
+
}
|
660 |
+
}
|
661 |
+
|
662 |
+
return $filepath;
|
663 |
+
}
|
664 |
+
|
665 |
+
/**
|
666 |
+
* Is the server PHP 5.3 or better
|
667 |
+
*
|
668 |
+
* @return bool Returns true if the server PHP 5.3 or better
|
669 |
+
*/
|
670 |
+
public static function PHP53()
|
671 |
+
{
|
672 |
+
return version_compare(PHP_VERSION, '5.3.2', '>=');
|
673 |
+
}
|
674 |
+
|
675 |
+
/**
|
676 |
+
* Returns an array of the WordPress core tables.
|
677 |
+
*
|
678 |
+
* @return array Returns all WP core tables
|
679 |
+
*/
|
680 |
+
public static function getWPCoreTables()
|
681 |
+
{
|
682 |
+
global $wpdb;
|
683 |
+
$result = array();
|
684 |
+
foreach (self::getWPCoreTablesEnd() as $tend) {
|
685 |
+
$result[] = $wpdb->prefix.$tend;
|
686 |
+
}
|
687 |
+
return $result;
|
688 |
+
}
|
689 |
+
|
690 |
+
public static function getWPCoreTablesEnd()
|
691 |
+
{
|
692 |
+
return array(
|
693 |
+
'commentmeta',
|
694 |
+
'comments',
|
695 |
+
'links',
|
696 |
+
'options',
|
697 |
+
'postmeta',
|
698 |
+
'posts',
|
699 |
+
'term_relationships',
|
700 |
+
'term_taxonomy',
|
701 |
+
'termmeta',
|
702 |
+
'terms',
|
703 |
+
'usermeta',
|
704 |
+
'blogs',
|
705 |
+
'blog_versions',
|
706 |
+
'blogmeta',
|
707 |
+
'users',
|
708 |
+
'site',
|
709 |
+
'sitemeta',
|
710 |
+
'signups',
|
711 |
+
'registration_log',
|
712 |
+
'blog_versions');
|
713 |
+
}
|
714 |
+
|
715 |
+
public static function isWPCoreTable($table)
|
716 |
+
{
|
717 |
+
global $wpdb;
|
718 |
+
|
719 |
+
if (strpos($table, $wpdb->prefix) !== 0) {
|
720 |
+
return false;
|
721 |
+
}
|
722 |
+
|
723 |
+
$subTName = substr($table, strlen($wpdb->prefix));
|
724 |
+
$coreEnds = self::getWPCoreTablesEnd();
|
725 |
+
|
726 |
+
if (in_array($subTName, $coreEnds)) {
|
727 |
+
return true;
|
728 |
+
} else if (is_multisite()) {
|
729 |
+
$exTable = explode('_', $subTName);
|
730 |
+
if (count($exTable) >= 2 && is_numeric($exTable[0])) {
|
731 |
+
$tChekc = implode('_', array_slice($exTable, 1));
|
732 |
+
if (get_blog_details((int) $exTable[0], false) !== false && in_array($tChekc, $coreEnds)) {
|
733 |
+
return true;
|
734 |
+
}
|
735 |
+
}
|
736 |
+
}
|
737 |
+
|
738 |
+
return false;
|
739 |
+
}
|
740 |
+
|
741 |
+
public static function getWPBlogIdTable($table)
|
742 |
+
{
|
743 |
+
global $wpdb;
|
744 |
+
|
745 |
+
if (!is_multisite() || strpos($table, $wpdb->prefix) !== 0) {
|
746 |
+
return 0;
|
747 |
+
}
|
748 |
+
|
749 |
+
$subTName = substr($table, strlen($wpdb->prefix));
|
750 |
+
$exTable = explode('_', $subTName);
|
751 |
+
if (count($exTable) >= 2 && is_numeric($exTable[0]) && get_blog_details((int) $exTable[0], false) !== false) {
|
752 |
+
return (int) $exTable[0];
|
753 |
+
} else {
|
754 |
+
return 0;
|
755 |
+
}
|
756 |
+
}
|
757 |
+
|
758 |
+
/**
|
759 |
+
* Check given table is exist in real
|
760 |
+
*
|
761 |
+
* @param $table string Table name
|
762 |
+
* @return booleam
|
763 |
+
*/
|
764 |
+
public static function isTableExists($table)
|
765 |
+
{
|
766 |
+
// It will clear the $GLOBALS['wpdb']->last_error var
|
767 |
+
$GLOBALS['wpdb']->flush();
|
768 |
+
$sql = "SELECT 1 FROM `".esc_sql($table)."` LIMIT 1;";
|
769 |
+
$ret = $GLOBALS['wpdb']->get_var($sql);
|
770 |
+
if (empty($GLOBALS['wpdb']->last_error))
|
771 |
+
return true;
|
772 |
+
return false;
|
773 |
+
}
|
774 |
+
|
775 |
+
/**
|
776 |
+
* Finds if its a valid executable or not
|
777 |
+
*
|
778 |
+
* @param type $exe A non zero length executable path to find if that is executable or not.
|
779 |
+
* @param type $expectedValue expected value for the result
|
780 |
+
* @return boolean
|
781 |
+
*/
|
782 |
+
public static function isExecutable($cmd)
|
783 |
+
{
|
784 |
+
if (strlen($cmd) < 1)
|
785 |
+
return false;
|
786 |
+
|
787 |
+
if (@is_executable($cmd)) {
|
788 |
+
return true;
|
789 |
+
}
|
790 |
+
|
791 |
+
$output = shell_exec($cmd);
|
792 |
+
if (!is_null($output)) {
|
793 |
+
return true;
|
794 |
+
}
|
795 |
+
|
796 |
+
$output = shell_exec($cmd.' -?');
|
797 |
+
if (!is_null($output)) {
|
798 |
+
return true;
|
799 |
+
}
|
800 |
+
|
801 |
+
return false;
|
802 |
+
}
|
803 |
+
|
804 |
+
/**
|
805 |
+
* Display human readable byte sizes
|
806 |
+
*
|
807 |
+
* @param string $size The size in bytes
|
808 |
+
*
|
809 |
+
* @return string Human readable bytes such as 50MB, 1GB
|
810 |
+
*/
|
811 |
+
public static function readableByteSize($size)
|
812 |
+
{
|
813 |
+
try {
|
814 |
+
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
815 |
+
for ($i = 0; $size >= 1024 && $i < 4; $i++)
|
816 |
+
$size /= 1024;
|
817 |
+
return round($size, 2).$units[$i];
|
818 |
+
}
|
819 |
+
catch (Exception $e) {
|
820 |
+
return "n/a";
|
821 |
+
}
|
822 |
+
}
|
823 |
+
|
824 |
+
public static function getTablePrefix()
|
825 |
+
{
|
826 |
+
global $wpdb;
|
827 |
+
$tablePrefix = (is_multisite() && is_plugin_active_for_network('duplicator/duplicator.php')) ? $wpdb->base_prefix : $wpdb->prefix;
|
828 |
+
return $tablePrefix;
|
829 |
+
}
|
830 |
+
|
831 |
+
/**
|
832 |
+
* return ini disable functions array
|
833 |
+
*
|
834 |
+
* @return array
|
835 |
+
*/
|
836 |
+
public static function getIniDisableFuncs()
|
837 |
+
{
|
838 |
+
if (is_null(self::$iniDisableFuncs)) {
|
839 |
+
$tmpFuncs = ini_get('disable_functions');
|
840 |
+
$tmpFuncs = explode(',', $tmpFuncs);
|
841 |
+
self::$iniDisableFuncs = array();
|
842 |
+
foreach ($tmpFuncs as $cFunc) {
|
843 |
+
self::$iniDisableFuncs[] = trim($cFunc);
|
844 |
+
}
|
845 |
+
}
|
846 |
+
|
847 |
+
return self::$iniDisableFuncs;
|
848 |
+
}
|
849 |
+
|
850 |
+
/**
|
851 |
+
* Check if function exists and isn't in ini disable_functions
|
852 |
+
*
|
853 |
+
* @param string $function_name
|
854 |
+
* @return bool
|
855 |
+
*/
|
856 |
+
public static function isIniFunctionEnalbe($function_name)
|
857 |
+
{
|
858 |
+
return function_exists($function_name) && !in_array($function_name, self::getIniDisableFuncs());
|
859 |
+
}
|
860 |
}
|
ctrls/class.web.services.php
CHANGED
@@ -92,7 +92,7 @@ class DUP_Web_Services
|
|
92 |
)
|
93 |
),
|
94 |
'hash' => array(
|
95 |
-
'filter' =>
|
96 |
'flags' => FILTER_REQUIRE_SCALAR,
|
97 |
'options' => array(
|
98 |
'default' => false
|
@@ -178,7 +178,7 @@ class DUP_Web_Services
|
|
178 |
throw new Exception('Security issue');
|
179 |
}
|
180 |
|
181 |
-
$notice_id = DupLiteSnapLibUtil::filterInputRequest('notice_id',
|
182 |
|
183 |
if (empty($notice_id)) {
|
184 |
throw new Exception(__('Invalid Request', 'duplicator'));
|
@@ -206,13 +206,13 @@ class DUP_Web_Services
|
|
206 |
try {
|
207 |
DUP_Util::hasCapability('export', DUP_Util::SECURE_ISSUE_THROW);
|
208 |
|
209 |
-
$nonce = filter_input(INPUT_POST, 'nonce',
|
210 |
if (!wp_verify_nonce($nonce, 'duplicator_admin_notice_to_dismiss')) {
|
211 |
DUP_Log::trace('Security issue');
|
212 |
throw new Exception('Security issue');
|
213 |
}
|
214 |
|
215 |
-
$noticeToDismiss = filter_input(INPUT_POST, 'notice',
|
216 |
switch ($noticeToDismiss) {
|
217 |
case DUP_UI_Notice::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL:
|
218 |
case DUP_UI_Notice::OPTION_KEY_NEW_NOTICE_TEMPLATE:
|
92 |
)
|
93 |
),
|
94 |
'hash' => array(
|
95 |
+
'filter' => FILTER_UNSAFE_RAW,
|
96 |
'flags' => FILTER_REQUIRE_SCALAR,
|
97 |
'options' => array(
|
98 |
'default' => false
|
178 |
throw new Exception('Security issue');
|
179 |
}
|
180 |
|
181 |
+
$notice_id = DupLiteSnapLibUtil::filterInputRequest('notice_id', FILTER_UNSAFE_RAW);
|
182 |
|
183 |
if (empty($notice_id)) {
|
184 |
throw new Exception(__('Invalid Request', 'duplicator'));
|
206 |
try {
|
207 |
DUP_Util::hasCapability('export', DUP_Util::SECURE_ISSUE_THROW);
|
208 |
|
209 |
+
$nonce = filter_input(INPUT_POST, 'nonce', FILTER_UNSAFE_RAW);
|
210 |
if (!wp_verify_nonce($nonce, 'duplicator_admin_notice_to_dismiss')) {
|
211 |
DUP_Log::trace('Security issue');
|
212 |
throw new Exception('Security issue');
|
213 |
}
|
214 |
|
215 |
+
$noticeToDismiss = filter_input(INPUT_POST, 'notice', FILTER_UNSAFE_RAW);
|
216 |
switch ($noticeToDismiss) {
|
217 |
case DUP_UI_Notice::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL:
|
218 |
case DUP_UI_Notice::OPTION_KEY_NEW_NOTICE_TEMPLATE:
|
ctrls/ctrl.ui.php
CHANGED
@@ -1,165 +1,165 @@
|
|
1 |
-
<?php
|
2 |
-
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
-
// Exit if accessed directly
|
4 |
-
if (! defined('DUPLICATOR_VERSION')) exit;
|
5 |
-
|
6 |
-
require_once(DUPLICATOR_PLUGIN_PATH . '/ctrls/ctrl.base.php');
|
7 |
-
require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.viewstate.php');
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Controller for Tools
|
11 |
-
* @package Duplicator\ctrls
|
12 |
-
*/
|
13 |
-
class DUP_CTRL_UI extends DUP_CTRL_Base
|
14 |
-
{
|
15 |
-
|
16 |
-
function __construct()
|
17 |
-
{
|
18 |
-
add_action('wp_ajax_DUP_CTRL_UI_SaveViewState', array($this, 'SaveViewState'));
|
19 |
-
}
|
20 |
-
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Calls the SaveViewState and returns a JSON result
|
24 |
-
*
|
25 |
-
* @param string $_POST['key'] A unique key that identifies the state of the UI element
|
26 |
-
* @param bool $_POST['value'] The value to store for the state of the UI element
|
27 |
-
*
|
28 |
-
* @notes: Testing: See Testing Interface
|
29 |
-
* URL = /wp-admin/admin-ajax.php?action=DUP_CTRL_UI_SaveViewState
|
30 |
-
*
|
31 |
-
* <code>
|
32 |
-
* //JavaScript Ajax Request
|
33 |
-
* Duplicator.UI.SaveViewState('dup-pack-archive-panel', 1);
|
34 |
-
*
|
35 |
-
* //Call PHP Code
|
36 |
-
* $view_state = DUP_UI_ViewState::getValue('dup-pack-archive-panel');
|
37 |
-
* $ui_css_archive = ($view_state == 1) ? 'display:block' : 'display:none';
|
38 |
-
* </code>
|
39 |
-
*/
|
40 |
-
public function SaveViewState()
|
41 |
-
{
|
42 |
-
DUP_Handler::init_error_handler();
|
43 |
-
check_ajax_referer('DUP_CTRL_UI_SaveViewState', 'nonce');
|
44 |
-
DUP_Util::hasCapability('export');
|
45 |
-
|
46 |
-
$payload = array(
|
47 |
-
'success' => false,
|
48 |
-
'message' => '',
|
49 |
-
'key' => '',
|
50 |
-
'value' => ''
|
51 |
-
);
|
52 |
-
$isValid = true;
|
53 |
-
|
54 |
-
$inputData = filter_input_array(INPUT_POST, array(
|
55 |
-
'states' => array(
|
56 |
-
'filter' =>
|
57 |
-
'flags' => FILTER_FORCE_ARRAY,
|
58 |
-
'options' => array(
|
59 |
-
'default' => array()
|
60 |
-
)
|
61 |
-
),
|
62 |
-
'key' => array(
|
63 |
-
'filter' =>
|
64 |
-
'options' => array(
|
65 |
-
'default' => false
|
66 |
-
)
|
67 |
-
),
|
68 |
-
'value' => array(
|
69 |
-
'filter' =>
|
70 |
-
'options' => array(
|
71 |
-
'default' => false
|
72 |
-
)
|
73 |
-
)
|
74 |
-
));
|
75 |
-
|
76 |
-
if (is_array($inputData) && is_array($inputData['states'])) {
|
77 |
-
foreach ($inputData['states'] as $index => $state) {
|
78 |
-
$filteredState = filter_var_array($state, array(
|
79 |
-
'key' => array(
|
80 |
-
'filter' =>
|
81 |
-
'options' => array(
|
82 |
-
'default' => false
|
83 |
-
)
|
84 |
-
),
|
85 |
-
'value' => array(
|
86 |
-
'filter' =>
|
87 |
-
'options' => array(
|
88 |
-
'default' => false
|
89 |
-
)
|
90 |
-
)
|
91 |
-
));
|
92 |
-
|
93 |
-
if ($filteredState['key'] === false && $filteredState['value']) {
|
94 |
-
$isValid = false;
|
95 |
-
break;
|
96 |
-
}
|
97 |
-
$inputData['states'][$index] = $filteredState;
|
98 |
-
}
|
99 |
-
}
|
100 |
-
|
101 |
-
if ($inputData['key'] === false || $inputData['value'] === false) {
|
102 |
-
$isValid = false;
|
103 |
-
}
|
104 |
-
|
105 |
-
$result = new DUP_CTRL_Result($this);
|
106 |
-
try {
|
107 |
-
if (!$isValid) {
|
108 |
-
throw new Exception(__('Invalid Request.', 'duplicator'));
|
109 |
-
}
|
110 |
-
|
111 |
-
if (!empty($inputData['states'])) {
|
112 |
-
$view_state = DUP_UI_ViewState::getArray();
|
113 |
-
$last_key = '';
|
114 |
-
foreach ($inputData['states'] as $state) {
|
115 |
-
$view_state[$state['key']] = $state['value'];
|
116 |
-
$last_key = $state['key'];
|
117 |
-
}
|
118 |
-
$payload['success'] = DUP_UI_ViewState::setArray($view_state);
|
119 |
-
$payload['key'] = esc_html($last_key);
|
120 |
-
$payload['value'] = esc_html($view_state[$last_key]);
|
121 |
-
} else {
|
122 |
-
$payload['success'] = DUP_UI_ViewState::save($inputData['key'], $inputData['value']);
|
123 |
-
$payload['key'] = esc_html($inputData['key']);
|
124 |
-
$payload['value'] = esc_html($inputData['value']);
|
125 |
-
}
|
126 |
-
|
127 |
-
//RETURN RESULT
|
128 |
-
$test = ($payload['success'])
|
129 |
-
? DUP_CTRL_Status::SUCCESS
|
130 |
-
: DUP_CTRL_Status::FAILED;
|
131 |
-
return $result->process($payload, $test);
|
132 |
-
} catch (Exception $exc) {
|
133 |
-
$result->processError($exc);
|
134 |
-
}
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Returns a JSON list of all saved view state items
|
139 |
-
*
|
140 |
-
*
|
141 |
-
* <code>
|
142 |
-
* See SaveViewState()
|
143 |
-
* </code>
|
144 |
-
*/
|
145 |
-
public function GetViewStateList()
|
146 |
-
{
|
147 |
-
$result = new DUP_CTRL_Result($this);
|
148 |
-
|
149 |
-
try
|
150 |
-
{
|
151 |
-
//CONTROLLER LOGIC
|
152 |
-
$payload = DUP_UI_ViewState::getArray();
|
153 |
-
|
154 |
-
//RETURN RESULT
|
155 |
-
$test = (is_array($payload) && count($payload))
|
156 |
-
? DUP_CTRL_Status::SUCCESS
|
157 |
-
: DUP_CTRL_Status::FAILED;
|
158 |
-
return $result->process($payload, $test);
|
159 |
-
}
|
160 |
-
catch (Exception $exc)
|
161 |
-
{
|
162 |
-
$result->processError($exc);
|
163 |
-
}
|
164 |
-
}
|
165 |
-
}
|
1 |
+
<?php
|
2 |
+
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
3 |
+
// Exit if accessed directly
|
4 |
+
if (! defined('DUPLICATOR_VERSION')) exit;
|
5 |
+
|
6 |
+
require_once(DUPLICATOR_PLUGIN_PATH . '/ctrls/ctrl.base.php');
|
7 |
+
require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.viewstate.php');
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Controller for Tools
|
11 |
+
* @package Duplicator\ctrls
|
12 |
+
*/
|
13 |
+
class DUP_CTRL_UI extends DUP_CTRL_Base
|
14 |
+
{
|
15 |
+
|
16 |
+
function __construct()
|
17 |
+
{
|
18 |
+
add_action('wp_ajax_DUP_CTRL_UI_SaveViewState', array($this, 'SaveViewState'));
|
19 |
+
}
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Calls the SaveViewState and returns a JSON result
|
24 |
+
*
|
25 |
+
* @param string $_POST['key'] A unique key that identifies the state of the UI element
|
26 |
+
* @param bool $_POST['value'] The value to store for the state of the UI element
|
27 |
+
*
|
28 |
+
* @notes: Testing: See Testing Interface
|
29 |
+
* URL = /wp-admin/admin-ajax.php?action=DUP_CTRL_UI_SaveViewState
|
30 |
+
*
|
31 |
+
* <code>
|
32 |
+
* //JavaScript Ajax Request
|
33 |
+
* Duplicator.UI.SaveViewState('dup-pack-archive-panel', 1);
|
34 |
+
*
|
35 |
+
* //Call PHP Code
|
36 |
+
* $view_state = DUP_UI_ViewState::getValue('dup-pack-archive-panel');
|
37 |
+
* $ui_css_archive = ($view_state == 1) ? 'display:block' : 'display:none';
|
38 |
+
* </code>
|
39 |
+
*/
|
40 |
+
public function SaveViewState()
|
41 |
+
{
|
42 |
+
DUP_Handler::init_error_handler();
|
43 |
+
check_ajax_referer('DUP_CTRL_UI_SaveViewState', 'nonce');
|
44 |
+
DUP_Util::hasCapability('export');
|
45 |
+
|
46 |
+
$payload = array(
|
47 |
+
'success' => false,
|
48 |
+
'message' => '',
|
49 |
+
'key' => '',
|
50 |
+
'value' => ''
|
51 |
+
);
|
52 |
+
$isValid = true;
|
53 |
+
|
54 |
+
$inputData = filter_input_array(INPUT_POST, array(
|
55 |
+
'states' => array(
|
56 |
+
'filter' => FILTER_UNSAFE_RAW,
|
57 |
+
'flags' => FILTER_FORCE_ARRAY,
|
58 |
+
'options' => array(
|
59 |
+
'default' => array()
|
60 |
+
)
|
61 |
+
),
|
62 |
+
'key' => array(
|
63 |
+
'filter' => FILTER_UNSAFE_RAW,
|
64 |
+
'options' => array(
|
65 |
+
'default' => false
|
66 |
+
)
|
67 |
+
),
|
68 |
+
'value' => array(
|
69 |
+
'filter' => FILTER_UNSAFE_RAW,
|
70 |
+
'options' => array(
|
71 |
+
'default' => false
|
72 |
+
)
|
73 |
+
)
|
74 |
+
));
|
75 |
+
|
76 |
+
if (is_array($inputData) && is_array($inputData['states'])) {
|
77 |
+
foreach ($inputData['states'] as $index => $state) {
|
78 |
+
$filteredState = filter_var_array($state, array(
|
79 |
+
'key' => array(
|
80 |
+
'filter' => FILTER_UNSAFE_RAW,
|
81 |
+
'options' => array(
|
82 |
+
'default' => false
|
83 |
+
)
|
84 |
+
),
|
85 |
+
'value' => array(
|
86 |
+
'filter' => FILTER_UNSAFE_RAW,
|
87 |
+
'options' => array(
|
88 |
+
'default' => false
|
89 |
+
)
|
90 |
+
)
|
91 |
+
));
|
92 |
+
|
93 |
+
if ($filteredState['key'] === false && $filteredState['value']) {
|
94 |
+
$isValid = false;
|
95 |
+
break;
|
96 |
+
}
|
97 |
+
$inputData['states'][$index] = $filteredState;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
if ($inputData['key'] === false || $inputData['value'] === false) {
|
102 |
+
$isValid = false;
|
103 |
+
}
|
104 |
+
|
105 |
+
$result = new DUP_CTRL_Result($this);
|
106 |
+
try {
|
107 |
+
if (!$isValid) {
|
108 |
+
throw new Exception(__('Invalid Request.', 'duplicator'));
|
109 |
+
}
|
110 |
+
|
111 |
+
if (!empty($inputData['states'])) {
|
112 |
+
$view_state = DUP_UI_ViewState::getArray();
|
113 |
+
$last_key = '';
|
114 |
+
foreach ($inputData['states'] as $state) {
|
115 |
+
$view_state[$state['key']] = $state['value'];
|
116 |
+
$last_key = $state['key'];
|
117 |
+
}
|
118 |
+
$payload['success'] = DUP_UI_ViewState::setArray($view_state);
|
119 |
+
$payload['key'] = esc_html($last_key);
|
120 |
+
$payload['value'] = esc_html($view_state[$last_key]);
|
121 |
+
} else {
|
122 |
+
$payload['success'] = DUP_UI_ViewState::save($inputData['key'], $inputData['value']);
|
123 |
+
$payload['key'] = esc_html($inputData['key']);
|
124 |
+
$payload['value'] = esc_html($inputData['value']);
|
125 |
+
}
|
126 |
+
|
127 |
+
//RETURN RESULT
|
128 |
+
$test = ($payload['success'])
|
129 |
+
? DUP_CTRL_Status::SUCCESS
|
130 |
+
: DUP_CTRL_Status::FAILED;
|
131 |
+
return $result->process($payload, $test);
|
132 |
+
} catch (Exception $exc) {
|
133 |
+
$result->processError($exc);
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Returns a JSON list of all saved view state items
|
139 |
+
*
|
140 |
+
*
|
141 |
+
* <code>
|
142 |
+
* See SaveViewState()
|
143 |
+
* </code>
|
144 |
+
*/
|
145 |
+
public function GetViewStateList()
|
146 |
+
{
|
147 |
+
$result = new DUP_CTRL_Result($this);
|
148 |
+
|
149 |
+
try
|
150 |
+
{
|
151 |
+
//CONTROLLER LOGIC
|
152 |
+
$payload = DUP_UI_ViewState::getArray();
|
153 |
+
|
154 |
+
//RETURN RESULT
|
155 |
+
$test = (is_array($payload) && count($payload))
|
156 |
+
? DUP_CTRL_Status::SUCCESS
|
157 |
+
: DUP_CTRL_Status::FAILED;
|
158 |
+
return $result->process($payload, $test);
|
159 |
+
}
|
160 |
+
catch (Exception $exc)
|
161 |
+
{
|
162 |
+
$result->processError($exc);
|
163 |
+
}
|
164 |
+
}
|
165 |
+
}
|
deactivation.php
CHANGED
@@ -363,21 +363,21 @@ if (!function_exists('duplicator_submit_uninstall_reason_action')) {
|
|
363 |
$isValid = true;
|
364 |
$inputData = filter_input_array(INPUT_POST, array(
|
365 |
'reason_id' => array(
|
366 |
-
'filter' =>
|
367 |
'flags' => FILTER_REQUIRE_SCALAR,
|
368 |
'options' => array(
|
369 |
'default' => false
|
370 |
)
|
371 |
),
|
372 |
'plugin' => array(
|
373 |
-
'filter' =>
|
374 |
'flags' => FILTER_REQUIRE_SCALAR,
|
375 |
'options' => array(
|
376 |
'default' => false
|
377 |
)
|
378 |
),
|
379 |
'reason_info' => array(
|
380 |
-
'filter' =>
|
381 |
'flags' => FILTER_REQUIRE_SCALAR,
|
382 |
'options' => array(
|
383 |
'default' => ''
|
363 |
$isValid = true;
|
364 |
$inputData = filter_input_array(INPUT_POST, array(
|
365 |
'reason_id' => array(
|
366 |
+
'filter' => FILTER_UNSAFE_RAW,
|
367 |
'flags' => FILTER_REQUIRE_SCALAR,
|
368 |
'options' => array(
|
369 |
'default' => false
|
370 |
)
|
371 |
),
|
372 |
'plugin' => array(
|
373 |
+
'filter' => FILTER_UNSAFE_RAW,
|
374 |
'flags' => FILTER_REQUIRE_SCALAR,
|
375 |
'options' => array(
|
376 |
'default' => false
|
377 |
)
|
378 |
),
|
379 |
'reason_info' => array(
|
380 |
+
'filter' => FILTER_UNSAFE_RAW,
|
381 |
'flags' => FILTER_REQUIRE_SCALAR,
|
382 |
'options' => array(
|
383 |
'default' => ''
|
define.php
CHANGED
@@ -5,8 +5,8 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
5 |
|
6 |
if (function_exists('plugin_dir_url'))
|
7 |
{
|
8 |
-
define('DUPLICATOR_VERSION', '1.4.
|
9 |
-
define('DUPLICATOR_VERSION_BUILD', '2022-
|
10 |
define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
|
11 |
define('DUPLICATOR_SITE_URL', get_site_url());
|
12 |
|
5 |
|
6 |
if (function_exists('plugin_dir_url'))
|
7 |
{
|
8 |
+
define('DUPLICATOR_VERSION', '1.4.5');
|
9 |
+
define('DUPLICATOR_VERSION_BUILD', '2022-04-12_19:00');
|
10 |
define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
|
11 |
define('DUPLICATOR_SITE_URL', get_site_url());
|
12 |
|
duplicator.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Duplicator
|
4 |
Plugin URI: https://snapcreek.com/duplicator/duplicator-free/
|
5 |
Description: Migrate and backup a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
|
6 |
-
Version: 1.4.
|
7 |
Requires at least: 4.0
|
8 |
Tested up to: 5.9
|
9 |
Requires PHP: 5.3.8
|
3 |
Plugin Name: Duplicator
|
4 |
Plugin URI: https://snapcreek.com/duplicator/duplicator-free/
|
5 |
Description: Migrate and backup a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
|
6 |
+
Version: 1.4.5
|
7 |
Requires at least: 4.0
|
8 |
Tested up to: 5.9
|
9 |
Requires PHP: 5.3.8
|
installer/dup-installer/assets/inc.js.php
CHANGED
@@ -1,227 +1,227 @@
|
|
1 |
-
<?php defined('ABSPATH') || defined('DUPXABSPATH') || exit; ?>
|
2 |
-
<script>
|
3 |
-
//Unique namespace
|
4 |
-
DUPX = new Object();
|
5 |
-
DUPX.Util = new Object();
|
6 |
-
DUPX.Const = new Object();
|
7 |
-
DUPX.GLB_DEBUG = <?php echo ($_GET['debug'] || $GLOBALS['DEBUG_JS']) ? 'true' : 'false'; ?>;
|
8 |
-
|
9 |
-
DUPX.parseJSON = function(mixData) {
|
10 |
-
try {
|
11 |
-
var parsed = JSON.parse(mixData);
|
12 |
-
return parsed;
|
13 |
-
} catch (e) {
|
14 |
-
console.log("JSON parse failed - 1");
|
15 |
-
console.log(mixData);
|
16 |
-
}
|
17 |
-
|
18 |
-
if (mixData.indexOf('[') > -1 && mixData.indexOf('{') > -1) {
|
19 |
-
if (mixData.indexOf('{') < mixData.indexOf('[')) {
|
20 |
-
var startBracket = '{';
|
21 |
-
var endBracket = '}';
|
22 |
-
} else {
|
23 |
-
var startBracket = '[';
|
24 |
-
var endBracket = ']';
|
25 |
-
}
|
26 |
-
} else if (mixData.indexOf('[') > -1 && mixData.indexOf('{') === -1) {
|
27 |
-
var startBracket = '[';
|
28 |
-
var endBracket = ']';
|
29 |
-
} else {
|
30 |
-
var startBracket = '{';
|
31 |
-
var endBracket = '}';
|
32 |
-
}
|
33 |
-
|
34 |
-
var jsonStartPos = mixData.indexOf(startBracket);
|
35 |
-
var jsonLastPos = mixData.lastIndexOf(endBracket);
|
36 |
-
if (jsonStartPos > -1 && jsonLastPos > -1) {
|
37 |
-
var expectedJsonStr = mixData.slice(jsonStartPos, jsonLastPos + 1);
|
38 |
-
try {
|
39 |
-
var parsed = JSON.parse(expectedJsonStr);
|
40 |
-
return parsed;
|
41 |
-
} catch (e) {
|
42 |
-
console.log("JSON parse failed - 2");
|
43 |
-
console.log(mixData);
|
44 |
-
throw e;
|
45 |
-
return false;
|
46 |
-
}
|
47 |
-
}
|
48 |
-
throw "could not parse the JSON";
|
49 |
-
return false;
|
50 |
-
}
|
51 |
-
|
52 |
-
DUPX.showProgressBar = function ()
|
53 |
-
{
|
54 |
-
DUPX.animateProgressBar('progress-bar');
|
55 |
-
$('#ajaxerr-area').hide();
|
56 |
-
$('#progress-area').show();
|
57 |
-
}
|
58 |
-
|
59 |
-
DUPX.hideProgressBar = function ()
|
60 |
-
{
|
61 |
-
$('#progress-area').hide(100);
|
62 |
-
$('#ajaxerr-area').fadeIn(400);
|
63 |
-
}
|
64 |
-
|
65 |
-
DUPX.animateProgressBar = function(id) {
|
66 |
-
//Create Progress Bar
|
67 |
-
var $mainbar = $("#" + id);
|
68 |
-
$mainbar.progressbar({ value: 100 });
|
69 |
-
$mainbar.height(25);
|
70 |
-
runAnimation($mainbar);
|
71 |
-
|
72 |
-
function runAnimation($pb) {
|
73 |
-
$pb.css({ "padding-left": "0%", "padding-right": "90%" });
|
74 |
-
$pb.progressbar("option", "value", 100);
|
75 |
-
$pb.animate({ paddingLeft: "90%", paddingRight: "0%" }, 3500, "linear", function () { runAnimation($pb); });
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
DUPX.initToggle = function() {
|
80 |
-
$("body").on('click', "*[data-type~='toggle']", DUPX.toggleClick);
|
81 |
-
|
82 |
-
var hasFailedReq = false;
|
83 |
-
$("*[data-type~='auto'][data-status='fail']").each(function(){
|
84 |
-
hasFailedReq = true;
|
85 |
-
$(this).trigger('click');
|
86 |
-
});
|
87 |
-
|
88 |
-
$("*[data-type~='auto'][data-status='warn']").each(function(){
|
89 |
-
if (hasFailedReq) {
|
90 |
-
return ;
|
91 |
-
}
|
92 |
-
|
93 |
-
$(this).trigger('click');
|
94 |
-
});
|
95 |
-
}
|
96 |
-
|
97 |
-
DUPX.toggleAllReqs = function(id) {
|
98 |
-
$(id + " *[data-type='toggle auto']").each(function() {
|
99 |
-
$(this).trigger('click');
|
100 |
-
});
|
101 |
-
}
|
102 |
-
|
103 |
-
DUPX.toggleAllNotices = function(id) {
|
104 |
-
$(id + " *[data-type='toggle']").each(function() {
|
105 |
-
$(this).trigger('click');
|
106 |
-
});
|
107 |
-
}
|
108 |
-
|
109 |
-
DUPX.toggleClick = function()
|
110 |
-
{
|
111 |
-
var src = 0;
|
112 |
-
var id = $(this).attr('data-target');
|
113 |
-
var text = $(this).text().replace(/\+|\-/, "");
|
114 |
-
var icon = $(this).find('i.fa');
|
115 |
-
var target = $(id);
|
116 |
-
var list = new Array();
|
117 |
-
|
118 |
-
var style = [
|
119 |
-
{ open: "fa-minus-square",
|
120 |
-
close: "fa-plus-square"
|
121 |
-
},
|
122 |
-
{ open: "fa-caret-down",
|
123 |
-
close: "fa-caret-right"
|
124 |
-
}];
|
125 |
-
|
126 |
-
//Create src
|
127 |
-
for (i = 0; i < style.length; i++) {
|
128 |
-
if ($(icon).hasClass(style[i].open) || $(icon).hasClass(style[i].close)) {
|
129 |
-
src = i;
|
130 |
-
break;
|
131 |
-
}
|
132 |
-
}
|
133 |
-
|
134 |
-
//Build remove list
|
135 |
-
for (i = 0; i < style.length; i++) {
|
136 |
-
list.push(style[i].open);
|
137 |
-
list.push(style[i].close);
|
138 |
-
}
|
139 |
-
|
140 |
-
$(icon).removeClass(list.join(" "));
|
141 |
-
if (target.is(':hidden') ) {
|
142 |
-
(icon.length)
|
143 |
-
? $(icon).addClass(style[src].open )
|
144 |
-
: $(this).html("- " + text );
|
145 |
-
target.show().removeClass('no-display');
|
146 |
-
} else {
|
147 |
-
(icon.length)
|
148 |
-
? $(icon).addClass(style[src].close)
|
149 |
-
: $(this).html("+ " + text );
|
150 |
-
target.hide();
|
151 |
-
}
|
152 |
-
}
|
153 |
-
|
154 |
-
DUPX.Util.formatBytes = function (bytes,decimals)
|
155 |
-
{
|
156 |
-
if(bytes == 0) return '0 Byte';
|
157 |
-
var k = 1000;
|
158 |
-
var dm = decimals + 1 || 3;
|
159 |
-
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
160 |
-
var i = Math.floor(Math.log(bytes) / Math.log(k));
|
161 |
-
return (bytes / Math.pow(k, i)).toPrecision(dm) + ' ' + sizes[i];
|
162 |
-
}
|
163 |
-
|
164 |
-
$(document).ready(function()
|
165 |
-
{
|
166 |
-
$('body').on( "click", ".copy-to-clipboard-block button", function(e) {
|
167 |
-
e.preventDefault();
|
168 |
-
var button = $(this);
|
169 |
-
var buttonText = button.html();
|
170 |
-
var textarea = button.parent().find("textarea")[0];
|
171 |
-
|
172 |
-
textarea.select();
|
173 |
-
|
174 |
-
try {
|
175 |
-
message = document.execCommand('copy') ? "Copied to Clipboard" : 'Unable to copy';
|
176 |
-
} catch (err) {
|
177 |
-
console.log(err);
|
178 |
-
}
|
179 |
-
|
180 |
-
button.html(message);
|
181 |
-
|
182 |
-
setTimeout(function () {
|
183 |
-
button.text(buttonText);
|
184 |
-
}, 2000);
|
185 |
-
});
|
186 |
-
|
187 |
-
<?php if (DUPX_Log::isLevel(DUPX_Log::LV_DEBUG)) : ?>
|
188 |
-
$("div.dupx-debug input[type=hidden], div.dupx-debug textarea").each(function() {
|
189 |
-
var label = '<label>' + $(this).attr('name') + ':</label>';
|
190 |
-
$(this).before(label);
|
191 |
-
$(this).after('<br/>');
|
192 |
-
});
|
193 |
-
$("div.dupx-debug input[type=hidden]").each(function() {
|
194 |
-
$(this).attr('type', 'text');
|
195 |
-
});
|
196 |
-
|
197 |
-
$("div.dupx-debug").prepend('<div class="dupx-debug-hdr">Debug View</div>');
|
198 |
-
<?php endif; ?>
|
199 |
-
|
200 |
-
DUPX.loadQtip = function()
|
201 |
-
{
|
202 |
-
//Look for tooltip data
|
203 |
-
$('i[data-tooltip!=""]').qtip({
|
204 |
-
content: {
|
205 |
-
attr: 'data-tooltip',
|
206 |
-
title: {
|
207 |
-
text: function() { return $(this).attr('data-tooltip-title'); }
|
208 |
-
}
|
209 |
-
},
|
210 |
-
style: {
|
211 |
-
classes: 'qtip-light qtip-rounded qtip-shadow',
|
212 |
-
width: 500
|
213 |
-
},
|
214 |
-
position: {
|
215 |
-
my: 'top left',
|
216 |
-
at: 'bottom center'
|
217 |
-
}
|
218 |
-
});
|
219 |
-
}
|
220 |
-
|
221 |
-
DUPX.loadQtip();
|
222 |
-
|
223 |
-
});
|
224 |
-
|
225 |
-
</script>
|
226 |
-
<?php
|
227 |
DUPX_U_Html::js();
|
1 |
+
<?php defined('ABSPATH') || defined('DUPXABSPATH') || exit; ?>
|
2 |
+
<script>
|
3 |
+
//Unique namespace
|
4 |
+
DUPX = new Object();
|
5 |
+
DUPX.Util = new Object();
|
6 |
+
DUPX.Const = new Object();
|
7 |
+
DUPX.GLB_DEBUG = <?php echo ($_GET['debug'] || $GLOBALS['DEBUG_JS']) ? 'true' : 'false'; ?>;
|
8 |
+
|
9 |
+
DUPX.parseJSON = function(mixData) {
|
10 |
+
try {
|
11 |
+
var parsed = JSON.parse(mixData);
|
12 |
+
return parsed;
|
13 |
+
} catch (e) {
|
14 |
+
console.log("JSON parse failed - 1");
|
15 |
+
console.log(mixData);
|
16 |
+
}
|
17 |
+
|
18 |
+
if (mixData.indexOf('[') > -1 && mixData.indexOf('{') > -1) {
|
19 |
+
if (mixData.indexOf('{') < mixData.indexOf('[')) {
|
20 |
+
var startBracket = '{';
|
21 |
+
var endBracket = '}';
|
22 |
+
} else {
|
23 |
+
var startBracket = '[';
|
24 |
+
var endBracket = ']';
|
25 |
+
}
|
26 |
+
} else if (mixData.indexOf('[') > -1 && mixData.indexOf('{') === -1) {
|
27 |
+
var startBracket = '[';
|
28 |
+
var endBracket = ']';
|
29 |
+
} else {
|
30 |
+
var startBracket = '{';
|
31 |
+
var endBracket = '}';
|
32 |
+
}
|
33 |
+
|
34 |
+
var jsonStartPos = mixData.indexOf(startBracket);
|
35 |
+
var jsonLastPos = mixData.lastIndexOf(endBracket);
|
36 |
+
if (jsonStartPos > -1 && jsonLastPos > -1) {
|
37 |
+
var expectedJsonStr = mixData.slice(jsonStartPos, jsonLastPos + 1);
|
38 |
+
try {
|
39 |
+
var parsed = JSON.parse(expectedJsonStr);
|
40 |
+
return parsed;
|
41 |
+
} catch (e) {
|
42 |
+
console.log("JSON parse failed - 2");
|
43 |
+
console.log(mixData);
|
44 |
+
throw e;
|
45 |
+
return false;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
throw "could not parse the JSON";
|
49 |
+
return false;
|
50 |
+
}
|
51 |
+
|
52 |
+
DUPX.showProgressBar = function ()
|
53 |
+
{
|
54 |
+
DUPX.animateProgressBar('progress-bar');
|
55 |
+
$('#ajaxerr-area').hide();
|
56 |
+
$('#progress-area').show();
|
57 |
+
}
|
58 |
+
|
59 |
+
DUPX.hideProgressBar = function ()
|
60 |
+
{
|
61 |
+
$('#progress-area').hide(100);
|
62 |
+
$('#ajaxerr-area').fadeIn(400);
|
63 |
+
}
|
64 |
+
|
65 |
+
DUPX.animateProgressBar = function(id) {
|
66 |
+
//Create Progress Bar
|
67 |
+
var $mainbar = $("#" + id);
|
68 |
+
$mainbar.progressbar({ value: 100 });
|
69 |
+
$mainbar.height(25);
|
70 |
+
runAnimation($mainbar);
|
71 |
+
|
72 |
+
function runAnimation($pb) {
|
73 |
+
$pb.css({ "padding-left": "0%", "padding-right": "90%" });
|
74 |
+
$pb.progressbar("option", "value", 100);
|
75 |
+
$pb.animate({ paddingLeft: "90%", paddingRight: "0%" }, 3500, "linear", function () { runAnimation($pb); });
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
DUPX.initToggle = function() {
|
80 |
+
$("body").on('click', "*[data-type~='toggle']", DUPX.toggleClick);
|
81 |
+
|
82 |
+
var hasFailedReq = false;
|
83 |
+
$("*[data-type~='auto'][data-status='fail']").each(function(){
|
84 |
+
hasFailedReq = true;
|
85 |
+
$(this).trigger('click');
|
86 |
+
});
|
87 |
+
|
88 |
+
$("*[data-type~='auto'][data-status='warn']").each(function(){
|
89 |
+
if (hasFailedReq) {
|
90 |
+
return ;
|
91 |
+
}
|
92 |
+
|
93 |
+
$(this).trigger('click');
|
94 |
+
});
|
95 |
+
}
|
96 |
+
|
97 |
+
DUPX.toggleAllReqs = function(id) {
|
98 |
+
$(id + " *[data-type='toggle auto']").each(function() {
|
99 |
+
$(this).trigger('click');
|
100 |
+
});
|
101 |
+
}
|
102 |
+
|
103 |
+
DUPX.toggleAllNotices = function(id) {
|
104 |
+
$(id + " *[data-type='toggle']").each(function() {
|
105 |
+
$(this).trigger('click');
|
106 |
+
});
|
107 |
+
}
|
108 |
+
|
109 |
+
DUPX.toggleClick = function()
|
110 |
+
{
|
111 |
+
var src = 0;
|
112 |
+
var id = $(this).attr('data-target');
|
113 |
+
var text = $(this).text().replace(/\+|\-/, "");
|
114 |
+
var icon = $(this).find('i.fa');
|
115 |
+
var target = $(id);
|
116 |
+
var list = new Array();
|
117 |
+
|
118 |
+
var style = [
|
119 |
+
{ open: "fa-minus-square",
|
120 |
+
close: "fa-plus-square"
|
121 |
+
},
|
122 |
+
{ open: "fa-caret-down",
|
123 |
+
close: "fa-caret-right"
|
124 |
+
}];
|
125 |
+
|
126 |
+
//Create src
|
127 |
+
for (i = 0; i < style.length; i++) {
|
128 |
+
if ($(icon).hasClass(style[i].open) || $(icon).hasClass(style[i].close)) {
|
129 |
+
src = i;
|
130 |
+
break;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
+
//Build remove list
|
135 |
+
for (i = 0; i < style.length; i++) {
|
136 |
+
list.push(style[i].open);
|
137 |
+
list.push(style[i].close);
|
138 |
+
}
|
139 |
+
|
140 |
+
$(icon).removeClass(list.join(" "));
|
141 |
+
if (target.is(':hidden') ) {
|
142 |
+
(icon.length)
|
143 |
+
? $(icon).addClass(style[src].open )
|
144 |
+
: $(this).html("- " + text );
|
145 |
+
target.show().removeClass('no-display');
|
146 |
+
} else {
|
147 |
+
(icon.length)
|
148 |
+
? $(icon).addClass(style[src].close)
|
149 |
+
: $(this).html("+ " + text );
|
150 |
+
target.hide();
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
DUPX.Util.formatBytes = function (bytes,decimals)
|
155 |
+
{
|
156 |
+
if(bytes == 0) return '0 Byte';
|
157 |
+
var k = 1000;
|
158 |
+
var dm = decimals + 1 || 3;
|
159 |
+
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
160 |
+
var i = Math.floor(Math.log(bytes) / Math.log(k));
|
161 |
+
return (bytes / Math.pow(k, i)).toPrecision(dm) + ' ' + sizes[i];
|
162 |
+
}
|
163 |
+
|
164 |
+
$(document).ready(function()
|
165 |
+
{
|
166 |
+
$('body').on( "click", ".copy-to-clipboard-block button", function(e) {
|
167 |
+
e.preventDefault();
|
168 |
+
var button = $(this);
|
169 |
+
var buttonText = button.html();
|
170 |
+
var textarea = button.parent().find("textarea")[0];
|
171 |
+
|
172 |
+
textarea.select();
|
173 |
+
|
174 |
+
try {
|
175 |
+
message = document.execCommand('copy') ? "Copied to Clipboard" : 'Unable to copy';
|
176 |
+
} catch (err) {
|
177 |
+
console.log(err);
|
178 |
+
}
|
179 |
+
|
180 |
+
button.html(message);
|
181 |
+
|
182 |
+
setTimeout(function () {
|
183 |
+
button.text(buttonText);
|
184 |
+
}, 2000);
|
185 |
+
});
|
186 |
+
|
187 |
+
<?php if (DUPX_Log::isLevel(DUPX_Log::LV_DEBUG)) : ?>
|
188 |
+
$("div.dupx-debug input[type=hidden], div.dupx-debug textarea").each(function() {
|
189 |
+
var label = '<label>' + $(this).attr('name') + ':</label>';
|
190 |
+
$(this).before(label);
|
191 |
+
$(this).after('<br/>');
|
192 |
+
});
|
193 |
+
$("div.dupx-debug input[type=hidden]").each(function() {
|
194 |
+
$(this).attr('type', 'text');
|
195 |
+
});
|
196 |
+
|
197 |
+
$("div.dupx-debug").prepend('<div class="dupx-debug-hdr">Debug View</div>');
|
198 |
+
<?php endif; ?>
|
199 |
+
|
200 |
+
DUPX.loadQtip = function()
|
201 |
+
{
|
202 |
+
//Look for tooltip data
|
203 |
+
$('i[data-tooltip!=""]').qtip({
|
204 |
+
content: {
|
205 |
+
attr: 'data-tooltip',
|
206 |
+
title: {
|
207 |
+
text: function() { return $(this).attr('data-tooltip-title'); }
|
208 |
+
}
|
209 |
+
},
|
210 |
+
style: {
|
211 |
+
classes: 'qtip-light qtip-rounded qtip-shadow',
|
212 |
+
width: 500
|
213 |
+
},
|
214 |
+
position: {
|
215 |
+
my: 'top left',
|
216 |
+
at: 'bottom center'
|
217 |
+
}
|
218 |
+
});
|
219 |
+
}
|
220 |
+
|
221 |
+
DUPX.loadQtip();
|
222 |
+
|
223 |
+
});
|
224 |
+
|
225 |
+
</script>
|
226 |
+
<?php
|
227 |
DUPX_U_Html::js();
|
installer/dup-installer/classes/class.csrf.php
CHANGED
@@ -31,8 +31,8 @@ class DUPX_CSRF
|
|
31 |
/**
|
32 |
* Set new CSRF
|
33 |
*
|
34 |
-
* @param string $key CSRF
|
35 |
-
* @param string $val CSRF
|
36 |
*
|
37 |
* @return Void
|
38 |
*/
|
@@ -110,7 +110,7 @@ class DUPX_CSRF
|
|
110 |
*/
|
111 |
protected static function token()
|
112 |
{
|
113 |
-
mt_srand((double) microtime() * 10000);
|
114 |
$charid = strtoupper(md5(uniqid(rand(), true)));
|
115 |
return substr($charid, 0, 8) . substr($charid, 8, 4) . substr($charid, 12, 4) . substr($charid, 16, 4) . substr($charid, 20, 12);
|
116 |
}
|
31 |
/**
|
32 |
* Set new CSRF
|
33 |
*
|
34 |
+
* @param string $key CSRF key
|
35 |
+
* @param string $val CSRF val
|
36 |
*
|
37 |
* @return Void
|
38 |
*/
|
110 |
*/
|
111 |
protected static function token()
|
112 |
{
|
113 |
+
mt_srand((int)((double) microtime() * 10000));
|
114 |
$charid = strtoupper(md5(uniqid(rand(), true)));
|
115 |
return substr($charid, 0, 8) . substr($charid, 8, 4) . substr($charid, 12, 4) . substr($charid, 16, 4) . substr($charid, 20, 12);
|
116 |
}
|
installer/dup-installer/classes/class.s3.func.php
CHANGED
@@ -211,7 +211,7 @@ final class DUPX_S3_Funcs
|
|
211 |
// OTHER
|
212 |
$this->post['exe_safe_mode'] = filter_input(INPUT_POST, 'exe_safe_mode', FILTER_VALIDATE_BOOLEAN, array('options' => array('default' => false)));
|
213 |
$this->post['config_mode'] = DUPX_U::isset_sanitize($_POST, 'config_mode', array('default' => 'NEW'));
|
214 |
-
$this->post['plugins'] = filter_input(INPUT_POST, 'plugins',
|
215 |
array(
|
216 |
'options' => array(
|
217 |
'default' => array()
|
@@ -984,7 +984,7 @@ LONGMSG;
|
|
984 |
mysqli_query($this->dbh,
|
985 |
"UPDATE `".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options` SET option_value = '".mysqli_real_escape_string($this->dbh, $this->post['siteurl'])."' WHERE option_name = 'siteurl' ");
|
986 |
mysqli_query($this->dbh,
|
987 |
-
"
|
988 |
$this->post['exe_safe_mode'])."','duplicator_exe_safe_mode')");
|
989 |
//Reset the postguid data
|
990 |
if ($this->post['postguid']) {
|
211 |
// OTHER
|
212 |
$this->post['exe_safe_mode'] = filter_input(INPUT_POST, 'exe_safe_mode', FILTER_VALIDATE_BOOLEAN, array('options' => array('default' => false)));
|
213 |
$this->post['config_mode'] = DUPX_U::isset_sanitize($_POST, 'config_mode', array('default' => 'NEW'));
|
214 |
+
$this->post['plugins'] = filter_input(INPUT_POST, 'plugins', FILTER_UNSAFE_RAW,
|
215 |
array(
|
216 |
'options' => array(
|
217 |
'default' => array()
|
984 |
mysqli_query($this->dbh,
|
985 |
"UPDATE `".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options` SET option_value = '".mysqli_real_escape_string($this->dbh, $this->post['siteurl'])."' WHERE option_name = 'siteurl' ");
|
986 |
mysqli_query($this->dbh,
|
987 |
+
"REPLACE INTO `".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options` (option_value, option_name) VALUES('".mysqli_real_escape_string($this->dbh,
|
988 |
$this->post['exe_safe_mode'])."','duplicator_exe_safe_mode')");
|
989 |
//Reset the postguid data
|
990 |
if ($this->post['postguid']) {
|
installer/dup-installer/classes/utilities/class.u.html.php
CHANGED
@@ -320,7 +320,7 @@ class DUPX_U_Html
|
|
320 |
*/
|
321 |
public static function getMoreContent($htmlContent, $classes = array(), $step = 200, $id = '', $echo = true)
|
322 |
{
|
323 |
-
$inputCls = filter_var($classes,
|
324 |
$mainClasses = array_merge(array('more-content'), $inputCls);
|
325 |
$atStep = max(100, $step);
|
326 |
$idAttr = empty($id) ? '' : 'id="'.$id.'" ';
|
320 |
*/
|
321 |
public static function getMoreContent($htmlContent, $classes = array(), $step = 200, $id = '', $echo = true)
|
322 |
{
|
323 |
+
$inputCls = filter_var($classes, FILTER_UNSAFE_RAW, FILTER_FORCE_ARRAY);
|
324 |
$mainClasses = array_merge(array('more-content'), $inputCls);
|
325 |
$atStep = max(100, $step);
|
326 |
$idAttr = empty($id) ? '' : 'id="'.$id.'" ';
|
installer/dup-installer/classes/utilities/class.u.notices.manager.php
CHANGED
@@ -1,1251 +1,1251 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Notice manager
|
4 |
-
*
|
5 |
-
* Standard: PSR-2
|
6 |
-
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
7 |
-
*
|
8 |
-
* @package SC\DUPX\U
|
9 |
-
*
|
10 |
-
*/
|
11 |
-
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Notice manager
|
15 |
-
* singleton class
|
16 |
-
*/
|
17 |
-
final class DUPX_NOTICE_MANAGER
|
18 |
-
{
|
19 |
-
const ADD_NORMAL = 0; // add notice in list
|
20 |
-
const ADD_UNIQUE = 1; // add if unique id don't exists
|
21 |
-
const ADD_UNIQUE_UPDATE = 2; // add or update notice unique id
|
22 |
-
const ADD_UNIQUE_APPEND = 3; // append long msg
|
23 |
-
const ADD_UNIQUE_APPEND_IF_EXISTS = 4; // append long msg if already exists item
|
24 |
-
const ADD_UNIQUE_PREPEND = 5; // append long msg
|
25 |
-
const ADD_UNIQUE_PREPEND_IF_EXISTS = 6; // prepend long msg if already exists item
|
26 |
-
const DEFAULT_UNIQUE_ID_PREFIX = '__auto_unique_id__';
|
27 |
-
|
28 |
-
private static $uniqueCountId = 0;
|
29 |
-
|
30 |
-
/**
|
31 |
-
*
|
32 |
-
* @var DUPX_NOTICE_ITEM[]
|
33 |
-
*/
|
34 |
-
private $nextStepNotices = array();
|
35 |
-
|
36 |
-
/**
|
37 |
-
*
|
38 |
-
* @var DUPX_NOTICE_ITEM[]
|
39 |
-
*/
|
40 |
-
private $finalReporNotices = array();
|
41 |
-
|
42 |
-
/**
|
43 |
-
*
|
44 |
-
* @var DUPX_NOTICE_MANAGER
|
45 |
-
*/
|
46 |
-
private static $instance = null;
|
47 |
-
|
48 |
-
/**
|
49 |
-
*
|
50 |
-
* @var string
|
51 |
-
*/
|
52 |
-
private $persistanceFile = null;
|
53 |
-
|
54 |
-
/**
|
55 |
-
*
|
56 |
-
* @return DUPX_S_R_MANAGER
|
57 |
-
*/
|
58 |
-
public static function getInstance()
|
59 |
-
{
|
60 |
-
if (is_null(self::$instance)) {
|
61 |
-
self::$instance = new self();
|
62 |
-
}
|
63 |
-
|
64 |
-
return self::$instance;
|
65 |
-
}
|
66 |
-
|
67 |
-
private function __construct()
|
68 |
-
{
|
69 |
-
$this->persistanceFile = $GLOBALS["NOTICES_FILE_PATH"];
|
70 |
-
$this->loadNotices();
|
71 |
-
}
|
72 |
-
|
73 |
-
/**
|
74 |
-
* save notices from json file
|
75 |
-
*/
|
76 |
-
public function saveNotices()
|
77 |
-
{
|
78 |
-
$notices = array(
|
79 |
-
'globalData' => array(
|
80 |
-
'uniqueCountId' => self::$uniqueCountId
|
81 |
-
),
|
82 |
-
'nextStep' => array(),
|
83 |
-
'finalReport' => array()
|
84 |
-
);
|
85 |
-
|
86 |
-
foreach ($this->nextStepNotices as $uniqueId => $notice) {
|
87 |
-
$notices['nextStep'][$uniqueId] = $notice->toArray();
|
88 |
-
}
|
89 |
-
|
90 |
-
foreach ($this->finalReporNotices as $uniqueId => $notice) {
|
91 |
-
$notices['finalReport'][$uniqueId] = $notice->toArray();
|
92 |
-
}
|
93 |
-
|
94 |
-
file_put_contents($this->persistanceFile, DupLiteSnapJsonU::wp_json_encode_pprint($notices));
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* load notice from json file
|
99 |
-
*/
|
100 |
-
private function loadNotices()
|
101 |
-
{
|
102 |
-
if (file_exists($this->persistanceFile)) {
|
103 |
-
$json = file_get_contents($this->persistanceFile);
|
104 |
-
$notices = json_decode($json, true);
|
105 |
-
|
106 |
-
$this->nextStepNotices = array();
|
107 |
-
$this->finalReporNotices = array();
|
108 |
-
|
109 |
-
if (!empty($notices['nextStep'])) {
|
110 |
-
foreach ($notices['nextStep'] as $uniqueId => $notice) {
|
111 |
-
$this->nextStepNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
|
112 |
-
}
|
113 |
-
}
|
114 |
-
|
115 |
-
if (!empty($notices['finalReport'])) {
|
116 |
-
foreach ($notices['finalReport'] as $uniqueId => $notice) {
|
117 |
-
$this->finalReporNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
|
118 |
-
}
|
119 |
-
}
|
120 |
-
|
121 |
-
self::$uniqueCountId = $notices['globalData']['uniqueCountId'];
|
122 |
-
} else {
|
123 |
-
$this->resetNotices();
|
124 |
-
}
|
125 |
-
}
|
126 |
-
|
127 |
-
/**
|
128 |
-
* remove all notices and save reset file
|
129 |
-
*/
|
130 |
-
public function resetNotices()
|
131 |
-
{
|
132 |
-
$this->nextStepNotices = array();
|
133 |
-
$this->finalReporNotices = array();
|
134 |
-
self::$uniqueCountId = 0;
|
135 |
-
$this->saveNotices();
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* return next step notice by id
|
140 |
-
*
|
141 |
-
* @param string $id
|
142 |
-
* @return DUPX_NOTICE_ITEM
|
143 |
-
*/
|
144 |
-
public function getNextStepNoticeById($id)
|
145 |
-
{
|
146 |
-
if (isset($this->nextStepNotices[$id])) {
|
147 |
-
return $this->nextStepNotices[$id];
|
148 |
-
} else {
|
149 |
-
return null;
|
150 |
-
}
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* return last report notice by id
|
155 |
-
*
|
156 |
-
* @param string $id
|
157 |
-
* @return DUPX_NOTICE_ITEM
|
158 |
-
*/
|
159 |
-
public function getFinalReporNoticeById($id)
|
160 |
-
{
|
161 |
-
if (isset($this->finalReporNotices[$id])) {
|
162 |
-
return $this->finalReporNotices[$id];
|
163 |
-
} else {
|
164 |
-
return null;
|
165 |
-
}
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
*
|
170 |
-
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
171 |
-
* // if array must be [
|
172 |
-
* 'shortMsg' => text,
|
173 |
-
* 'level' => level,
|
174 |
-
* 'longMsg' => html text,
|
175 |
-
* 'sections' => sections list,
|
176 |
-
* 'faqLink' => [
|
177 |
-
* 'url' => external link
|
178 |
-
* 'label' => link text if empty get external url link
|
179 |
-
* ]
|
180 |
-
* ]
|
181 |
-
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
182 |
-
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
183 |
-
*
|
184 |
-
* @return string // notice insert id
|
185 |
-
*
|
186 |
-
* @throws Exception
|
187 |
-
*/
|
188 |
-
public function addBothNextAndFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
189 |
-
{
|
190 |
-
$this->addNextStepNotice($item, $mode, $uniqueId);
|
191 |
-
$this->addFinalReportNotice($item, $mode, $uniqueId);
|
192 |
-
}
|
193 |
-
|
194 |
-
/**
|
195 |
-
*
|
196 |
-
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
197 |
-
* // if array must be [
|
198 |
-
* 'shortMsg' => text,
|
199 |
-
* 'level' => level,
|
200 |
-
* 'longMsg' => html text,
|
201 |
-
* 'sections' => sections list,
|
202 |
-
* 'faqLink' => [
|
203 |
-
* 'url' => external link
|
204 |
-
* 'label' => link text if empty get external url link
|
205 |
-
* ]
|
206 |
-
* ]
|
207 |
-
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
208 |
-
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
209 |
-
*
|
210 |
-
* @return string // notice insert id
|
211 |
-
*
|
212 |
-
* @throws Exception
|
213 |
-
*/
|
214 |
-
public function addNextStepNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
215 |
-
{
|
216 |
-
if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
|
217 |
-
throw new Exception('Invalid item param');
|
218 |
-
}
|
219 |
-
return self::addReportNoticeToList($this->nextStepNotices, $item, $mode, $uniqueId);
|
220 |
-
}
|
221 |
-
|
222 |
-
/**
|
223 |
-
* addNextStepNotice wrapper to add simple message with error level
|
224 |
-
*
|
225 |
-
* @param string $message
|
226 |
-
* @param int $level // warning level
|
227 |
-
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
228 |
-
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
229 |
-
*
|
230 |
-
* @return string // notice insert id
|
231 |
-
*
|
232 |
-
* @throws Exception
|
233 |
-
*/
|
234 |
-
public function addNextStepNoticeMessage($message, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
|
235 |
-
{
|
236 |
-
return $this->addNextStepNotice(array(
|
237 |
-
'shortMsg' => $message,
|
238 |
-
'level' => $level,
|
239 |
-
), $mode, $uniqueId);
|
240 |
-
}
|
241 |
-
|
242 |
-
/**
|
243 |
-
*
|
244 |
-
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
245 |
-
* // if array must be [
|
246 |
-
* 'shortMsg' => text,
|
247 |
-
* 'level' => level,
|
248 |
-
* 'longMsg' => html text,
|
249 |
-
* 'sections' => sections list,
|
250 |
-
* 'faqLink' => [
|
251 |
-
* 'url' => external link
|
252 |
-
* 'label' => link text if empty get external url link
|
253 |
-
* ]
|
254 |
-
* ]
|
255 |
-
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
256 |
-
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
257 |
-
*
|
258 |
-
* @return string // notice insert id
|
259 |
-
*
|
260 |
-
* @throws Exception
|
261 |
-
*/
|
262 |
-
public function addFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
263 |
-
{
|
264 |
-
if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
|
265 |
-
throw new Exception('Invalid item param');
|
266 |
-
}
|
267 |
-
return self::addReportNoticeToList($this->finalReporNotices, $item, $mode, $uniqueId);
|
268 |
-
}
|
269 |
-
|
270 |
-
/**
|
271 |
-
* addFinalReportNotice wrapper to add simple message with error level
|
272 |
-
*
|
273 |
-
* @param string $message
|
274 |
-
* @param string|string[] $sections // message sections on final report
|
275 |
-
* @param int $level // warning level
|
276 |
-
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
277 |
-
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
278 |
-
*
|
279 |
-
* @return string // notice insert id
|
280 |
-
*
|
281 |
-
* @throws Exception
|
282 |
-
*/
|
283 |
-
public function addFinalReportNoticeMessage($message, $sections, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
|
284 |
-
{
|
285 |
-
return $this->addFinalReportNotice(array(
|
286 |
-
'shortMsg' => $message,
|
287 |
-
'level' => $level,
|
288 |
-
'sections' => $sections,
|
289 |
-
), $mode, $uniqueId);
|
290 |
-
}
|
291 |
-
|
292 |
-
/**
|
293 |
-
*
|
294 |
-
* @param array $list
|
295 |
-
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
296 |
-
* // if array must be [
|
297 |
-
* 'shortMsg' => text,
|
298 |
-
* 'level' => level,
|
299 |
-
* 'longMsg' => html text,
|
300 |
-
* 'sections' => sections list,
|
301 |
-
* 'faqLink' => [
|
302 |
-
* 'url' => external link
|
303 |
-
* 'label' => link text if empty get external url link
|
304 |
-
* ]
|
305 |
-
* ]
|
306 |
-
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
307 |
-
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
308 |
-
*
|
309 |
-
* @return string // notice insert id
|
310 |
-
*
|
311 |
-
* @throws Exception
|
312 |
-
*/
|
313 |
-
private static function addReportNoticeToList(&$list, $item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
314 |
-
{
|
315 |
-
switch ($mode) {
|
316 |
-
case self::ADD_UNIQUE:
|
317 |
-
if (empty($uniqueId)) {
|
318 |
-
throw new Exception('uniqueId can\'t be empty');
|
319 |
-
}
|
320 |
-
if (isset($list[$uniqueId])) {
|
321 |
-
return $uniqueId;
|
322 |
-
}
|
323 |
-
// no break -> continue on unique update
|
324 |
-
case self::ADD_UNIQUE_UPDATE:
|
325 |
-
if (empty($uniqueId)) {
|
326 |
-
throw new Exception('uniqueId can\'t be empty');
|
327 |
-
}
|
328 |
-
$insertId = $uniqueId;
|
329 |
-
break;
|
330 |
-
case self::ADD_UNIQUE_APPEND_IF_EXISTS:
|
331 |
-
if (empty($uniqueId)) {
|
332 |
-
throw new Exception('uniqueId can\'t be empty');
|
333 |
-
}
|
334 |
-
if (!isset($list[$uniqueId])) {
|
335 |
-
return false;
|
336 |
-
}
|
337 |
-
// no break
|
338 |
-
case self::ADD_UNIQUE_APPEND:
|
339 |
-
if (empty($uniqueId)) {
|
340 |
-
throw new Exception('uniqueId can\'t be empty');
|
341 |
-
}
|
342 |
-
$insertId = $uniqueId;
|
343 |
-
// if item id exist append long msg
|
344 |
-
if (isset($list[$uniqueId])) {
|
345 |
-
$tempObj = self::getObjFromParams($item);
|
346 |
-
$list[$uniqueId]->longMsg .= $tempObj->longMsg;
|
347 |
-
$item = $list[$uniqueId];
|
348 |
-
}
|
349 |
-
break;
|
350 |
-
case self::ADD_UNIQUE_PREPEND_IF_EXISTS:
|
351 |
-
if (empty($uniqueId)) {
|
352 |
-
throw new Exception('uniqueId can\'t be empty');
|
353 |
-
}
|
354 |
-
if (!isset($list[$uniqueId])) {
|
355 |
-
return false;
|
356 |
-
}
|
357 |
-
// no break
|
358 |
-
case self::ADD_UNIQUE_PREPEND:
|
359 |
-
if (empty($uniqueId)) {
|
360 |
-
throw new Exception('uniqueId can\'t be empty');
|
361 |
-
}
|
362 |
-
$insertId = $uniqueId;
|
363 |
-
// if item id exist append long msg
|
364 |
-
if (isset($list[$uniqueId])) {
|
365 |
-
$tempObj = self::getObjFromParams($item);
|
366 |
-
$list[$uniqueId]->longMsg = $tempObj->longMsg.$list[$uniqueId]->longMsg;
|
367 |
-
$item = $list[$uniqueId];
|
368 |
-
}
|
369 |
-
break;
|
370 |
-
case self::ADD_NORMAL:
|
371 |
-
default:
|
372 |
-
if (empty($uniqueId)) {
|
373 |
-
$insertId = self::getNewAutoUniqueId();
|
374 |
-
} else {
|
375 |
-
$insertId = $uniqueId;
|
376 |
-
}
|
377 |
-
}
|
378 |
-
|
379 |
-
$list[$insertId] = self::getObjFromParams($item);
|
380 |
-
return $insertId;
|
381 |
-
}
|
382 |
-
|
383 |
-
/**
|
384 |
-
*
|
385 |
-
* @param string|array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
386 |
-
* // if array must be [
|
387 |
-
* 'shortMsg' => text,
|
388 |
-
* 'level' => level,
|
389 |
-
* 'longMsg' => html text,
|
390 |
-
* 'sections' => sections list,
|
391 |
-
* 'faqLink' => [
|
392 |
-
* 'url' => external link
|
393 |
-
* 'label' => link text if empty get external url link
|
394 |
-
* ]
|
395 |
-
* ]
|
396 |
-
* @param int $level message level considered only in the case where $item is a string.
|
397 |
-
* @return \DUPX_NOTICE_ITEM
|
398 |
-
*
|
399 |
-
* @throws Exception
|
400 |
-
*/
|
401 |
-
private static function getObjFromParams($item, $level = DUPX_NOTICE_ITEM::INFO)
|
402 |
-
{
|
403 |
-
if ($item instanceof DUPX_NOTICE_ITEM) {
|
404 |
-
$newObj = $item;
|
405 |
-
} else if (is_array($item)) {
|
406 |
-
$newObj = DUPX_NOTICE_ITEM::getItemFromArray($item);
|
407 |
-
} else if (is_string($item)) {
|
408 |
-
$newObj = new DUPX_NOTICE_ITEM($item, $level);
|
409 |
-
} else {
|
410 |
-
throw new Exception('Notice input not valid');
|
411 |
-
}
|
412 |
-
|
413 |
-
return $newObj;
|
414 |
-
}
|
415 |
-
|
416 |
-
/**
|
417 |
-
*
|
418 |
-
* @param null|string $section if null is count global
|
419 |
-
* @param int $level error level
|
420 |
-
* @param string $operator > < >= <= = !=
|
421 |
-
*
|
422 |
-
* @return int
|
423 |
-
*/
|
424 |
-
public function countFinalReportNotices($section = null, $level = DUPX_NOTICE_ITEM::INFO, $operator = '>=')
|
425 |
-
{
|
426 |
-
$result = 0;
|
427 |
-
foreach ($this->finalReporNotices as $notice) {
|
428 |
-
if (is_null($section) || in_array($section, $notice->sections)) {
|
429 |
-
switch ($operator) {
|
430 |
-
case '>=':
|
431 |
-
$result += (int) ($notice->level >= $level);
|
432 |
-
break;
|
433 |
-
case '>':
|
434 |
-
$result += (int) ($notice->level > $level);
|
435 |
-
break;
|
436 |
-
case '=':
|
437 |
-
$result += (int) ($notice->level = $level);
|
438 |
-
break;
|
439 |
-
case '<=':
|
440 |
-
$result += (int) ($notice->level <= $level);
|
441 |
-
break;
|
442 |
-
case '<':
|
443 |
-
$result += (int) ($notice->level < $level);
|
444 |
-
break;
|
445 |
-
case '!=':
|
446 |
-
$result += (int) ($notice->level != $level);
|
447 |
-
break;
|
448 |
-
}
|
449 |
-
}
|
450 |
-
}
|
451 |
-
return $result;
|
452 |
-
}
|
453 |
-
|
454 |
-
/**
|
455 |
-
* sort final report notice from priority and notice level
|
456 |
-
*/
|
457 |
-
public function sortFinalReport()
|
458 |
-
{
|
459 |
-
uasort($this->finalReporNotices, 'DUPX_NOTICE_ITEM::sortNoticeForPriorityAndLevel');
|
460 |
-
}
|
461 |
-
|
462 |
-
/**
|
463 |
-
* display final final report notice section
|
464 |
-
*
|
465 |
-
* @param string $section
|
466 |
-
*/
|
467 |
-
public function displayFinalReport($section)
|
468 |
-
{
|
469 |
-
foreach ($this->finalReporNotices as $id => $notice) {
|
470 |
-
if (in_array($section, $notice->sections)) {
|
471 |
-
self::finalReportNotice($id, $notice);
|
472 |
-
}
|
473 |
-
}
|
474 |
-
}
|
475 |
-
|
476 |
-
/**
|
477 |
-
*
|
478 |
-
* @param string $section
|
479 |
-
* @param string $title
|
480 |
-
*/
|
481 |
-
public function displayFinalRepostSectionHtml($section, $title)
|
482 |
-
{
|
483 |
-
if ($this->haveSection($section)) {
|
484 |
-
?>
|
485 |
-
<div id="report-section-<?php echo $section; ?>" class="section" >
|
486 |
-
<div class="section-title" ><?php echo $title; ?></div>
|
487 |
-
<div class="section-content">
|
488 |
-
<?php
|
489 |
-
$this->displayFinalReport($section);
|
490 |
-
?>
|
491 |
-
</div>
|
492 |
-
</div>
|
493 |
-
<?php
|
494 |
-
}
|
495 |
-
}
|
496 |
-
|
497 |
-
/**
|
498 |
-
*
|
499 |
-
* @param string $section
|
500 |
-
* @return boolean
|
501 |
-
*/
|
502 |
-
public function haveSection($section)
|
503 |
-
{
|
504 |
-
foreach ($this->finalReporNotices as $notice) {
|
505 |
-
if (in_array($section, $notice->sections)) {
|
506 |
-
return true;
|
507 |
-
}
|
508 |
-
}
|
509 |
-
return false;
|
510 |
-
}
|
511 |
-
|
512 |
-
/**
|
513 |
-
*
|
514 |
-
* @param null|string $section if null is a global result
|
515 |
-
*
|
516 |
-
* @return int // returns the worst level found
|
517 |
-
*
|
518 |
-
*/
|
519 |
-
public function getSectionErrLevel($section = null)
|
520 |
-
{
|
521 |
-
$result = DUPX_NOTICE_ITEM::INFO;
|
522 |
-
|
523 |
-
foreach ($this->finalReporNotices as $notice) {
|
524 |
-
if (is_null($section) || in_array($section, $notice->sections)) {
|
525 |
-
$result = max($result, $notice->level);
|
526 |
-
}
|
527 |
-
}
|
528 |
-
return $result;
|
529 |
-
}
|
530 |
-
|
531 |
-
/**
|
532 |
-
*
|
533 |
-
* @param string $section
|
534 |
-
* @param bool $echo
|
535 |
-
* @return void|string
|
536 |
-
*/
|
537 |
-
public function getSectionErrLevelHtml($section = null, $echo = true)
|
538 |
-
{
|
539 |
-
return self::getErrorLevelHtml($this->getSectionErrLevel($section), $echo);
|
540 |
-
}
|
541 |
-
|
542 |
-
/**
|
543 |
-
* Displa next step notice message
|
544 |
-
*
|
545 |
-
* @param bool $deleteListAfterDisaply
|
546 |
-
* @return void
|
547 |
-
*/
|
548 |
-
public function displayStepMessages($deleteListAfterDisaply = true)
|
549 |
-
{
|
550 |
-
if (empty($this->nextStepNotices)) {
|
551 |
-
return;
|
552 |
-
}
|
553 |
-
?>
|
554 |
-
<div id="step-messages">
|
555 |
-
<?php
|
556 |
-
foreach ($this->nextStepNotices as $notice) {
|
557 |
-
self::stepMsg($notice);
|
558 |
-
}
|
559 |
-
?>
|
560 |
-
</div>
|
561 |
-
<?php
|
562 |
-
if ($deleteListAfterDisaply) {
|
563 |
-
$this->nextStepNotices = array();
|
564 |
-
$this->saveNotices();
|
565 |
-
}
|
566 |
-
}
|
567 |
-
|
568 |
-
/**
|
569 |
-
*
|
570 |
-
* @param DUPX_NOTICE_ITEM $notice
|
571 |
-
*/
|
572 |
-
private static function stepMsg($notice)
|
573 |
-
{
|
574 |
-
$classes = array(
|
575 |
-
'notice',
|
576 |
-
'next-step',
|
577 |
-
self::getClassFromLevel($notice->level)
|
578 |
-
);
|
579 |
-
$haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
|
580 |
-
?>
|
581 |
-
<div class="<?php echo implode(' ', $classes); ?>">
|
582 |
-
<div class="title">
|
583 |
-
<?php echo self::getNextStepLevelPrefixMessage($notice->level).': <b>'.htmlentities($notice->shortMsg).'</b>'; ?>
|
584 |
-
</div>
|
585 |
-
<?php if ($haveContent) { ?>
|
586 |
-
<div class="title-separator" ></div>
|
587 |
-
<?php
|
588 |
-
ob_start();
|
589 |
-
if (!empty($notice->faqLink)) {
|
590 |
-
?>
|
591 |
-
See FAQ: <a href="<?php echo $notice->faqLink['url']; ?>" >
|
592 |
-
<b><?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?></b>
|
593 |
-
</a>
|
594 |
-
<?php
|
595 |
-
}
|
596 |
-
if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
|
597 |
-
echo '<br><br>';
|
598 |
-
}
|
599 |
-
if (!empty($notice->longMsg)) {
|
600 |
-
switch ($notice->longMsgMode) {
|
601 |
-
case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
|
602 |
-
echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
|
603 |
-
break;
|
604 |
-
case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
|
605 |
-
echo $notice->longMsg;
|
606 |
-
break;
|
607 |
-
case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
|
608 |
-
default:
|
609 |
-
echo htmlentities($notice->longMsg);
|
610 |
-
}
|
611 |
-
}
|
612 |
-
$longContent = ob_get_clean();
|
613 |
-
DUPX_U_Html::getMoreContent($longContent, 'info', 200);
|
614 |
-
}
|
615 |
-
?>
|
616 |
-
</div>
|
617 |
-
<?php
|
618 |
-
}
|
619 |
-
|
620 |
-
/**
|
621 |
-
*
|
622 |
-
* @param string $id
|
623 |
-
* @param DUPX_NOTICE_ITEM $notice
|
624 |
-
*/
|
625 |
-
private static function finalReportNotice($id, $notice)
|
626 |
-
{
|
627 |
-
$classes = array(
|
628 |
-
'notice-report',
|
629 |
-
'notice',
|
630 |
-
self::getClassFromLevel($notice->level)
|
631 |
-
);
|
632 |
-
$haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
|
633 |
-
$contentId = 'notice-content-'.$id;
|
634 |
-
$iconClasses = $haveContent ? 'fa fa-caret-right' : 'fa fa-toggle-empty';
|
635 |
-
$toggleLinkData = $haveContent ? 'data-type="toggle" data-target="#'.$contentId.'"' : '';
|
636 |
-
?>
|
637 |
-
<div class="<?php echo implode(' ', $classes); ?>">
|
638 |
-
<div class="title" <?php echo $toggleLinkData; ?>>
|
639 |
-
<i class="<?php echo $iconClasses; ?>"></i> <?php echo htmlentities($notice->shortMsg); ?>
|
640 |
-
</div>
|
641 |
-
<?php
|
642 |
-
if ($haveContent) {
|
643 |
-
$infoClasses = array('info');
|
644 |
-
if (!$notice->open) {
|
645 |
-
$infoClasses[] = 'no-display';
|
646 |
-
}
|
647 |
-
?>
|
648 |
-
<div id="<?php echo $contentId; ?>" class="<?php echo implode(' ', $infoClasses); ?>" >
|
649 |
-
<?php
|
650 |
-
if (!empty($notice->faqLink)) {
|
651 |
-
?>
|
652 |
-
<b>See FAQ</b>: <a href="<?php echo $notice->faqLink['url']; ?>" >
|
653 |
-
<?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?>
|
654 |
-
</a>
|
655 |
-
<?php
|
656 |
-
}
|
657 |
-
if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
|
658 |
-
echo '<br><br>';
|
659 |
-
}
|
660 |
-
if (!empty($notice->longMsg)) {
|
661 |
-
switch ($notice->longMsgMode) {
|
662 |
-
case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
|
663 |
-
echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
|
664 |
-
break;
|
665 |
-
case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
|
666 |
-
echo $notice->longMsg;
|
667 |
-
break;
|
668 |
-
case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
|
669 |
-
default:
|
670 |
-
echo htmlentities($notice->longMsg);
|
671 |
-
}
|
672 |
-
}
|
673 |
-
?>
|
674 |
-
</div>
|
675 |
-
<?php
|
676 |
-
}
|
677 |
-
?>
|
678 |
-
</div>
|
679 |
-
<?php
|
680 |
-
}
|
681 |
-
|
682 |
-
/**
|
683 |
-
*
|
684 |
-
* @param DUPX_NOTICE_ITEM $notice
|
685 |
-
*/
|
686 |
-
private static function noticeToText($notice)
|
687 |
-
{
|
688 |
-
$result = '-----------------------'."\n".
|
689 |
-
'['.self::getNextStepLevelPrefixMessage($notice->level, false).'] '.$notice->shortMsg;
|
690 |
-
|
691 |
-
if (!empty($notice->sections)) {
|
692 |
-
$result .= "\n\t".'SECTIONS: '.implode(',', $notice->sections);
|
693 |
-
}
|
694 |
-
if (!empty($notice->longMsg)) {
|
695 |
-
$result .= "\n\t".'LONG MSG: '.$notice->longMsg;
|
696 |
-
}
|
697 |
-
return $result."\n";
|
698 |
-
}
|
699 |
-
|
700 |
-
public function nextStepLog()
|
701 |
-
{
|
702 |
-
if (!empty($this->nextStepNotices)) {
|
703 |
-
DUPX_Log::info(
|
704 |
-
'===================================='."\n".
|
705 |
-
'NEXT STEP NOTICES'."\n".
|
706 |
-
'====================================');
|
707 |
-
foreach ($this->nextStepNotices as $notice) {
|
708 |
-
DUPX_Log::info(self::noticeToText($notice));
|
709 |
-
}
|
710 |
-
DUPX_Log::info(
|
711 |
-
'====================================');
|
712 |
-
}
|
713 |
-
}
|
714 |
-
|
715 |
-
public function finalReportLog($sections = array())
|
716 |
-
{
|
717 |
-
if (!empty($this->finalReporNotices)) {
|
718 |
-
DUPX_Log::info(
|
719 |
-
'===================================='."\n".
|
720 |
-
'FINAL REPORT NOTICES LIST'."\n".
|
721 |
-
'====================================');
|
722 |
-
foreach ($this->finalReporNotices as $notice) {
|
723 |
-
if (count(array_intersect($notice->sections, $sections)) > 0) {
|
724 |
-
DUPX_Log::info(self::noticeToText($notice));
|
725 |
-
}
|
726 |
-
}
|
727 |
-
DUPX_Log::info(
|
728 |
-
'====================================');
|
729 |
-
}
|
730 |
-
}
|
731 |
-
|
732 |
-
/**
|
733 |
-
* get html class from level
|
734 |
-
*
|
735 |
-
* @param int $level
|
736 |
-
* @return string
|
737 |
-
*/
|
738 |
-
private static function getClassFromLevel($level)
|
739 |
-
{
|
740 |
-
switch ($level) {
|
741 |
-
case DUPX_NOTICE_ITEM::INFO:
|
742 |
-
return 'l-info';
|
743 |
-
case DUPX_NOTICE_ITEM::NOTICE:
|
744 |
-
return 'l-notice';
|
745 |
-
case DUPX_NOTICE_ITEM::SOFT_WARNING:
|
746 |
-
return 'l-swarning';
|
747 |
-
case DUPX_NOTICE_ITEM::HARD_WARNING:
|
748 |
-
return 'l-hwarning';
|
749 |
-
case DUPX_NOTICE_ITEM::CRITICAL:
|
750 |
-
return 'l-critical';
|
751 |
-
case DUPX_NOTICE_ITEM::FATAL:
|
752 |
-
return 'l-fatal';
|
753 |
-
}
|
754 |
-
}
|
755 |
-
|
756 |
-
/**
|
757 |
-
* get level label from level
|
758 |
-
*
|
759 |
-
* @param int $level
|
760 |
-
* @param bool $echo
|
761 |
-
* @return type
|
762 |
-
*/
|
763 |
-
public static function getErrorLevelHtml($level, $echo = true)
|
764 |
-
{
|
765 |
-
switch ($level) {
|
766 |
-
case DUPX_NOTICE_ITEM::INFO:
|
767 |
-
$label = 'good';
|
768 |
-
break;
|
769 |
-
case DUPX_NOTICE_ITEM::NOTICE:
|
770 |
-
$label = 'good';
|
771 |
-
break;
|
772 |
-
case DUPX_NOTICE_ITEM::SOFT_WARNING:
|
773 |
-
$label = 'warning';
|
774 |
-
break;
|
775 |
-
case DUPX_NOTICE_ITEM::HARD_WARNING:
|
776 |
-
$label = 'warning';
|
777 |
-
break;
|
778 |
-
case DUPX_NOTICE_ITEM::CRITICAL:
|
779 |
-
$label = 'critical error';
|
780 |
-
break;
|
781 |
-
case DUPX_NOTICE_ITEM::FATAL:
|
782 |
-
$label = 'fatal error';
|
783 |
-
break;
|
784 |
-
default:
|
785 |
-
return;
|
786 |
-
}
|
787 |
-
$classes = self::getClassFromLevel($level);
|
788 |
-
ob_start();
|
789 |
-
?>
|
790 |
-
<span class="notice-level-status <?php echo $classes; ?>"><?php echo $label; ?></span>
|
791 |
-
<?php
|
792 |
-
if ($echo) {
|
793 |
-
ob_end_flush();
|
794 |
-
} else {
|
795 |
-
return ob_get_clean();
|
796 |
-
}
|
797 |
-
}
|
798 |
-
|
799 |
-
/**
|
800 |
-
* get next step message prefix
|
801 |
-
*
|
802 |
-
* @param int $level
|
803 |
-
* @param bool $echo
|
804 |
-
* @return string
|
805 |
-
*/
|
806 |
-
public static function getNextStepLevelPrefixMessage($level, $echo = true)
|
807 |
-
{
|
808 |
-
switch ($level) {
|
809 |
-
case DUPX_NOTICE_ITEM::INFO:
|
810 |
-
$label = 'INFO';
|
811 |
-
break;
|
812 |
-
case DUPX_NOTICE_ITEM::NOTICE:
|
813 |
-
$label = 'NOTICE';
|
814 |
-
break;
|
815 |
-
case DUPX_NOTICE_ITEM::SOFT_WARNING:
|
816 |
-
$label = 'WARNING';
|
817 |
-
break;
|
818 |
-
case DUPX_NOTICE_ITEM::HARD_WARNING:
|
819 |
-
$label = 'WARNING';
|
820 |
-
break;
|
821 |
-
case DUPX_NOTICE_ITEM::CRITICAL:
|
822 |
-
$label = 'CRITICAL ERROR';
|
823 |
-
break;
|
824 |
-
case DUPX_NOTICE_ITEM::FATAL:
|
825 |
-
$label = 'FATAL ERROR';
|
826 |
-
break;
|
827 |
-
default:
|
828 |
-
return;
|
829 |
-
}
|
830 |
-
|
831 |
-
if ($echo) {
|
832 |
-
echo $label;
|
833 |
-
} else {
|
834 |
-
return $label;
|
835 |
-
}
|
836 |
-
}
|
837 |
-
|
838 |
-
/**
|
839 |
-
* get unique id
|
840 |
-
*
|
841 |
-
* @return string
|
842 |
-
*/
|
843 |
-
private static function getNewAutoUniqueId()
|
844 |
-
{
|
845 |
-
self::$uniqueCountId ++;
|
846 |
-
return self::DEFAULT_UNIQUE_ID_PREFIX.self::$uniqueCountId;
|
847 |
-
}
|
848 |
-
|
849 |
-
/**
|
850 |
-
* function for internal test
|
851 |
-
*
|
852 |
-
* display all messages levels
|
853 |
-
*/
|
854 |
-
public static function testNextStepMessaesLevels()
|
855 |
-
{
|
856 |
-
$manager = self::getInstance();
|
857 |
-
$manager->addNextStepNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', DUPX_NOTICE_ITEM::INFO);
|
858 |
-
$manager->addNextStepNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', DUPX_NOTICE_ITEM::NOTICE);
|
859 |
-
$manager->addNextStepNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', DUPX_NOTICE_ITEM::SOFT_WARNING);
|
860 |
-
$manager->addNextStepNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', DUPX_NOTICE_ITEM::HARD_WARNING);
|
861 |
-
$manager->addNextStepNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', DUPX_NOTICE_ITEM::CRITICAL);
|
862 |
-
$manager->addNextStepNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', DUPX_NOTICE_ITEM::FATAL);
|
863 |
-
$manager->saveNotices();
|
864 |
-
}
|
865 |
-
|
866 |
-
/**
|
867 |
-
* test function
|
868 |
-
*/
|
869 |
-
public static function testNextStepFullMessageData()
|
870 |
-
{
|
871 |
-
$manager = self::getInstance();
|
872 |
-
$longMsg = <<<LONGMSG
|
873 |
-
<b>Formattend long text</b><br>
|
874 |
-
<ul>
|
875 |
-
<li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
|
876 |
-
<li>Nunc venenatis eros et sapien ornare consequat.</li>
|
877 |
-
<li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
|
878 |
-
<li>Etiam volutpat lectus quis risus molestie faucibus.</li>
|
879 |
-
<li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
|
880 |
-
<li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
|
881 |
-
</ul>
|
882 |
-
LONGMSG;
|
883 |
-
$manager->addNextStepNotice(array(
|
884 |
-
'shortMsg' => 'Full elements next step message MODE HTML',
|
885 |
-
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
886 |
-
'longMsg' => $longMsg,
|
887 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
888 |
-
'faqLink' => array(
|
889 |
-
'url' => 'http://www.google.it',
|
890 |
-
'label' => 'google link'
|
891 |
-
)
|
892 |
-
));
|
893 |
-
|
894 |
-
$longMsg = <<<LONGMSG
|
895 |
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
|
896 |
-
Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
|
897 |
-
|
898 |
-
Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
|
899 |
-
at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
|
900 |
-
Ut ac faucibus tellus, in lobortis odio.
|
901 |
-
LONGMSG;
|
902 |
-
$manager->addNextStepNotice(array(
|
903 |
-
'shortMsg' => 'Full elements next step message MODE PRE',
|
904 |
-
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
905 |
-
'longMsg' => $longMsg,
|
906 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE,
|
907 |
-
'faqLink' => array(
|
908 |
-
'url' => 'http://www.google.it',
|
909 |
-
'label' => 'google link'
|
910 |
-
)
|
911 |
-
));
|
912 |
-
|
913 |
-
$longMsg = <<<LONGMSG
|
914 |
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
|
915 |
-
Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
|
916 |
-
|
917 |
-
Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
|
918 |
-
at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
|
919 |
-
Ut ac faucibus tellus, in lobortis odio.
|
920 |
-
LONGMSG;
|
921 |
-
$manager->addNextStepNotice(array(
|
922 |
-
'shortMsg' => 'Full elements next step message MODE DEFAULT',
|
923 |
-
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
924 |
-
'longMsg' => $longMsg,
|
925 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
|
926 |
-
'faqLink' => array(
|
927 |
-
'url' => 'http://www.google.it',
|
928 |
-
'label' => 'google link'
|
929 |
-
)
|
930 |
-
));
|
931 |
-
|
932 |
-
|
933 |
-
$longMsg = <<<LONGMSG
|
934 |
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam cursus porttitor consectetur. Nunc faucibus elementum nisl nec ornare. Phasellus sit amet urna in diam ultricies ornare nec sit amet nibh. Nulla a aliquet leo. Quisque aliquet posuere lectus sit amet commodo. Nullam tempus enim eget urna rutrum egestas. Aliquam eget lorem nisl. Nulla tincidunt massa erat. Phasellus lectus tellus, mollis sit amet aliquam in, dapibus quis metus. Nunc venenatis nulla vitae convallis accumsan.
|
935 |
-
|
936 |
-
Mauris eu ullamcorper metus. Aenean ultricies et turpis eget mollis. Aliquam auctor, elit scelerisque placerat pellentesque, quam augue fermentum lectus, vel pretium nisi justo sit amet ante. Donec blandit porttitor tempus. Duis vulputate nulla ut orci rutrum, et consectetur urna mollis. Sed at iaculis velit. Pellentesque id quam turpis. Curabitur eu ligula velit. Cras gravida, ipsum sed iaculis eleifend, mauris nunc posuere quam, vel blandit nisi justo congue ligula. Phasellus aliquam eu odio ac porttitor. Fusce dictum mollis turpis sit amet fringilla.
|
937 |
-
|
938 |
-
Nulla eu ligula mauris. Fusce lobortis ligula elit, a interdum nibh pulvinar eu. Pellentesque rhoncus nec turpis id blandit. Morbi fringilla, justo non varius consequat, arcu ante efficitur ante, sit amet cursus lorem elit vel odio. Phasellus neque ligula, vehicula vel ipsum sed, volutpat dignissim eros. Curabitur at lacus id felis elementum auctor. Nullam ac tempus nisi. Phasellus nibh purus, aliquam nec purus ut, sodales lobortis nulla. Cras viverra dictum magna, ac malesuada nibh dictum ac. Mauris euismod, magna sit amet pretium posuere, ligula nibh ultrices tellus, sit amet pretium odio urna egestas justo. Suspendisse purus erat, eleifend sed magna in, efficitur interdum nibh.
|
939 |
-
|
940 |
-
Vivamus nibh nunc, fermentum non tortor volutpat, consectetur vulputate velit. Phasellus lobortis, purus et faucibus mollis, metus eros viverra ante, sit amet euismod nibh est eu orci. Duis sodales cursus lacinia. Praesent laoreet ut ipsum ut interdum. Praesent venenatis massa vitae ligula consequat aliquet. Fusce in purus in odio molestie laoreet at ac augue. Fusce consectetur elit a magna mollis aliquet.
|
941 |
-
|
942 |
-
Nulla eros nisi, dapibus eget diam vitae, tincidunt blandit odio. Fusce interdum tellus nec varius condimentum. Fusce non magna a purus sodales imperdiet sit amet vitae ligula. Quisque viverra leo sit amet mi egestas, et posuere nunc tincidunt. Suspendisse feugiat malesuada urna sed tincidunt. Morbi a urna sed magna volutpat pellentesque sit amet ac mauris. Nulla sed ultrices dui. Etiam massa arcu, tempor ut erat at, cursus malesuada ipsum. Duis sit amet felis dolor.
|
943 |
-
|
944 |
-
Morbi gravida nisl nunc, vulputate iaculis risus vehicula non. Proin cursus, velit et laoreet consectetur, lacus libero sagittis lacus, quis accumsan odio lectus non erat. Aenean dolor lectus, euismod sit amet justo eget, dictum gravida nisl. Phasellus sed nunc non odio ullamcorper rhoncus non ut ipsum. Duis ante ligula, pellentesque sit amet imperdiet eget, congue vel dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Suspendisse luctus leo eget justo mollis, convallis convallis ex suscipit. Integer et justo eget odio lobortis sollicitudin. Pellentesque accumsan rhoncus augue, luctus suscipit ex accumsan nec. Maecenas lacinia consectetur risus at bibendum. Etiam venenatis purus lorem, sit amet elementum turpis tristique eu. Proin vulputate faucibus feugiat. Nunc vehicula congue odio consequat vulputate. Quisque bibendum augue id iaculis faucibus. Donec blandit cursus sem, eget accumsan orci commodo sed.
|
945 |
-
|
946 |
-
Suspendisse iaculis est quam, sed scelerisque purus tincidunt non. Cras hendrerit ante turpis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse purus ipsum, rutrum id sem in, venenatis laoreet metus. Aliquam ac bibendum mauris. Cras egestas rhoncus est, sed lacinia nibh vestibulum id. Proin diam quam, sagittis congue molestie ac, rhoncus et mauris. Phasellus massa neque, ornare vel erat a, rutrum pharetra arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi et nulla eget massa auctor fermentum. Quisque maximus tellus sed cursus cursus. Ut vehicula erat at purus aliquet, quis imperdiet dui sagittis. Nullam eget quam leo.
|
947 |
-
|
948 |
-
Nulla magna ipsum, congue nec dui ut, lacinia malesuada felis. Cras mattis metus non maximus venenatis. Aliquam euismod est vitae erat sollicitudin, at pellentesque augue sollicitudin. Curabitur euismod maximus cursus. In tortor dui, convallis sed sapien ac, varius congue metus. Nunc ullamcorper ac orci sit amet finibus. Vivamus molestie nibh vitae quam rhoncus, eu ultrices est molestie. Maecenas consectetur eu quam sit amet placerat.
|
949 |
-
|
950 |
-
Curabitur ut fermentum mauris. Donec et congue nibh. Sed cursus elit sit amet convallis varius. Donec malesuada porta odio condimentum varius. Pellentesque ornare tempor ante, ut volutpat nulla lobortis sed. Nunc congue aliquet erat ac elementum. Quisque a ex sit amet turpis placerat sagittis eget ac ligula. Etiam in augue malesuada, aliquam est non, lacinia justo. Vivamus tincidunt dolor orci, id dignissim lorem maximus at. Vivamus ligula mauris, venenatis vel nibh id, lacinia ultrices ipsum. Mauris cursus, urna ac rutrum aliquet, risus ipsum tincidunt purus, sit amet blandit nunc sem sit amet nibh.
|
951 |
-
|
952 |
-
Nam eleifend risus lacus, eu pharetra risus egestas eu. Maecenas hendrerit nisl in semper placerat. Vestibulum massa tellus, laoreet non euismod quis, sollicitudin id sapien. Morbi vel cursus metus. Aenean tincidunt nisi est, ut elementum est auctor id. Duis auctor elit leo, ac scelerisque risus suscipit et. Pellentesque lectus nisi, ultricies in elit sed, pulvinar iaculis massa. Morbi viverra eros mi, pretium facilisis neque egestas id. Curabitur non massa accumsan, porttitor sem vitae, ultricies lacus. Curabitur blandit nisl velit. Mauris sollicitudin ultricies purus sit amet placerat. Fusce ac neque sed leo venenatis laoreet ut non ex. Integer elementum rhoncus orci, eu maximus neque tempus eu. Curabitur euismod dignissim tellus, vitae lacinia metus. Mauris imperdiet metus vitae vulputate accumsan. Duis eget luctus nibh, sit amet finibus libero.
|
953 |
-
|
954 |
-
LONGMSG;
|
955 |
-
$manager->addNextStepNotice(array(
|
956 |
-
'shortMsg' => 'Full elements LONG LONG',
|
957 |
-
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
958 |
-
'longMsg' => $longMsg,
|
959 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
|
960 |
-
'faqLink' => array(
|
961 |
-
'url' => 'http://www.google.it',
|
962 |
-
'label' => 'google link'
|
963 |
-
)
|
964 |
-
));
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
$manager->saveNotices();
|
970 |
-
}
|
971 |
-
|
972 |
-
/**
|
973 |
-
* test function
|
974 |
-
*/
|
975 |
-
public static function testFinalReporMessaesLevels()
|
976 |
-
{
|
977 |
-
$section = 'general';
|
978 |
-
|
979 |
-
$manager = self::getInstance();
|
980 |
-
$manager->addFinalReportNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', $section, DUPX_NOTICE_ITEM::INFO, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_0');
|
981 |
-
$manager->addFinalReportNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', $section, DUPX_NOTICE_ITEM::NOTICE, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_1');
|
982 |
-
$manager->addFinalReportNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', $section, DUPX_NOTICE_ITEM::SOFT_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_2');
|
983 |
-
$manager->addFinalReportNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', $section, DUPX_NOTICE_ITEM::HARD_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_3');
|
984 |
-
$manager->addFinalReportNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', $section, DUPX_NOTICE_ITEM::CRITICAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_4');
|
985 |
-
$manager->addFinalReportNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', $section, DUPX_NOTICE_ITEM::FATAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_5');
|
986 |
-
$manager->saveNotices();
|
987 |
-
}
|
988 |
-
|
989 |
-
/**
|
990 |
-
* test function
|
991 |
-
*/
|
992 |
-
public static function testFinalReportFullMessages()
|
993 |
-
{
|
994 |
-
$section = 'general';
|
995 |
-
$manager = self::getInstance();
|
996 |
-
|
997 |
-
$longMsg = <<<LONGMSG
|
998 |
-
<b>Formattend long text</b><br>
|
999 |
-
<ul>
|
1000 |
-
<li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
|
1001 |
-
<li>Nunc venenatis eros et sapien ornare consequat.</li>
|
1002 |
-
<li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
|
1003 |
-
<li>Etiam volutpat lectus quis risus molestie faucibus.</li>
|
1004 |
-
<li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
|
1005 |
-
<li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
|
1006 |
-
</ul>
|
1007 |
-
LONGMSG;
|
1008 |
-
|
1009 |
-
$manager->addFinalReportNotice(array(
|
1010 |
-
'shortMsg' => 'Full elements final report message',
|
1011 |
-
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
1012 |
-
'longMsg' => $longMsg,
|
1013 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
1014 |
-
'sections' => $section,
|
1015 |
-
'faqLink' => array(
|
1016 |
-
'url' => 'http://www.google.it',
|
1017 |
-
'label' => 'google link'
|
1018 |
-
)
|
1019 |
-
), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_1');
|
1020 |
-
|
1021 |
-
$manager->addFinalReportNotice(array(
|
1022 |
-
'shortMsg' => 'Full elements final report message info high priority',
|
1023 |
-
'level' => DUPX_NOTICE_ITEM::INFO,
|
1024 |
-
'longMsg' => $longMsg,
|
1025 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
1026 |
-
'sections' => $section,
|
1027 |
-
'faqLink' => array(
|
1028 |
-
'url' => 'http://www.google.it',
|
1029 |
-
'label' => 'google link'
|
1030 |
-
),
|
1031 |
-
'priority' => 5
|
1032 |
-
), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_2');
|
1033 |
-
$manager->saveNotices();
|
1034 |
-
}
|
1035 |
-
|
1036 |
-
//PHP 8 Requires method to be public
|
1037 |
-
public function __wakeup()
|
1038 |
-
{
|
1039 |
-
}
|
1040 |
-
|
1041 |
-
private function __clone()
|
1042 |
-
{
|
1043 |
-
|
1044 |
-
}
|
1045 |
-
}
|
1046 |
-
|
1047 |
-
class DUPX_NOTICE_ITEM
|
1048 |
-
{
|
1049 |
-
const INFO = 0;
|
1050 |
-
const NOTICE = 1;
|
1051 |
-
const SOFT_WARNING = 2;
|
1052 |
-
const HARD_WARNING = 3;
|
1053 |
-
const CRITICAL = 4;
|
1054 |
-
const FATAL = 5;
|
1055 |
-
const MSG_MODE_DEFAULT = 'def';
|
1056 |
-
const MSG_MODE_HTML = 'html';
|
1057 |
-
const MSG_MODE_PRE = 'pre';
|
1058 |
-
|
1059 |
-
/**
|
1060 |
-
*
|
1061 |
-
* @var string text
|
1062 |
-
*/
|
1063 |
-
public $shortMsg = '';
|
1064 |
-
|
1065 |
-
/**
|
1066 |
-
*
|
1067 |
-
* @var string html text
|
1068 |
-
*/
|
1069 |
-
public $longMsg = '';
|
1070 |
-
|
1071 |
-
/**
|
1072 |
-
*
|
1073 |
-
* @var bool if true long msg can be html
|
1074 |
-
*/
|
1075 |
-
public $longMsgMode = self::MSG_MODE_DEFAULT;
|
1076 |
-
|
1077 |
-
/**
|
1078 |
-
*
|
1079 |
-
* @var null|array // null = no faq link
|
1080 |
-
* array( 'label' => link text , 'url' => faq url)
|
1081 |
-
*/
|
1082 |
-
public $faqLink = array(
|
1083 |
-
'label' => '',
|
1084 |
-
'url' => ''
|
1085 |
-
);
|
1086 |
-
|
1087 |
-
/**
|
1088 |
-
*
|
1089 |
-
* @var string[] notice sections for final report only
|
1090 |
-
*/
|
1091 |
-
public $sections = array();
|
1092 |
-
|
1093 |
-
/**
|
1094 |
-
*
|
1095 |
-
* @var int
|
1096 |
-
*/
|
1097 |
-
public $level = self::NOTICE;
|
1098 |
-
|
1099 |
-
/**
|
1100 |
-
*
|
1101 |
-
* @var int
|
1102 |
-
*/
|
1103 |
-
public $priority = 10;
|
1104 |
-
|
1105 |
-
/**
|
1106 |
-
*
|
1107 |
-
* @var bool if true notice start open. For final report only
|
1108 |
-
*/
|
1109 |
-
public $open = false;
|
1110 |
-
|
1111 |
-
/**
|
1112 |
-
*
|
1113 |
-
* @param string $shortMsg text
|
1114 |
-
* @param int $level
|
1115 |
-
* @param string $longMsg html text
|
1116 |
-
* @param string|string[] $sections
|
1117 |
-
* @param null|array $faqLink [
|
1118 |
-
* 'url' => external link
|
1119 |
-
* 'label' => link text if empty get external url link
|
1120 |
-
* ]
|
1121 |
-
* @param int priority
|
1122 |
-
* @param bool open
|
1123 |
-
* @param string longMsgMode MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
|
1124 |
-
*/
|
1125 |
-
public function __construct($shortMsg, $level = self::INFO, $longMsg = '', $sections = array(), $faqLink = null, $priority = 10, $open = false, $longMsgMode = self::MSG_MODE_DEFAULT)
|
1126 |
-
{
|
1127 |
-
$this->shortMsg = (string) $shortMsg;
|
1128 |
-
$this->level = (int) $level;
|
1129 |
-
$this->longMsg = (string) $longMsg;
|
1130 |
-
$this->sections = is_array($sections) ? $sections : array($sections);
|
1131 |
-
$this->faqLink = $faqLink;
|
1132 |
-
$this->priority = $priority;
|
1133 |
-
$this->open = $open;
|
1134 |
-
$this->longMsgMode = $longMsgMode;
|
1135 |
-
}
|
1136 |
-
|
1137 |
-
/**
|
1138 |
-
*
|
1139 |
-
* @return array [
|
1140 |
-
* 'shortMsg' => text,
|
1141 |
-
* 'level' => level,
|
1142 |
-
* 'longMsg' => html text,
|
1143 |
-
* 'sections' => string|string[],
|
1144 |
-
* 'faqLink' => [
|
1145 |
-
* 'url' => external link
|
1146 |
-
* 'label' => link text if empty get external url link
|
1147 |
-
* ]
|
1148 |
-
* 'priority' => int low first
|
1149 |
-
* 'open' => if true the tab is opene on final report
|
1150 |
-
* 'longMsgMode'=> MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
|
1151 |
-
* ]
|
1152 |
-
*/
|
1153 |
-
public function toArray()
|
1154 |
-
{
|
1155 |
-
return array(
|
1156 |
-
'shortMsg' => $this->shortMsg,
|
1157 |
-
'level' => $this->level,
|
1158 |
-
'longMsg' => $this->longMsg,
|
1159 |
-
'sections' => $this->sections,
|
1160 |
-
'faqLink' => $this->faqLink,
|
1161 |
-
'priority' => $this->priority,
|
1162 |
-
'open' => $this->open,
|
1163 |
-
'longMsgMode' => $this->longMsgMode
|
1164 |
-
);
|
1165 |
-
}
|
1166 |
-
|
1167 |
-
/**
|
1168 |
-
*
|
1169 |
-
* @return array [
|
1170 |
-
* 'shortMsg' => text,
|
1171 |
-
* 'level' => level,
|
1172 |
-
* 'longMsg' => html text,
|
1173 |
-
* 'sections' => string|string[],
|
1174 |
-
* 'faqLink' => [
|
1175 |
-
* 'url' => external link
|
1176 |
-
* 'label' => link text if empty get external url link
|
1177 |
-
* ],
|
1178 |
-
* priority
|
1179 |
-
* open
|
1180 |
-
* longMsgMode
|
1181 |
-
* ]
|
1182 |
-
* @return DUPX_NOTICE_ITEM
|
1183 |
-
*/
|
1184 |
-
public static function getItemFromArray($array)
|
1185 |
-
{
|
1186 |
-
if (isset($array['sections']) && !is_array($array['sections'])) {
|
1187 |
-
if (empty($array['sections'])) {
|
1188 |
-
$array['sections'] = array();
|
1189 |
-
} else {
|
1190 |
-
$array['sections'] = array($array['sections']);
|
1191 |
-
}
|
1192 |
-
}
|
1193 |
-
$params = array_merge(self::getDefaultArrayParams(), $array);
|
1194 |
-
$result = new self($params['shortMsg'], $params['level'], $params['longMsg'], $params['sections'], $params['faqLink'], $params['priority'], $params['open'], $params['longMsgMode']);
|
1195 |
-
return $result;
|
1196 |
-
}
|
1197 |
-
|
1198 |
-
/**
|
1199 |
-
*
|
1200 |
-
* @return array [
|
1201 |
-
* 'shortMsg' => text,
|
1202 |
-
* 'level' => level,
|
1203 |
-
* 'longMsg' => html text,
|
1204 |
-
* 'sections' => string|string[],
|
1205 |
-
* 'faqLink' => [
|
1206 |
-
* 'url' => external link
|
1207 |
-
* 'label' => link text if empty get external url link
|
1208 |
-
* ],
|
1209 |
-
* priority
|
1210 |
-
* open
|
1211 |
-
* longMsgMode
|
1212 |
-
* ]
|
1213 |
-
*/
|
1214 |
-
public static function getDefaultArrayParams()
|
1215 |
-
{
|
1216 |
-
return array(
|
1217 |
-
'shortMsg' => '',
|
1218 |
-
'level' => self::INFO,
|
1219 |
-
'longMsg' => '',
|
1220 |
-
'sections' => array(),
|
1221 |
-
'faqLink' => null,
|
1222 |
-
'priority' => 10,
|
1223 |
-
'open' => false,
|
1224 |
-
'longMsgMode' => self::MSG_MODE_DEFAULT
|
1225 |
-
);
|
1226 |
-
}
|
1227 |
-
|
1228 |
-
/**
|
1229 |
-
* before lower priority
|
1230 |
-
* before highest level
|
1231 |
-
*
|
1232 |
-
* @param DUPX_NOTICE_ITEM $a
|
1233 |
-
* @param DUPX_NOTICE_ITEM $b
|
1234 |
-
*/
|
1235 |
-
public static function sortNoticeForPriorityAndLevel($a, $b)
|
1236 |
-
{
|
1237 |
-
if ($a->priority == $b->priority) {
|
1238 |
-
if ($a->level == $b->level) {
|
1239 |
-
return 0;
|
1240 |
-
} else if ($a->level < $b->level) {
|
1241 |
-
return 1;
|
1242 |
-
} else {
|
1243 |
-
return -1;
|
1244 |
-
}
|
1245 |
-
} else if ($a->priority < $b->priority) {
|
1246 |
-
return -1;
|
1247 |
-
} else {
|
1248 |
-
return 1;
|
1249 |
-
}
|
1250 |
-
}
|
1251 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Notice manager
|
4 |
+
*
|
5 |
+
* Standard: PSR-2
|
6 |
+
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
7 |
+
*
|
8 |
+
* @package SC\DUPX\U
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Notice manager
|
15 |
+
* singleton class
|
16 |
+
*/
|
17 |
+
final class DUPX_NOTICE_MANAGER
|
18 |
+
{
|
19 |
+
const ADD_NORMAL = 0; // add notice in list
|
20 |
+
const ADD_UNIQUE = 1; // add if unique id don't exists
|
21 |
+
const ADD_UNIQUE_UPDATE = 2; // add or update notice unique id
|
22 |
+
const ADD_UNIQUE_APPEND = 3; // append long msg
|
23 |
+
const ADD_UNIQUE_APPEND_IF_EXISTS = 4; // append long msg if already exists item
|
24 |
+
const ADD_UNIQUE_PREPEND = 5; // append long msg
|
25 |
+
const ADD_UNIQUE_PREPEND_IF_EXISTS = 6; // prepend long msg if already exists item
|
26 |
+
const DEFAULT_UNIQUE_ID_PREFIX = '__auto_unique_id__';
|
27 |
+
|
28 |
+
private static $uniqueCountId = 0;
|
29 |
+
|
30 |
+
/**
|
31 |
+
*
|
32 |
+
* @var DUPX_NOTICE_ITEM[]
|
33 |
+
*/
|
34 |
+
private $nextStepNotices = array();
|
35 |
+
|
36 |
+
/**
|
37 |
+
*
|
38 |
+
* @var DUPX_NOTICE_ITEM[]
|
39 |
+
*/
|
40 |
+
private $finalReporNotices = array();
|
41 |
+
|
42 |
+
/**
|
43 |
+
*
|
44 |
+
* @var DUPX_NOTICE_MANAGER
|
45 |
+
*/
|
46 |
+
private static $instance = null;
|
47 |
+
|
48 |
+
/**
|
49 |
+
*
|
50 |
+
* @var string
|
51 |
+
*/
|
52 |
+
private $persistanceFile = null;
|
53 |
+
|
54 |
+
/**
|
55 |
+
*
|
56 |
+
* @return DUPX_S_R_MANAGER
|
57 |
+
*/
|
58 |
+
public static function getInstance()
|
59 |
+
{
|
60 |
+
if (is_null(self::$instance)) {
|
61 |
+
self::$instance = new self();
|
62 |
+
}
|
63 |
+
|
64 |
+
return self::$instance;
|
65 |
+
}
|
66 |
+
|
67 |
+
private function __construct()
|
68 |
+
{
|
69 |
+
$this->persistanceFile = $GLOBALS["NOTICES_FILE_PATH"];
|
70 |
+
$this->loadNotices();
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* save notices from json file
|
75 |
+
*/
|
76 |
+
public function saveNotices()
|
77 |
+
{
|
78 |
+
$notices = array(
|
79 |
+
'globalData' => array(
|
80 |
+
'uniqueCountId' => self::$uniqueCountId
|
81 |
+
),
|
82 |
+
'nextStep' => array(),
|
83 |
+
'finalReport' => array()
|
84 |
+
);
|
85 |
+
|
86 |
+
foreach ($this->nextStepNotices as $uniqueId => $notice) {
|
87 |
+
$notices['nextStep'][$uniqueId] = $notice->toArray();
|
88 |
+
}
|
89 |
+
|
90 |
+
foreach ($this->finalReporNotices as $uniqueId => $notice) {
|
91 |
+
$notices['finalReport'][$uniqueId] = $notice->toArray();
|
92 |
+
}
|
93 |
+
|
94 |
+
file_put_contents($this->persistanceFile, DupLiteSnapJsonU::wp_json_encode_pprint($notices));
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* load notice from json file
|
99 |
+
*/
|
100 |
+
private function loadNotices()
|
101 |
+
{
|
102 |
+
if (file_exists($this->persistanceFile)) {
|
103 |
+
$json = file_get_contents($this->persistanceFile);
|
104 |
+
$notices = json_decode($json, true);
|
105 |
+
|
106 |
+
$this->nextStepNotices = array();
|
107 |
+
$this->finalReporNotices = array();
|
108 |
+
|
109 |
+
if (!empty($notices['nextStep'])) {
|
110 |
+
foreach ($notices['nextStep'] as $uniqueId => $notice) {
|
111 |
+
$this->nextStepNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
if (!empty($notices['finalReport'])) {
|
116 |
+
foreach ($notices['finalReport'] as $uniqueId => $notice) {
|
117 |
+
$this->finalReporNotices[$uniqueId] = DUPX_NOTICE_ITEM::getItemFromArray($notice);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
self::$uniqueCountId = $notices['globalData']['uniqueCountId'];
|
122 |
+
} else {
|
123 |
+
$this->resetNotices();
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* remove all notices and save reset file
|
129 |
+
*/
|
130 |
+
public function resetNotices()
|
131 |
+
{
|
132 |
+
$this->nextStepNotices = array();
|
133 |
+
$this->finalReporNotices = array();
|
134 |
+
self::$uniqueCountId = 0;
|
135 |
+
$this->saveNotices();
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* return next step notice by id
|
140 |
+
*
|
141 |
+
* @param string $id
|
142 |
+
* @return DUPX_NOTICE_ITEM
|
143 |
+
*/
|
144 |
+
public function getNextStepNoticeById($id)
|
145 |
+
{
|
146 |
+
if (isset($this->nextStepNotices[$id])) {
|
147 |
+
return $this->nextStepNotices[$id];
|
148 |
+
} else {
|
149 |
+
return null;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* return last report notice by id
|
155 |
+
*
|
156 |
+
* @param string $id
|
157 |
+
* @return DUPX_NOTICE_ITEM
|
158 |
+
*/
|
159 |
+
public function getFinalReporNoticeById($id)
|
160 |
+
{
|
161 |
+
if (isset($this->finalReporNotices[$id])) {
|
162 |
+
return $this->finalReporNotices[$id];
|
163 |
+
} else {
|
164 |
+
return null;
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
*
|
170 |
+
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
171 |
+
* // if array must be [
|
172 |
+
* 'shortMsg' => text,
|
173 |
+
* 'level' => level,
|
174 |
+
* 'longMsg' => html text,
|
175 |
+
* 'sections' => sections list,
|
176 |
+
* 'faqLink' => [
|
177 |
+
* 'url' => external link
|
178 |
+
* 'label' => link text if empty get external url link
|
179 |
+
* ]
|
180 |
+
* ]
|
181 |
+
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
182 |
+
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
183 |
+
*
|
184 |
+
* @return string // notice insert id
|
185 |
+
*
|
186 |
+
* @throws Exception
|
187 |
+
*/
|
188 |
+
public function addBothNextAndFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
189 |
+
{
|
190 |
+
$this->addNextStepNotice($item, $mode, $uniqueId);
|
191 |
+
$this->addFinalReportNotice($item, $mode, $uniqueId);
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
*
|
196 |
+
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
197 |
+
* // if array must be [
|
198 |
+
* 'shortMsg' => text,
|
199 |
+
* 'level' => level,
|
200 |
+
* 'longMsg' => html text,
|
201 |
+
* 'sections' => sections list,
|
202 |
+
* 'faqLink' => [
|
203 |
+
* 'url' => external link
|
204 |
+
* 'label' => link text if empty get external url link
|
205 |
+
* ]
|
206 |
+
* ]
|
207 |
+
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
208 |
+
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
209 |
+
*
|
210 |
+
* @return string // notice insert id
|
211 |
+
*
|
212 |
+
* @throws Exception
|
213 |
+
*/
|
214 |
+
public function addNextStepNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
215 |
+
{
|
216 |
+
if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
|
217 |
+
throw new Exception('Invalid item param');
|
218 |
+
}
|
219 |
+
return self::addReportNoticeToList($this->nextStepNotices, $item, $mode, $uniqueId);
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* addNextStepNotice wrapper to add simple message with error level
|
224 |
+
*
|
225 |
+
* @param string $message
|
226 |
+
* @param int $level // warning level
|
227 |
+
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
228 |
+
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
229 |
+
*
|
230 |
+
* @return string // notice insert id
|
231 |
+
*
|
232 |
+
* @throws Exception
|
233 |
+
*/
|
234 |
+
public function addNextStepNoticeMessage($message, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
|
235 |
+
{
|
236 |
+
return $this->addNextStepNotice(array(
|
237 |
+
'shortMsg' => $message,
|
238 |
+
'level' => $level,
|
239 |
+
), $mode, $uniqueId);
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
*
|
244 |
+
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
245 |
+
* // if array must be [
|
246 |
+
* 'shortMsg' => text,
|
247 |
+
* 'level' => level,
|
248 |
+
* 'longMsg' => html text,
|
249 |
+
* 'sections' => sections list,
|
250 |
+
* 'faqLink' => [
|
251 |
+
* 'url' => external link
|
252 |
+
* 'label' => link text if empty get external url link
|
253 |
+
* ]
|
254 |
+
* ]
|
255 |
+
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
256 |
+
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
257 |
+
*
|
258 |
+
* @return string // notice insert id
|
259 |
+
*
|
260 |
+
* @throws Exception
|
261 |
+
*/
|
262 |
+
public function addFinalReportNotice($item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
263 |
+
{
|
264 |
+
if (!is_array($item) && !($item instanceof DUPX_NOTICE_ITEM)) {
|
265 |
+
throw new Exception('Invalid item param');
|
266 |
+
}
|
267 |
+
return self::addReportNoticeToList($this->finalReporNotices, $item, $mode, $uniqueId);
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* addFinalReportNotice wrapper to add simple message with error level
|
272 |
+
*
|
273 |
+
* @param string $message
|
274 |
+
* @param string|string[] $sections // message sections on final report
|
275 |
+
* @param int $level // warning level
|
276 |
+
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
277 |
+
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
278 |
+
*
|
279 |
+
* @return string // notice insert id
|
280 |
+
*
|
281 |
+
* @throws Exception
|
282 |
+
*/
|
283 |
+
public function addFinalReportNoticeMessage($message, $sections, $level = DUPX_NOTICE_ITEM::INFO, $mode = self::ADD_NORMAL, $uniqueId = null)
|
284 |
+
{
|
285 |
+
return $this->addFinalReportNotice(array(
|
286 |
+
'shortMsg' => $message,
|
287 |
+
'level' => $level,
|
288 |
+
'sections' => $sections,
|
289 |
+
), $mode, $uniqueId);
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
*
|
294 |
+
* @param array $list
|
295 |
+
* @param array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
296 |
+
* // if array must be [
|
297 |
+
* 'shortMsg' => text,
|
298 |
+
* 'level' => level,
|
299 |
+
* 'longMsg' => html text,
|
300 |
+
* 'sections' => sections list,
|
301 |
+
* 'faqLink' => [
|
302 |
+
* 'url' => external link
|
303 |
+
* 'label' => link text if empty get external url link
|
304 |
+
* ]
|
305 |
+
* ]
|
306 |
+
* @param int $mode // ADD_NORMAL | ADD_UNIQUE | ADD_UNIQUE_UPDATE | ADD_UNIQUE_APPEND
|
307 |
+
* @param string $uniqueId // used for ADD_UNIQUE or ADD_UNIQUE_UPDATE or ADD_UNIQUE_APPEND
|
308 |
+
*
|
309 |
+
* @return string // notice insert id
|
310 |
+
*
|
311 |
+
* @throws Exception
|
312 |
+
*/
|
313 |
+
private static function addReportNoticeToList(&$list, $item, $mode = self::ADD_NORMAL, $uniqueId = null)
|
314 |
+
{
|
315 |
+
switch ($mode) {
|
316 |
+
case self::ADD_UNIQUE:
|
317 |
+
if (empty($uniqueId)) {
|
318 |
+
throw new Exception('uniqueId can\'t be empty');
|
319 |
+
}
|
320 |
+
if (isset($list[$uniqueId])) {
|
321 |
+
return $uniqueId;
|
322 |
+
}
|
323 |
+
// no break -> continue on unique update
|
324 |
+
case self::ADD_UNIQUE_UPDATE:
|
325 |
+
if (empty($uniqueId)) {
|
326 |
+
throw new Exception('uniqueId can\'t be empty');
|
327 |
+
}
|
328 |
+
$insertId = $uniqueId;
|
329 |
+
break;
|
330 |
+
case self::ADD_UNIQUE_APPEND_IF_EXISTS:
|
331 |
+
if (empty($uniqueId)) {
|
332 |
+
throw new Exception('uniqueId can\'t be empty');
|
333 |
+
}
|
334 |
+
if (!isset($list[$uniqueId])) {
|
335 |
+
return false;
|
336 |
+
}
|
337 |
+
// no break
|
338 |
+
case self::ADD_UNIQUE_APPEND:
|
339 |
+
if (empty($uniqueId)) {
|
340 |
+
throw new Exception('uniqueId can\'t be empty');
|
341 |
+
}
|
342 |
+
$insertId = $uniqueId;
|
343 |
+
// if item id exist append long msg
|
344 |
+
if (isset($list[$uniqueId])) {
|
345 |
+
$tempObj = self::getObjFromParams($item);
|
346 |
+
$list[$uniqueId]->longMsg .= $tempObj->longMsg;
|
347 |
+
$item = $list[$uniqueId];
|
348 |
+
}
|
349 |
+
break;
|
350 |
+
case self::ADD_UNIQUE_PREPEND_IF_EXISTS:
|
351 |
+
if (empty($uniqueId)) {
|
352 |
+
throw new Exception('uniqueId can\'t be empty');
|
353 |
+
}
|
354 |
+
if (!isset($list[$uniqueId])) {
|
355 |
+
return false;
|
356 |
+
}
|
357 |
+
// no break
|
358 |
+
case self::ADD_UNIQUE_PREPEND:
|
359 |
+
if (empty($uniqueId)) {
|
360 |
+
throw new Exception('uniqueId can\'t be empty');
|
361 |
+
}
|
362 |
+
$insertId = $uniqueId;
|
363 |
+
// if item id exist append long msg
|
364 |
+
if (isset($list[$uniqueId])) {
|
365 |
+
$tempObj = self::getObjFromParams($item);
|
366 |
+
$list[$uniqueId]->longMsg = $tempObj->longMsg.$list[$uniqueId]->longMsg;
|
367 |
+
$item = $list[$uniqueId];
|
368 |
+
}
|
369 |
+
break;
|
370 |
+
case self::ADD_NORMAL:
|
371 |
+
default:
|
372 |
+
if (empty($uniqueId)) {
|
373 |
+
$insertId = self::getNewAutoUniqueId();
|
374 |
+
} else {
|
375 |
+
$insertId = $uniqueId;
|
376 |
+
}
|
377 |
+
}
|
378 |
+
|
379 |
+
$list[$insertId] = self::getObjFromParams($item);
|
380 |
+
return $insertId;
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
*
|
385 |
+
* @param string|array|DUPX_NOTICE_ITEM $item // if string add new notice obj with item message and level param
|
386 |
+
* // if array must be [
|
387 |
+
* 'shortMsg' => text,
|
388 |
+
* 'level' => level,
|
389 |
+
* 'longMsg' => html text,
|
390 |
+
* 'sections' => sections list,
|
391 |
+
* 'faqLink' => [
|
392 |
+
* 'url' => external link
|
393 |
+
* 'label' => link text if empty get external url link
|
394 |
+
* ]
|
395 |
+
* ]
|
396 |
+
* @param int $level message level considered only in the case where $item is a string.
|
397 |
+
* @return \DUPX_NOTICE_ITEM
|
398 |
+
*
|
399 |
+
* @throws Exception
|
400 |
+
*/
|
401 |
+
private static function getObjFromParams($item, $level = DUPX_NOTICE_ITEM::INFO)
|
402 |
+
{
|
403 |
+
if ($item instanceof DUPX_NOTICE_ITEM) {
|
404 |
+
$newObj = $item;
|
405 |
+
} else if (is_array($item)) {
|
406 |
+
$newObj = DUPX_NOTICE_ITEM::getItemFromArray($item);
|
407 |
+
} else if (is_string($item)) {
|
408 |
+
$newObj = new DUPX_NOTICE_ITEM($item, $level);
|
409 |
+
} else {
|
410 |
+
throw new Exception('Notice input not valid');
|
411 |
+
}
|
412 |
+
|
413 |
+
return $newObj;
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
*
|
418 |
+
* @param null|string $section if null is count global
|
419 |
+
* @param int $level error level
|
420 |
+
* @param string $operator > < >= <= = !=
|
421 |
+
*
|
422 |
+
* @return int
|
423 |
+
*/
|
424 |
+
public function countFinalReportNotices($section = null, $level = DUPX_NOTICE_ITEM::INFO, $operator = '>=')
|
425 |
+
{
|
426 |
+
$result = 0;
|
427 |
+
foreach ($this->finalReporNotices as $notice) {
|
428 |
+
if (is_null($section) || in_array($section, $notice->sections)) {
|
429 |
+
switch ($operator) {
|
430 |
+
case '>=':
|
431 |
+
$result += (int) ($notice->level >= $level);
|
432 |
+
break;
|
433 |
+
case '>':
|
434 |
+
$result += (int) ($notice->level > $level);
|
435 |
+
break;
|
436 |
+
case '=':
|
437 |
+
$result += (int) ($notice->level = $level);
|
438 |
+
break;
|
439 |
+
case '<=':
|
440 |
+
$result += (int) ($notice->level <= $level);
|
441 |
+
break;
|
442 |
+
case '<':
|
443 |
+
$result += (int) ($notice->level < $level);
|
444 |
+
break;
|
445 |
+
case '!=':
|
446 |
+
$result += (int) ($notice->level != $level);
|
447 |
+
break;
|
448 |
+
}
|
449 |
+
}
|
450 |
+
}
|
451 |
+
return $result;
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* sort final report notice from priority and notice level
|
456 |
+
*/
|
457 |
+
public function sortFinalReport()
|
458 |
+
{
|
459 |
+
uasort($this->finalReporNotices, 'DUPX_NOTICE_ITEM::sortNoticeForPriorityAndLevel');
|
460 |
+
}
|
461 |
+
|
462 |
+
/**
|
463 |
+
* display final final report notice section
|
464 |
+
*
|
465 |
+
* @param string $section
|
466 |
+
*/
|
467 |
+
public function displayFinalReport($section)
|
468 |
+
{
|
469 |
+
foreach ($this->finalReporNotices as $id => $notice) {
|
470 |
+
if (in_array($section, $notice->sections)) {
|
471 |
+
self::finalReportNotice($id, $notice);
|
472 |
+
}
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
*
|
478 |
+
* @param string $section
|
479 |
+
* @param string $title
|
480 |
+
*/
|
481 |
+
public function displayFinalRepostSectionHtml($section, $title)
|
482 |
+
{
|
483 |
+
if ($this->haveSection($section)) {
|
484 |
+
?>
|
485 |
+
<div id="report-section-<?php echo $section; ?>" class="section" >
|
486 |
+
<div class="section-title" ><?php echo $title; ?></div>
|
487 |
+
<div class="section-content">
|
488 |
+
<?php
|
489 |
+
$this->displayFinalReport($section);
|
490 |
+
?>
|
491 |
+
</div>
|
492 |
+
</div>
|
493 |
+
<?php
|
494 |
+
}
|
495 |
+
}
|
496 |
+
|
497 |
+
/**
|
498 |
+
*
|
499 |
+
* @param string $section
|
500 |
+
* @return boolean
|
501 |
+
*/
|
502 |
+
public function haveSection($section)
|
503 |
+
{
|
504 |
+
foreach ($this->finalReporNotices as $notice) {
|
505 |
+
if (in_array($section, $notice->sections)) {
|
506 |
+
return true;
|
507 |
+
}
|
508 |
+
}
|
509 |
+
return false;
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
*
|
514 |
+
* @param null|string $section if null is a global result
|
515 |
+
*
|
516 |
+
* @return int // returns the worst level found
|
517 |
+
*
|
518 |
+
*/
|
519 |
+
public function getSectionErrLevel($section = null)
|
520 |
+
{
|
521 |
+
$result = DUPX_NOTICE_ITEM::INFO;
|
522 |
+
|
523 |
+
foreach ($this->finalReporNotices as $notice) {
|
524 |
+
if (is_null($section) || in_array($section, $notice->sections)) {
|
525 |
+
$result = max($result, $notice->level);
|
526 |
+
}
|
527 |
+
}
|
528 |
+
return $result;
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
*
|
533 |
+
* @param string $section
|
534 |
+
* @param bool $echo
|
535 |
+
* @return void|string
|
536 |
+
*/
|
537 |
+
public function getSectionErrLevelHtml($section = null, $echo = true)
|
538 |
+
{
|
539 |
+
return self::getErrorLevelHtml($this->getSectionErrLevel($section), $echo);
|
540 |
+
}
|
541 |
+
|
542 |
+
/**
|
543 |
+
* Displa next step notice message
|
544 |
+
*
|
545 |
+
* @param bool $deleteListAfterDisaply
|
546 |
+
* @return void
|
547 |
+
*/
|
548 |
+
public function displayStepMessages($deleteListAfterDisaply = true)
|
549 |
+
{
|
550 |
+
if (empty($this->nextStepNotices)) {
|
551 |
+
return;
|
552 |
+
}
|
553 |
+
?>
|
554 |
+
<div id="step-messages">
|
555 |
+
<?php
|
556 |
+
foreach ($this->nextStepNotices as $notice) {
|
557 |
+
self::stepMsg($notice);
|
558 |
+
}
|
559 |
+
?>
|
560 |
+
</div>
|
561 |
+
<?php
|
562 |
+
if ($deleteListAfterDisaply) {
|
563 |
+
$this->nextStepNotices = array();
|
564 |
+
$this->saveNotices();
|
565 |
+
}
|
566 |
+
}
|
567 |
+
|
568 |
+
/**
|
569 |
+
*
|
570 |
+
* @param DUPX_NOTICE_ITEM $notice
|
571 |
+
*/
|
572 |
+
private static function stepMsg($notice)
|
573 |
+
{
|
574 |
+
$classes = array(
|
575 |
+
'notice',
|
576 |
+
'next-step',
|
577 |
+
self::getClassFromLevel($notice->level)
|
578 |
+
);
|
579 |
+
$haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
|
580 |
+
?>
|
581 |
+
<div class="<?php echo implode(' ', $classes); ?>">
|
582 |
+
<div class="title">
|
583 |
+
<?php echo self::getNextStepLevelPrefixMessage($notice->level).': <b>'.htmlentities($notice->shortMsg).'</b>'; ?>
|
584 |
+
</div>
|
585 |
+
<?php if ($haveContent) { ?>
|
586 |
+
<div class="title-separator" ></div>
|
587 |
+
<?php
|
588 |
+
ob_start();
|
589 |
+
if (!empty($notice->faqLink)) {
|
590 |
+
?>
|
591 |
+
See FAQ: <a href="<?php echo $notice->faqLink['url']; ?>" >
|
592 |
+
<b><?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?></b>
|
593 |
+
</a>
|
594 |
+
<?php
|
595 |
+
}
|
596 |
+
if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
|
597 |
+
echo '<br><br>';
|
598 |
+
}
|
599 |
+
if (!empty($notice->longMsg)) {
|
600 |
+
switch ($notice->longMsgMode) {
|
601 |
+
case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
|
602 |
+
echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
|
603 |
+
break;
|
604 |
+
case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
|
605 |
+
echo $notice->longMsg;
|
606 |
+
break;
|
607 |
+
case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
|
608 |
+
default:
|
609 |
+
echo htmlentities($notice->longMsg);
|
610 |
+
}
|
611 |
+
}
|
612 |
+
$longContent = ob_get_clean();
|
613 |
+
DUPX_U_Html::getMoreContent($longContent, 'info', 200);
|
614 |
+
}
|
615 |
+
?>
|
616 |
+
</div>
|
617 |
+
<?php
|
618 |
+
}
|
619 |
+
|
620 |
+
/**
|
621 |
+
*
|
622 |
+
* @param string $id
|
623 |
+
* @param DUPX_NOTICE_ITEM $notice
|
624 |
+
*/
|
625 |
+
private static function finalReportNotice($id, $notice)
|
626 |
+
{
|
627 |
+
$classes = array(
|
628 |
+
'notice-report',
|
629 |
+
'notice',
|
630 |
+
self::getClassFromLevel($notice->level)
|
631 |
+
);
|
632 |
+
$haveContent = !empty($notice->faqLink) || !empty($notice->longMsg);
|
633 |
+
$contentId = 'notice-content-'.$id;
|
634 |
+
$iconClasses = $haveContent ? 'fa fa-caret-right' : 'fa fa-toggle-empty';
|
635 |
+
$toggleLinkData = $haveContent ? 'data-type="toggle" data-target="#'.$contentId.'"' : '';
|
636 |
+
?>
|
637 |
+
<div class="<?php echo implode(' ', $classes); ?>">
|
638 |
+
<div class="title" <?php echo $toggleLinkData; ?>>
|
639 |
+
<i class="<?php echo $iconClasses; ?>"></i> <?php echo htmlentities($notice->shortMsg); ?>
|
640 |
+
</div>
|
641 |
+
<?php
|
642 |
+
if ($haveContent) {
|
643 |
+
$infoClasses = array('info');
|
644 |
+
if (!$notice->open) {
|
645 |
+
$infoClasses[] = 'no-display';
|
646 |
+
}
|
647 |
+
?>
|
648 |
+
<div id="<?php echo $contentId; ?>" class="<?php echo implode(' ', $infoClasses); ?>" >
|
649 |
+
<?php
|
650 |
+
if (!empty($notice->faqLink)) {
|
651 |
+
?>
|
652 |
+
<b>See FAQ</b>: <a href="<?php echo $notice->faqLink['url']; ?>" >
|
653 |
+
<?php echo htmlentities(empty($notice->faqLink['label']) ? $notice->faqLink['url'] : $notice->faqLink['label']); ?>
|
654 |
+
</a>
|
655 |
+
<?php
|
656 |
+
}
|
657 |
+
if (!empty($notice->faqLink) && !empty($notice->longMsg)) {
|
658 |
+
echo '<br><br>';
|
659 |
+
}
|
660 |
+
if (!empty($notice->longMsg)) {
|
661 |
+
switch ($notice->longMsgMode) {
|
662 |
+
case DUPX_NOTICE_ITEM::MSG_MODE_PRE:
|
663 |
+
echo '<pre>'.htmlentities($notice->longMsg).'</pre>';
|
664 |
+
break;
|
665 |
+
case DUPX_NOTICE_ITEM::MSG_MODE_HTML:
|
666 |
+
echo $notice->longMsg;
|
667 |
+
break;
|
668 |
+
case DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT:
|
669 |
+
default:
|
670 |
+
echo htmlentities($notice->longMsg);
|
671 |
+
}
|
672 |
+
}
|
673 |
+
?>
|
674 |
+
</div>
|
675 |
+
<?php
|
676 |
+
}
|
677 |
+
?>
|
678 |
+
</div>
|
679 |
+
<?php
|
680 |
+
}
|
681 |
+
|
682 |
+
/**
|
683 |
+
*
|
684 |
+
* @param DUPX_NOTICE_ITEM $notice
|
685 |
+
*/
|
686 |
+
private static function noticeToText($notice)
|
687 |
+
{
|
688 |
+
$result = '-----------------------'."\n".
|
689 |
+
'['.self::getNextStepLevelPrefixMessage($notice->level, false).'] '.$notice->shortMsg;
|
690 |
+
|
691 |
+
if (!empty($notice->sections)) {
|
692 |
+
$result .= "\n\t".'SECTIONS: '.implode(',', $notice->sections);
|
693 |
+
}
|
694 |
+
if (!empty($notice->longMsg)) {
|
695 |
+
$result .= "\n\t".'LONG MSG: '.$notice->longMsg;
|
696 |
+
}
|
697 |
+
return $result."\n";
|
698 |
+
}
|
699 |
+
|
700 |
+
public function nextStepLog()
|
701 |
+
{
|
702 |
+
if (!empty($this->nextStepNotices)) {
|
703 |
+
DUPX_Log::info(
|
704 |
+
'===================================='."\n".
|
705 |
+
'NEXT STEP NOTICES'."\n".
|
706 |
+
'====================================');
|
707 |
+
foreach ($this->nextStepNotices as $notice) {
|
708 |
+
DUPX_Log::info(self::noticeToText($notice));
|
709 |
+
}
|
710 |
+
DUPX_Log::info(
|
711 |
+
'====================================');
|
712 |
+
}
|
713 |
+
}
|
714 |
+
|
715 |
+
public function finalReportLog($sections = array())
|
716 |
+
{
|
717 |
+
if (!empty($this->finalReporNotices)) {
|
718 |
+
DUPX_Log::info(
|
719 |
+
'===================================='."\n".
|
720 |
+
'FINAL REPORT NOTICES LIST'."\n".
|
721 |
+
'====================================');
|
722 |
+
foreach ($this->finalReporNotices as $notice) {
|
723 |
+
if (count(array_intersect($notice->sections, $sections)) > 0) {
|
724 |
+
DUPX_Log::info(self::noticeToText($notice));
|
725 |
+
}
|
726 |
+
}
|
727 |
+
DUPX_Log::info(
|
728 |
+
'====================================');
|
729 |
+
}
|
730 |
+
}
|
731 |
+
|
732 |
+
/**
|
733 |
+
* get html class from level
|
734 |
+
*
|
735 |
+
* @param int $level
|
736 |
+
* @return string
|
737 |
+
*/
|
738 |
+
private static function getClassFromLevel($level)
|
739 |
+
{
|
740 |
+
switch ($level) {
|
741 |
+
case DUPX_NOTICE_ITEM::INFO:
|
742 |
+
return 'l-info';
|
743 |
+
case DUPX_NOTICE_ITEM::NOTICE:
|
744 |
+
return 'l-notice';
|
745 |
+
case DUPX_NOTICE_ITEM::SOFT_WARNING:
|
746 |
+
return 'l-swarning';
|
747 |
+
case DUPX_NOTICE_ITEM::HARD_WARNING:
|
748 |
+
return 'l-hwarning';
|
749 |
+
case DUPX_NOTICE_ITEM::CRITICAL:
|
750 |
+
return 'l-critical';
|
751 |
+
case DUPX_NOTICE_ITEM::FATAL:
|
752 |
+
return 'l-fatal';
|
753 |
+
}
|
754 |
+
}
|
755 |
+
|
756 |
+
/**
|
757 |
+
* get level label from level
|
758 |
+
*
|
759 |
+
* @param int $level
|
760 |
+
* @param bool $echo
|
761 |
+
* @return type
|
762 |
+
*/
|
763 |
+
public static function getErrorLevelHtml($level, $echo = true)
|
764 |
+
{
|
765 |
+
switch ($level) {
|
766 |
+
case DUPX_NOTICE_ITEM::INFO:
|
767 |
+
$label = 'good';
|
768 |
+
break;
|
769 |
+
case DUPX_NOTICE_ITEM::NOTICE:
|
770 |
+
$label = 'good';
|
771 |
+
break;
|
772 |
+
case DUPX_NOTICE_ITEM::SOFT_WARNING:
|
773 |
+
$label = 'warning';
|
774 |
+
break;
|
775 |
+
case DUPX_NOTICE_ITEM::HARD_WARNING:
|
776 |
+
$label = 'warning';
|
777 |
+
break;
|
778 |
+
case DUPX_NOTICE_ITEM::CRITICAL:
|
779 |
+
$label = 'critical error';
|
780 |
+
break;
|
781 |
+
case DUPX_NOTICE_ITEM::FATAL:
|
782 |
+
$label = 'fatal error';
|
783 |
+
break;
|
784 |
+
default:
|
785 |
+
return;
|
786 |
+
}
|
787 |
+
$classes = self::getClassFromLevel($level);
|
788 |
+
ob_start();
|
789 |
+
?>
|
790 |
+
<span class="notice-level-status <?php echo $classes; ?>"><?php echo $label; ?></span>
|
791 |
+
<?php
|
792 |
+
if ($echo) {
|
793 |
+
ob_end_flush();
|
794 |
+
} else {
|
795 |
+
return ob_get_clean();
|
796 |
+
}
|
797 |
+
}
|
798 |
+
|
799 |
+
/**
|
800 |
+
* get next step message prefix
|
801 |
+
*
|
802 |
+
* @param int $level
|
803 |
+
* @param bool $echo
|
804 |
+
* @return string
|
805 |
+
*/
|
806 |
+
public static function getNextStepLevelPrefixMessage($level, $echo = true)
|
807 |
+
{
|
808 |
+
switch ($level) {
|
809 |
+
case DUPX_NOTICE_ITEM::INFO:
|
810 |
+
$label = 'INFO';
|
811 |
+
break;
|
812 |
+
case DUPX_NOTICE_ITEM::NOTICE:
|
813 |
+
$label = 'NOTICE';
|
814 |
+
break;
|
815 |
+
case DUPX_NOTICE_ITEM::SOFT_WARNING:
|
816 |
+
$label = 'WARNING';
|
817 |
+
break;
|
818 |
+
case DUPX_NOTICE_ITEM::HARD_WARNING:
|
819 |
+
$label = 'WARNING';
|
820 |
+
break;
|
821 |
+
case DUPX_NOTICE_ITEM::CRITICAL:
|
822 |
+
$label = 'CRITICAL ERROR';
|
823 |
+
break;
|
824 |
+
case DUPX_NOTICE_ITEM::FATAL:
|
825 |
+
$label = 'FATAL ERROR';
|
826 |
+
break;
|
827 |
+
default:
|
828 |
+
return;
|
829 |
+
}
|
830 |
+
|
831 |
+
if ($echo) {
|
832 |
+
echo $label;
|
833 |
+
} else {
|
834 |
+
return $label;
|
835 |
+
}
|
836 |
+
}
|
837 |
+
|
838 |
+
/**
|
839 |
+
* get unique id
|
840 |
+
*
|
841 |
+
* @return string
|
842 |
+
*/
|
843 |
+
private static function getNewAutoUniqueId()
|
844 |
+
{
|
845 |
+
self::$uniqueCountId ++;
|
846 |
+
return self::DEFAULT_UNIQUE_ID_PREFIX.self::$uniqueCountId;
|
847 |
+
}
|
848 |
+
|
849 |
+
/**
|
850 |
+
* function for internal test
|
851 |
+
*
|
852 |
+
* display all messages levels
|
853 |
+
*/
|
854 |
+
public static function testNextStepMessaesLevels()
|
855 |
+
{
|
856 |
+
$manager = self::getInstance();
|
857 |
+
$manager->addNextStepNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', DUPX_NOTICE_ITEM::INFO);
|
858 |
+
$manager->addNextStepNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', DUPX_NOTICE_ITEM::NOTICE);
|
859 |
+
$manager->addNextStepNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', DUPX_NOTICE_ITEM::SOFT_WARNING);
|
860 |
+
$manager->addNextStepNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', DUPX_NOTICE_ITEM::HARD_WARNING);
|
861 |
+
$manager->addNextStepNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', DUPX_NOTICE_ITEM::CRITICAL);
|
862 |
+
$manager->addNextStepNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', DUPX_NOTICE_ITEM::FATAL);
|
863 |
+
$manager->saveNotices();
|
864 |
+
}
|
865 |
+
|
866 |
+
/**
|
867 |
+
* test function
|
868 |
+
*/
|
869 |
+
public static function testNextStepFullMessageData()
|
870 |
+
{
|
871 |
+
$manager = self::getInstance();
|
872 |
+
$longMsg = <<<LONGMSG
|
873 |
+
<b>Formattend long text</b><br>
|
874 |
+
<ul>
|
875 |
+
<li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
|
876 |
+
<li>Nunc venenatis eros et sapien ornare consequat.</li>
|
877 |
+
<li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
|
878 |
+
<li>Etiam volutpat lectus quis risus molestie faucibus.</li>
|
879 |
+
<li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
|
880 |
+
<li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
|
881 |
+
</ul>
|
882 |
+
LONGMSG;
|
883 |
+
$manager->addNextStepNotice(array(
|
884 |
+
'shortMsg' => 'Full elements next step message MODE HTML',
|
885 |
+
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
886 |
+
'longMsg' => $longMsg,
|
887 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
888 |
+
'faqLink' => array(
|
889 |
+
'url' => 'http://www.google.it',
|
890 |
+
'label' => 'google link'
|
891 |
+
)
|
892 |
+
));
|
893 |
+
|
894 |
+
$longMsg = <<<LONGMSG
|
895 |
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
|
896 |
+
Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
|
897 |
+
|
898 |
+
Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
|
899 |
+
at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
|
900 |
+
Ut ac faucibus tellus, in lobortis odio.
|
901 |
+
LONGMSG;
|
902 |
+
$manager->addNextStepNotice(array(
|
903 |
+
'shortMsg' => 'Full elements next step message MODE PRE',
|
904 |
+
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
905 |
+
'longMsg' => $longMsg,
|
906 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE,
|
907 |
+
'faqLink' => array(
|
908 |
+
'url' => 'http://www.google.it',
|
909 |
+
'label' => 'google link'
|
910 |
+
)
|
911 |
+
));
|
912 |
+
|
913 |
+
$longMsg = <<<LONGMSG
|
914 |
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a auctor erat, et lobortis libero.
|
915 |
+
Suspendisse aliquet neque in massa posuere mollis. Donec venenatis finibus sapien in bibendum. Donec et ex massa.
|
916 |
+
|
917 |
+
Aliquam venenatis dapibus tellus nec ullamcorper. Mauris ante velit, tincidunt sit amet egestas et, mattis non lorem. In semper ex ut velit suscipit,
|
918 |
+
at luctus nunc dapibus. Etiam blandit maximus dapibus. Nullam eu porttitor augue. Suspendisse pulvinar, massa eget condimentum aliquet, dolor massa tempus dui, vel rhoncus tellus ligula non odio.
|
919 |
+
Ut ac faucibus tellus, in lobortis odio.
|
920 |
+
LONGMSG;
|
921 |
+
$manager->addNextStepNotice(array(
|
922 |
+
'shortMsg' => 'Full elements next step message MODE DEFAULT',
|
923 |
+
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
924 |
+
'longMsg' => $longMsg,
|
925 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
|
926 |
+
'faqLink' => array(
|
927 |
+
'url' => 'http://www.google.it',
|
928 |
+
'label' => 'google link'
|
929 |
+
)
|
930 |
+
));
|
931 |
+
|
932 |
+
|
933 |
+
$longMsg = <<<LONGMSG
|
934 |
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam cursus porttitor consectetur. Nunc faucibus elementum nisl nec ornare. Phasellus sit amet urna in diam ultricies ornare nec sit amet nibh. Nulla a aliquet leo. Quisque aliquet posuere lectus sit amet commodo. Nullam tempus enim eget urna rutrum egestas. Aliquam eget lorem nisl. Nulla tincidunt massa erat. Phasellus lectus tellus, mollis sit amet aliquam in, dapibus quis metus. Nunc venenatis nulla vitae convallis accumsan.
|
935 |
+
|
936 |
+
Mauris eu ullamcorper metus. Aenean ultricies et turpis eget mollis. Aliquam auctor, elit scelerisque placerat pellentesque, quam augue fermentum lectus, vel pretium nisi justo sit amet ante. Donec blandit porttitor tempus. Duis vulputate nulla ut orci rutrum, et consectetur urna mollis. Sed at iaculis velit. Pellentesque id quam turpis. Curabitur eu ligula velit. Cras gravida, ipsum sed iaculis eleifend, mauris nunc posuere quam, vel blandit nisi justo congue ligula. Phasellus aliquam eu odio ac porttitor. Fusce dictum mollis turpis sit amet fringilla.
|
937 |
+
|
938 |
+
Nulla eu ligula mauris. Fusce lobortis ligula elit, a interdum nibh pulvinar eu. Pellentesque rhoncus nec turpis id blandit. Morbi fringilla, justo non varius consequat, arcu ante efficitur ante, sit amet cursus lorem elit vel odio. Phasellus neque ligula, vehicula vel ipsum sed, volutpat dignissim eros. Curabitur at lacus id felis elementum auctor. Nullam ac tempus nisi. Phasellus nibh purus, aliquam nec purus ut, sodales lobortis nulla. Cras viverra dictum magna, ac malesuada nibh dictum ac. Mauris euismod, magna sit amet pretium posuere, ligula nibh ultrices tellus, sit amet pretium odio urna egestas justo. Suspendisse purus erat, eleifend sed magna in, efficitur interdum nibh.
|
939 |
+
|
940 |
+
Vivamus nibh nunc, fermentum non tortor volutpat, consectetur vulputate velit. Phasellus lobortis, purus et faucibus mollis, metus eros viverra ante, sit amet euismod nibh est eu orci. Duis sodales cursus lacinia. Praesent laoreet ut ipsum ut interdum. Praesent venenatis massa vitae ligula consequat aliquet. Fusce in purus in odio molestie laoreet at ac augue. Fusce consectetur elit a magna mollis aliquet.
|
941 |
+
|
942 |
+
Nulla eros nisi, dapibus eget diam vitae, tincidunt blandit odio. Fusce interdum tellus nec varius condimentum. Fusce non magna a purus sodales imperdiet sit amet vitae ligula. Quisque viverra leo sit amet mi egestas, et posuere nunc tincidunt. Suspendisse feugiat malesuada urna sed tincidunt. Morbi a urna sed magna volutpat pellentesque sit amet ac mauris. Nulla sed ultrices dui. Etiam massa arcu, tempor ut erat at, cursus malesuada ipsum. Duis sit amet felis dolor.
|
943 |
+
|
944 |
+
Morbi gravida nisl nunc, vulputate iaculis risus vehicula non. Proin cursus, velit et laoreet consectetur, lacus libero sagittis lacus, quis accumsan odio lectus non erat. Aenean dolor lectus, euismod sit amet justo eget, dictum gravida nisl. Phasellus sed nunc non odio ullamcorper rhoncus non ut ipsum. Duis ante ligula, pellentesque sit amet imperdiet eget, congue vel dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Suspendisse luctus leo eget justo mollis, convallis convallis ex suscipit. Integer et justo eget odio lobortis sollicitudin. Pellentesque accumsan rhoncus augue, luctus suscipit ex accumsan nec. Maecenas lacinia consectetur risus at bibendum. Etiam venenatis purus lorem, sit amet elementum turpis tristique eu. Proin vulputate faucibus feugiat. Nunc vehicula congue odio consequat vulputate. Quisque bibendum augue id iaculis faucibus. Donec blandit cursus sem, eget accumsan orci commodo sed.
|
945 |
+
|
946 |
+
Suspendisse iaculis est quam, sed scelerisque purus tincidunt non. Cras hendrerit ante turpis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse purus ipsum, rutrum id sem in, venenatis laoreet metus. Aliquam ac bibendum mauris. Cras egestas rhoncus est, sed lacinia nibh vestibulum id. Proin diam quam, sagittis congue molestie ac, rhoncus et mauris. Phasellus massa neque, ornare vel erat a, rutrum pharetra arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi et nulla eget massa auctor fermentum. Quisque maximus tellus sed cursus cursus. Ut vehicula erat at purus aliquet, quis imperdiet dui sagittis. Nullam eget quam leo.
|
947 |
+
|
948 |
+
Nulla magna ipsum, congue nec dui ut, lacinia malesuada felis. Cras mattis metus non maximus venenatis. Aliquam euismod est vitae erat sollicitudin, at pellentesque augue sollicitudin. Curabitur euismod maximus cursus. In tortor dui, convallis sed sapien ac, varius congue metus. Nunc ullamcorper ac orci sit amet finibus. Vivamus molestie nibh vitae quam rhoncus, eu ultrices est molestie. Maecenas consectetur eu quam sit amet placerat.
|
949 |
+
|
950 |
+
Curabitur ut fermentum mauris. Donec et congue nibh. Sed cursus elit sit amet convallis varius. Donec malesuada porta odio condimentum varius. Pellentesque ornare tempor ante, ut volutpat nulla lobortis sed. Nunc congue aliquet erat ac elementum. Quisque a ex sit amet turpis placerat sagittis eget ac ligula. Etiam in augue malesuada, aliquam est non, lacinia justo. Vivamus tincidunt dolor orci, id dignissim lorem maximus at. Vivamus ligula mauris, venenatis vel nibh id, lacinia ultrices ipsum. Mauris cursus, urna ac rutrum aliquet, risus ipsum tincidunt purus, sit amet blandit nunc sem sit amet nibh.
|
951 |
+
|
952 |
+
Nam eleifend risus lacus, eu pharetra risus egestas eu. Maecenas hendrerit nisl in semper placerat. Vestibulum massa tellus, laoreet non euismod quis, sollicitudin id sapien. Morbi vel cursus metus. Aenean tincidunt nisi est, ut elementum est auctor id. Duis auctor elit leo, ac scelerisque risus suscipit et. Pellentesque lectus nisi, ultricies in elit sed, pulvinar iaculis massa. Morbi viverra eros mi, pretium facilisis neque egestas id. Curabitur non massa accumsan, porttitor sem vitae, ultricies lacus. Curabitur blandit nisl velit. Mauris sollicitudin ultricies purus sit amet placerat. Fusce ac neque sed leo venenatis laoreet ut non ex. Integer elementum rhoncus orci, eu maximus neque tempus eu. Curabitur euismod dignissim tellus, vitae lacinia metus. Mauris imperdiet metus vitae vulputate accumsan. Duis eget luctus nibh, sit amet finibus libero.
|
953 |
+
|
954 |
+
LONGMSG;
|
955 |
+
$manager->addNextStepNotice(array(
|
956 |
+
'shortMsg' => 'Full elements LONG LONG',
|
957 |
+
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
958 |
+
'longMsg' => $longMsg,
|
959 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT,
|
960 |
+
'faqLink' => array(
|
961 |
+
'url' => 'http://www.google.it',
|
962 |
+
'label' => 'google link'
|
963 |
+
)
|
964 |
+
));
|
965 |
+
|
966 |
+
|
967 |
+
|
968 |
+
|
969 |
+
$manager->saveNotices();
|
970 |
+
}
|
971 |
+
|
972 |
+
/**
|
973 |
+
* test function
|
974 |
+
*/
|
975 |
+
public static function testFinalReporMessaesLevels()
|
976 |
+
{
|
977 |
+
$section = 'general';
|
978 |
+
|
979 |
+
$manager = self::getInstance();
|
980 |
+
$manager->addFinalReportNoticeMessage('Level info ('.DUPX_NOTICE_ITEM::INFO.')', $section, DUPX_NOTICE_ITEM::INFO, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_0');
|
981 |
+
$manager->addFinalReportNoticeMessage('Level notice ('.DUPX_NOTICE_ITEM::NOTICE.')', $section, DUPX_NOTICE_ITEM::NOTICE, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_1');
|
982 |
+
$manager->addFinalReportNoticeMessage('Level soft warning ('.DUPX_NOTICE_ITEM::SOFT_WARNING.')', $section, DUPX_NOTICE_ITEM::SOFT_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_2');
|
983 |
+
$manager->addFinalReportNoticeMessage('Level hard warning ('.DUPX_NOTICE_ITEM::HARD_WARNING.')', $section, DUPX_NOTICE_ITEM::HARD_WARNING, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_3');
|
984 |
+
$manager->addFinalReportNoticeMessage('Level critical error ('.DUPX_NOTICE_ITEM::CRITICAL.')', $section, DUPX_NOTICE_ITEM::CRITICAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_4');
|
985 |
+
$manager->addFinalReportNoticeMessage('Level fatal error ('.DUPX_NOTICE_ITEM::FATAL.')', $section, DUPX_NOTICE_ITEM::FATAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_5');
|
986 |
+
$manager->saveNotices();
|
987 |
+
}
|
988 |
+
|
989 |
+
/**
|
990 |
+
* test function
|
991 |
+
*/
|
992 |
+
public static function testFinalReportFullMessages()
|
993 |
+
{
|
994 |
+
$section = 'general';
|
995 |
+
$manager = self::getInstance();
|
996 |
+
|
997 |
+
$longMsg = <<<LONGMSG
|
998 |
+
<b>Formattend long text</b><br>
|
999 |
+
<ul>
|
1000 |
+
<li>Proin dapibus mi eu erat pulvinar, id congue nisl egestas.</li>
|
1001 |
+
<li>Nunc venenatis eros et sapien ornare consequat.</li>
|
1002 |
+
<li>Mauris tincidunt est sit amet turpis placerat, a tristique dui porttitor.</li>
|
1003 |
+
<li>Etiam volutpat lectus quis risus molestie faucibus.</li>
|
1004 |
+
<li>Integer gravida eros sit amet sem viverra, a volutpat neque rutrum.</li>
|
1005 |
+
<li>Aenean varius ipsum vitae lorem tempus rhoncus.</li>
|
1006 |
+
</ul>
|
1007 |
+
LONGMSG;
|
1008 |
+
|
1009 |
+
$manager->addFinalReportNotice(array(
|
1010 |
+
'shortMsg' => 'Full elements final report message',
|
1011 |
+
'level' => DUPX_NOTICE_ITEM::HARD_WARNING,
|
1012 |
+
'longMsg' => $longMsg,
|
1013 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
1014 |
+
'sections' => $section,
|
1015 |
+
'faqLink' => array(
|
1016 |
+
'url' => 'http://www.google.it',
|
1017 |
+
'label' => 'google link'
|
1018 |
+
)
|
1019 |
+
), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_1');
|
1020 |
+
|
1021 |
+
$manager->addFinalReportNotice(array(
|
1022 |
+
'shortMsg' => 'Full elements final report message info high priority',
|
1023 |
+
'level' => DUPX_NOTICE_ITEM::INFO,
|
1024 |
+
'longMsg' => $longMsg,
|
1025 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
1026 |
+
'sections' => $section,
|
1027 |
+
'faqLink' => array(
|
1028 |
+
'url' => 'http://www.google.it',
|
1029 |
+
'label' => 'google link'
|
1030 |
+
),
|
1031 |
+
'priority' => 5
|
1032 |
+
), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'test_fr_full_2');
|
1033 |
+
$manager->saveNotices();
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
//PHP 8 Requires method to be public
|
1037 |
+
public function __wakeup()
|
1038 |
+
{
|
1039 |
+
}
|
1040 |
+
|
1041 |
+
private function __clone()
|
1042 |
+
{
|
1043 |
+
|
1044 |
+
}
|
1045 |
+
}
|
1046 |
+
|
1047 |
+
class DUPX_NOTICE_ITEM
|
1048 |
+
{
|
1049 |
+
const INFO = 0;
|
1050 |
+
const NOTICE = 1;
|
1051 |
+
const SOFT_WARNING = 2;
|
1052 |
+
const HARD_WARNING = 3;
|
1053 |
+
const CRITICAL = 4;
|
1054 |
+
const FATAL = 5;
|
1055 |
+
const MSG_MODE_DEFAULT = 'def';
|
1056 |
+
const MSG_MODE_HTML = 'html';
|
1057 |
+
const MSG_MODE_PRE = 'pre';
|
1058 |
+
|
1059 |
+
/**
|
1060 |
+
*
|
1061 |
+
* @var string text
|
1062 |
+
*/
|
1063 |
+
public $shortMsg = '';
|
1064 |
+
|
1065 |
+
/**
|
1066 |
+
*
|
1067 |
+
* @var string html text
|
1068 |
+
*/
|
1069 |
+
public $longMsg = '';
|
1070 |
+
|
1071 |
+
/**
|
1072 |
+
*
|
1073 |
+
* @var bool if true long msg can be html
|
1074 |
+
*/
|
1075 |
+
public $longMsgMode = self::MSG_MODE_DEFAULT;
|
1076 |
+
|
1077 |
+
/**
|
1078 |
+
*
|
1079 |
+
* @var null|array // null = no faq link
|
1080 |
+
* array( 'label' => link text , 'url' => faq url)
|
1081 |
+
*/
|
1082 |
+
public $faqLink = array(
|
1083 |
+
'label' => '',
|
1084 |
+
'url' => ''
|
1085 |
+
);
|
1086 |
+
|
1087 |
+
/**
|
1088 |
+
*
|
1089 |
+
* @var string[] notice sections for final report only
|
1090 |
+
*/
|
1091 |
+
public $sections = array();
|
1092 |
+
|
1093 |
+
/**
|
1094 |
+
*
|
1095 |
+
* @var int
|
1096 |
+
*/
|
1097 |
+
public $level = self::NOTICE;
|
1098 |
+
|
1099 |
+
/**
|
1100 |
+
*
|
1101 |
+
* @var int
|
1102 |
+
*/
|
1103 |
+
public $priority = 10;
|
1104 |
+
|
1105 |
+
/**
|
1106 |
+
*
|
1107 |
+
* @var bool if true notice start open. For final report only
|
1108 |
+
*/
|
1109 |
+
public $open = false;
|
1110 |
+
|
1111 |
+
/**
|
1112 |
+
*
|
1113 |
+
* @param string $shortMsg text
|
1114 |
+
* @param int $level
|
1115 |
+
* @param string $longMsg html text
|
1116 |
+
* @param string|string[] $sections
|
1117 |
+
* @param null|array $faqLink [
|
1118 |
+
* 'url' => external link
|
1119 |
+
* 'label' => link text if empty get external url link
|
1120 |
+
* ]
|
1121 |
+
* @param int priority
|
1122 |
+
* @param bool open
|
1123 |
+
* @param string longMsgMode MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
|
1124 |
+
*/
|
1125 |
+
public function __construct($shortMsg, $level = self::INFO, $longMsg = '', $sections = array(), $faqLink = null, $priority = 10, $open = false, $longMsgMode = self::MSG_MODE_DEFAULT)
|
1126 |
+
{
|
1127 |
+
$this->shortMsg = (string) $shortMsg;
|
1128 |
+
$this->level = (int) $level;
|
1129 |
+
$this->longMsg = (string) $longMsg;
|
1130 |
+
$this->sections = is_array($sections) ? $sections : array($sections);
|
1131 |
+
$this->faqLink = $faqLink;
|
1132 |
+
$this->priority = $priority;
|
1133 |
+
$this->open = $open;
|
1134 |
+
$this->longMsgMode = $longMsgMode;
|
1135 |
+
}
|
1136 |
+
|
1137 |
+
/**
|
1138 |
+
*
|
1139 |
+
* @return array [
|
1140 |
+
* 'shortMsg' => text,
|
1141 |
+
* 'level' => level,
|
1142 |
+
* 'longMsg' => html text,
|
1143 |
+
* 'sections' => string|string[],
|
1144 |
+
* 'faqLink' => [
|
1145 |
+
* 'url' => external link
|
1146 |
+
* 'label' => link text if empty get external url link
|
1147 |
+
* ]
|
1148 |
+
* 'priority' => int low first
|
1149 |
+
* 'open' => if true the tab is opene on final report
|
1150 |
+
* 'longMsgMode'=> MSG_MODE_DEFAULT | MSG_MODE_HTML | MSG_MODE_PRE
|
1151 |
+
* ]
|
1152 |
+
*/
|
1153 |
+
public function toArray()
|
1154 |
+
{
|
1155 |
+
return array(
|
1156 |
+
'shortMsg' => $this->shortMsg,
|
1157 |
+
'level' => $this->level,
|
1158 |
+
'longMsg' => $this->longMsg,
|
1159 |
+
'sections' => $this->sections,
|
1160 |
+
'faqLink' => $this->faqLink,
|
1161 |
+
'priority' => $this->priority,
|
1162 |
+
'open' => $this->open,
|
1163 |
+
'longMsgMode' => $this->longMsgMode
|
1164 |
+
);
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
/**
|
1168 |
+
*
|
1169 |
+
* @return array [
|
1170 |
+
* 'shortMsg' => text,
|
1171 |
+
* 'level' => level,
|
1172 |
+
* 'longMsg' => html text,
|
1173 |
+
* 'sections' => string|string[],
|
1174 |
+
* 'faqLink' => [
|
1175 |
+
* 'url' => external link
|
1176 |
+
* 'label' => link text if empty get external url link
|
1177 |
+
* ],
|
1178 |
+
* priority
|
1179 |
+
* open
|
1180 |
+
* longMsgMode
|
1181 |
+
* ]
|
1182 |
+
* @return DUPX_NOTICE_ITEM
|
1183 |
+
*/
|
1184 |
+
public static function getItemFromArray($array)
|
1185 |
+
{
|
1186 |
+
if (isset($array['sections']) && !is_array($array['sections'])) {
|
1187 |
+
if (empty($array['sections'])) {
|
1188 |
+
$array['sections'] = array();
|
1189 |
+
} else {
|
1190 |
+
$array['sections'] = array($array['sections']);
|
1191 |
+
}
|
1192 |
+
}
|
1193 |
+
$params = array_merge(self::getDefaultArrayParams(), $array);
|
1194 |
+
$result = new self($params['shortMsg'], $params['level'], $params['longMsg'], $params['sections'], $params['faqLink'], $params['priority'], $params['open'], $params['longMsgMode']);
|
1195 |
+
return $result;
|
1196 |
+
}
|
1197 |
+
|
1198 |
+
/**
|
1199 |
+
*
|
1200 |
+
* @return array [
|
1201 |
+
* 'shortMsg' => text,
|
1202 |
+
* 'level' => level,
|
1203 |
+
* 'longMsg' => html text,
|
1204 |
+
* 'sections' => string|string[],
|
1205 |
+
* 'faqLink' => [
|
1206 |
+
* 'url' => external link
|
1207 |
+
* 'label' => link text if empty get external url link
|
1208 |
+
* ],
|
1209 |
+
* priority
|
1210 |
+
* open
|
1211 |
+
* longMsgMode
|
1212 |
+
* ]
|
1213 |
+
*/
|
1214 |
+
public static function getDefaultArrayParams()
|
1215 |
+
{
|
1216 |
+
return array(
|
1217 |
+
'shortMsg' => '',
|
1218 |
+
'level' => self::INFO,
|
1219 |
+
'longMsg' => '',
|
1220 |
+
'sections' => array(),
|
1221 |
+
'faqLink' => null,
|
1222 |
+
'priority' => 10,
|
1223 |
+
'open' => false,
|
1224 |
+
'longMsgMode' => self::MSG_MODE_DEFAULT
|
1225 |
+
);
|
1226 |
+
}
|
1227 |
+
|
1228 |
+
/**
|
1229 |
+
* before lower priority
|
1230 |
+
* before highest level
|
1231 |
+
*
|
1232 |
+
* @param DUPX_NOTICE_ITEM $a
|
1233 |
+
* @param DUPX_NOTICE_ITEM $b
|
1234 |
+
*/
|
1235 |
+
public static function sortNoticeForPriorityAndLevel($a, $b)
|
1236 |
+
{
|
1237 |
+
if ($a->priority == $b->priority) {
|
1238 |
+
if ($a->level == $b->level) {
|
1239 |
+
return 0;
|
1240 |
+
} else if ($a->level < $b->level) {
|
1241 |
+
return 1;
|
1242 |
+
} else {
|
1243 |
+
return -1;
|
1244 |
+
}
|
1245 |
+
} else if ($a->priority < $b->priority) {
|
1246 |
+
return -1;
|
1247 |
+
} else {
|
1248 |
+
return 1;
|
1249 |
+
}
|
1250 |
+
}
|
1251 |
}
|
installer/dup-installer/ctrls/classes/class.ctrl.extraction.php
CHANGED
@@ -1,604 +1,605 @@
|
|
1 |
-
<?php
|
2 |
-
defined("DUPXABSPATH") or die("");
|
3 |
-
|
4 |
-
class DUP_LITE_Extraction
|
5 |
-
{
|
6 |
-
|
7 |
-
const ACTION_DO_NOTHING = 'donothing';
|
8 |
-
const ACTION_REMOVE_ALL_FILES = 'removeall';
|
9 |
-
const ACTION_REMOVE_WP_FILES = 'removewpfiles';
|
10 |
-
const INPUT_NAME_ARCHIVE_ACTION = 'archive_action';
|
11 |
-
|
12 |
-
public $archive_action
|
13 |
-
|
14 |
-
/**
|
15 |
-
*
|
16 |
-
* @var self
|
17 |
-
*/
|
18 |
-
protected static $instance = null;
|
19 |
-
|
20 |
-
/**
|
21 |
-
*
|
22 |
-
* @return self
|
23 |
-
*/
|
24 |
-
public static function getInstance()
|
25 |
-
{
|
26 |
-
if (is_null(self::$instance)) {
|
27 |
-
self::$instance = new self;
|
28 |
-
}
|
29 |
-
return self::$instance;
|
30 |
-
}
|
31 |
-
|
32 |
-
private function __construct()
|
33 |
-
{
|
34 |
-
$this->initData();
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* initialize extraction data
|
39 |
-
*/
|
40 |
-
public function initData()
|
41 |
-
{
|
42 |
-
if ($_POST['archive_engine'] == 'manual') {
|
43 |
-
$GLOBALS['DUPX_STATE']->isManualExtraction = true;
|
44 |
-
$GLOBALS['DUPX_STATE']->save();
|
45 |
-
}
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
*
|
50 |
-
* @param string[] $folders
|
51 |
-
*/
|
52 |
-
protected function removeFiles($folders = array())
|
53 |
-
{
|
54 |
-
$archive_path = $GLOBALS['FW_PACKAGE_PATH'];
|
55 |
-
|
56 |
-
$excludeFiles = array(
|
57 |
-
'/^'.preg_quote($archive_path, '/').'$/',
|
58 |
-
'/^'.preg_quote(DUPX_CSRF::getVal('bootLogFile'), '/').'$/',
|
59 |
-
'/^'.preg_quote(DUPX_CSRF::getVal('installerOrigPath'), '/').'$/',
|
60 |
-
'/^'.preg_quote($GLOBALS['DUPX_ROOT'].'/wp-config.php', '/').'$/'
|
61 |
-
);
|
62 |
-
|
63 |
-
$excludeFolders = array(
|
64 |
-
'/.+\/backups-dup-(lite|pro)$/',
|
65 |
-
'/^'.preg_quote($GLOBALS['DUPX_INIT'], '/').'$/'
|
66 |
-
);
|
67 |
-
|
68 |
-
foreach (DUPX_Server::getWpAddonsSiteLists() as $addonPath) {
|
69 |
-
$excludeFolders[] = '/^'.preg_quote($addonPath, '/').'$/';
|
70 |
-
}
|
71 |
-
|
72 |
-
foreach ($folders as $folder) {
|
73 |
-
DUPX_Log::info('REMOVE FOLDER '.DUPX_Log::varToString($folder));
|
74 |
-
DupLiteSnapLibIOU::regexGlobCallback($folder, function ($path) {
|
75 |
-
|
76 |
-
if (is_dir($path)) {
|
77 |
-
rmdir($path);
|
78 |
-
} else {
|
79 |
-
unlink($path);
|
80 |
-
}
|
81 |
-
}, array(
|
82 |
-
'regexFile' => $excludeFiles,
|
83 |
-
'regexFolder' => $excludeFolders,
|
84 |
-
'checkFullPath' => true,
|
85 |
-
'recursive' => true,
|
86 |
-
'invert' => true,
|
87 |
-
'childFirst' => true
|
88 |
-
));
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
protected function removeWpFiles()
|
93 |
-
{
|
94 |
-
try {
|
95 |
-
DUPX_Log::info('REMOVE WP FILES');
|
96 |
-
DUPX_Log::resetTime(DUPX_Log::LV_DEFAULT, false);
|
97 |
-
|
98 |
-
$absDir = DupLiteSnapLibIOU::trailingslashit($GLOBALS['DUPX_ROOT']);
|
99 |
-
if (!is_dir($absDir) || !is_readable($absDir)) {
|
100 |
-
return false;
|
101 |
-
}
|
102 |
-
|
103 |
-
$removeFolders = array();
|
104 |
-
|
105 |
-
if (($dh = opendir($absDir))) {
|
106 |
-
while (($elem = readdir($dh)) !== false) {
|
107 |
-
if ($elem === '.' || $elem === '..') {
|
108 |
-
continue;
|
109 |
-
}
|
110 |
-
|
111 |
-
if (DupLiteSnapLibUtilWp::isWpCore($elem, DupLiteSnapLibUtilWp::PATH_RELATIVE)) {
|
112 |
-
$fullPath = $absDir.$elem;
|
113 |
-
if (is_dir($fullPath)) {
|
114 |
-
$removeFolders[] = $fullPath;
|
115 |
-
} else {
|
116 |
-
if (is_writable($fullPath)) {
|
117 |
-
unlink($fullPath);
|
118 |
-
}
|
119 |
-
}
|
120 |
-
}
|
121 |
-
}
|
122 |
-
closedir($dh);
|
123 |
-
}
|
124 |
-
|
125 |
-
$this->removeFiles(array_unique($removeFolders));
|
126 |
-
DUPX_Log::logTime('FOLDERS REMOVED', DUPX_Log::LV_DEFAULT, false);
|
127 |
-
}
|
128 |
-
catch (Exception $e) {
|
129 |
-
DUPX_Log::logException($e);
|
130 |
-
}
|
131 |
-
catch (Error $e) {
|
132 |
-
DUPX_Log::logException($e);
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
*
|
138 |
-
*/
|
139 |
-
protected function removeAllFiles()
|
140 |
-
{
|
141 |
-
try {
|
142 |
-
DUPX_Log::info('REMOVE ALL FILES');
|
143 |
-
DUPX_Log::resetTime(DUPX_Log::LV_DEFAULT, false);
|
144 |
-
$this->removeFiles(array($GLOBALS['DUPX_ROOT']));
|
145 |
-
DUPX_Log::logTime('FOLDERS REMOVED', DUPX_Log::LV_DEFAULT, false);
|
146 |
-
}
|
147 |
-
catch (Exception $e) {
|
148 |
-
DUPX_Log::logException($e);
|
149 |
-
}
|
150 |
-
catch (Error $e) {
|
151 |
-
DUPX_Log::logException($e);
|
152 |
-
}
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* preliminary actions before the extraction.
|
157 |
-
*
|
158 |
-
* @return void
|
159 |
-
*/
|
160 |
-
protected function beforeExtraction()
|
161 |
-
{
|
162 |
-
DUPX_Log::info('BEFORE EXTRACION ACTIONS');
|
163 |
-
|
164 |
-
if (!$GLOBALS['DUPX_AC']->exportOnlyDB) {
|
165 |
-
switch ($_POST[self::INPUT_NAME_ARCHIVE_ACTION]) {
|
166 |
-
case self::ACTION_REMOVE_ALL_FILES:
|
167 |
-
$this->removeAllFiles();
|
168 |
-
break;
|
169 |
-
case self::ACTION_REMOVE_WP_FILES:
|
170 |
-
$this->removeWpFiles();
|
171 |
-
break;
|
172 |
-
case self::ACTION_DO_NOTHING:
|
173 |
-
break;
|
174 |
-
default:
|
175 |
-
throw new Exception('Invalid engine action '.$_POST[self::INPUT_NAME_ARCHIVE_ACTION]);
|
176 |
-
}
|
177 |
-
}
|
178 |
-
}
|
179 |
-
|
180 |
-
/**
|
181 |
-
*
|
182 |
-
* @throws Exception
|
183 |
-
*/
|
184 |
-
public function runExtraction()
|
185 |
-
{
|
186 |
-
//OPTIONS
|
187 |
-
$_POST['set_file_perms'] = (isset($_POST['set_file_perms'])) ? 1 : 0;
|
188 |
-
$_POST['set_dir_perms'] = (isset($_POST['set_dir_perms'])) ? 1 : 0;
|
189 |
-
$_POST['file_perms_value'] = (isset($_POST['file_perms_value'])) ? DUPX_U::sanitize_text_field($_POST['file_perms_value']) : 0755;
|
190 |
-
$_POST['dir_perms_value'] = (isset($_POST['dir_perms_value'])) ? DUPX_U::sanitize_text_field($_POST['dir_perms_value']) : 0644;
|
191 |
-
$_POST['zip_filetime'] = (isset($_POST['zip_filetime'])) ? $_POST['zip_filetime'] : 'current';
|
192 |
-
$_POST['config_mode'] = (isset($_POST['config_mode'])) ? $_POST['config_mode'] : 'NEW';
|
193 |
-
$_POST[self::INPUT_NAME_ARCHIVE_ACTION] = (isset($_POST[self::INPUT_NAME_ARCHIVE_ACTION])) ? $_POST[self::INPUT_NAME_ARCHIVE_ACTION] : self::ACTION_DO_NOTHING;
|
194 |
-
$_POST['archive_engine'] = (isset($_POST['archive_engine'])) ? $_POST['archive_engine'] : 'manual';
|
195 |
-
$_POST['exe_safe_mode'] = (isset($_POST['exe_safe_mode'])) ? $_POST['exe_safe_mode'] : 0;
|
196 |
-
|
197 |
-
//LOGGING
|
198 |
-
$POST_LOG = $_POST;
|
199 |
-
unset($POST_LOG['dbpass']);
|
200 |
-
ksort($POST_LOG);
|
201 |
-
|
202 |
-
//ACTION VARS
|
203 |
-
$ajax1_start = DUPX_U::getMicrotime();
|
204 |
-
$root_path = $GLOBALS['DUPX_ROOT'];
|
205 |
-
$wpconfig_ark_path = ($GLOBALS['DUPX_AC']->installSiteOverwriteOn) ?
|
206 |
-
"{$root_path}/dup-wp-config-arc__{$GLOBALS['DUPX_AC']->package_hash}.txt" : "{$root_path}/wp-config.php";
|
207 |
-
|
208 |
-
$archive_path = $GLOBALS['FW_PACKAGE_PATH'];
|
209 |
-
$dataResult = array();
|
210 |
-
$dataResult['pass'] = 0;
|
211 |
-
|
212 |
-
/** JSON RESPONSE: Most sites have warnings turned off by default, but if they're turned on the warnings
|
213 |
-
cause errors in the JSON data Here we hide the status so warning level is reset at it at the end */
|
214 |
-
$ajax1_error_level = error_reporting();
|
215 |
-
error_reporting(E_ERROR);
|
216 |
-
|
217 |
-
$nManager = DUPX_NOTICE_MANAGER::getInstance();
|
218 |
-
|
219 |
-
//===============================
|
220 |
-
//ARCHIVE ERROR MESSAGES
|
221 |
-
//===============================
|
222 |
-
($GLOBALS['LOG_FILE_HANDLE'] != false) or DUPX_Log::error(ERR_MAKELOG);
|
223 |
-
|
224 |
-
if (!$GLOBALS['DUPX_AC']->exportOnlyDB) {
|
225 |
-
|
226 |
-
$post_archive_engine = DUPX_U::sanitize_text_field($_POST['archive_engine']);
|
227 |
-
|
228 |
-
if ($post_archive_engine == 'manual') {
|
229 |
-
if (!file_exists($wpconfig_ark_path) && !file_exists("database.sql")) {
|
230 |
-
DUPX_Log::error(ERR_ZIPMANUAL);
|
231 |
-
}
|
232 |
-
} else {
|
233 |
-
if (!is_readable("{$archive_path}")) {
|
234 |
-
DUPX_Log::error("archive path:{$archive_path}<br/>".ERR_ZIPNOTFOUND);
|
235 |
-
}
|
236 |
-
}
|
237 |
-
|
238 |
-
//ERR_ZIPMANUAL
|
239 |
-
if (('ziparchive' == $post_archive_engine || 'shellexec_unzip' == $post_archive_engine) && !$GLOBALS['DUPX_AC']->installSiteOverwriteOn) {
|
240 |
-
//ERR_CONFIG_FOUND
|
241 |
-
$outer_root_path = dirname($root_path);
|
242 |
-
|
243 |
-
if ((file_exists($wpconfig_ark_path) || (@file_exists("{$outer_root_path}/wp-config.php") && !@file_exists("{$outer_root_path}/wp-settings.php"))) && @file_exists("{$root_path}/wp-admin") && @file_exists("{$root_path}/wp-includes")) {
|
244 |
-
DUPX_Log::error(ERR_CONFIG_FOUND);
|
245 |
-
}
|
246 |
-
}
|
247 |
-
}
|
248 |
-
|
249 |
-
DUPX_Log::info("********************************************************************************");
|
250 |
-
DUPX_Log::info('* DUPLICATOR-LITE: Install-Log');
|
251 |
-
DUPX_Log::info('* STEP-1 START @ '.@date('h:i:s'));
|
252 |
-
DUPX_Log::info("* VERSION: {$GLOBALS['DUPX_AC']->version_dup}");
|
253 |
-
DUPX_Log::info('* NOTICE: Do NOT post to public sites or forums!!');
|
254 |
-
DUPX_Log::info("********************************************************************************");
|
255 |
-
|
256 |
-
$colSize = 60;
|
257 |
-
$labelPadSize = 20;
|
258 |
-
$os = defined('PHP_OS') ? PHP_OS : 'unknown';
|
259 |
-
$log = str_pad(str_pad('PACKAGE INFO', $labelPadSize, '_', STR_PAD_RIGHT).' '.'CURRENT SERVER', $colSize, ' ', STR_PAD_RIGHT).'|'.'ORIGINAL SERVER'."\n".
|
260 |
-
str_pad(str_pad('PHP VERSION', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_php, $colSize, ' ', STR_PAD_RIGHT).'|'.phpversion()."\n".
|
261 |
-
str_pad(str_pad('OS', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_os, $colSize, ' ', STR_PAD_RIGHT).'|'.$os."\n".
|
262 |
-
str_pad('CREATED', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->created."\n".
|
263 |
-
str_pad('WP VERSION', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_wp."\n".
|
264 |
-
str_pad('DUP VERSION', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_dup."\n".
|
265 |
-
str_pad('DB', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_db."\n".
|
266 |
-
str_pad('DB TABLES', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->dbInfo->tablesFinalCount."\n".
|
267 |
-
str_pad('DB ROWS', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->dbInfo->tablesRowCount."\n".
|
268 |
-
str_pad('DB FILE SIZE', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->dbInfo->tablesSizeOnDisk."\n".
|
269 |
-
"********************************************************************************";
|
270 |
-
DUPX_Log::info($log);
|
271 |
-
DUPX_Log::info("SERVER INFO");
|
272 |
-
DUPX_Log::info(str_pad('PHP', $labelPadSize, '_', STR_PAD_RIGHT).': '.phpversion().' | SAPI: '.php_sapi_name());
|
273 |
-
DUPX_Log::info(str_pad('PHP MEMORY', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['PHP_MEMORY_LIMIT'].' | SUHOSIN: '.$GLOBALS['PHP_SUHOSIN_ON']);
|
274 |
-
DUPX_Log::info(str_pad('SERVER', $labelPadSize, '_', STR_PAD_RIGHT).': '.$_SERVER['SERVER_SOFTWARE']);
|
275 |
-
DUPX_Log::info(str_pad('DOC ROOT', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($root_path));
|
276 |
-
DUPX_Log::info(str_pad('DOC ROOT 755', $labelPadSize, '_', STR_PAD_RIGHT).': '.var_export($GLOBALS['CHOWN_ROOT_PATH'], true));
|
277 |
-
DUPX_Log::info(str_pad('LOG FILE 644', $labelPadSize, '_', STR_PAD_RIGHT).': '.var_export($GLOBALS['CHOWN_LOG_PATH'], true));
|
278 |
-
DUPX_Log::info(str_pad('REQUEST URL', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($GLOBALS['URL_PATH']));
|
279 |
-
|
280 |
-
DUPX_Log::info("********************************************************************************");
|
281 |
-
DUPX_Log::info("USER INPUTS");
|
282 |
-
DUPX_Log::info(str_pad('ARCHIVE ACTION', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST[self::INPUT_NAME_ARCHIVE_ACTION]));
|
283 |
-
DUPX_Log::info(str_pad('ARCHIVE ENGINE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['archive_engine']));
|
284 |
-
DUPX_Log::info(str_pad('SET DIR PERMS', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['set_dir_perms']));
|
285 |
-
DUPX_Log::info(str_pad('DIR PERMS VALUE', $labelPadSize, '_', STR_PAD_RIGHT).': '.decoct($_POST['dir_perms_value']));
|
286 |
-
DUPX_Log::info(str_pad('SET FILE PERMS', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['set_file_perms']));
|
287 |
-
DUPX_Log::info(str_pad('FILE PERMS VALUE', $labelPadSize, '_', STR_PAD_RIGHT).': '.decoct($_POST['file_perms_value']));
|
288 |
-
DUPX_Log::info(str_pad('SAFE MODE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['exe_safe_mode']));
|
289 |
-
DUPX_Log::info(str_pad('LOGGING', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['logging']));
|
290 |
-
DUPX_Log::info(str_pad('CONFIG MODE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['config_mode']));
|
291 |
-
DUPX_Log::info(str_pad('FILE TIME', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['zip_filetime']));
|
292 |
-
DUPX_Log::info("********************************************************************************\n");
|
293 |
-
|
294 |
-
$log = "--------------------------------------\n";
|
295 |
-
$log .= "POST DATA\n";
|
296 |
-
$log .= "--------------------------------------\n";
|
297 |
-
$log .= print_r($POST_LOG, true);
|
298 |
-
DUPX_Log::info($log, DUPX_Log::LV_DEBUG);
|
299 |
-
|
300 |
-
$log = "\n--------------------------------------\n";
|
301 |
-
$log .= "ARCHIVE SETUP\n";
|
302 |
-
$log .= "--------------------------------------\n";
|
303 |
-
$log .= str_pad('NAME', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($GLOBALS['FW_PACKAGE_PATH'])."\n";
|
304 |
-
if (file_exists($GLOBALS['FW_PACKAGE_PATH'])) {
|
305 |
-
$log .= str_pad('SIZE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_U::readableByteSize(@filesize($GLOBALS['FW_PACKAGE_PATH']));
|
306 |
-
}
|
307 |
-
DUPX_Log::info($log."\n", DUPX_Log::LV_DEFAULT, true);
|
308 |
-
|
309 |
-
DUPX_Log::info('PRE-EXTRACT-CHECKS');
|
310 |
-
DUPX_ServerConfig::beforeExtractionSetup();
|
311 |
-
|
312 |
-
$this->beforeExtraction();
|
313 |
-
|
314 |
-
$target = $root_path;
|
315 |
-
DUPX_U::maintenanceMode(true);
|
316 |
-
|
317 |
-
$post_archive_engine = DUPX_U::sanitize_text_field($_POST['archive_engine']);
|
318 |
-
switch ($post_archive_engine) {
|
319 |
-
|
320 |
-
//-----------------------
|
321 |
-
//MANUAL EXTRACTION
|
322 |
-
case 'manual':
|
323 |
-
DUPX_Log::info("\n** PACKAGE EXTRACTION IS IN MANUAL MODE ** \n");
|
324 |
-
break;
|
325 |
-
|
326 |
-
//-----------------------
|
327 |
-
//SHELL EXEC
|
328 |
-
case 'shellexec_unzip':
|
329 |
-
DUPX_Log::info("\n\nSTART ZIP FILE EXTRACTION SHELLEXEC >>> ");
|
330 |
-
$shell_exec_path = DUPX_Server::get_unzip_filepath();
|
331 |
-
|
332 |
-
|
333 |
-
$command = escapeshellcmd($shell_exec_path)." -o -qq ".escapeshellarg($archive_path)." -d ".escapeshellarg($target)." 2>&1";
|
334 |
-
if ($_POST['zip_filetime'] == 'original') {
|
335 |
-
DUPX_Log::info("\nShell Exec Current does not support orginal file timestamp please use ZipArchive");
|
336 |
-
}
|
337 |
-
|
338 |
-
DUPX_Log::info(">>> Starting Shell-Exec Unzip:\nCommand: {$command}", DUPX_Log::LV_DEBUG);
|
339 |
-
$stderr = shell_exec($command);
|
340 |
-
if ($stderr != '') {
|
341 |
-
$zip_err_msg = ERR_SHELLEXEC_ZIPOPEN.": $stderr";
|
342 |
-
$zip_err_msg .= "<br/><br/><b>To resolve error see <a href='https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q' target='_blank'>https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q</a></b>";
|
343 |
-
DUPX_Log::error($zip_err_msg);
|
344 |
-
}
|
345 |
-
DUPX_Log::info("<<< Shell-Exec Unzip Complete.");
|
346 |
-
|
347 |
-
break;
|
348 |
-
|
349 |
-
//-----------------------
|
350 |
-
//ZIP-ARCHIVE
|
351 |
-
case 'ziparchive':
|
352 |
-
DUPX_Log::info("\n\nSTART ZIP FILE EXTRACTION STANDARD >>> ");
|
353 |
-
|
354 |
-
if (!class_exists('ZipArchive')) {
|
355 |
-
DUPX_Log::info("ERROR: Stopping install process. Trying to extract without ZipArchive module installed. Please use the 'Manual Archive Extraction' mode to extract zip file.");
|
356 |
-
DUPX_Log::error(ERR_ZIPARCHIVE);
|
357 |
-
}
|
358 |
-
|
359 |
-
if (($dupInstallerFolder = DUPX_U::findDupInstallerFolder($archive_path)) === false) {
|
360 |
-
DUPX_Log::info("findDupInstallerFolder error; set no subfolder");
|
361 |
-
// if not found set not subfolder
|
362 |
-
$dupInstallerFolder = '';
|
363 |
-
}
|
364 |
-
if (!empty($dupInstallerFolder)) {
|
365 |
-
DUPX_Log::info("ARCHIVE dup-installer SUBFOLDER:\"".$dupInstallerFolder."\"");
|
366 |
-
} else {
|
367 |
-
DUPX_Log::info("ARCHIVE dup-installer SUBFOLDER:\"".$dupInstallerFolder."\"", 2);
|
368 |
-
}
|
369 |
-
|
370 |
-
$dupInstallerZipPath = $dupInstallerFolder.'/dup-installer';
|
371 |
-
|
372 |
-
$zip = new ZipArchive();
|
373 |
-
|
374 |
-
if ($zip->open($archive_path) === TRUE) {
|
375 |
-
$extract_filenames = array();
|
376 |
-
DUPX_Handler::setMode(DUPX_Handler::MODE_VAR, false, false);
|
377 |
-
|
378 |
-
for ($i = 0; $i < $zip->numFiles; $i++) {
|
379 |
-
$extract_filename = $zip->getNameIndex($i);
|
380 |
-
|
381 |
-
// skip dup-installer folder. Alrady extracted in bootstrap
|
382 |
-
if (
|
383 |
-
(strpos($extract_filename, $dupInstallerZipPath) === 0) ||
|
384 |
-
(!empty($dupInstallerFolder) && strpos($extract_filename, $dupInstallerFolder) !== 0)
|
385 |
-
) {
|
386 |
-
DUPX_Log::info("SKIPPING NOT IN ZIPATH:\"".DUPX_Log::varToString($extract_filename)."\"", DUPX_Log::LV_DETAILED);
|
387 |
-
continue;
|
388 |
-
}
|
389 |
-
|
390 |
-
try {
|
391 |
-
if (!$zip->extractTo($target, $extract_filename)) {
|
392 |
-
if (DupLiteSnapLibUtilWp::isWpCore($extract_filename, DupLiteSnapLibUtilWp::PATH_RELATIVE)) {
|
393 |
-
DUPX_Log::info("FILE CORE EXTRACION ERROR: ".$extract_filename);
|
394 |
-
$shortMsg = 'Can\'t extract wp core files';
|
395 |
-
$finalShortMsg = 'Wp core files not extracted';
|
396 |
-
$errLevel = DUPX_NOTICE_ITEM::CRITICAL;
|
397 |
-
$idManager = 'wp-extract-error-file-core';
|
398 |
-
} else {
|
399 |
-
DUPX_Log::info("FILE EXTRACION ERROR: ".$extract_filename);
|
400 |
-
$shortMsg = 'Can\'t extract files';
|
401 |
-
$finalShortMsg = 'Files not extracted';
|
402 |
-
$errLevel = DUPX_NOTICE_ITEM::SOFT_WARNING;
|
403 |
-
$idManager = 'wp-extract-error-file-no-core';
|
404 |
-
}
|
405 |
-
$longMsg = 'FILE: <b>'.htmlspecialchars($extract_filename).'</b><br>Message: '.htmlspecialchars(DUPX_Handler::getVarLogClean()).'<br><br>';
|
406 |
-
|
407 |
-
$nManager->addNextStepNotice(array(
|
408 |
-
'shortMsg' => $shortMsg,
|
409 |
-
'longMsg' => $longMsg,
|
410 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
411 |
-
'level' => $errLevel
|
412 |
-
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
413 |
-
$nManager->addFinalReportNotice(array(
|
414 |
-
'shortMsg' => $finalShortMsg,
|
415 |
-
'longMsg' => $longMsg,
|
416 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
417 |
-
'level' => $errLevel,
|
418 |
-
'sections' => array('files'),
|
419 |
-
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
420 |
-
} else {
|
421 |
-
DUPX_Log::info("FILE EXTRACTION DONE: ".DUPX_Log::varToString($extract_filename), DUPX_Log::LV_HARD_DEBUG);
|
422 |
-
}
|
423 |
-
}
|
424 |
-
catch (Exception $ex) {
|
425 |
-
if (DupLiteSnapLibUtilWp::isWpCore($extract_filename, DupLiteSnapLibUtilWp::PATH_RELATIVE)) {
|
426 |
-
DUPX_Log::info("FILE CORE EXTRACION ERROR: {$extract_filename} | MSG:".$ex->getMessage());
|
427 |
-
$shortMsg = 'Can\'t extract wp core files';
|
428 |
-
$finalShortMsg = 'Wp core files not extracted';
|
429 |
-
$errLevel = DUPX_NOTICE_ITEM::CRITICAL;
|
430 |
-
$idManager = 'wp-extract-error-file-core';
|
431 |
-
} else {
|
432 |
-
DUPX_Log::info("FILE EXTRACION ERROR: {$extract_filename} | MSG:".$ex->getMessage());
|
433 |
-
$shortMsg = 'Can\'t extract files';
|
434 |
-
$finalShortMsg = 'Files not extracted';
|
435 |
-
$errLevel = DUPX_NOTICE_ITEM::SOFT_WARNING;
|
436 |
-
$idManager = 'wp-extract-error-file-no-core';
|
437 |
-
}
|
438 |
-
$longMsg = 'FILE: <b>'.htmlspecialchars($extract_filename).'</b><br>Message: '.htmlspecialchars($ex->getMessage()).'<br><br>';
|
439 |
-
|
440 |
-
$nManager->addNextStepNotice(array(
|
441 |
-
'shortMsg' => $shortMsg,
|
442 |
-
'longMsg' => $longMsg,
|
443 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
444 |
-
'level' => $errLevel
|
445 |
-
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
446 |
-
$nManager->addFinalReportNotice(array(
|
447 |
-
'shortMsg' => $finalShortMsg,
|
448 |
-
'longMsg' => $longMsg,
|
449 |
-
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
450 |
-
'level' => $errLevel,
|
451 |
-
'sections' => array('files'),
|
452 |
-
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
453 |
-
}
|
454 |
-
}
|
455 |
-
|
456 |
-
if (!empty($dupInstallerFolder)) {
|
457 |
-
DUPX_U::moveUpfromSubFolder($target.'/'.$dupInstallerFolder, true);
|
458 |
-
}
|
459 |
-
|
460 |
-
//Uncomment if needed
|
461 |
-
//if (DUPX_Log::isLevel(DUPX_Log::LV_DEBUG)) {
|
462 |
-
// $log = print_r($zip, true);
|
463 |
-
//}
|
464 |
-
//FILE-TIMESTAMP
|
465 |
-
if ($_POST['zip_filetime'] == 'original') {
|
466 |
-
$log .= "File timestamp set to Original\n";
|
467 |
-
for ($idx = 0; $s = $zip->statIndex($idx); $idx++) {
|
468 |
-
touch($target.DIRECTORY_SEPARATOR.$s['name'], $s['mtime']);
|
469 |
-
}
|
470 |
-
} else {
|
471 |
-
$now = @date("Y-m-d H:i:s");
|
472 |
-
$log .= "File timestamp set to Current: {$now}\n";
|
473 |
-
}
|
474 |
-
|
475 |
-
// set handler as default
|
476 |
-
DUPX_Handler::setMode();
|
477 |
-
|
478 |
-
$close_response = $zip->close();
|
479 |
-
$log .= "<<< ZipArchive Unzip Complete: ".var_export($close_response, true);
|
480 |
-
DUPX_Log::info($log);
|
481 |
-
} else {
|
482 |
-
$zip_err_msg = ERR_ZIPOPEN;
|
483 |
-
$zip_err_msg .= "<br/><br/><b>To resolve error see <a href='https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q' target='_blank'>https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q</a></b>";
|
484 |
-
DUPX_Log::error($zip_err_msg);
|
485 |
-
}
|
486 |
-
|
487 |
-
break;
|
488 |
-
|
489 |
-
//-----------------------
|
490 |
-
//DUP-ARCHIVE
|
491 |
-
case 'duparchive':
|
492 |
-
DUPX_Log::info(">>> DupArchive Extraction Complete");
|
493 |
-
|
494 |
-
if (isset($_POST['extra_data'])) {
|
495 |
-
$extraData = $_POST['extra_data'];
|
496 |
-
|
497 |
-
$log = "\n--------------------------------------\n";
|
498 |
-
$log .= "DUPARCHIVE EXTRACTION STATUS\n";
|
499 |
-
$log .= "--------------------------------------\n";
|
500 |
-
|
501 |
-
$dawsStatus = json_decode($extraData);
|
502 |
-
|
503 |
-
if ($dawsStatus === null) {
|
504 |
-
$log .= "Can't decode the dawsStatus!\n";
|
505 |
-
$log .= print_r(extraData, true);
|
506 |
-
} else {
|
507 |
-
$criticalPresent = false;
|
508 |
-
|
509 |
-
if (count($dawsStatus->failures) > 0) {
|
510 |
-
$log .= "Archive extracted with errors.\n";
|
511 |
-
|
512 |
-
foreach ($dawsStatus->failures as $failure) {
|
513 |
-
if ($failure->isCritical) {
|
514 |
-
$log .= '(C) ';
|
515 |
-
$criticalPresent = true;
|
516 |
-
}
|
517 |
-
$log .= "{$failure->description}\n";
|
518 |
-
}
|
519 |
-
} else {
|
520 |
-
$log .= "Archive extracted with no errors.\n";
|
521 |
-
}
|
522 |
-
|
523 |
-
if ($criticalPresent) {
|
524 |
-
$log .= "\n\nCritical Errors present so stopping install.\n";
|
525 |
-
exit();
|
526 |
-
}
|
527 |
-
}
|
528 |
-
|
529 |
-
DUPX_Log::info($log);
|
530 |
-
} else {
|
531 |
-
DUPX_LOG::info("DAWS STATUS: UNKNOWN since extra_data wasn't in post!");
|
532 |
-
}
|
533 |
-
|
534 |
-
break;
|
535 |
-
}
|
536 |
-
|
537 |
-
$log = "--------------------------------------\n";
|
538 |
-
$log .= "POST-
|
539 |
-
$log .= "--------------------------------------";
|
540 |
-
DUPX_Log::info($log);
|
541 |
-
|
542 |
-
//===============================
|
543 |
-
//FILE PERMISSIONS
|
544 |
-
if ($_POST['set_file_perms'] || $_POST['set_dir_perms']) {
|
545 |
-
$set_file_perms = $_POST['set_file_perms'];
|
546 |
-
$set_dir_perms = $_POST['set_dir_perms'];
|
547 |
-
$set_file_mtime = ($_POST['zip_filetime'] == 'current');
|
548 |
-
$file_perms_value = $_POST['file_perms_value'] ? $_POST['file_perms_value'] : 0755;
|
549 |
-
$dir_perms_value = $_POST['dir_perms_value'] ? $_POST['dir_perms_value'] : 0644;
|
550 |
-
|
551 |
-
DUPX_Log::info("PERMISSION UPDATES:");
|
552 |
-
DUPX_Log::info(" -DIRS: '{$dir_perms_value}'");
|
553 |
-
DUPX_Log::info(" -FILES: '{$file_perms_value}'");
|
554 |
-
|
555 |
-
$objects = new RecursiveIteratorIterator(
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
}
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
|
|
604 |
}
|
1 |
+
<?php
|
2 |
+
defined("DUPXABSPATH") or die("");
|
3 |
+
|
4 |
+
class DUP_LITE_Extraction
|
5 |
+
{
|
6 |
+
|
7 |
+
const ACTION_DO_NOTHING = 'donothing';
|
8 |
+
const ACTION_REMOVE_ALL_FILES = 'removeall';
|
9 |
+
const ACTION_REMOVE_WP_FILES = 'removewpfiles';
|
10 |
+
const INPUT_NAME_ARCHIVE_ACTION = 'archive_action';
|
11 |
+
|
12 |
+
public $archive_action = self::ACTION_DO_NOTHING;
|
13 |
+
|
14 |
+
/**
|
15 |
+
*
|
16 |
+
* @var self
|
17 |
+
*/
|
18 |
+
protected static $instance = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
*
|
22 |
+
* @return self
|
23 |
+
*/
|
24 |
+
public static function getInstance()
|
25 |
+
{
|
26 |
+
if (is_null(self::$instance)) {
|
27 |
+
self::$instance = new self;
|
28 |
+
}
|
29 |
+
return self::$instance;
|
30 |
+
}
|
31 |
+
|
32 |
+
private function __construct()
|
33 |
+
{
|
34 |
+
$this->initData();
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* initialize extraction data
|
39 |
+
*/
|
40 |
+
public function initData()
|
41 |
+
{
|
42 |
+
if ($_POST['archive_engine'] == 'manual') {
|
43 |
+
$GLOBALS['DUPX_STATE']->isManualExtraction = true;
|
44 |
+
$GLOBALS['DUPX_STATE']->save();
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
*
|
50 |
+
* @param string[] $folders
|
51 |
+
*/
|
52 |
+
protected function removeFiles($folders = array())
|
53 |
+
{
|
54 |
+
$archive_path = $GLOBALS['FW_PACKAGE_PATH'];
|
55 |
+
|
56 |
+
$excludeFiles = array(
|
57 |
+
'/^'.preg_quote($archive_path, '/').'$/',
|
58 |
+
'/^'.preg_quote(DUPX_CSRF::getVal('bootLogFile'), '/').'$/',
|
59 |
+
'/^'.preg_quote(DUPX_CSRF::getVal('installerOrigPath'), '/').'$/',
|
60 |
+
'/^'.preg_quote($GLOBALS['DUPX_ROOT'].'/wp-config.php', '/').'$/'
|
61 |
+
);
|
62 |
+
|
63 |
+
$excludeFolders = array(
|
64 |
+
'/.+\/backups-dup-(lite|pro)$/',
|
65 |
+
'/^'.preg_quote($GLOBALS['DUPX_INIT'], '/').'$/'
|
66 |
+
);
|
67 |
+
|
68 |
+
foreach (DUPX_Server::getWpAddonsSiteLists() as $addonPath) {
|
69 |
+
$excludeFolders[] = '/^'.preg_quote($addonPath, '/').'$/';
|
70 |
+
}
|
71 |
+
|
72 |
+
foreach ($folders as $folder) {
|
73 |
+
DUPX_Log::info('REMOVE FOLDER '.DUPX_Log::varToString($folder));
|
74 |
+
DupLiteSnapLibIOU::regexGlobCallback($folder, function ($path) {
|
75 |
+
|
76 |
+
if (is_dir($path)) {
|
77 |
+
rmdir($path);
|
78 |
+
} else {
|
79 |
+
unlink($path);
|
80 |
+
}
|
81 |
+
}, array(
|
82 |
+
'regexFile' => $excludeFiles,
|
83 |
+
'regexFolder' => $excludeFolders,
|
84 |
+
'checkFullPath' => true,
|
85 |
+
'recursive' => true,
|
86 |
+
'invert' => true,
|
87 |
+
'childFirst' => true
|
88 |
+
));
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
protected function removeWpFiles()
|
93 |
+
{
|
94 |
+
try {
|
95 |
+
DUPX_Log::info('REMOVE WP FILES');
|
96 |
+
DUPX_Log::resetTime(DUPX_Log::LV_DEFAULT, false);
|
97 |
+
|
98 |
+
$absDir = DupLiteSnapLibIOU::trailingslashit($GLOBALS['DUPX_ROOT']);
|
99 |
+
if (!is_dir($absDir) || !is_readable($absDir)) {
|
100 |
+
return false;
|
101 |
+
}
|
102 |
+
|
103 |
+
$removeFolders = array();
|
104 |
+
|
105 |
+
if (($dh = opendir($absDir))) {
|
106 |
+
while (($elem = readdir($dh)) !== false) {
|
107 |
+
if ($elem === '.' || $elem === '..') {
|
108 |
+
continue;
|
109 |
+
}
|
110 |
+
|
111 |
+
if (DupLiteSnapLibUtilWp::isWpCore($elem, DupLiteSnapLibUtilWp::PATH_RELATIVE)) {
|
112 |
+
$fullPath = $absDir.$elem;
|
113 |
+
if (is_dir($fullPath)) {
|
114 |
+
$removeFolders[] = $fullPath;
|
115 |
+
} else {
|
116 |
+
if (is_writable($fullPath)) {
|
117 |
+
unlink($fullPath);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
}
|
121 |
+
}
|
122 |
+
closedir($dh);
|
123 |
+
}
|
124 |
+
|
125 |
+
$this->removeFiles(array_unique($removeFolders));
|
126 |
+
DUPX_Log::logTime('FOLDERS REMOVED', DUPX_Log::LV_DEFAULT, false);
|
127 |
+
}
|
128 |
+
catch (Exception $e) {
|
129 |
+
DUPX_Log::logException($e);
|
130 |
+
}
|
131 |
+
catch (Error $e) {
|
132 |
+
DUPX_Log::logException($e);
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
*
|
138 |
+
*/
|
139 |
+
protected function removeAllFiles()
|
140 |
+
{
|
141 |
+
try {
|
142 |
+
DUPX_Log::info('REMOVE ALL FILES');
|
143 |
+
DUPX_Log::resetTime(DUPX_Log::LV_DEFAULT, false);
|
144 |
+
$this->removeFiles(array($GLOBALS['DUPX_ROOT']));
|
145 |
+
DUPX_Log::logTime('FOLDERS REMOVED', DUPX_Log::LV_DEFAULT, false);
|
146 |
+
}
|
147 |
+
catch (Exception $e) {
|
148 |
+
DUPX_Log::logException($e);
|
149 |
+
}
|
150 |
+
catch (Error $e) {
|
151 |
+
DUPX_Log::logException($e);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* preliminary actions before the extraction.
|
157 |
+
*
|
158 |
+
* @return void
|
159 |
+
*/
|
160 |
+
protected function beforeExtraction()
|
161 |
+
{
|
162 |
+
DUPX_Log::info('BEFORE EXTRACION ACTIONS');
|
163 |
+
|
164 |
+
if (!$GLOBALS['DUPX_AC']->exportOnlyDB) {
|
165 |
+
switch ($_POST[self::INPUT_NAME_ARCHIVE_ACTION]) {
|
166 |
+
case self::ACTION_REMOVE_ALL_FILES:
|
167 |
+
$this->removeAllFiles();
|
168 |
+
break;
|
169 |
+
case self::ACTION_REMOVE_WP_FILES:
|
170 |
+
$this->removeWpFiles();
|
171 |
+
break;
|
172 |
+
case self::ACTION_DO_NOTHING:
|
173 |
+
break;
|
174 |
+
default:
|
175 |
+
throw new Exception('Invalid engine action '.$_POST[self::INPUT_NAME_ARCHIVE_ACTION]);
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
*
|
182 |
+
* @throws Exception
|
183 |
+
*/
|
184 |
+
public function runExtraction()
|
185 |
+
{
|
186 |
+
//OPTIONS
|
187 |
+
$_POST['set_file_perms'] = (isset($_POST['set_file_perms'])) ? 1 : 0;
|
188 |
+
$_POST['set_dir_perms'] = (isset($_POST['set_dir_perms'])) ? 1 : 0;
|
189 |
+
$_POST['file_perms_value'] = (isset($_POST['file_perms_value'])) ? DUPX_U::sanitize_text_field($_POST['file_perms_value']) : 0755;
|
190 |
+
$_POST['dir_perms_value'] = (isset($_POST['dir_perms_value'])) ? DUPX_U::sanitize_text_field($_POST['dir_perms_value']) : 0644;
|
191 |
+
$_POST['zip_filetime'] = (isset($_POST['zip_filetime'])) ? $_POST['zip_filetime'] : 'current';
|
192 |
+
$_POST['config_mode'] = (isset($_POST['config_mode'])) ? $_POST['config_mode'] : 'NEW';
|
193 |
+
$_POST[self::INPUT_NAME_ARCHIVE_ACTION] = (isset($_POST[self::INPUT_NAME_ARCHIVE_ACTION])) ? $_POST[self::INPUT_NAME_ARCHIVE_ACTION] : self::ACTION_DO_NOTHING;
|
194 |
+
$_POST['archive_engine'] = (isset($_POST['archive_engine'])) ? $_POST['archive_engine'] : 'manual';
|
195 |
+
$_POST['exe_safe_mode'] = (isset($_POST['exe_safe_mode'])) ? $_POST['exe_safe_mode'] : 0;
|
196 |
+
|
197 |
+
//LOGGING
|
198 |
+
$POST_LOG = $_POST;
|
199 |
+
unset($POST_LOG['dbpass']);
|
200 |
+
ksort($POST_LOG);
|
201 |
+
|
202 |
+
//ACTION VARS
|
203 |
+
$ajax1_start = DUPX_U::getMicrotime();
|
204 |
+
$root_path = $GLOBALS['DUPX_ROOT'];
|
205 |
+
$wpconfig_ark_path = ($GLOBALS['DUPX_AC']->installSiteOverwriteOn) ?
|
206 |
+
"{$root_path}/dup-wp-config-arc__{$GLOBALS['DUPX_AC']->package_hash}.txt" : "{$root_path}/wp-config.php";
|
207 |
+
|
208 |
+
$archive_path = $GLOBALS['FW_PACKAGE_PATH'];
|
209 |
+
$dataResult = array();
|
210 |
+
$dataResult['pass'] = 0;
|
211 |
+
|
212 |
+
/** JSON RESPONSE: Most sites have warnings turned off by default, but if they're turned on the warnings
|
213 |
+
cause errors in the JSON data Here we hide the status so warning level is reset at it at the end */
|
214 |
+
$ajax1_error_level = error_reporting();
|
215 |
+
error_reporting(E_ERROR);
|
216 |
+
|
217 |
+
$nManager = DUPX_NOTICE_MANAGER::getInstance();
|
218 |
+
|
219 |
+
//===============================
|
220 |
+
//ARCHIVE ERROR MESSAGES
|
221 |
+
//===============================
|
222 |
+
($GLOBALS['LOG_FILE_HANDLE'] != false) or DUPX_Log::error(ERR_MAKELOG);
|
223 |
+
|
224 |
+
if (!$GLOBALS['DUPX_AC']->exportOnlyDB) {
|
225 |
+
|
226 |
+
$post_archive_engine = DUPX_U::sanitize_text_field($_POST['archive_engine']);
|
227 |
+
|
228 |
+
if ($post_archive_engine == 'manual') {
|
229 |
+
if (!file_exists($wpconfig_ark_path) && !file_exists("database.sql")) {
|
230 |
+
DUPX_Log::error(ERR_ZIPMANUAL);
|
231 |
+
}
|
232 |
+
} else {
|
233 |
+
if (!is_readable("{$archive_path}")) {
|
234 |
+
DUPX_Log::error("archive path:{$archive_path}<br/>".ERR_ZIPNOTFOUND);
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
//ERR_ZIPMANUAL
|
239 |
+
if (('ziparchive' == $post_archive_engine || 'shellexec_unzip' == $post_archive_engine) && !$GLOBALS['DUPX_AC']->installSiteOverwriteOn) {
|
240 |
+
//ERR_CONFIG_FOUND
|
241 |
+
$outer_root_path = dirname($root_path);
|
242 |
+
|
243 |
+
if ((file_exists($wpconfig_ark_path) || (@file_exists("{$outer_root_path}/wp-config.php") && !@file_exists("{$outer_root_path}/wp-settings.php"))) && @file_exists("{$root_path}/wp-admin") && @file_exists("{$root_path}/wp-includes")) {
|
244 |
+
DUPX_Log::error(ERR_CONFIG_FOUND);
|
245 |
+
}
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
DUPX_Log::info("********************************************************************************");
|
250 |
+
DUPX_Log::info('* DUPLICATOR-LITE: Install-Log');
|
251 |
+
DUPX_Log::info('* STEP-1 START @ '.@date('h:i:s'));
|
252 |
+
DUPX_Log::info("* VERSION: {$GLOBALS['DUPX_AC']->version_dup}");
|
253 |
+
DUPX_Log::info('* NOTICE: Do NOT post to public sites or forums!!');
|
254 |
+
DUPX_Log::info("********************************************************************************");
|
255 |
+
|
256 |
+
$colSize = 60;
|
257 |
+
$labelPadSize = 20;
|
258 |
+
$os = defined('PHP_OS') ? PHP_OS : 'unknown';
|
259 |
+
$log = str_pad(str_pad('PACKAGE INFO', $labelPadSize, '_', STR_PAD_RIGHT).' '.'CURRENT SERVER', $colSize, ' ', STR_PAD_RIGHT).'|'.'ORIGINAL SERVER'."\n".
|
260 |
+
str_pad(str_pad('PHP VERSION', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_php, $colSize, ' ', STR_PAD_RIGHT).'|'.phpversion()."\n".
|
261 |
+
str_pad(str_pad('OS', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_os, $colSize, ' ', STR_PAD_RIGHT).'|'.$os."\n".
|
262 |
+
str_pad('CREATED', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->created."\n".
|
263 |
+
str_pad('WP VERSION', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_wp."\n".
|
264 |
+
str_pad('DUP VERSION', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_dup."\n".
|
265 |
+
str_pad('DB', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->version_db."\n".
|
266 |
+
str_pad('DB TABLES', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->dbInfo->tablesFinalCount."\n".
|
267 |
+
str_pad('DB ROWS', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->dbInfo->tablesRowCount."\n".
|
268 |
+
str_pad('DB FILE SIZE', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['DUPX_AC']->dbInfo->tablesSizeOnDisk."\n".
|
269 |
+
"********************************************************************************";
|
270 |
+
DUPX_Log::info($log);
|
271 |
+
DUPX_Log::info("SERVER INFO");
|
272 |
+
DUPX_Log::info(str_pad('PHP', $labelPadSize, '_', STR_PAD_RIGHT).': '.phpversion().' | SAPI: '.php_sapi_name());
|
273 |
+
DUPX_Log::info(str_pad('PHP MEMORY', $labelPadSize, '_', STR_PAD_RIGHT).': '.$GLOBALS['PHP_MEMORY_LIMIT'].' | SUHOSIN: '.$GLOBALS['PHP_SUHOSIN_ON']);
|
274 |
+
DUPX_Log::info(str_pad('SERVER', $labelPadSize, '_', STR_PAD_RIGHT).': '.$_SERVER['SERVER_SOFTWARE']);
|
275 |
+
DUPX_Log::info(str_pad('DOC ROOT', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($root_path));
|
276 |
+
DUPX_Log::info(str_pad('DOC ROOT 755', $labelPadSize, '_', STR_PAD_RIGHT).': '.var_export($GLOBALS['CHOWN_ROOT_PATH'], true));
|
277 |
+
DUPX_Log::info(str_pad('LOG FILE 644', $labelPadSize, '_', STR_PAD_RIGHT).': '.var_export($GLOBALS['CHOWN_LOG_PATH'], true));
|
278 |
+
DUPX_Log::info(str_pad('REQUEST URL', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($GLOBALS['URL_PATH']));
|
279 |
+
|
280 |
+
DUPX_Log::info("********************************************************************************");
|
281 |
+
DUPX_Log::info("USER INPUTS");
|
282 |
+
DUPX_Log::info(str_pad('ARCHIVE ACTION', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST[self::INPUT_NAME_ARCHIVE_ACTION]));
|
283 |
+
DUPX_Log::info(str_pad('ARCHIVE ENGINE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['archive_engine']));
|
284 |
+
DUPX_Log::info(str_pad('SET DIR PERMS', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['set_dir_perms']));
|
285 |
+
DUPX_Log::info(str_pad('DIR PERMS VALUE', $labelPadSize, '_', STR_PAD_RIGHT).': '.decoct($_POST['dir_perms_value']));
|
286 |
+
DUPX_Log::info(str_pad('SET FILE PERMS', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['set_file_perms']));
|
287 |
+
DUPX_Log::info(str_pad('FILE PERMS VALUE', $labelPadSize, '_', STR_PAD_RIGHT).': '.decoct($_POST['file_perms_value']));
|
288 |
+
DUPX_Log::info(str_pad('SAFE MODE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['exe_safe_mode']));
|
289 |
+
DUPX_Log::info(str_pad('LOGGING', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['logging']));
|
290 |
+
DUPX_Log::info(str_pad('CONFIG MODE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['config_mode']));
|
291 |
+
DUPX_Log::info(str_pad('FILE TIME', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($_POST['zip_filetime']));
|
292 |
+
DUPX_Log::info("********************************************************************************\n");
|
293 |
+
|
294 |
+
$log = "--------------------------------------\n";
|
295 |
+
$log .= "POST DATA\n";
|
296 |
+
$log .= "--------------------------------------\n";
|
297 |
+
$log .= print_r($POST_LOG, true);
|
298 |
+
DUPX_Log::info($log, DUPX_Log::LV_DEBUG);
|
299 |
+
|
300 |
+
$log = "\n--------------------------------------\n";
|
301 |
+
$log .= "ARCHIVE SETUP\n";
|
302 |
+
$log .= "--------------------------------------\n";
|
303 |
+
$log .= str_pad('NAME', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($GLOBALS['FW_PACKAGE_PATH'])."\n";
|
304 |
+
if (file_exists($GLOBALS['FW_PACKAGE_PATH'])) {
|
305 |
+
$log .= str_pad('SIZE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_U::readableByteSize(@filesize($GLOBALS['FW_PACKAGE_PATH']));
|
306 |
+
}
|
307 |
+
DUPX_Log::info($log."\n", DUPX_Log::LV_DEFAULT, true);
|
308 |
+
|
309 |
+
DUPX_Log::info('PRE-EXTRACT-CHECKS');
|
310 |
+
DUPX_ServerConfig::beforeExtractionSetup();
|
311 |
+
|
312 |
+
$this->beforeExtraction();
|
313 |
+
|
314 |
+
$target = $root_path;
|
315 |
+
DUPX_U::maintenanceMode(true);
|
316 |
+
|
317 |
+
$post_archive_engine = DUPX_U::sanitize_text_field($_POST['archive_engine']);
|
318 |
+
switch ($post_archive_engine) {
|
319 |
+
|
320 |
+
//-----------------------
|
321 |
+
//MANUAL EXTRACTION
|
322 |
+
case 'manual':
|
323 |
+
DUPX_Log::info("\n** PACKAGE EXTRACTION IS IN MANUAL MODE ** \n");
|
324 |
+
break;
|
325 |
+
|
326 |
+
//-----------------------
|
327 |
+
//SHELL EXEC
|
328 |
+
case 'shellexec_unzip':
|
329 |
+
DUPX_Log::info("\n\nSTART ZIP FILE EXTRACTION SHELLEXEC >>> ");
|
330 |
+
$shell_exec_path = DUPX_Server::get_unzip_filepath();
|
331 |
+
|
332 |
+
|
333 |
+
$command = escapeshellcmd($shell_exec_path)." -o -qq ".escapeshellarg($archive_path)." -d ".escapeshellarg($target)." 2>&1";
|
334 |
+
if ($_POST['zip_filetime'] == 'original') {
|
335 |
+
DUPX_Log::info("\nShell Exec Current does not support orginal file timestamp please use ZipArchive");
|
336 |
+
}
|
337 |
+
|
338 |
+
DUPX_Log::info(">>> Starting Shell-Exec Unzip:\nCommand: {$command}", DUPX_Log::LV_DEBUG);
|
339 |
+
$stderr = shell_exec($command);
|
340 |
+
if ($stderr != '') {
|
341 |
+
$zip_err_msg = ERR_SHELLEXEC_ZIPOPEN.": $stderr";
|
342 |
+
$zip_err_msg .= "<br/><br/><b>To resolve error see <a href='https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q' target='_blank'>https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q</a></b>";
|
343 |
+
DUPX_Log::error($zip_err_msg);
|
344 |
+
}
|
345 |
+
DUPX_Log::info("<<< Shell-Exec Unzip Complete.");
|
346 |
+
|
347 |
+
break;
|
348 |
+
|
349 |
+
//-----------------------
|
350 |
+
//ZIP-ARCHIVE
|
351 |
+
case 'ziparchive':
|
352 |
+
DUPX_Log::info("\n\nSTART ZIP FILE EXTRACTION STANDARD >>> ");
|
353 |
+
|
354 |
+
if (!class_exists('ZipArchive')) {
|
355 |
+
DUPX_Log::info("ERROR: Stopping install process. Trying to extract without ZipArchive module installed. Please use the 'Manual Archive Extraction' mode to extract zip file.");
|
356 |
+
DUPX_Log::error(ERR_ZIPARCHIVE);
|
357 |
+
}
|
358 |
+
|
359 |
+
if (($dupInstallerFolder = DUPX_U::findDupInstallerFolder($archive_path)) === false) {
|
360 |
+
DUPX_Log::info("findDupInstallerFolder error; set no subfolder");
|
361 |
+
// if not found set not subfolder
|
362 |
+
$dupInstallerFolder = '';
|
363 |
+
}
|
364 |
+
if (!empty($dupInstallerFolder)) {
|
365 |
+
DUPX_Log::info("ARCHIVE dup-installer SUBFOLDER:\"".$dupInstallerFolder."\"");
|
366 |
+
} else {
|
367 |
+
DUPX_Log::info("ARCHIVE dup-installer SUBFOLDER:\"".$dupInstallerFolder."\"", 2);
|
368 |
+
}
|
369 |
+
|
370 |
+
$dupInstallerZipPath = $dupInstallerFolder.'/dup-installer';
|
371 |
+
|
372 |
+
$zip = new ZipArchive();
|
373 |
+
|
374 |
+
if ($zip->open($archive_path) === TRUE) {
|
375 |
+
$extract_filenames = array();
|
376 |
+
DUPX_Handler::setMode(DUPX_Handler::MODE_VAR, false, false);
|
377 |
+
|
378 |
+
for ($i = 0; $i < $zip->numFiles; $i++) {
|
379 |
+
$extract_filename = $zip->getNameIndex($i);
|
380 |
+
|
381 |
+
// skip dup-installer folder. Alrady extracted in bootstrap
|
382 |
+
if (
|
383 |
+
(strpos($extract_filename, $dupInstallerZipPath) === 0) ||
|
384 |
+
(!empty($dupInstallerFolder) && strpos($extract_filename, $dupInstallerFolder) !== 0)
|
385 |
+
) {
|
386 |
+
DUPX_Log::info("SKIPPING NOT IN ZIPATH:\"".DUPX_Log::varToString($extract_filename)."\"", DUPX_Log::LV_DETAILED);
|
387 |
+
continue;
|
388 |
+
}
|
389 |
+
|
390 |
+
try {
|
391 |
+
if (!$zip->extractTo($target, $extract_filename)) {
|
392 |
+
if (DupLiteSnapLibUtilWp::isWpCore($extract_filename, DupLiteSnapLibUtilWp::PATH_RELATIVE)) {
|
393 |
+
DUPX_Log::info("FILE CORE EXTRACION ERROR: ".$extract_filename);
|
394 |
+
$shortMsg = 'Can\'t extract wp core files';
|
395 |
+
$finalShortMsg = 'Wp core files not extracted';
|
396 |
+
$errLevel = DUPX_NOTICE_ITEM::CRITICAL;
|
397 |
+
$idManager = 'wp-extract-error-file-core';
|
398 |
+
} else {
|
399 |
+
DUPX_Log::info("FILE EXTRACION ERROR: ".$extract_filename);
|
400 |
+
$shortMsg = 'Can\'t extract files';
|
401 |
+
$finalShortMsg = 'Files not extracted';
|
402 |
+
$errLevel = DUPX_NOTICE_ITEM::SOFT_WARNING;
|
403 |
+
$idManager = 'wp-extract-error-file-no-core';
|
404 |
+
}
|
405 |
+
$longMsg = 'FILE: <b>'.htmlspecialchars($extract_filename).'</b><br>Message: '.htmlspecialchars(DUPX_Handler::getVarLogClean()).'<br><br>';
|
406 |
+
|
407 |
+
$nManager->addNextStepNotice(array(
|
408 |
+
'shortMsg' => $shortMsg,
|
409 |
+
'longMsg' => $longMsg,
|
410 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
411 |
+
'level' => $errLevel
|
412 |
+
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
413 |
+
$nManager->addFinalReportNotice(array(
|
414 |
+
'shortMsg' => $finalShortMsg,
|
415 |
+
'longMsg' => $longMsg,
|
416 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
417 |
+
'level' => $errLevel,
|
418 |
+
'sections' => array('files'),
|
419 |
+
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
420 |
+
} else {
|
421 |
+
DUPX_Log::info("FILE EXTRACTION DONE: ".DUPX_Log::varToString($extract_filename), DUPX_Log::LV_HARD_DEBUG);
|
422 |
+
}
|
423 |
+
}
|
424 |
+
catch (Exception $ex) {
|
425 |
+
if (DupLiteSnapLibUtilWp::isWpCore($extract_filename, DupLiteSnapLibUtilWp::PATH_RELATIVE)) {
|
426 |
+
DUPX_Log::info("FILE CORE EXTRACION ERROR: {$extract_filename} | MSG:".$ex->getMessage());
|
427 |
+
$shortMsg = 'Can\'t extract wp core files';
|
428 |
+
$finalShortMsg = 'Wp core files not extracted';
|
429 |
+
$errLevel = DUPX_NOTICE_ITEM::CRITICAL;
|
430 |
+
$idManager = 'wp-extract-error-file-core';
|
431 |
+
} else {
|
432 |
+
DUPX_Log::info("FILE EXTRACION ERROR: {$extract_filename} | MSG:".$ex->getMessage());
|
433 |
+
$shortMsg = 'Can\'t extract files';
|
434 |
+
$finalShortMsg = 'Files not extracted';
|
435 |
+
$errLevel = DUPX_NOTICE_ITEM::SOFT_WARNING;
|
436 |
+
$idManager = 'wp-extract-error-file-no-core';
|
437 |
+
}
|
438 |
+
$longMsg = 'FILE: <b>'.htmlspecialchars($extract_filename).'</b><br>Message: '.htmlspecialchars($ex->getMessage()).'<br><br>';
|
439 |
+
|
440 |
+
$nManager->addNextStepNotice(array(
|
441 |
+
'shortMsg' => $shortMsg,
|
442 |
+
'longMsg' => $longMsg,
|
443 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
444 |
+
'level' => $errLevel
|
445 |
+
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
446 |
+
$nManager->addFinalReportNotice(array(
|
447 |
+
'shortMsg' => $finalShortMsg,
|
448 |
+
'longMsg' => $longMsg,
|
449 |
+
'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML,
|
450 |
+
'level' => $errLevel,
|
451 |
+
'sections' => array('files'),
|
452 |
+
), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager);
|
453 |
+
}
|
454 |
+
}
|
455 |
+
|
456 |
+
if (!empty($dupInstallerFolder)) {
|
457 |
+
DUPX_U::moveUpfromSubFolder($target.'/'.$dupInstallerFolder, true);
|
458 |
+
}
|
459 |
+
|
460 |
+
//Uncomment if needed
|
461 |
+
//if (DUPX_Log::isLevel(DUPX_Log::LV_DEBUG)) {
|
462 |
+
// $log = print_r($zip, true);
|
463 |
+
//}
|
464 |
+
//FILE-TIMESTAMP
|
465 |
+
if ($_POST['zip_filetime'] == 'original') {
|
466 |
+
$log .= "File timestamp set to Original\n";
|
467 |
+
for ($idx = 0; $s = $zip->statIndex($idx); $idx++) {
|
468 |
+
touch($target.DIRECTORY_SEPARATOR.$s['name'], $s['mtime']);
|
469 |
+
}
|
470 |
+
} else {
|
471 |
+
$now = @date("Y-m-d H:i:s");
|
472 |
+
$log .= "File timestamp set to Current: {$now}\n";
|
473 |
+
}
|
474 |
+
|
475 |
+
// set handler as default
|
476 |
+
DUPX_Handler::setMode();
|
477 |
+
|
478 |
+
$close_response = $zip->close();
|
479 |
+
$log .= "<<< ZipArchive Unzip Complete: ".var_export($close_response, true);
|
480 |
+
DUPX_Log::info($log);
|
481 |
+
} else {
|
482 |
+
$zip_err_msg = ERR_ZIPOPEN;
|
483 |
+
$zip_err_msg .= "<br/><br/><b>To resolve error see <a href='https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q' target='_blank'>https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-130-q</a></b>";
|
484 |
+
DUPX_Log::error($zip_err_msg);
|
485 |
+
}
|
486 |
+
|
487 |
+
break;
|
488 |
+
|
489 |
+
//-----------------------
|
490 |
+
//DUP-ARCHIVE
|
491 |
+
case 'duparchive':
|
492 |
+
DUPX_Log::info(">>> DupArchive Extraction Complete");
|
493 |
+
|
494 |
+
if (isset($_POST['extra_data'])) {
|
495 |
+
$extraData = $_POST['extra_data'];
|
496 |
+
|
497 |
+
$log = "\n--------------------------------------\n";
|
498 |
+
$log .= "DUPARCHIVE EXTRACTION STATUS\n";
|
499 |
+
$log .= "--------------------------------------\n";
|
500 |
+
|
501 |
+
$dawsStatus = json_decode($extraData);
|
502 |
+
|
503 |
+
if ($dawsStatus === null) {
|
504 |
+
$log .= "Can't decode the dawsStatus!\n";
|
505 |
+
$log .= print_r(extraData, true);
|
506 |
+
} else {
|
507 |
+
$criticalPresent = false;
|
508 |
+
|
509 |
+
if (count($dawsStatus->failures) > 0) {
|
510 |
+
$log .= "Archive extracted with errors.\n";
|
511 |
+
|
512 |
+
foreach ($dawsStatus->failures as $failure) {
|
513 |
+
if ($failure->isCritical) {
|
514 |
+
$log .= '(C) ';
|
515 |
+
$criticalPresent = true;
|
516 |
+
}
|
517 |
+
$log .= "{$failure->description}\n";
|
518 |
+
}
|
519 |
+
} else {
|
520 |
+
$log .= "Archive extracted with no errors.\n";
|
521 |
+
}
|
522 |
+
|
523 |
+
if ($criticalPresent) {
|
524 |
+
$log .= "\n\nCritical Errors present so stopping install.\n";
|
525 |
+
exit();
|
526 |
+
}
|
527 |
+
}
|
528 |
+
|
529 |
+
DUPX_Log::info($log);
|
530 |
+
} else {
|
531 |
+
DUPX_LOG::info("DAWS STATUS: UNKNOWN since extra_data wasn't in post!");
|
532 |
+
}
|
533 |
+
|
534 |
+
break;
|
535 |
+
}
|
536 |
+
|
537 |
+
$log = "--------------------------------------\n";
|
538 |
+
$log .= "POST-EXTRACT-CHECKS\n";
|
539 |
+
$log .= "--------------------------------------";
|
540 |
+
DUPX_Log::info($log);
|
541 |
+
|
542 |
+
//===============================
|
543 |
+
//FILE PERMISSIONS
|
544 |
+
if ($_POST['set_file_perms'] || $_POST['set_dir_perms']) {
|
545 |
+
$set_file_perms = $_POST['set_file_perms'];
|
546 |
+
$set_dir_perms = $_POST['set_dir_perms'];
|
547 |
+
$set_file_mtime = ($_POST['zip_filetime'] == 'current');
|
548 |
+
$file_perms_value = $_POST['file_perms_value'] ? $_POST['file_perms_value'] : 0755;
|
549 |
+
$dir_perms_value = $_POST['dir_perms_value'] ? $_POST['dir_perms_value'] : 0644;
|
550 |
+
|
551 |
+
DUPX_Log::info("PERMISSION UPDATES:");
|
552 |
+
DUPX_Log::info(" -DIRS: '{$dir_perms_value}'");
|
553 |
+
DUPX_Log::info(" -FILES: '{$file_perms_value}'");
|
554 |
+
|
555 |
+
$objects = new RecursiveIteratorIterator(
|
556 |
+
new IgnorantRecursiveDirectoryIterator($root_path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
|
557 |
+
|
558 |
+
foreach ($objects as $name => $object) {
|
559 |
+
if ($set_file_perms && is_file($name)) {
|
560 |
+
DUPX_Log::info("SET PERMISSION: ".DUPX_Log::varToString($name).'[MODE:'.$file_perms_value.']', DUPX_Log::LV_HARD_DEBUG);
|
561 |
+
if (!DupLiteSnapLibIOU::chmod($name, $file_perms_value)) {
|
562 |
+
DUPX_Log::info("Permissions setting on file '{$name}' failed");
|
563 |
+
}
|
564 |
+
} else if ($set_dir_perms && is_dir($name)) {
|
565 |
+
DUPX_Log::info("SET PERMISSION: ".DUPX_Log::varToString($name).'[MODE:'.$dir_perms_value.']', DUPX_Log::LV_HARD_DEBUG);
|
566 |
+
if (!DupLiteSnapLibIOU::chmod($name, $dir_perms_value)) {
|
567 |
+
DUPX_Log::info("Permissions setting on directory '{$name}' failed");
|
568 |
+
}
|
569 |
+
}
|
570 |
+
if ($set_file_mtime) {
|
571 |
+
@touch($name);
|
572 |
+
}
|
573 |
+
}
|
574 |
+
} else {
|
575 |
+
DUPX_Log::info("\nPERMISSION UPDATES: None Applied");
|
576 |
+
}
|
577 |
+
|
578 |
+
DUPX_ServerConfig::afterExtractionSetup();
|
579 |
+
$nManager->saveNotices();
|
580 |
+
|
581 |
+
//FINAL RESULTS
|
582 |
+
$ajax1_sum = DUPX_U::elapsedTime(DUPX_U::getMicrotime(), $ajax1_start);
|
583 |
+
DUPX_Log::info("\nSTEP-1 COMPLETE @ ".@date('h:i:s')." - RUNTIME: {$ajax1_sum}");
|
584 |
+
|
585 |
+
$dataResult['pass'] = 1;
|
586 |
+
error_reporting($ajax1_error_level);
|
587 |
+
fclose($GLOBALS["LOG_FILE_HANDLE"]);
|
588 |
+
return $dataResult;
|
589 |
+
}
|
590 |
+
}
|
591 |
+
|
592 |
+
// Skips past paths it can't read
|
593 |
+
class IgnorantRecursiveDirectoryIterator extends RecursiveDirectoryIterator
|
594 |
+
{
|
595 |
+
#[\ReturnTypeWillChange]
|
596 |
+
public function getChildren()
|
597 |
+
{
|
598 |
+
try {
|
599 |
+
return new IgnorantRecursiveDirectoryIterator($this->getPathname(), RecursiveDirectoryIterator::SKIP_DOTS);
|
600 |
+
}
|
601 |
+
catch (UnexpectedValueException $e) {
|
602 |
+
return new RecursiveArrayIterator(array());
|
603 |
+
}
|
604 |
+
}
|
605 |
}
|
installer/dup-installer/views/view.help.php
CHANGED
@@ -4,7 +4,7 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
4 |
//indicate if this help lives in lite or pro
|
5 |
//$pro_version = true;
|
6 |
|
7 |
-
$open_section = filter_input(INPUT_GET, 'open_section',
|
8 |
|
9 |
?>
|
10 |
<div class="hdr-main">
|
4 |
//indicate if this help lives in lite or pro
|
5 |
//$pro_version = true;
|
6 |
|
7 |
+
$open_section = filter_input(INPUT_GET, 'open_section', FILTER_UNSAFE_RAW, array('options' => array('default' => '')));
|
8 |
|
9 |
?>
|
10 |
<div class="hdr-main">
|
installer/dup-installer/views/view.s3.php
CHANGED
@@ -416,7 +416,10 @@ VIEW: STEP 3 - AJAX RESULT -->
|
|
416 |
<div id="ajaxerr-area" style="display:none">
|
417 |
<p>Please try again an issue has occurred.</p>
|
418 |
<div style="padding: 0px 10px 10px 10px;">
|
419 |
-
<div id="ajaxerr-data">
|
|
|
|
|
|
|
420 |
<div style="text-align:center; margin:10px auto 0px auto">
|
421 |
<input type="button" onclick='DUPX.hideErrorResult2()' value="« Try Again" class="default-btn" /><br/><br/>
|
422 |
<i style='font-size:11px'>See online help for more details at <a href='https://snapcreek.com' target='_blank'>snapcreek.com</a></i>
|
@@ -518,17 +521,28 @@ DUPX.runUpdate = function()
|
|
518 |
DUPX.hideProgressBar();
|
519 |
return false;
|
520 |
}
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
532 |
},
|
533 |
error: function(xhr) {
|
534 |
var status = "<b>Server Code:</b> " + xhr.status + "<br/>";
|
416 |
<div id="ajaxerr-area" style="display:none">
|
417 |
<p>Please try again an issue has occurred.</p>
|
418 |
<div style="padding: 0px 10px 10px 10px;">
|
419 |
+
<div id="ajaxerr-data">
|
420 |
+
<b>Overview:</b><br/>
|
421 |
+
An issue has occurred in step 3. Please see the <?php DUPX_View_Funcs::installerLogLink(); ?> file for more details.
|
422 |
+
</div>
|
423 |
<div style="text-align:center; margin:10px auto 0px auto">
|
424 |
<input type="button" onclick='DUPX.hideErrorResult2()' value="« Try Again" class="default-btn" /><br/><br/>
|
425 |
<i style='font-size:11px'>See online help for more details at <a href='https://snapcreek.com' target='_blank'>snapcreek.com</a></i>
|
521 |
DUPX.hideProgressBar();
|
522 |
return false;
|
523 |
}
|
524 |
+
|
525 |
+
try {
|
526 |
+
if (typeof(data) != 'undefined' && data.step3.pass == 1) {
|
527 |
+
$("#ajax-url_new").val($("#url_new").val());
|
528 |
+
$("#ajax-exe-safe-mode").val($("#exe-safe-mode").val());
|
529 |
+
$("#ajax-json").val(escape(JSON.stringify(data)));
|
530 |
+
<?php if (!DUPX_Log::isLevel(DUPX_Log::LV_DEBUG)) : ?>
|
531 |
+
setTimeout(function(){$('#s3-result-form').submit();}, 1000);
|
532 |
+
<?php endif; ?>
|
533 |
+
} else {
|
534 |
+
if (typeof(data) != 'undefined' && data.step3.pass == -1) {
|
535 |
+
console.log(data);
|
536 |
+
let details = (data.step3.error_message.length > 0) ? data.step3.error_message : "No details found.";
|
537 |
+
$('#ajaxerr-data').append(`<br/><br/><b>Details:</b><br/> ${details}`);
|
538 |
+
}
|
539 |
+
DUPX.hideProgressBar();
|
540 |
+
}
|
541 |
+
} catch(err) {
|
542 |
+
console.log(err);
|
543 |
+
DUPX.hideProgressBar();
|
544 |
+
}
|
545 |
+
|
546 |
},
|
547 |
error: function(xhr) {
|
548 |
var status = "<b>Server Code:</b> " + xhr.status + "<br/>";
|
installer/dup-installer/views/view.s4.php
CHANGED
@@ -114,7 +114,7 @@ VIEW: STEP 4- INPUT -->
|
|
114 |
|
115 |
<?php
|
116 |
$nManager = DUPX_NOTICE_MANAGER::getInstance();
|
117 |
-
if ($json_decode->step1->query_errs > 0) {
|
118 |
$linkAttr = './'.DUPX_U::esc_attr($GLOBALS["LOG_FILE_NAME"]);
|
119 |
$longMsg = <<<LONGMSG
|
120 |
Queries that error during the deploy step are logged to the <a href="{$linkAttr}" target="dup-installer">install-log.txt</a> file and
|
@@ -146,7 +146,7 @@ LONGMSG;
|
|
146 |
));
|
147 |
}
|
148 |
|
149 |
-
if ($json_decode->step3->errsql_sum > 0) {
|
150 |
$longMsg = <<<LONGMSG
|
151 |
Update errors that show here are queries that could not be performed because the database server being used has issues running it. Please validate the query, if
|
152 |
it looks to be of concern please try to run the query manually. In many cases if your site performs well without any issues you can ignore the error.
|
@@ -162,7 +162,7 @@ LONGMSG;
|
|
162 |
));
|
163 |
}
|
164 |
|
165 |
-
if ($json_decode->step3->errkey_sum > 0) {
|
166 |
$longMsg = <<<LONGMSG
|
167 |
Notices should be ignored unless issues are found after you have tested an installed site. This notice indicates that a primary key is required to run the
|
168 |
update engine. Below is a list of tables and the rows that were not updated. On some databases you can remove these notices by checking the box 'Enable Full Search'
|
@@ -186,7 +186,7 @@ LONGMSG;
|
|
186 |
));
|
187 |
}
|
188 |
|
189 |
-
if ($json_decode->step3->errser_sum > 0) {
|
190 |
$longMsg = <<<LONGMSG
|
191 |
Notices should be ignored unless issues are found after you have tested an installed site. The SQL below will show data that may have not been
|
192 |
updated during the serialization process. Best practices for serialization notices is to just re-save the plugin/post/page in question.
|
@@ -326,9 +326,14 @@ LONGMSG;
|
|
326 |
</li>
|
327 |
<?php
|
328 |
$wpconfigNotice = $nManager->getFinalReporNoticeById('wp-config-changes');
|
329 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
?>
|
331 |
-
<li>Please validate <?php echo $wpconfigNotice->longMsg; ?> and <?php echo $htaccessNorice->longMsg; ?></li>
|
332 |
<li>For additional help and questions visit the <a href='https://snapcreek.com/duplicator/docs/faqs-tech/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_campaign=problem_resolution&utm_content=inst4_step4_troubleshoot' target='_blank'>online FAQs</a></li>
|
333 |
</ul>
|
334 |
</div>
|
114 |
|
115 |
<?php
|
116 |
$nManager = DUPX_NOTICE_MANAGER::getInstance();
|
117 |
+
if ($json_decode && $json_decode->step1->query_errs > 0) {
|
118 |
$linkAttr = './'.DUPX_U::esc_attr($GLOBALS["LOG_FILE_NAME"]);
|
119 |
$longMsg = <<<LONGMSG
|
120 |
Queries that error during the deploy step are logged to the <a href="{$linkAttr}" target="dup-installer">install-log.txt</a> file and
|
146 |
));
|
147 |
}
|
148 |
|
149 |
+
if ($json_decode && $json_decode->step3->errsql_sum > 0) {
|
150 |
$longMsg = <<<LONGMSG
|
151 |
Update errors that show here are queries that could not be performed because the database server being used has issues running it. Please validate the query, if
|
152 |
it looks to be of concern please try to run the query manually. In many cases if your site performs well without any issues you can ignore the error.
|
162 |
));
|
163 |
}
|
164 |
|
165 |
+
if ($json_decode && $json_decode->step3->errkey_sum > 0) {
|
166 |
$longMsg = <<<LONGMSG
|
167 |
Notices should be ignored unless issues are found after you have tested an installed site. This notice indicates that a primary key is required to run the
|
168 |
update engine. Below is a list of tables and the rows that were not updated. On some databases you can remove these notices by checking the box 'Enable Full Search'
|
186 |
));
|
187 |
}
|
188 |
|
189 |
+
if ($json_decode && $json_decode->step3->errser_sum > 0) {
|
190 |
$longMsg = <<<LONGMSG
|
191 |
Notices should be ignored unless issues are found after you have tested an installed site. The SQL below will show data that may have not been
|
192 |
updated during the serialization process. Best practices for serialization notices is to just re-save the plugin/post/page in question.
|
326 |
</li>
|
327 |
<?php
|
328 |
$wpconfigNotice = $nManager->getFinalReporNoticeById('wp-config-changes');
|
329 |
+
$htaccessNotice = $nManager->getFinalReporNoticeById('htaccess-changes');
|
330 |
+
if ($wpconfigNotice) {
|
331 |
+
print("<li>Please validate ".$wpconfigNotice->longMsg."</li>");
|
332 |
+
}
|
333 |
+
if ($htaccessNotice) {
|
334 |
+
print("<li>Please validate ".$htaccessNotice->longMsg."</li>");
|
335 |
+
}
|
336 |
?>
|
|
|
337 |
<li>For additional help and questions visit the <a href='https://snapcreek.com/duplicator/docs/faqs-tech/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_campaign=problem_resolution&utm_content=inst4_step4_troubleshoot' target='_blank'>online FAQs</a></li>
|
338 |
</ul>
|
339 |
</div>
|
lib/snaplib/class.snaplib.u.util.php
CHANGED
@@ -175,7 +175,7 @@ if (!class_exists('DupLiteSnapLibUtil', false)) {
|
|
175 |
*/
|
176 |
public static function sanitize($input)
|
177 |
{
|
178 |
-
return filter_var($input,
|
179 |
}
|
180 |
|
181 |
/**
|
175 |
*/
|
176 |
public static function sanitize($input)
|
177 |
{
|
178 |
+
return filter_var($input, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
179 |
}
|
180 |
|
181 |
/**
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: migration, backup, duplicate, move, migrate, restore, transfer, clone, aut
|
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 5.9
|
6 |
Requires PHP: 5.3.8
|
7 |
-
Stable tag: 1.4.
|
8 |
License: GPLv2
|
9 |
|
10 |
WordPress migration and backups are much easier with Duplicator! Clone, backup, move and transfer an entire site from one location to another.
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 5.9
|
6 |
Requires PHP: 5.3.8
|
7 |
+
Stable tag: 1.4.5
|
8 |
License: GPLv2
|
9 |
|
10 |
WordPress migration and backups are much easier with Duplicator! Clone, backup, move and transfer an entire site from one location to another.
|
views/packages/details/detail.php
CHANGED
@@ -6,18 +6,13 @@ $ui_css_storage = (isset($view_state['dup-package-dtl-storage-panel']) && $view_
|
|
6 |
$ui_css_archive = (isset($view_state['dup-package-dtl-archive-panel']) && $view_state['dup-package-dtl-archive-panel']) ? 'display:block' : 'display:none';
|
7 |
$ui_css_install = (isset($view_state['dup-package-dtl-install-panel']) && $view_state['dup-package-dtl-install-panel']) ? 'display:block' : 'display:none';
|
8 |
|
9 |
-
$sqlDownloadInfo = $package->getPackageFileDownloadInfo(DUP_PackageFileType::SQL);
|
10 |
$archiveDownloadInfo = $package->getPackageFileDownloadInfo(DUP_PackageFileType::Archive);
|
11 |
$logDownloadInfo = $package->getPackageFileDownloadInfo(DUP_PackageFileType::Log);
|
12 |
-
$scanDownloadInfo = $package->getPackageFileDownloadInfo(DUP_PackageFileType::Scan);
|
13 |
$installerDownloadInfo = $package->getInstallerDownloadInfo();
|
14 |
-
$sqlDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($sqlDownloadInfo);
|
15 |
$archiveDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($archiveDownloadInfo);
|
16 |
$logDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($logDownloadInfo);
|
17 |
-
$scanDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($scanDownloadInfo);
|
18 |
$installerDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($installerDownloadInfo);
|
19 |
$showLinksDialogJson = DupLiteSnapJsonU::json_encode_esc_attr(array(
|
20 |
-
"sql" => $sqlDownloadInfo["url"],
|
21 |
"archive" => $archiveDownloadInfo["url"],
|
22 |
"log" => $logDownloadInfo["url"],
|
23 |
));
|
@@ -41,12 +36,10 @@ $dup_install_secure_pass = isset($package->Installer->OptsSecurePass) ? DUP_Util
|
|
41 |
table.dup-dtl-data-tbl tr:first-child td {margin:0; padding-top:0 !important;}
|
42 |
table.dup-dtl-data-tbl td {padding:0 5px 0 0; padding-top:10px !important;}
|
43 |
table.dup-dtl-data-tbl td:first-child {font-weight: bold; width:130px}
|
44 |
-
table.dup-sub-list td:first-child {white-space: nowrap; vertical-align: middle; width:
|
45 |
-
table.dup-sub-list td {white-space: nowrap; vertical-align:top; padding:
|
46 |
-
div.dup-box-panel-hdr {font-size:14px; display:block; border-bottom: 1px
|
47 |
-
|
48 |
-
tr.sub-item td {font-size: 12px}
|
49 |
-
tr.sub-item-disabled td {color:gray}
|
50 |
|
51 |
/*STORAGE*/
|
52 |
div.dup-store-pro {font-size:12px; font-style:italic;}
|
@@ -54,7 +47,10 @@ $dup_install_secure_pass = isset($package->Installer->OptsSecurePass) ? DUP_Util
|
|
54 |
div.dup-store-pro a {text-decoration: underline}
|
55 |
|
56 |
/*GENERAL*/
|
57 |
-
div#dup-name-info, div#dup-version-info {display: none;
|
|
|
|
|
|
|
58 |
div#dup-downloads-area {padding: 5px 0 5px 0; }
|
59 |
div#dup-downloads-msg {margin-bottom:-5px; font-style: italic}
|
60 |
div.sub-section {padding:7px 0 0 0}
|
@@ -90,9 +86,20 @@ GENERAL -->
|
|
90 |
<td>
|
91 |
<a href="javascript:void(0);" onclick="jQuery('#dup-name-info').toggle()"><?php echo esc_js($package->Name); ?></a>
|
92 |
<div id="dup-name-info">
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
</div>
|
97 |
</td>
|
98 |
</tr>
|
@@ -100,16 +107,32 @@ GENERAL -->
|
|
100 |
<td><?php esc_html_e('Notes', 'duplicator') ?>:</td>
|
101 |
<td><?php echo strlen($package->Notes) ? $package->Notes : esc_html__('- no notes -', 'duplicator') ?></td>
|
102 |
</tr>
|
|
|
|
|
|
|
|
|
103 |
<tr>
|
104 |
<td><?php esc_html_e('Versions', 'duplicator') ?>:</td>
|
105 |
<td>
|
106 |
<a href="javascript:void(0);" onclick="jQuery('#dup-version-info').toggle()"><?php echo esc_html($package->Version); ?></a>
|
107 |
<div id="dup-version-info">
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
</div>
|
114 |
</td>
|
115 |
</tr>
|
@@ -130,14 +153,12 @@ GENERAL -->
|
|
130 |
<td>
|
131 |
<div id="dup-downloads-area">
|
132 |
<?php if (!$err_found) :?>
|
133 |
-
|
134 |
-
<button class="button" onclick="Duplicator.Pack.
|
135 |
-
|
136 |
-
|
137 |
-
<button class="button" onclick="Duplicator.Pack.DownloadFile(<?php echo $logDownloadInfoJson; ?>);return false;"><i class="fa fa-table fa-sm"></i> <?php esc_html_e('Log', 'duplicator'); ?> </button>
|
138 |
-
<button class="button" onclick="Duplicator.Pack.ShowLinksDialog(<?php echo $showLinksDialogJson;?>);" class="thickbox"><i class="fa fa-lock fa-xs"></i> <?php esc_html_e("Share", 'duplicator')?></button>
|
139 |
<?php else: ?>
|
140 |
-
<button class="button" onclick="Duplicator.Pack.DownloadFile(<?php echo $logDownloadInfoJson; ?>);return false;"><i class="
|
141 |
<?php endif; ?>
|
142 |
</div>
|
143 |
<?php if (!$err_found) :?>
|
@@ -150,10 +171,15 @@ GENERAL -->
|
|
150 |
<td><?php esc_html_e('Installer', 'duplicator') ?>: </td>
|
151 |
<td><a href="#" onclick="Duplicator.Pack.DownloadInstaller(<?php echo $installerDownloadInfoJson; ?>);return false;" ><?php echo esc_html($package->Installer->File) ?></a></td>
|
152 |
</tr>
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
|
|
|
|
|
|
|
|
|
|
157 |
</table>
|
158 |
<?php endif; ?>
|
159 |
</td>
|
@@ -166,21 +192,21 @@ GENERAL -->
|
|
166 |
DIALOG: QUICK PATH -->
|
167 |
<?php add_thickbox(); ?>
|
168 |
<div id="dup-dlg-quick-path" title="<?php esc_attr_e('Download Links', 'duplicator'); ?>" style="display:none">
|
169 |
-
<p>
|
170 |
<i class="fa fa-lock fa-xs"></i>
|
171 |
-
<?php esc_html_e("The following links contain sensitive data.
|
172 |
</p>
|
173 |
|
174 |
-
<div style="padding: 0px
|
175 |
<a href="javascript:void(0)" style="display:inline-block; text-align:right" onclick="Duplicator.Pack.GetLinksText()">[Select All]</a> <br/>
|
176 |
-
<textarea id="dup-dlg-quick-path-data" style='border:1px solid silver; border-radius:
|
177 |
<i style='font-size:11px'>
|
178 |
<?php
|
179 |
printf("%s <a href='https://snapcreek.com/duplicator/docs/faqs-tech/#faq-trouble-052-q' target='_blank'>%s</a>",
|
180 |
-
esc_html__("
|
181 |
. "Download and extract the archive file to get a copy of the installer which will be named 'installer-backup.php'. "
|
182 |
. "For details on how to extract a archive.daf file please see: ", 'duplicator'),
|
183 |
-
esc_html__("How
|
184 |
?>
|
185 |
</i>
|
186 |
</div>
|
@@ -190,7 +216,8 @@ DIALOG: QUICK PATH -->
|
|
190 |
STORAGE -->
|
191 |
<div class="dup-box">
|
192 |
<div class="dup-box-title">
|
193 |
-
|
|
|
194 |
<div class="dup-box-arrow"></div>
|
195 |
</div>
|
196 |
<div class="dup-box-panel" id="dup-package-dtl-storage-panel" style="<?php echo esc_attr($ui_css_storage); ?>">
|
@@ -217,7 +244,10 @@ STORAGE -->
|
|
217 |
?>
|
218 |
</i>
|
219 |
</td>
|
220 |
-
<td
|
|
|
|
|
|
|
221 |
<td><?php echo DUP_Settings::getSsdirPath(); ?></td>
|
222 |
</tr>
|
223 |
<tr>
|
@@ -249,9 +279,6 @@ STORAGE -->
|
|
249 |
|
250 |
<!-- ===============================
|
251 |
ARCHIVE -->
|
252 |
-
<?php
|
253 |
-
$css_db_filter_on = $package->Database->FilterOn == 1 ? '' : 'sub-item-disabled';
|
254 |
-
?>
|
255 |
<div class="dup-box">
|
256 |
<div class="dup-box-title">
|
257 |
<i class="far fa-file-archive"></i> <?php esc_html_e('Archive', 'duplicator') ?>
|
@@ -260,6 +287,10 @@ ARCHIVE -->
|
|
260 |
<div class="dup-box-panel" id="dup-package-dtl-archive-panel" style="<?php echo esc_attr($ui_css_archive); ?>">
|
261 |
|
262 |
<!-- FILES -->
|
|
|
|
|
|
|
|
|
263 |
<table class='dup-dtl-data-tbl'>
|
264 |
<tr>
|
265 |
<td><?php esc_html_e('Build Mode', 'duplicator') ?>: </td>
|
@@ -311,14 +342,21 @@ ARCHIVE -->
|
|
311 |
</table><br/>
|
312 |
|
313 |
<!-- DATABASE -->
|
314 |
-
<div class="dup-box-panel-hdr"
|
|
|
|
|
|
|
315 |
<table class='dup-dtl-data-tbl'>
|
|
|
|
|
|
|
|
|
316 |
<tr>
|
317 |
<td><?php esc_html_e('Type', 'duplicator') ?>: </td>
|
318 |
<td><?php echo esc_html($package->Database->Type); ?></td>
|
319 |
</tr>
|
320 |
<tr>
|
321 |
-
<td><?php esc_html_e('
|
322 |
<td>
|
323 |
<a href="?page=duplicator-settings&tab=package" target="_blank"><?php echo esc_html($dbbuild_mode); ?></a>
|
324 |
<?php if ($mysqlcompat_on) : ?>
|
@@ -334,9 +372,10 @@ ARCHIVE -->
|
|
334 |
<td><?php esc_html_e('Filters', 'duplicator') ?>: </td>
|
335 |
<td><?php echo $package->Database->FilterOn == 1 ? 'On' : 'Off'; ?></td>
|
336 |
</tr>
|
337 |
-
<tr class="sub-
|
338 |
-
<td
|
339 |
<td>
|
|
|
340 |
<?php
|
341 |
echo isset($package->Database->FilterTables) && strlen($package->Database->FilterTables)
|
342 |
? str_replace(',', "<br>\n", $package->Database->FilterTables)
|
@@ -419,15 +458,17 @@ jQuery(document).ready(function($)
|
|
419 |
* @param pack The path to the package file */
|
420 |
Duplicator.Pack.ShowLinksDialog = function(json)
|
421 |
{
|
422 |
-
var url = '#TB_inline?width=650&height=
|
423 |
tb_show("<?php esc_html_e('Package File Links', 'duplicator') ?>", url);
|
424 |
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
|
|
|
|
431 |
$("#dup-dlg-quick-path-data").val(msg);
|
432 |
return false;
|
433 |
}
|
6 |
$ui_css_archive = (isset($view_state['dup-package-dtl-archive-panel']) && $view_state['dup-package-dtl-archive-panel']) ? 'display:block' : 'display:none';
|
7 |
$ui_css_install = (isset($view_state['dup-package-dtl-install-panel']) && $view_state['dup-package-dtl-install-panel']) ? 'display:block' : 'display:none';
|
8 |
|
|
|
9 |
$archiveDownloadInfo = $package->getPackageFileDownloadInfo(DUP_PackageFileType::Archive);
|
10 |
$logDownloadInfo = $package->getPackageFileDownloadInfo(DUP_PackageFileType::Log);
|
|
|
11 |
$installerDownloadInfo = $package->getInstallerDownloadInfo();
|
|
|
12 |
$archiveDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($archiveDownloadInfo);
|
13 |
$logDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($logDownloadInfo);
|
|
|
14 |
$installerDownloadInfoJson = DupLiteSnapJsonU::json_encode_esc_attr($installerDownloadInfo);
|
15 |
$showLinksDialogJson = DupLiteSnapJsonU::json_encode_esc_attr(array(
|
|
|
16 |
"archive" => $archiveDownloadInfo["url"],
|
17 |
"log" => $logDownloadInfo["url"],
|
18 |
));
|
36 |
table.dup-dtl-data-tbl tr:first-child td {margin:0; padding-top:0 !important;}
|
37 |
table.dup-dtl-data-tbl td {padding:0 5px 0 0; padding-top:10px !important;}
|
38 |
table.dup-dtl-data-tbl td:first-child {font-weight: bold; width:130px}
|
39 |
+
table.dup-sub-list td:first-child {white-space: nowrap; vertical-align: middle; width:100px !important;}
|
40 |
+
table.dup-sub-list td {white-space: nowrap; vertical-align:top; padding:2px !important;}
|
41 |
+
div.dup-box-panel-hdr {font-size:14px; display:block; border-bottom: 1px solid #efefef; margin:5px 0 5px 0; font-weight: bold; padding: 0 0 5px 0}
|
42 |
+
td.sub-notes {font-weight: normal !important; font-style: italic; color:#999; padding-top:10px;}
|
|
|
|
|
43 |
|
44 |
/*STORAGE*/
|
45 |
div.dup-store-pro {font-size:12px; font-style:italic;}
|
47 |
div.dup-store-pro a {text-decoration: underline}
|
48 |
|
49 |
/*GENERAL*/
|
50 |
+
div#dup-name-info, div#dup-version-info {display: none; line-height:20px; margin:4px 0 0 0}
|
51 |
+
table.dup-sub-info td {padding: 1px !important}
|
52 |
+
table.dup-sub-info td:first-child {font-weight: bold; width:100px; padding-left:10px}
|
53 |
+
|
54 |
div#dup-downloads-area {padding: 5px 0 5px 0; }
|
55 |
div#dup-downloads-msg {margin-bottom:-5px; font-style: italic}
|
56 |
div.sub-section {padding:7px 0 0 0}
|
86 |
<td>
|
87 |
<a href="javascript:void(0);" onclick="jQuery('#dup-name-info').toggle()"><?php echo esc_js($package->Name); ?></a>
|
88 |
<div id="dup-name-info">
|
89 |
+
<table class="dup-sub-info">
|
90 |
+
<tr>
|
91 |
+
<td><?php esc_html_e('ID', 'duplicator') ?>:</td>
|
92 |
+
<td><?php echo absint($package->ID); ?></td>
|
93 |
+
</tr>
|
94 |
+
<tr>
|
95 |
+
<td><?php esc_html_e('Hash', 'duplicator') ?>:</td>
|
96 |
+
<td><?php echo esc_html($package->Hash); ?></td>
|
97 |
+
</tr>
|
98 |
+
<tr>
|
99 |
+
<td><?php esc_html_e('Full Name', 'duplicator') ?>:</td>
|
100 |
+
<td><?php echo esc_html($package->NameHash); ?></td>
|
101 |
+
</tr>
|
102 |
+
</table>
|
103 |
</div>
|
104 |
</td>
|
105 |
</tr>
|
107 |
<td><?php esc_html_e('Notes', 'duplicator') ?>:</td>
|
108 |
<td><?php echo strlen($package->Notes) ? $package->Notes : esc_html__('- no notes -', 'duplicator') ?></td>
|
109 |
</tr>
|
110 |
+
<tr>
|
111 |
+
<td><?php esc_html_e('Created', 'duplicator') ?>:</td>
|
112 |
+
<td><?php echo $package->Created; ?></td>
|
113 |
+
</tr>
|
114 |
<tr>
|
115 |
<td><?php esc_html_e('Versions', 'duplicator') ?>:</td>
|
116 |
<td>
|
117 |
<a href="javascript:void(0);" onclick="jQuery('#dup-version-info').toggle()"><?php echo esc_html($package->Version); ?></a>
|
118 |
<div id="dup-version-info">
|
119 |
+
<table class="dup-sub-info">
|
120 |
+
<tr>
|
121 |
+
<td><?php esc_html_e('WordPress', 'duplicator') ?>:</td>
|
122 |
+
<td><?php echo strlen($package->VersionWP) ? esc_html($package->VersionWP) : esc_html__('- unknown -', 'duplicator') ?></td>
|
123 |
+
</tr>
|
124 |
+
<tr>
|
125 |
+
<td><?php esc_html_e('PHP', 'duplicator') ?>: </td>
|
126 |
+
<td><?php echo strlen($package->VersionPHP) ? esc_html($package->VersionPHP) : esc_html__('- unknown -', 'duplicator') ?></td>
|
127 |
+
</tr>
|
128 |
+
<tr>
|
129 |
+
<td><?php esc_html_e('Mysql', 'duplicator') ?>:</td>
|
130 |
+
<td>
|
131 |
+
<?php echo strlen($package->VersionDB) ? esc_html($package->VersionDB) : esc_html__('- unknown -', 'duplicator') ?> |
|
132 |
+
<?php echo strlen($package->Database->Comments) ? esc_html($package->Database->Comments) : esc_html__('- unknown -', 'duplicator') ?>
|
133 |
+
</td>
|
134 |
+
</tr>
|
135 |
+
</table>
|
136 |
</div>
|
137 |
</td>
|
138 |
</tr>
|
153 |
<td>
|
154 |
<div id="dup-downloads-area">
|
155 |
<?php if (!$err_found) :?>
|
156 |
+
<button class="button" onclick="Duplicator.Pack.DownloadInstaller(<?php echo $installerDownloadInfoJson; ?>);return false;"><i class="fa fa-bolt fa-sm"></i> Installer</button>
|
157 |
+
<button class="button" onclick="Duplicator.Pack.DownloadFile(<?php echo $archiveDownloadInfoJson; ?>);return false;"><i class="far fa-file-archive"></i> Archive - <?php echo esc_html($package->ZipSize); ?></button>
|
158 |
+
<!--button class="button" onclick="Duplicator.Pack.DownloadFile(<?php echo $logDownloadInfoJson; ?>);return false;"><i class="fas fa-file-contract fa-sm"></i> <?php esc_html_e('Log', 'duplicator'); ?> </button-->
|
159 |
+
<button class="button" onclick="Duplicator.Pack.ShowLinksDialog(<?php echo $showLinksDialogJson;?>);" class="thickbox"><i class="fas fa-share-alt"></i> <?php esc_html_e("Share File Links", 'duplicator')?></button>
|
|
|
|
|
160 |
<?php else: ?>
|
161 |
+
<button class="button" onclick="Duplicator.Pack.DownloadFile(<?php echo $logDownloadInfoJson; ?>);return false;"><i class="fas fa-file-contract fa-sm"></i> Log </button>
|
162 |
<?php endif; ?>
|
163 |
</div>
|
164 |
<?php if (!$err_found) :?>
|
171 |
<td><?php esc_html_e('Installer', 'duplicator') ?>: </td>
|
172 |
<td><a href="#" onclick="Duplicator.Pack.DownloadInstaller(<?php echo $installerDownloadInfoJson; ?>);return false;" ><?php echo esc_html($package->Installer->File) ?></a></td>
|
173 |
</tr>
|
174 |
+
<tr>
|
175 |
+
<td><?php esc_html_e("Build Log", 'duplicator') ?>: </td>
|
176 |
+
<td><a href="<?php echo $logDownloadInfo["url"] ?>" target="file_results"><?php echo $logDownloadInfo["filename"]; ?></a></td>
|
177 |
+
</tr>
|
178 |
+
<tr>
|
179 |
+
<td class="sub-notes">
|
180 |
+
<i class="fas fa-download"></i> <?php _e("Click links to download", 'duplicator-pro') ?>
|
181 |
+
</td>
|
182 |
+
</tr>
|
183 |
</table>
|
184 |
<?php endif; ?>
|
185 |
</td>
|
192 |
DIALOG: QUICK PATH -->
|
193 |
<?php add_thickbox(); ?>
|
194 |
<div id="dup-dlg-quick-path" title="<?php esc_attr_e('Download Links', 'duplicator'); ?>" style="display:none">
|
195 |
+
<p style="color:maroon">
|
196 |
<i class="fa fa-lock fa-xs"></i>
|
197 |
+
<?php esc_html_e("The following links contain sensitive data. Share with caution!", 'duplicator'); ?>
|
198 |
</p>
|
199 |
|
200 |
+
<div style="padding: 0px 5px 5px 5px;">
|
201 |
<a href="javascript:void(0)" style="display:inline-block; text-align:right" onclick="Duplicator.Pack.GetLinksText()">[Select All]</a> <br/>
|
202 |
+
<textarea id="dup-dlg-quick-path-data" style='border:1px solid silver; border-radius:2px; width:100%; height:175px; font-size:11px'></textarea><br/>
|
203 |
<i style='font-size:11px'>
|
204 |
<?php
|
205 |
printf("%s <a href='https://snapcreek.com/duplicator/docs/faqs-tech/#faq-trouble-052-q' target='_blank'>%s</a>",
|
206 |
+
esc_html__("A copy of the database.sql and installer.php files can both be found inside of the archive.zip/daf file. "
|
207 |
. "Download and extract the archive file to get a copy of the installer which will be named 'installer-backup.php'. "
|
208 |
. "For details on how to extract a archive.daf file please see: ", 'duplicator'),
|
209 |
+
esc_html__("How to work with DAF files and the DupArchive extraction tool?", 'duplicator'));
|
210 |
?>
|
211 |
</i>
|
212 |
</div>
|
216 |
STORAGE -->
|
217 |
<div class="dup-box">
|
218 |
<div class="dup-box-title">
|
219 |
+
<i class="fas fa-server fa-sm"></i>
|
220 |
+
<?php esc_html_e('Storage', 'duplicator') ?>
|
221 |
<div class="dup-box-arrow"></div>
|
222 |
</div>
|
223 |
<div class="dup-box-panel" id="dup-package-dtl-storage-panel" style="<?php echo esc_attr($ui_css_storage); ?>">
|
244 |
?>
|
245 |
</i>
|
246 |
</td>
|
247 |
+
<td>
|
248 |
+
<i class="far fa-hdd fa-fw"></i>
|
249 |
+
<?php esc_html_e("Local", 'duplicator'); ?>
|
250 |
+
</td>
|
251 |
<td><?php echo DUP_Settings::getSsdirPath(); ?></td>
|
252 |
</tr>
|
253 |
<tr>
|
279 |
|
280 |
<!-- ===============================
|
281 |
ARCHIVE -->
|
|
|
|
|
|
|
282 |
<div class="dup-box">
|
283 |
<div class="dup-box-title">
|
284 |
<i class="far fa-file-archive"></i> <?php esc_html_e('Archive', 'duplicator') ?>
|
287 |
<div class="dup-box-panel" id="dup-package-dtl-archive-panel" style="<?php echo esc_attr($ui_css_archive); ?>">
|
288 |
|
289 |
<!-- FILES -->
|
290 |
+
<div class="dup-box-panel-hdr">
|
291 |
+
<i class="fas fa-folder-open fa-sm"></i>
|
292 |
+
<?php esc_html_e('FILES', 'duplicator'); ?>
|
293 |
+
</div>
|
294 |
<table class='dup-dtl-data-tbl'>
|
295 |
<tr>
|
296 |
<td><?php esc_html_e('Build Mode', 'duplicator') ?>: </td>
|
342 |
</table><br/>
|
343 |
|
344 |
<!-- DATABASE -->
|
345 |
+
<div class="dup-box-panel-hdr">
|
346 |
+
<i class="fas fa-database fa-sm"></i>
|
347 |
+
<?php esc_html_e('DATABASE', 'duplicator'); ?>
|
348 |
+
</div>
|
349 |
<table class='dup-dtl-data-tbl'>
|
350 |
+
<tr>
|
351 |
+
<td><?php esc_html_e('Name', 'duplicator') ?>: </td>
|
352 |
+
<td><?php echo esc_html($package->Database->info->name); ?></td>
|
353 |
+
</tr>
|
354 |
<tr>
|
355 |
<td><?php esc_html_e('Type', 'duplicator') ?>: </td>
|
356 |
<td><?php echo esc_html($package->Database->Type); ?></td>
|
357 |
</tr>
|
358 |
<tr>
|
359 |
+
<td><?php esc_html_e('SQL Mode', 'duplicator') ?>: </td>
|
360 |
<td>
|
361 |
<a href="?page=duplicator-settings&tab=package" target="_blank"><?php echo esc_html($dbbuild_mode); ?></a>
|
362 |
<?php if ($mysqlcompat_on) : ?>
|
372 |
<td><?php esc_html_e('Filters', 'duplicator') ?>: </td>
|
373 |
<td><?php echo $package->Database->FilterOn == 1 ? 'On' : 'Off'; ?></td>
|
374 |
</tr>
|
375 |
+
<tr class="sub-section">
|
376 |
+
<td> </td>
|
377 |
<td>
|
378 |
+
<b><?php esc_html_e('Tables', 'duplicator') ?>:</b><br/>
|
379 |
<?php
|
380 |
echo isset($package->Database->FilterTables) && strlen($package->Database->FilterTables)
|
381 |
? str_replace(',', "<br>\n", $package->Database->FilterTables)
|
458 |
* @param pack The path to the package file */
|
459 |
Duplicator.Pack.ShowLinksDialog = function(json)
|
460 |
{
|
461 |
+
var url = '#TB_inline?width=650&height=325&inlineId=dup-dlg-quick-path';
|
462 |
tb_show("<?php esc_html_e('Package File Links', 'duplicator') ?>", url);
|
463 |
|
464 |
+
var msg = <?php printf(
|
465 |
+
'"%s" + "\n\n%s:\n" + json.archive + "\n\n%s:\n" + json.log + "\n\n%s";',
|
466 |
+
'=========== SENSITIVE INFORMATION START ===========',
|
467 |
+
esc_html__("ARCHIVE", 'duplicator'),
|
468 |
+
esc_html__("LOG", 'duplicator'),
|
469 |
+
'=========== SENSITIVE INFORMATION END ==========='
|
470 |
+
);
|
471 |
+
?>
|
472 |
$("#dup-dlg-quick-path-data").val(msg);
|
473 |
return false;
|
474 |
}
|
views/packages/details/transfer.php
CHANGED
@@ -21,8 +21,8 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
21 |
<li><i class="fab fa-dropbox"></i> <?php esc_html_e('Dropbox', 'duplicator'); ?></li>
|
22 |
<li><i class="fab fa-google-drive"></i> <?php esc_html_e('Google Drive', 'duplicator'); ?></li>
|
23 |
<li><i class="fa fa-cloud fa-sm"></i> <?php esc_html_e('One Drive', 'duplicator'); ?></li>
|
24 |
-
<li><i class="
|
25 |
-
<li><i class="
|
26 |
</ul>
|
27 |
</div>
|
28 |
<?php
|
21 |
<li><i class="fab fa-dropbox"></i> <?php esc_html_e('Dropbox', 'duplicator'); ?></li>
|
22 |
<li><i class="fab fa-google-drive"></i> <?php esc_html_e('Google Drive', 'duplicator'); ?></li>
|
23 |
<li><i class="fa fa-cloud fa-sm"></i> <?php esc_html_e('One Drive', 'duplicator'); ?></li>
|
24 |
+
<li><i class="fas fa-network-wired"></i> <?php esc_html_e('FTP & SFTP', 'duplicator'); ?></li>
|
25 |
+
<li><i class="fas fa-hdd"></i> <?php esc_html_e('Custom Directory', 'duplicator'); ?></li>
|
26 |
</ul>
|
27 |
</div>
|
28 |
<?php
|
views/packages/main/packages.php
CHANGED
@@ -120,10 +120,10 @@ if (DUP_Settings::Get('installer_name_mode') == DUP_Settings::INSTALLER_NAME_MOD
|
|
120 |
<td>
|
121 |
<div id='dup-list-alert-nodata'>
|
122 |
<i class="fa fa-archive fa-sm"></i>
|
123 |
-
<?php esc_html_e("No Packages Found
|
124 |
-
|
125 |
<div class="dup-quick-start" <?php echo ($is_mu) ? 'style="display:none"' : ''; ?>>
|
126 |
-
|
127 |
<a href="https://snapcreek.com/duplicator/docs/quick-start/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=packages_empty1&utm_campaign=quick_start" target="_blank">
|
128 |
<?php esc_html_e("Check out the 'Quick Start' guide!", 'duplicator'); ?>
|
129 |
</a>
|
@@ -173,8 +173,8 @@ if (DUP_Settings::Get('installer_name_mode') == DUP_Settings::INSTALLER_NAME_MOD
|
|
173 |
<td colspan="6">
|
174 |
<div id='dup-list-alert-nodata'>
|
175 |
<i class="fa fa-archive fa-sm"></i>
|
176 |
-
<?php esc_html_e("No Packages Found
|
177 |
-
|
178 |
<div class="dup-quick-start">
|
179 |
<?php esc_html_e("New to Duplicator?", 'duplicator'); ?><br/>
|
180 |
<a href="https://snapcreek.com/duplicator/docs/quick-start/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=packages_empty2&utm_campaign=quick_start" target="_blank">
|
@@ -367,10 +367,14 @@ DIALOG: HELP DIALOG -->
|
|
367 |
<br/><br/>
|
368 |
|
369 |
<b><?php esc_html_e("Other Resources:", 'duplicator') ?></b><hr size='1'/>
|
370 |
-
<i class="fas fa-question-circle fa-sm"></i>
|
371 |
-
<
|
|
|
|
|
|
|
372 |
<?php if ($completeCount >= 3) : ?>
|
373 |
-
<i class="fa fa-star"></i>
|
|
|
374 |
<?php endif; ?>
|
375 |
</div>
|
376 |
|
120 |
<td>
|
121 |
<div id='dup-list-alert-nodata'>
|
122 |
<i class="fa fa-archive fa-sm"></i>
|
123 |
+
<?php esc_html_e("No Packages Found", 'duplicator'); ?><br/>
|
124 |
+
<i><?php esc_html_e("Click 'Create New' To Build Package", 'duplicator'); ?></i><br/>
|
125 |
<div class="dup-quick-start" <?php echo ($is_mu) ? 'style="display:none"' : ''; ?>>
|
126 |
+
<b><?php esc_html_e("New to Duplicator?", 'duplicator'); ?></b><br/>
|
127 |
<a href="https://snapcreek.com/duplicator/docs/quick-start/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=packages_empty1&utm_campaign=quick_start" target="_blank">
|
128 |
<?php esc_html_e("Check out the 'Quick Start' guide!", 'duplicator'); ?>
|
129 |
</a>
|
173 |
<td colspan="6">
|
174 |
<div id='dup-list-alert-nodata'>
|
175 |
<i class="fa fa-archive fa-sm"></i>
|
176 |
+
<?php esc_html_e("No Packages Found", 'duplicator'); ?><br/>
|
177 |
+
<i><?php esc_html_e("Click 'Create New' To Build Package", 'duplicator'); ?></i><br/>
|
178 |
<div class="dup-quick-start">
|
179 |
<?php esc_html_e("New to Duplicator?", 'duplicator'); ?><br/>
|
180 |
<a href="https://snapcreek.com/duplicator/docs/quick-start/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=packages_empty2&utm_campaign=quick_start" target="_blank">
|
367 |
<br/><br/>
|
368 |
|
369 |
<b><?php esc_html_e("Other Resources:", 'duplicator') ?></b><hr size='1'/>
|
370 |
+
<i class="fas fa-question-circle fa-sm fa-fw"></i>
|
371 |
+
<a href="https://snapcreek.com/ticket?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=help_btn_ticket&utm_campaign=duplicator_free" target="_blank"><?php esc_html_e("Need help with the plugin?", 'duplicator') ?></a> <br/>
|
372 |
+
|
373 |
+
<i class="fa fa-lightbulb fa-fw"></i>
|
374 |
+
<a href="https://snapcreek.com/ticket/index.php?a=add&category=69" target="_blank"><?php esc_html_e("Have an idea for the plugin?", 'duplicator') ?></a> <br/>
|
375 |
<?php if ($completeCount >= 3) : ?>
|
376 |
+
<i class="fa fa-star fa-fw"></i>
|
377 |
+
<a href="https://wordpress.org/support/plugin/duplicator/reviews/?filter=5" target="vote-wp"><?php esc_html_e("Help review the plugin!", 'duplicator') ?></a>
|
378 |
<?php endif; ?>
|
379 |
</div>
|
380 |
|
views/packages/main/s1.setup2.php
CHANGED
@@ -7,17 +7,18 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
7 |
form#dup-form-opts label {line-height:22px}
|
8 |
form#dup-form-opts input[type=checkbox] {margin-top:3px}
|
9 |
form#dup-form-opts textarea, input[type="text"] {width:100%}
|
10 |
-
|
11 |
-
form#dup-form-opts textarea#filter-exts {height:27px}
|
12 |
textarea#package-notes {height:75px;}
|
13 |
div.dup-notes-add {float:right; margin:-4px 2px 4px 0;}
|
14 |
div#dup-notes-area {display:none}
|
15 |
input#package-name {padding:4px; height: 2em; font-size: 1.2em; line-height: 100%; width: 100%; margin: 0 0 3px;}
|
16 |
tr.dup-store-path td {padding:14px}
|
17 |
label.lbl-larger {font-size:1.2em}
|
|
|
|
|
18 |
|
19 |
-
/*ARCHIVE SECTION*/
|
20 |
-
form#dup-form-opts div.tabs-panel{max-height:800px; padding:
|
21 |
form#dup-form-opts ul li.tabs{font-weight:bold}
|
22 |
sup.archive-ext {font-style:italic;font-size:10px; cursor: pointer; vertical-align: baseline; position: relative; top: -0.8em; font-weight: normal}
|
23 |
ul.category-tabs li {padding:4px 15px 4px 15px}
|
@@ -25,25 +26,33 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
25 |
span#dup-archive-filter-file {color:#A62426; display:none}
|
26 |
span#dup-archive-filter-db {color:#A62426; display:none}
|
27 |
span#dup-archive-db-only {color:#A62426; display:none}
|
28 |
-
div#dup-file-filter-items
|
|
|
29 |
div#dup-db-filter-items {font-stretch:ultra-condensed; font-family:Calibri; }
|
30 |
-
|
|
|
|
|
31 |
div.dup-quick-links {font-size:11px; float:right; display:inline-block; margin-top:2px; font-style:italic}
|
32 |
-
div.dup-tabs-opts-help {font-style:italic; font-size:11px; margin:10px 0 0
|
33 |
|
34 |
-
/*
|
35 |
-
table#dup-dbtables td {padding:
|
|
|
|
|
36 |
label.core-table {color:#9A1E26;font-style:italic;font-weight:bold}
|
37 |
i.core-table-info {color:#9A1E26;font-style:italic;}
|
38 |
label.non-core-table {color:#000}
|
39 |
label.non-core-table:hover, label.core-table:hover {text-decoration:line-through}
|
40 |
-
table.dbmysql-compatibility
|
|
|
41 |
div.dup-store-pro {font-size:12px; font-style:italic;}
|
42 |
div.dup-store-pro img {height:14px; width:14px; vertical-align:text-top}
|
43 |
div.dup-store-pro a {text-decoration:underline}
|
44 |
span.dup-pro-text {font-style:italic; font-size:12px; color:#555; font-style:italic }
|
45 |
div#dup-exportdb-items-checked, div#dup-exportdb-items-off {min-height:275px; display:none}
|
46 |
div#dup-exportdb-items-checked {padding: 5px; max-width:700px}
|
|
|
|
|
47 |
|
48 |
/*INSTALLER SECTION*/
|
49 |
div.dup-installer-header-1 {font-weight:bold; padding-bottom:2px; width:100%}
|
@@ -59,6 +68,7 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
59 |
div#dup-pass-toggle {position: relative; margin:8px 0 0 0; width:243px}
|
60 |
input#secure-pass {border-radius:4px 0 0 4px; width:217px; height: 23px; min-height: auto; margin:0; padding: 0 4px;}
|
61 |
button.pass-toggle {height: 23px; width: 27px; position:absolute; top:0px; right:0px; border:1px solid silver; border-radius:0 4px 4px 0; cursor:pointer}
|
|
|
62 |
|
63 |
/*TABS*/
|
64 |
ul.add-menu-item-tabs li, ul.category-tabs li {padding:3px 30px 5px}
|
@@ -93,7 +103,8 @@ $storage_position = DUP_Settings::Get('storage_position');
|
|
93 |
STORAGE -->
|
94 |
<div class="dup-box">
|
95 |
<div class="dup-box-title">
|
96 |
-
<i class="fas fa-
|
|
|
97 |
<div class="dup-box-arrow"></div>
|
98 |
</div>
|
99 |
<div class="dup-box-panel" id="dup-pack-storage-panel" style="<?php echo esc_html($ui_css_storage); ?>">
|
@@ -132,7 +143,10 @@ STORAGE -->
|
|
132 |
?>
|
133 |
</i>
|
134 |
</td>
|
135 |
-
<td
|
|
|
|
|
|
|
136 |
<td><?php echo DUP_Settings::getSsdirPath(); ?></td>
|
137 |
</tr>
|
138 |
<tr>
|
@@ -172,9 +186,15 @@ ARCHIVE -->
|
|
172 |
echo " <sup class='archive-ext'>{$archive_build_mode}</sup>";
|
173 |
?>
|
174 |
<span style="font-size:13px">
|
175 |
-
<span id="dup-archive-filter-file" title="<?php esc_attr_e('File filter enabled', 'duplicator') ?>"
|
176 |
-
|
177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
</span>
|
179 |
<div class="dup-box-arrow"></div>
|
180 |
</div>
|
@@ -190,6 +210,10 @@ ARCHIVE -->
|
|
190 |
|
191 |
<!-- TAB1:PACKAGE -->
|
192 |
<div>
|
|
|
|
|
|
|
|
|
193 |
<!-- FILTERS -->
|
194 |
<?php
|
195 |
$uploads = wp_upload_dir();
|
@@ -213,7 +237,7 @@ ARCHIVE -->
|
|
213 |
<div id="dup-file-filter-items">
|
214 |
<label for="filter-dirs" title="<?php esc_attr_e("Separate all filters by semicolon", 'duplicator'); ?>">
|
215 |
<?php
|
216 |
-
_e("
|
217 |
echo sprintf("<sup title='%s'>({$filter_dir_count})</sup>", esc_html__("Number of directories filtered", 'duplicator'));
|
218 |
?>
|
219 |
</label>
|
@@ -223,15 +247,19 @@ ARCHIVE -->
|
|
223 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo esc_js(DUP_Util::safePath(WP_CONTENT_DIR)); ?>/cache')">[<?php esc_html_e("cache", 'duplicator') ?>]</a>
|
224 |
<a href="javascript:void(0)" onclick="jQuery('#filter-dirs').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
|
225 |
</div>
|
226 |
-
<textarea name="filter-dirs" id="filter-dirs" placeholder="/full_path/exclude_path1;/full_path/exclude_path2;"><?php echo str_replace(";", ";\n", esc_textarea($Package->Archive->FilterDirs)) ?></textarea
|
|
|
227 |
|
228 |
-
<label class="no-select" title="<?php esc_attr_e("Separate all filters by semicolon", 'duplicator'); ?>"
|
|
|
|
|
229 |
<div class='dup-quick-links'>
|
230 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludeExts('avi;mov;mp4;mpeg;mpg;swf;wmv;aac;m3u;mp3;mpa;wav;wma')">[<?php esc_html_e("media", 'duplicator') ?>]</a>
|
231 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludeExts('zip;rar;tar;gz;bz2;7z')">[<?php esc_html_e("archive", 'duplicator') ?>]</a>
|
232 |
<a href="javascript:void(0)" onclick="jQuery('#filter-exts').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
|
233 |
</div>
|
234 |
-
<textarea name="filter-exts" id="filter-exts" placeholder="
|
|
|
235 |
|
236 |
<label class="no-select" title="<?php esc_attr_e("Separate all filters by semicolon", 'duplicator'); ?>">
|
237 |
<?php
|
@@ -282,18 +310,16 @@ ARCHIVE -->
|
|
282 |
</div>
|
283 |
|
284 |
<!-- TAB2: DATABASE -->
|
285 |
-
<div>
|
|
|
|
|
|
|
|
|
286 |
<table>
|
287 |
-
<tr>
|
288 |
-
<td colspan="2" style="padding:0 0 10px 0">
|
289 |
-
<?php esc_html_e("Build Mode", 'duplicator') ?>:
|
290 |
-
<a href="?page=duplicator-settings&tab=package" target="settings"><?php echo esc_html($dbbuild_mode); ?></a>
|
291 |
-
</td>
|
292 |
-
</tr>
|
293 |
<tr>
|
294 |
<td><input type="checkbox" id="dbfilter-on" name="dbfilter-on" onclick="Duplicator.Pack.ToggleDBFilters()" <?php echo ($Package->Database->FilterOn) ? "checked='checked'" :""; ?> /></td>
|
295 |
<td>
|
296 |
-
<label for="dbfilter-on"><?php esc_html_e("Enable Table Filters", 'duplicator')
|
297 |
<i class="fas fa-question-circle fa-sm"
|
298 |
data-tooltip-title="<?php esc_attr_e("Enable Table Filters:", 'duplicator'); ?>"
|
299 |
data-tooltip="<?php esc_attr_e('Checked tables will not be added to the database script. Excluding certain tables can possibly cause your site or plugins to not work correctly after install!', 'duplicator'); ?>">
|
@@ -302,9 +328,11 @@ ARCHIVE -->
|
|
302 |
</tr>
|
303 |
</table>
|
304 |
<div id="dup-db-filter-items">
|
305 |
-
<
|
306 |
-
|
307 |
-
|
|
|
|
|
308 |
<?php
|
309 |
$tables = $wpdb->get_results("SHOW FULL TABLES FROM `" . DB_NAME . "` WHERE Table_Type = 'BASE TABLE' ", ARRAY_N);
|
310 |
$num_rows = count($tables);
|
@@ -352,51 +380,64 @@ ARCHIVE -->
|
|
352 |
_e("<i class='core-table-info'> Use caution when excluding tables! It is highly recommended to not exclude WordPress core tables*, unless you know the impact.</i>", 'duplicator');
|
353 |
?>
|
354 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
|
356 |
-
<br/>
|
357 |
-
<?php esc_html_e("Compatibility Mode", 'duplicator') ?>
|
358 |
-
<i class="fas fa-question-circle fa-sm"
|
359 |
-
data-tooltip-title="<?php esc_attr_e("Compatibility Mode:", 'duplicator'); ?>"
|
360 |
-
data-tooltip="<?php esc_attr_e('This is an advanced database backwards compatibility feature that should ONLY be used if having problems installing packages.'
|
361 |
-
. ' If the database server version is lower than the version where the package was built then these options may help generate a script that is more compliant'
|
362 |
-
. ' with the older database server. It is recommended to try each option separately starting with mysql40.', 'duplicator'); ?>">
|
363 |
-
</i>
|
364 |
-
<small style="font-style:italic">
|
365 |
-
<a href="https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_compatible" target="_blank">[<?php esc_html_e('details', 'duplicator'); ?>]</a>
|
366 |
-
</small>
|
367 |
-
<br/>
|
368 |
-
|
369 |
-
<?php if ($dbbuild_mode == 'mysqldump') :?>
|
370 |
-
<?php
|
371 |
-
$modes = explode(',', $Package->Database->Compatible);
|
372 |
-
$is_mysql40 = in_array('mysql40', $modes);
|
373 |
-
$is_no_table = in_array('no_table_options', $modes);
|
374 |
-
$is_no_key = in_array('no_key_options', $modes);
|
375 |
-
$is_no_field = in_array('no_field_options', $modes);
|
376 |
-
?>
|
377 |
-
<table class="dbmysql-compatibility">
|
378 |
-
<tr>
|
379 |
-
<td>
|
380 |
-
<input type="checkbox" name="dbcompat[]" id="dbcompat-mysql40" value="mysql40" <?php echo $is_mysql40 ? 'checked="true"' :''; ?> >
|
381 |
-
<label for="dbcompat-mysql40"><?php esc_html_e("mysql40", 'duplicator') ?></label>
|
382 |
-
</td>
|
383 |
-
<td>
|
384 |
-
<input type="checkbox" name="dbcompat[]" id="dbcompat-no_table_options" value="no_table_options" <?php echo $is_no_table ? 'checked="true"' :''; ?>>
|
385 |
-
<label for="dbcompat-no_table_options"><?php esc_html_e("no_table_options", 'duplicator') ?></label>
|
386 |
-
</td>
|
387 |
-
<td>
|
388 |
-
<input type="checkbox" name="dbcompat[]" id="dbcompat-no_key_options" value="no_key_options" <?php echo $is_no_key ? 'checked="true"' :''; ?>>
|
389 |
-
<label for="dbcompat-no_key_options"><?php esc_html_e("no_key_options", 'duplicator') ?></label>
|
390 |
-
</td>
|
391 |
-
<td>
|
392 |
-
<input type="checkbox" name="dbcompat[]" id="dbcompat-no_field_options" value="no_field_options" <?php echo $is_no_field ? 'checked="true"' :''; ?>>
|
393 |
-
<label for="dbcompat-no_field_options"><?php esc_html_e("no_field_options", 'duplicator') ?></label>
|
394 |
-
</td>
|
395 |
-
</tr>
|
396 |
-
</table>
|
397 |
-
<?php else :?>
|
398 |
-
<i><?php esc_html_e("This option is only available with mysqldump mode.", 'duplicator'); ?></i>
|
399 |
-
<?php endif; ?>
|
400 |
|
401 |
</div>
|
402 |
</div>
|
@@ -601,9 +642,11 @@ jQuery(document).ready(function ($)
|
|
601 |
$filterItems.removeAttr('disabled').css({color:'#000'});
|
602 |
$('#dup-dbtables input').removeAttr('readonly').css({color:'#000'});
|
603 |
$('#dup-archive-filter-db').show();
|
|
|
604 |
} else {
|
605 |
$filterItems.attr('disabled', 'disabled').css({color:'#999'});
|
606 |
$('#dup-dbtables input').attr('readonly', 'readonly').css({color:'#999'});
|
|
|
607 |
$('#dup-archive-filter-db').hide();
|
608 |
}
|
609 |
};
|
7 |
form#dup-form-opts label {line-height:22px}
|
8 |
form#dup-form-opts input[type=checkbox] {margin-top:3px}
|
9 |
form#dup-form-opts textarea, input[type="text"] {width:100%}
|
10 |
+
|
|
|
11 |
textarea#package-notes {height:75px;}
|
12 |
div.dup-notes-add {float:right; margin:-4px 2px 4px 0;}
|
13 |
div#dup-notes-area {display:none}
|
14 |
input#package-name {padding:4px; height: 2em; font-size: 1.2em; line-height: 100%; width: 100%; margin: 0 0 3px;}
|
15 |
tr.dup-store-path td {padding:14px}
|
16 |
label.lbl-larger {font-size:1.2em}
|
17 |
+
form#dup-form-opts ul li.tabs {font-size:16px}
|
18 |
+
div.tab-hdr-title {font-size: 16px; font-weight: bold; padding: 1px; margin:2px 0 5px 0; border-bottom:1px solid #dcdcde }
|
19 |
|
20 |
+
/*TAB-1: ARCHIVE SECTION*/
|
21 |
+
form#dup-form-opts div.tabs-panel{max-height:800px; padding:15px 20px 20px 20px; min-height:280px}
|
22 |
form#dup-form-opts ul li.tabs{font-weight:bold}
|
23 |
sup.archive-ext {font-style:italic;font-size:10px; cursor: pointer; vertical-align: baseline; position: relative; top: -0.8em; font-weight: normal}
|
24 |
ul.category-tabs li {padding:4px 15px 4px 15px}
|
26 |
span#dup-archive-filter-file {color:#A62426; display:none}
|
27 |
span#dup-archive-filter-db {color:#A62426; display:none}
|
28 |
span#dup-archive-db-only {color:#A62426; display:none}
|
29 |
+
div#dup-file-filter-items {padding:5px 0 0;}
|
30 |
+
div#dup-db-filter-items {padding:0; margin-top:-15px}
|
31 |
div#dup-db-filter-items {font-stretch:ultra-condensed; font-family:Calibri; }
|
32 |
+
form#dup-form-opts textarea#filter-dirs {height:125px; background:#fafafa; padding:5px 10px 5px 10px;}
|
33 |
+
form#dup-form-opts textarea#filter-exts {height:30px; background:#fafafa; padding:3px 10px 1px 10px;}
|
34 |
+
form#dup-form-opts textarea#filter-files {height:125px; background:#fafafa; padding:5px 10px 5px 10px;}
|
35 |
div.dup-quick-links {font-size:11px; float:right; display:inline-block; margin-top:2px; font-style:italic}
|
36 |
+
div.dup-tabs-opts-help {font-style:italic; font-size:11px; margin:10px 0 0 2px; color:#777;}
|
37 |
|
38 |
+
/* TAB-2: DATABASE */
|
39 |
+
table#dup-dbtables td {padding:0 20px 5px 10px;}
|
40 |
+
label.core-table,
|
41 |
+
label.non-core-table {padding:2px 0 2px 0; font-size:14px; display: inline-block}
|
42 |
label.core-table {color:#9A1E26;font-style:italic;font-weight:bold}
|
43 |
i.core-table-info {color:#9A1E26;font-style:italic;}
|
44 |
label.non-core-table {color:#000}
|
45 |
label.non-core-table:hover, label.core-table:hover {text-decoration:line-through}
|
46 |
+
table.dbmysql-compatibility {margin-top:-10px}
|
47 |
+
table.dbmysql-compatibility td{padding:0 20px 0 2px}
|
48 |
div.dup-store-pro {font-size:12px; font-style:italic;}
|
49 |
div.dup-store-pro img {height:14px; width:14px; vertical-align:text-top}
|
50 |
div.dup-store-pro a {text-decoration:underline}
|
51 |
span.dup-pro-text {font-style:italic; font-size:12px; color:#555; font-style:italic }
|
52 |
div#dup-exportdb-items-checked, div#dup-exportdb-items-off {min-height:275px; display:none}
|
53 |
div#dup-exportdb-items-checked {padding: 5px; max-width:700px}
|
54 |
+
div.dup-tbl-scroll {white-space:nowrap; height:350px; overflow-y: scroll; border:1px solid silver; padding:5px 10px; border-radius: 2px;
|
55 |
+
background:#fafafa; margin:3px 0 0 0; width:98%}
|
56 |
|
57 |
/*INSTALLER SECTION*/
|
58 |
div.dup-installer-header-1 {font-weight:bold; padding-bottom:2px; width:100%}
|
68 |
div#dup-pass-toggle {position: relative; margin:8px 0 0 0; width:243px}
|
69 |
input#secure-pass {border-radius:4px 0 0 4px; width:217px; height: 23px; min-height: auto; margin:0; padding: 0 4px;}
|
70 |
button.pass-toggle {height: 23px; width: 27px; position:absolute; top:0px; right:0px; border:1px solid silver; border-radius:0 4px 4px 0; cursor:pointer}
|
71 |
+
div.dup-install-prefill-tab-pnl.tabs-panel {overflow:visible;}
|
72 |
|
73 |
/*TABS*/
|
74 |
ul.add-menu-item-tabs li, ul.category-tabs li {padding:3px 30px 5px}
|
103 |
STORAGE -->
|
104 |
<div class="dup-box">
|
105 |
<div class="dup-box-title">
|
106 |
+
<i class="fas fa-server fa-fw fa-sm"></i>
|
107 |
+
<?php esc_html_e("Storage", 'duplicator'); ?>
|
108 |
<div class="dup-box-arrow"></div>
|
109 |
</div>
|
110 |
<div class="dup-box-panel" id="dup-pack-storage-panel" style="<?php echo esc_html($ui_css_storage); ?>">
|
143 |
?>
|
144 |
</i>
|
145 |
</td>
|
146 |
+
<td>
|
147 |
+
<i class="far fa-hdd fa-fw"></i>
|
148 |
+
<?php esc_html_e("Local", 'duplicator'); ?>
|
149 |
+
</td>
|
150 |
<td><?php echo DUP_Settings::getSsdirPath(); ?></td>
|
151 |
</tr>
|
152 |
<tr>
|
186 |
echo " <sup class='archive-ext'>{$archive_build_mode}</sup>";
|
187 |
?>
|
188 |
<span style="font-size:13px">
|
189 |
+
<span id="dup-archive-filter-file" title="<?php esc_attr_e('File filter enabled', 'duplicator') ?>">
|
190 |
+
<i class="far fa-copy fa-sm"></i> <i class="fa fa-filter fa-sm"></i>
|
191 |
+
</span>
|
192 |
+
<span id="dup-archive-filter-db" title="<?php esc_attr_e('Database filter enabled', 'duplicator') ?>">
|
193 |
+
<i class="fa fa-table fa-sm"></i> <i class="fa fa-filter fa-sm"></i>
|
194 |
+
</span>
|
195 |
+
<span id="dup-archive-db-only" title="<?php esc_attr_e('Archive Only the Database', 'duplicator') ?>">
|
196 |
+
<i class="fas fa-database fa-sm"></i> <?php esc_html_e('Database Only', 'duplicator') ?>
|
197 |
+
</span>
|
198 |
</span>
|
199 |
<div class="dup-box-arrow"></div>
|
200 |
</div>
|
210 |
|
211 |
<!-- TAB1:PACKAGE -->
|
212 |
<div>
|
213 |
+
<div class="tab-hdr-title">
|
214 |
+
<?php esc_html_e('Filters', 'duplicator') ?>
|
215 |
+
</div>
|
216 |
+
|
217 |
<!-- FILTERS -->
|
218 |
<?php
|
219 |
$uploads = wp_upload_dir();
|
237 |
<div id="dup-file-filter-items">
|
238 |
<label for="filter-dirs" title="<?php esc_attr_e("Separate all filters by semicolon", 'duplicator'); ?>">
|
239 |
<?php
|
240 |
+
_e("Folders:", 'duplicator');
|
241 |
echo sprintf("<sup title='%s'>({$filter_dir_count})</sup>", esc_html__("Number of directories filtered", 'duplicator'));
|
242 |
?>
|
243 |
</label>
|
247 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo esc_js(DUP_Util::safePath(WP_CONTENT_DIR)); ?>/cache')">[<?php esc_html_e("cache", 'duplicator') ?>]</a>
|
248 |
<a href="javascript:void(0)" onclick="jQuery('#filter-dirs').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
|
249 |
</div>
|
250 |
+
<textarea name="filter-dirs" id="filter-dirs" placeholder="/full_path/exclude_path1;/full_path/exclude_path2;"><?php echo str_replace(";", ";\n", esc_textarea($Package->Archive->FilterDirs)) ?></textarea>
|
251 |
+
<br/><br/>
|
252 |
|
253 |
+
<label class="no-select" title="<?php esc_attr_e("Separate all filters by semicolon", 'duplicator'); ?>">
|
254 |
+
<?php esc_html_e("File extensions", 'duplicator') ?>:
|
255 |
+
</label>
|
256 |
<div class='dup-quick-links'>
|
257 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludeExts('avi;mov;mp4;mpeg;mpg;swf;wmv;aac;m3u;mp3;mpa;wav;wma')">[<?php esc_html_e("media", 'duplicator') ?>]</a>
|
258 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludeExts('zip;rar;tar;gz;bz2;7z')">[<?php esc_html_e("archive", 'duplicator') ?>]</a>
|
259 |
<a href="javascript:void(0)" onclick="jQuery('#filter-exts').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
|
260 |
</div>
|
261 |
+
<textarea name="filter-exts" id="filter-exts" placeholder="<?php esc_attr_e("example:", 'duplicator'); ?> mov;zip;mp4"><?php echo esc_textarea($Package->Archive->FilterExts); ?></textarea>
|
262 |
+
<br/><br/>
|
263 |
|
264 |
<label class="no-select" title="<?php esc_attr_e("Separate all filters by semicolon", 'duplicator'); ?>">
|
265 |
<?php
|
310 |
</div>
|
311 |
|
312 |
<!-- TAB2: DATABASE -->
|
313 |
+
<div>
|
314 |
+
<div class="tab-hdr-title">
|
315 |
+
<?php esc_html_e('Filters', 'duplicator') ?>
|
316 |
+
</div>
|
317 |
+
|
318 |
<table>
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
<tr>
|
320 |
<td><input type="checkbox" id="dbfilter-on" name="dbfilter-on" onclick="Duplicator.Pack.ToggleDBFilters()" <?php echo ($Package->Database->FilterOn) ? "checked='checked'" :""; ?> /></td>
|
321 |
<td>
|
322 |
+
<label for="dbfilter-on"><?php esc_html_e("Enable Table Filters", 'duplicator') ?> </label>
|
323 |
<i class="fas fa-question-circle fa-sm"
|
324 |
data-tooltip-title="<?php esc_attr_e("Enable Table Filters:", 'duplicator'); ?>"
|
325 |
data-tooltip="<?php esc_attr_e('Checked tables will not be added to the database script. Excluding certain tables can possibly cause your site or plugins to not work correctly after install!', 'duplicator'); ?>">
|
328 |
</tr>
|
329 |
</table>
|
330 |
<div id="dup-db-filter-items">
|
331 |
+
<div style="float:right; padding-right:10px;">
|
332 |
+
<a href="javascript:void(0)" id="dball" onclick="jQuery('#dup-dbtables .checkbox').prop('checked', true).trigger('click');"><?php esc_html_e('Include All', 'duplicator'); ?></a>
|
333 |
+
<a href="javascript:void(0)" id="dbnone" onclick="jQuery('#dup-dbtables .checkbox').prop('checked', false).trigger('click');"><?php esc_html_e('Exclude All', 'duplicator'); ?></a>
|
334 |
+
</div>
|
335 |
+
<div class="dup-tbl-scroll">
|
336 |
<?php
|
337 |
$tables = $wpdb->get_results("SHOW FULL TABLES FROM `" . DB_NAME . "` WHERE Table_Type = 'BASE TABLE' ", ARRAY_N);
|
338 |
$num_rows = count($tables);
|
380 |
_e("<i class='core-table-info'> Use caution when excluding tables! It is highly recommended to not exclude WordPress core tables*, unless you know the impact.</i>", 'duplicator');
|
381 |
?>
|
382 |
</div>
|
383 |
+
<br/>
|
384 |
+
|
385 |
+
<div class="tab-hdr-title">
|
386 |
+
<?php esc_html_e('Configuration', 'duplicator') ?>
|
387 |
+
</div>
|
388 |
+
|
389 |
+
<div class="db-configuration" style="line-height: 30px">
|
390 |
+
|
391 |
+
<?php esc_html_e("SQL Mode", 'duplicator') ?>:
|
392 |
+
<a href="?page=duplicator-settings&tab=package" target="settings"><?php echo esc_html($dbbuild_mode); ?></a>
|
393 |
+
|
394 |
+
<br/>
|
395 |
+
<?php esc_html_e("Compatibility Mode", 'duplicator') ?>:
|
396 |
+
<i class="fas fa-question-circle fa-sm"
|
397 |
+
data-tooltip-title="<?php esc_attr_e("Compatibility Mode:", 'duplicator'); ?>"
|
398 |
+
data-tooltip="<?php esc_attr_e('This is an advanced database backwards compatibility feature that should ONLY be used if having problems installing packages.'
|
399 |
+
. ' If the database server version is lower than the version where the package was built then these options may help generate a script that is more compliant'
|
400 |
+
. ' with the older database server. It is recommended to try each option separately starting with mysql40.', 'duplicator'); ?>">
|
401 |
+
</i>
|
402 |
+
<small style="font-style:italic">
|
403 |
+
<a href="https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_compatible" target="_blank">[<?php esc_html_e('details', 'duplicator'); ?>]</a>
|
404 |
+
</small>
|
405 |
+
|
406 |
+
<?php if ($dbbuild_mode == 'mysqldump') :?>
|
407 |
+
<?php
|
408 |
+
$modes = explode(',', $Package->Database->Compatible);
|
409 |
+
$is_mysql40 = in_array('mysql40', $modes);
|
410 |
+
$is_no_table = in_array('no_table_options', $modes);
|
411 |
+
$is_no_key = in_array('no_key_options', $modes);
|
412 |
+
$is_no_field = in_array('no_field_options', $modes);
|
413 |
+
?>
|
414 |
+
<table class="dbmysql-compatibility">
|
415 |
+
<tr>
|
416 |
+
<td>
|
417 |
+
<input type="checkbox" name="dbcompat[]" id="dbcompat-mysql40" value="mysql40" <?php echo $is_mysql40 ? 'checked="true"' :''; ?> >
|
418 |
+
<label for="dbcompat-mysql40"><?php esc_html_e("mysql40", 'duplicator') ?></label>
|
419 |
+
</td>
|
420 |
+
<td>
|
421 |
+
<input type="checkbox" name="dbcompat[]" id="dbcompat-no_table_options" value="no_table_options" <?php echo $is_no_table ? 'checked="true"' :''; ?>>
|
422 |
+
<label for="dbcompat-no_table_options"><?php esc_html_e("no_table_options", 'duplicator') ?></label>
|
423 |
+
</td>
|
424 |
+
<td>
|
425 |
+
<input type="checkbox" name="dbcompat[]" id="dbcompat-no_key_options" value="no_key_options" <?php echo $is_no_key ? 'checked="true"' :''; ?>>
|
426 |
+
<label for="dbcompat-no_key_options"><?php esc_html_e("no_key_options", 'duplicator') ?></label>
|
427 |
+
</td>
|
428 |
+
<td>
|
429 |
+
<input type="checkbox" name="dbcompat[]" id="dbcompat-no_field_options" value="no_field_options" <?php echo $is_no_field ? 'checked="true"' :''; ?>>
|
430 |
+
<label for="dbcompat-no_field_options"><?php esc_html_e("no_field_options", 'duplicator') ?></label>
|
431 |
+
</td>
|
432 |
+
</tr>
|
433 |
+
</table>
|
434 |
+
<?php else :?>
|
435 |
+
<i><?php esc_html_e("This option is only available with mysqldump mode.", 'duplicator'); ?></i>
|
436 |
+
<?php endif; ?>
|
437 |
+
|
438 |
+
</div>
|
439 |
+
|
440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
|
442 |
</div>
|
443 |
</div>
|
642 |
$filterItems.removeAttr('disabled').css({color:'#000'});
|
643 |
$('#dup-dbtables input').removeAttr('readonly').css({color:'#000'});
|
644 |
$('#dup-archive-filter-db').show();
|
645 |
+
$('div.dup-tbl-scroll label').css({color:'#000'});
|
646 |
} else {
|
647 |
$filterItems.attr('disabled', 'disabled').css({color:'#999'});
|
648 |
$('#dup-dbtables input').attr('readonly', 'readonly').css({color:'#999'});
|
649 |
+
$('div.dup-tbl-scroll label').css({color:'#999'});
|
650 |
$('#dup-archive-filter-db').hide();
|
651 |
}
|
652 |
};
|
views/packages/main/s2.scan2.php
CHANGED
@@ -4,7 +4,7 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
4 |
<!-- ================================================================
|
5 |
SETUP -->
|
6 |
<div class="details-title">
|
7 |
-
<i class="
|
8 |
<div class="dup-more-details">
|
9 |
<a href="?page=duplicator-tools&tab=diagnostics" target="_blank" title="<?php esc_attr_e('Show Diagnostics', 'duplicator');?>"><i class="fa fa-microchip"></i></a>
|
10 |
<a href="site-health.php" target="_blank" title="<?php esc_attr_e('Check Site Health', 'duplicator');?>"><i class="fas fa-file-medical-alt"></i></a>
|
@@ -137,7 +137,7 @@ WP SETTINGS -->
|
|
137 |
$filter_text="";
|
138 |
if($core_dir_notice) {
|
139 |
echo '<small id="data-srv-wp-core-missing-dirs">';
|
140 |
-
esc_html_e("The core WordPress paths below will
|
141 |
echo "<br/>";
|
142 |
foreach($core_dir_included as $core_dir) {
|
143 |
echo ' <b><i class="fa fa-exclamation-circle scan-warn"></i> '. $core_dir . '</b><br/>';
|
@@ -148,7 +148,7 @@ WP SETTINGS -->
|
|
148 |
|
149 |
if($core_file_notice) {
|
150 |
echo '<small id="data-srv-wp-core-missing-dirs">';
|
151 |
-
esc_html_e("The core WordPress file below will
|
152 |
echo "<br/>";
|
153 |
foreach($core_files_included as $core_file) {
|
154 |
echo ' <b><i class="fa fa-exclamation-circle scan-warn"></i> '. $core_file . '</b><br/>';
|
4 |
<!-- ================================================================
|
5 |
SETUP -->
|
6 |
<div class="details-title">
|
7 |
+
<i class="fas fa-tasks"></i> <?php esc_html_e("Setup", 'duplicator'); ?>
|
8 |
<div class="dup-more-details">
|
9 |
<a href="?page=duplicator-tools&tab=diagnostics" target="_blank" title="<?php esc_attr_e('Show Diagnostics', 'duplicator');?>"><i class="fa fa-microchip"></i></a>
|
10 |
<a href="site-health.php" target="_blank" title="<?php esc_attr_e('Check Site Health', 'duplicator');?>"><i class="fas fa-file-medical-alt"></i></a>
|
137 |
$filter_text="";
|
138 |
if($core_dir_notice) {
|
139 |
echo '<small id="data-srv-wp-core-missing-dirs">';
|
140 |
+
esc_html_e("The core WordPress paths below will NOT be included in the archive. These paths are required for WordPress to function!", 'duplicator');
|
141 |
echo "<br/>";
|
142 |
foreach($core_dir_included as $core_dir) {
|
143 |
echo ' <b><i class="fa fa-exclamation-circle scan-warn"></i> '. $core_dir . '</b><br/>';
|
148 |
|
149 |
if($core_file_notice) {
|
150 |
echo '<small id="data-srv-wp-core-missing-dirs">';
|
151 |
+
esc_html_e("The core WordPress file below will NOT be included in the archive. This file is required for WordPress to function!", 'duplicator');
|
152 |
echo "<br/>";
|
153 |
foreach($core_files_included as $core_file) {
|
154 |
echo ' <b><i class="fa fa-exclamation-circle scan-warn"></i> '. $core_file . '</b><br/>';
|
views/packages/main/s2.scan3.php
CHANGED
@@ -24,7 +24,7 @@ ARCHIVE -->
|
|
24 |
</div>
|
25 |
|
26 |
<div class="scan-header scan-item-first">
|
27 |
-
<i class="
|
28 |
<?php esc_html_e("Files", 'duplicator'); ?>
|
29 |
|
30 |
<div class="scan-header-details">
|
@@ -390,7 +390,7 @@ Restore only package -->
|
|
390 |
DATABASE -->
|
391 |
<div id="dup-scan-db">
|
392 |
<div class="scan-header">
|
393 |
-
<i class="
|
394 |
<?php esc_html_e("Database", 'duplicator'); ?>
|
395 |
<div class="scan-header-details">
|
396 |
<div class="dup-scan-filter-status">
|
@@ -616,7 +616,7 @@ DIALOG: Scan Results -->
|
|
616 |
<br/><br/>
|
617 |
|
618 |
<!-- DATABASE -->
|
619 |
-
<h2><i class="
|
620 |
<table id="db-area">
|
621 |
<tr><td><b><?php esc_html_e('Name:', 'duplicator');?></b></td><td><?php echo DB_NAME; ?> </td></tr>
|
622 |
<tr><td><b><?php esc_html_e('Host:', 'duplicator');?></b></td><td><?php echo DB_HOST; ?> </td></tr>
|
24 |
</div>
|
25 |
|
26 |
<div class="scan-header scan-item-first">
|
27 |
+
<i class="fas fa-folder-open"></i>
|
28 |
<?php esc_html_e("Files", 'duplicator'); ?>
|
29 |
|
30 |
<div class="scan-header-details">
|
390 |
DATABASE -->
|
391 |
<div id="dup-scan-db">
|
392 |
<div class="scan-header">
|
393 |
+
<i class="fas fa-database fa-sm"></i>
|
394 |
<?php esc_html_e("Database", 'duplicator'); ?>
|
395 |
<div class="scan-header-details">
|
396 |
<div class="dup-scan-filter-status">
|
616 |
<br/><br/>
|
617 |
|
618 |
<!-- DATABASE -->
|
619 |
+
<h2><i class="fas fa-database fa-sm"></i> <?php esc_html_e('Database', 'duplicator');?></h2>
|
620 |
<table id="db-area">
|
621 |
<tr><td><b><?php esc_html_e('Name:', 'duplicator');?></b></td><td><?php echo DB_NAME; ?> </td></tr>
|
622 |
<tr><td><b><?php esc_html_e('Host:', 'duplicator');?></b></td><td><?php echo DB_HOST; ?> </td></tr>
|
views/packages/main/s3.build.php
CHANGED
@@ -36,7 +36,8 @@ $rand_txt[0] = $atext0;
|
|
36 |
|
37 |
<style>
|
38 |
a#dup-create-new {margin-left:-5px}
|
39 |
-
div#dup-progress-area {text-align:center; max-width:800px; min-height:200px; border:1px solid silver; border-radius:3px; margin:25px auto 10px auto;
|
|
|
40 |
div.dup-progress-title {font-size:22px;padding:5px 0 20px 0; font-weight:bold}
|
41 |
div#dup-progress-area div.inner {padding:10px; line-height:22px}
|
42 |
div#dup-progress-area h2.title {background-color:#efefef; margin:0px}
|
@@ -86,7 +87,8 @@ $rand_txt[0] = $atext0;
|
|
86 |
div.dup-box-panel {text-align:left}
|
87 |
div.no-top {border-top:none}
|
88 |
div.dup-box-panel b.opt-title {font-size:18px}
|
89 |
-
div.dup-msg-error-area {overflow-y:scroll; padding:5px 15px 15px 15px;
|
|
|
90 |
div#dup-logs {text-align:center; margin:auto; padding:5px; width:350px;}
|
91 |
div#dup-logs a {display:inline-block;}
|
92 |
span.sub-data {display:inline-block; padding-left:20px}
|
@@ -114,7 +116,7 @@ TOOL BAR:STEPS -->
|
|
114 |
<a id="dup-packages-btn" href="?page=duplicator" class="button <?php echo ($active_package_present ? 'no-display' :''); ?>">
|
115 |
<?php esc_html_e("Packages",'duplicator'); ?>
|
116 |
</a>
|
117 |
-
</span>
|
118 |
<?php
|
119 |
$package_url = admin_url('admin.php?page=duplicator&tab=new1');
|
120 |
$package_nonce_url = wp_nonce_url($package_url, 'new1-package');
|
@@ -127,7 +129,7 @@ TOOL BAR:STEPS -->
|
|
127 |
</a>
|
128 |
</td>
|
129 |
</tr>
|
130 |
-
</table>
|
131 |
<hr class="dup-toolbar-line">
|
132 |
|
133 |
|
@@ -185,11 +187,11 @@ TOOL BAR:STEPS -->
|
|
185 |
</sup>
|
186 |
</div>
|
187 |
<div style="margin-top:20px; font-size:11px">
|
188 |
-
<span id="dup-click-to-copy-installer-name"
|
189 |
class="link-style no-decoration"
|
190 |
data-dup-copy-text="<?php echo esc_attr(DUP_Installer::DEFAULT_INSTALLER_FILE_NAME_WITHOUT_HASH); ?>">
|
191 |
<?php esc_html_e("[Copy Installer Name to Clipboard]", 'duplicator'); ?>
|
192 |
-
<i class="far fa-copy"></i>
|
193 |
</span><br/>
|
194 |
<span id="dup-installer-name" data-installer-name="">
|
195 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.ShowInstallerName()">
|
@@ -217,7 +219,7 @@ TOOL BAR:STEPS -->
|
|
217 |
}
|
218 |
?>
|
219 |
|
220 |
-
<div class="dup-howto-exe">
|
221 |
<div class="dup-howto-exe-title" onclick="Duplicator.Pack.ToggleHelpInstall(this)">
|
222 |
<a href="javascript:void(0)">
|
223 |
<i class="far fa-plus-square"></i>
|
@@ -254,7 +256,7 @@ TOOL BAR:STEPS -->
|
|
254 |
|
255 |
|
256 |
<!-- IMPORT -->
|
257 |
-
<i class="fas fa-
|
258 |
<a href="https://snapcreek.com/duplicator/docs/quick-start/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=package_built_install_help3_collapse&utm_campaign=duplicator_free#quick-045-q" target="_blank">
|
259 |
<?php esc_html_e('Import Install Feature', 'duplicator'); ?>
|
260 |
<sup><i class="fas fa-external-link-alt fa-xs"></i></sup>
|
@@ -276,18 +278,18 @@ TOOL BAR:STEPS -->
|
|
276 |
ERROR MESSAGE -->
|
277 |
<div id="dup-msg-error" style="display:none; color:#000">
|
278 |
<div class="done-title"><i class="fa fa-chain-broken"></i> <?php esc_html_e('Host Build Interrupt', 'duplicator'); ?></div>
|
279 |
-
<b><?php esc_html_e('This server cannot complete the build due to host setup constraints.', 'duplicator'); ?></b><br/>
|
280 |
-
|
281 |
-
|
282 |
|
283 |
<!-- OPTION 1:Try DupArchive Engine -->
|
284 |
<div class="dup-box">
|
285 |
<div class="dup-box-title">
|
286 |
-
<
|
|
|
287 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
288 |
</div>
|
289 |
<div class="dup-box-panel" id="dup-pack-build-try1" style="display:none">
|
290 |
-
<!--<b class="opt-title"><?php esc_html_e('OPTION 1:', 'duplicator'); ?></b><br/>-->
|
291 |
|
292 |
<?php esc_html_e('Enable the DupArchive format which is specific to Duplicator and designed to perform better on constrained budget hosts.', 'duplicator'); ?>
|
293 |
<br/><br/>
|
@@ -295,7 +297,7 @@ TOOL BAR:STEPS -->
|
|
295 |
<div style="font-style:italic">
|
296 |
<?php esc_html_e('Note:DupArchive on Duplicator only supports sites up to 500MB. If your site is over 500MB then use a file filter on step 1 to get the size '
|
297 |
. 'below 500MB or try the other options mentioned below. Alternatively, you may want to consider',
|
298 |
-
'duplicator'); ?>
|
299 |
<a href="https://snapcreek.com/duplicator/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=build_interrupt&utm_campaign=duplicator_pro" target="_blank">
|
300 |
Duplicator Pro,
|
301 |
</a>
|
@@ -324,10 +326,11 @@ TOOL BAR:STEPS -->
|
|
324 |
<!-- OPTION 2:TRY AGAIN -->
|
325 |
<div class="dup-box no-top">
|
326 |
<div class="dup-box-title">
|
327 |
-
<
|
|
|
328 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
329 |
</div>
|
330 |
-
<div class="dup-box-panel"
|
331 |
<?php
|
332 |
esc_html_e('The first pass for reading files on some budget hosts maybe slow and have conflicts with strict timeout settings setup by the hosting provider. '
|
333 |
. 'In these cases, it is recommended to retry the build by adding file filters to larger files/directories.', 'duplicator');
|
@@ -358,11 +361,11 @@ TOOL BAR:STEPS -->
|
|
358 |
<!-- OPTION 3:Two-Part Install -->
|
359 |
<div class="dup-box no-top">
|
360 |
<div class="dup-box-title">
|
361 |
-
<
|
|
|
362 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
363 |
</div>
|
364 |
-
<div class="dup-box-panel"
|
365 |
-
|
366 |
|
367 |
<?php esc_html_e('A two-part install minimizes server load and can avoid I/O and CPU issues encountered on some budget hosts. With this procedure you simply build a '
|
368 |
.'\'database-only\' archive, manually move the website files, and then run the installer to complete the process.', 'duplicator');
|
@@ -395,7 +398,8 @@ TOOL BAR:STEPS -->
|
|
395 |
<!-- OPTION 4:DIAGNOSE SERVER -->
|
396 |
<div class="dup-box no-top">
|
397 |
<div class="dup-box-title">
|
398 |
-
<
|
|
|
399 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
400 |
</div>
|
401 |
<div class="dup-box-panel" id="dup-pack-build-try3" style="display:none">
|
@@ -445,41 +449,51 @@ TOOL BAR:STEPS -->
|
|
445 |
?>"></i>
|
446 |
</span>
|
447 |
</div>
|
448 |
-
|
449 |
<div id="dup-msg-error-response-status">
|
450 |
<span class="label"><?php esc_html_e("Server Status:", 'duplicator'); ?></span>
|
451 |
-
<span class="data"
|
452 |
-
</div>
|
453 |
-
<div id="dup-msg-error-response-text">
|
454 |
-
<span class="label"><?php esc_html_e("Error Message:", 'duplicator'); ?></span><br/>
|
455 |
-
<span class="data"></span>
|
456 |
</div>
|
457 |
</div>
|
458 |
-
|
459 |
-
<!-- LOGS -->
|
460 |
-
<div id="dup-logs">
|
461 |
-
<br/>
|
462 |
-
<i class="fa fa-list-alt"></i>
|
463 |
-
<a href='javascript:void(0)' style="color:#000" onclick='Duplicator.OpenLogWindow(true)'><?php esc_html_e('Read Package Log File',
|
464 |
-
'duplicator'); ?></a>
|
465 |
-
<br/><br/>
|
466 |
-
</div>
|
467 |
</div>
|
468 |
</div>
|
|
|
469 |
|
470 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
471 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
472 |
|
473 |
-
<br/><br/><br/>
|
474 |
</div>
|
475 |
|
|
|
476 |
</div>
|
477 |
</div>
|
478 |
</form>
|
479 |
|
480 |
<script>
|
481 |
-
jQuery(document).ready(function ($)
|
482 |
-
{
|
483 |
|
484 |
Duplicator.Pack.DupArchiveFailureCount = 0;
|
485 |
Duplicator.Pack.DupArchiveMaxRetries = 10;
|
@@ -490,8 +504,7 @@ jQuery(document).ready(function ($)
|
|
490 |
/* ----------------------------------------
|
491 |
* METHOD:Performs Ajax post to create a new package
|
492 |
* Timeout (10000000 = 166 minutes) */
|
493 |
-
Duplicator.Pack.CreateZip = function ()
|
494 |
-
{
|
495 |
var startTime;
|
496 |
var data = {action:'duplicator_package_build', nonce:'<?php echo esc_js($zip_build_nonce); ?>'}
|
497 |
var statusInterval = setInterval(Duplicator.Pack.GetActivePackageStatus, Duplicator.Pack.StatusFrequency);
|
@@ -518,26 +531,30 @@ jQuery(document).ready(function ($)
|
|
518 |
$('#dup-progress-bar-area').hide();
|
519 |
$('#dup-progress-area, #dup-msg-error').show(200);
|
520 |
var status = xHr.status + ' -' + data.statusText;
|
521 |
-
var response = (xHr.responseText != undefined && xHr.responseText.trim().length > 1)
|
|
|
|
|
522 |
$('#dup-msg-error-response-status span.data').html(status)
|
523 |
$('#dup-msg-error-response-text span.data').html(response);
|
524 |
console.log(xHr);
|
525 |
return false;
|
526 |
}
|
527 |
-
|
528 |
if ((data != null) && (typeof (data) != 'undefined') && data.status == 1) {
|
529 |
Duplicator.Pack.WireDownloadLinks(data);
|
530 |
} else {
|
531 |
var message = (typeof (data.error) != 'undefined' && data.error.length) ? data.error :'Error processing package';
|
532 |
Duplicator.Pack.DupArchiveProcessingFailed(message);
|
533 |
}
|
534 |
-
|
535 |
},
|
536 |
error:function (xHr) {
|
537 |
$('#dup-progress-bar-area').hide();
|
538 |
$('#dup-progress-area, #dup-msg-error').show(200);
|
539 |
var status = xHr.status + ' -' + data.statusText;
|
540 |
-
var response = (xHr.responseText != undefined && xHr.responseText.trim().length > 1)
|
|
|
|
|
541 |
$('#dup-msg-error-response-status span.data').html(status)
|
542 |
$('#dup-msg-error-response-text span.data').html(response);
|
543 |
console.log(xHr);
|
@@ -548,12 +565,11 @@ jQuery(document).ready(function ($)
|
|
548 |
|
549 |
/* ----------------------------------------
|
550 |
* METHOD:Performs Ajax post to create a new DupArchive-based package */
|
551 |
-
Duplicator.Pack.CreateDupArchive = function ()
|
552 |
-
{
|
553 |
console.log('Duplicator.Pack.CreateDupArchive');
|
554 |
var data = {action:'duplicator_duparchive_package_build', nonce:'<?php echo esc_js($duparchive_build_nonce); ?>'}
|
555 |
var statusInterval = setInterval(Duplicator.Pack.GetActivePackageStatus, Duplicator.Pack.StatusFrequency);
|
556 |
-
|
557 |
$.ajax({
|
558 |
type:"POST",
|
559 |
timeout:0, // no timeout
|
@@ -579,7 +595,6 @@ jQuery(document).ready(function ($)
|
|
579 |
}
|
580 |
|
581 |
console.log("CreateDupArchive:AJAX success. Data equals:");
|
582 |
-
|
583 |
console.log(data);
|
584 |
// DATA FIELDS
|
585 |
// archive_offset, archive_size, failures, file_index, is_done, timestamp
|
@@ -603,7 +618,6 @@ jQuery(document).ready(function ($)
|
|
603 |
// Don't stop for non-critical failures - just display those at the end TODO:put these in the log not popup
|
604 |
console.log("CreateDupArchive:archive has completed");
|
605 |
if (data.failures.length > 0) {
|
606 |
-
|
607 |
console.log(data.failures);
|
608 |
var errorMessage = "CreateDupArchive:Problems during package creation. These may be non-critical so continue with install.\n------\n";
|
609 |
var len = data.failures.length;
|
@@ -623,7 +637,6 @@ jQuery(document).ready(function ($)
|
|
623 |
setTimeout(Duplicator.Pack.CreateDupArchive, 500);
|
624 |
}
|
625 |
} else {
|
626 |
-
|
627 |
console.log("CreateDupArchive:critical failures present");
|
628 |
// If we get a critical failure it means it's something we can't recover from so no purpose in retrying, just fail immediately.
|
629 |
var errorString = 'Error Processing Step 1<br/>';
|
@@ -658,8 +671,7 @@ jQuery(document).ready(function ($)
|
|
658 |
|
659 |
/* ----------------------------------------
|
660 |
* METHOD:Retrieves package status and updates UI with build percentage */
|
661 |
-
Duplicator.Pack.GetActivePackageStatus = function ()
|
662 |
-
{
|
663 |
var data = {action:'DUP_CTRL_Package_getActivePackageStatus', nonce:'<?php echo wp_create_nonce('DUP_CTRL_Package_getActivePackageStatus'); ?>'}
|
664 |
console.log('####Duplicator.Pack.GetActivePackageStatus');
|
665 |
|
@@ -694,8 +706,7 @@ jQuery(document).ready(function ($)
|
|
694 |
return false;
|
695 |
}
|
696 |
|
697 |
-
Duplicator.Pack.PostTransferCleanup = function(statusInterval, startTime)
|
698 |
-
{
|
699 |
clearInterval(statusInterval);
|
700 |
endTime = new Date().getTime();
|
701 |
var millis = (endTime - startTime);
|
@@ -703,12 +714,9 @@ jQuery(document).ready(function ($)
|
|
703 |
var seconds = ((millis % 60000) / 1000).toFixed(0);
|
704 |
var status = minutes + ":" + (seconds < 10 ? '0' :'') + seconds;
|
705 |
$('#dup-msg-error-response-time span.data').html(status);
|
706 |
-
//$('#dup-create-area-nolink').hide();
|
707 |
-
//$('#dup-create-area-link').show();
|
708 |
};
|
709 |
|
710 |
-
Duplicator.Pack.WireDownloadLinks = function(data)
|
711 |
-
{
|
712 |
var pack = data.package;
|
713 |
var archive_json = {
|
714 |
filename:pack.Archive.File,
|
@@ -727,7 +735,7 @@ jQuery(document).ready(function ($)
|
|
727 |
$('#data-time').text(data.runtime || 'unable to read time');
|
728 |
$('#dup-create-new').removeClass('no-display');
|
729 |
$('#dup-packages-btn').removeClass('no-display');
|
730 |
-
|
731 |
//Wire Up Downloads
|
732 |
$('#dup-btn-installer').click(function() {
|
733 |
Duplicator.Pack.DownloadInstaller(installer_json);
|
@@ -746,13 +754,12 @@ jQuery(document).ready(function ($)
|
|
746 |
}, 700);
|
747 |
return false;
|
748 |
});
|
749 |
-
|
750 |
$('#dup-click-to-copy-installer-name').data('dup-copy-text', data.instDownloadName);
|
751 |
$('#dup-installer-name').data('data-installer-name', data.instDownloadName);
|
752 |
};
|
753 |
|
754 |
-
Duplicator.Pack.HandleDupArchiveInterruption = function (errorText)
|
755 |
-
{
|
756 |
Duplicator.Pack.DupArchiveFailureCount++;
|
757 |
|
758 |
if (Duplicator.Pack.DupArchiveFailureCount <= Duplicator.Pack.DupArchiveMaxRetries) {
|
@@ -767,17 +774,16 @@ jQuery(document).ready(function ($)
|
|
767 |
}
|
768 |
};
|
769 |
|
770 |
-
Duplicator.Pack.DupArchiveProcessingFailed = function (errorText)
|
771 |
-
{
|
772 |
$('#dup-progress-bar-area').hide();
|
773 |
$('#dup-progress-area, #dup-msg-error').show(200);
|
774 |
$('#dup-msg-error-response-text span.data').html(errorText);
|
|
|
775 |
};
|
776 |
|
777 |
Duplicator.Pack.GetFailureText = function (failures, onlyCritical)
|
778 |
{
|
779 |
var retVal = '';
|
780 |
-
|
781 |
if ((failures !== null) && (typeof failures !== 'undefined')) {
|
782 |
var len = failures.length;
|
783 |
|
@@ -818,7 +824,6 @@ jQuery(document).ready(function ($)
|
|
818 |
var txt = $('#dup-installer-name').data('data-installer-name');
|
819 |
$('#dup-installer-name').html(txt);
|
820 |
$('#dup-installer-name-help-icon').show();
|
821 |
-
|
822 |
};
|
823 |
|
824 |
//Page Init:
|
@@ -830,4 +835,4 @@ jQuery(document).ready(function ($)
|
|
830 |
Duplicator.Pack.CreateDupArchive();
|
831 |
<?php endif; ?>
|
832 |
});
|
833 |
-
</script>
|
36 |
|
37 |
<style>
|
38 |
a#dup-create-new {margin-left:-5px}
|
39 |
+
div#dup-progress-area {text-align:center; max-width:800px; min-height:200px; border:1px solid silver; border-radius:3px; margin:25px auto 10px auto;
|
40 |
+
padding:0px; box-shadow:0 8px 6px -6px #999;}
|
41 |
div.dup-progress-title {font-size:22px;padding:5px 0 20px 0; font-weight:bold}
|
42 |
div#dup-progress-area div.inner {padding:10px; line-height:22px}
|
43 |
div#dup-progress-area h2.title {background-color:#efefef; margin:0px}
|
87 |
div.dup-box-panel {text-align:left}
|
88 |
div.no-top {border-top:none}
|
89 |
div.dup-box-panel b.opt-title {font-size:18px}
|
90 |
+
div.dup-msg-error-area {overflow-y:scroll; padding:5px 15px 15px 15px; height:100px; width:95%; border:1px solid #EEEEEE;
|
91 |
+
border-radius:2px; line-height:22px; text-align: left; background-color: #FFFFF3}
|
92 |
div#dup-logs {text-align:center; margin:auto; padding:5px; width:350px;}
|
93 |
div#dup-logs a {display:inline-block;}
|
94 |
span.sub-data {display:inline-block; padding-left:20px}
|
116 |
<a id="dup-packages-btn" href="?page=duplicator" class="button <?php echo ($active_package_present ? 'no-display' :''); ?>">
|
117 |
<?php esc_html_e("Packages",'duplicator'); ?>
|
118 |
</a>
|
119 |
+
</span>
|
120 |
<?php
|
121 |
$package_url = admin_url('admin.php?page=duplicator&tab=new1');
|
122 |
$package_nonce_url = wp_nonce_url($package_url, 'new1-package');
|
129 |
</a>
|
130 |
</td>
|
131 |
</tr>
|
132 |
+
</table>
|
133 |
<hr class="dup-toolbar-line">
|
134 |
|
135 |
|
187 |
</sup>
|
188 |
</div>
|
189 |
<div style="margin-top:20px; font-size:11px">
|
190 |
+
<span id="dup-click-to-copy-installer-name"
|
191 |
class="link-style no-decoration"
|
192 |
data-dup-copy-text="<?php echo esc_attr(DUP_Installer::DEFAULT_INSTALLER_FILE_NAME_WITHOUT_HASH); ?>">
|
193 |
<?php esc_html_e("[Copy Installer Name to Clipboard]", 'duplicator'); ?>
|
194 |
+
<i class="far fa-copy"></i>
|
195 |
</span><br/>
|
196 |
<span id="dup-installer-name" data-installer-name="">
|
197 |
<a href="javascript:void(0)" onclick="Duplicator.Pack.ShowInstallerName()">
|
219 |
}
|
220 |
?>
|
221 |
|
222 |
+
<div class="dup-howto-exe">
|
223 |
<div class="dup-howto-exe-title" onclick="Duplicator.Pack.ToggleHelpInstall(this)">
|
224 |
<a href="javascript:void(0)">
|
225 |
<i class="far fa-plus-square"></i>
|
256 |
|
257 |
|
258 |
<!-- IMPORT -->
|
259 |
+
<i class="fas fa-arrow-alt-circle-down fa-sm fa-fw"></i>
|
260 |
<a href="https://snapcreek.com/duplicator/docs/quick-start/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=package_built_install_help3_collapse&utm_campaign=duplicator_free#quick-045-q" target="_blank">
|
261 |
<?php esc_html_e('Import Install Feature', 'duplicator'); ?>
|
262 |
<sup><i class="fas fa-external-link-alt fa-xs"></i></sup>
|
278 |
ERROR MESSAGE -->
|
279 |
<div id="dup-msg-error" style="display:none; color:#000">
|
280 |
<div class="done-title"><i class="fa fa-chain-broken"></i> <?php esc_html_e('Host Build Interrupt', 'duplicator'); ?></div>
|
281 |
+
<b><?php esc_html_e('This server cannot complete the build due to host setup constraints, see the error message for more details.', 'duplicator'); ?></b><br/>
|
282 |
+
<i><?php esc_html_e("If the error details are not specific consider the options below by clicking each section.", 'duplicator'); ?></i>
|
283 |
+
<br/><br/>
|
284 |
|
285 |
<!-- OPTION 1:Try DupArchive Engine -->
|
286 |
<div class="dup-box">
|
287 |
<div class="dup-box-title">
|
288 |
+
<i class="far fa-check-circle fa-sm fa-fw"></i>
|
289 |
+
<?php esc_html_e('Option 1: DupArchive', 'duplicator'); ?>
|
290 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
291 |
</div>
|
292 |
<div class="dup-box-panel" id="dup-pack-build-try1" style="display:none">
|
|
|
293 |
|
294 |
<?php esc_html_e('Enable the DupArchive format which is specific to Duplicator and designed to perform better on constrained budget hosts.', 'duplicator'); ?>
|
295 |
<br/><br/>
|
297 |
<div style="font-style:italic">
|
298 |
<?php esc_html_e('Note:DupArchive on Duplicator only supports sites up to 500MB. If your site is over 500MB then use a file filter on step 1 to get the size '
|
299 |
. 'below 500MB or try the other options mentioned below. Alternatively, you may want to consider',
|
300 |
+
'duplicator'); ?>
|
301 |
<a href="https://snapcreek.com/duplicator/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=build_interrupt&utm_campaign=duplicator_pro" target="_blank">
|
302 |
Duplicator Pro,
|
303 |
</a>
|
326 |
<!-- OPTION 2:TRY AGAIN -->
|
327 |
<div class="dup-box no-top">
|
328 |
<div class="dup-box-title">
|
329 |
+
<i class="fas fa-filter fa-sm fa-fw"></i>
|
330 |
+
<?php esc_html_e('Option 2: File Filters', 'duplicator'); ?>
|
331 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
332 |
</div>
|
333 |
+
<div class="dup-box-panel" style="display:none">
|
334 |
<?php
|
335 |
esc_html_e('The first pass for reading files on some budget hosts maybe slow and have conflicts with strict timeout settings setup by the hosting provider. '
|
336 |
. 'In these cases, it is recommended to retry the build by adding file filters to larger files/directories.', 'duplicator');
|
361 |
<!-- OPTION 3:Two-Part Install -->
|
362 |
<div class="dup-box no-top">
|
363 |
<div class="dup-box-title">
|
364 |
+
<i class="fas fa-random fa-sm fa-fw"></i>
|
365 |
+
<?php esc_html_e('Option 3: Two-Part Install', 'duplicator'); ?>
|
366 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
367 |
</div>
|
368 |
+
<div class="dup-box-panel" style="display:none">
|
|
|
369 |
|
370 |
<?php esc_html_e('A two-part install minimizes server load and can avoid I/O and CPU issues encountered on some budget hosts. With this procedure you simply build a '
|
371 |
.'\'database-only\' archive, manually move the website files, and then run the installer to complete the process.', 'duplicator');
|
398 |
<!-- OPTION 4:DIAGNOSE SERVER -->
|
399 |
<div class="dup-box no-top">
|
400 |
<div class="dup-box-title">
|
401 |
+
<i class="fas fa-cog fa-sm fa-fw"></i>
|
402 |
+
<?php esc_html_e('Option 4: Configure Server', 'duplicator'); ?>
|
403 |
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
404 |
</div>
|
405 |
<div class="dup-box-panel" id="dup-pack-build-try3" style="display:none">
|
449 |
?>"></i>
|
450 |
</span>
|
451 |
</div>
|
|
|
452 |
<div id="dup-msg-error-response-status">
|
453 |
<span class="label"><?php esc_html_e("Server Status:", 'duplicator'); ?></span>
|
454 |
+
<span class="data"><?php esc_html_e("unavailable", 'duplicator'); ?></span>
|
|
|
|
|
|
|
|
|
455 |
</div>
|
456 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
457 |
</div>
|
458 |
</div>
|
459 |
+
<br/><br/>
|
460 |
|
461 |
|
462 |
+
<!-- ERROR DETAILS-->
|
463 |
+
<div class="dup-box no-top">
|
464 |
+
<div class="dup-box-title" id="dup-pack-build-err-info" >
|
465 |
+
<i class="fas fa-file-contract fa-fw fa-sm"></i>
|
466 |
+
<?php esc_html_e('System Details', 'duplicator'); ?>
|
467 |
+
<div class="dup-box-arrow"><i class="fa fa-caret-down"></i></div>
|
468 |
+
</div>
|
469 |
+
<div class="dup-box-panel" style="display:none">
|
470 |
+
<span class="label"><?php esc_html_e("Error Message:", 'duplicator'); ?></span>
|
471 |
+
<div class="dup-msg-error-area">
|
472 |
+
<div id="dup-msg-error-response-text">
|
473 |
+
<span class="data"><?php esc_html_e("Error status unavailable.", 'duplicator'); ?></span>
|
474 |
+
</div>
|
475 |
+
</div>
|
476 |
|
477 |
+
<div id="dup-logs" style="color:maroon; font-size:16px">
|
478 |
+
<br/>
|
479 |
+
<i class="fas fa-file-contract fa-fw "></i>
|
480 |
+
<a href='javascript:void(0)' style="color:maroon" onclick='Duplicator.OpenLogWindow(true)'>
|
481 |
+
<?php esc_html_e('See Package Log For Complete Details', 'duplicator'); ?>
|
482 |
+
</a>
|
483 |
+
</div>
|
484 |
+
</div>
|
485 |
+
</div>
|
486 |
+
<br/><br/>
|
487 |
|
|
|
488 |
</div>
|
489 |
|
490 |
+
|
491 |
</div>
|
492 |
</div>
|
493 |
</form>
|
494 |
|
495 |
<script>
|
496 |
+
jQuery(document).ready(function ($) {
|
|
|
497 |
|
498 |
Duplicator.Pack.DupArchiveFailureCount = 0;
|
499 |
Duplicator.Pack.DupArchiveMaxRetries = 10;
|
504 |
/* ----------------------------------------
|
505 |
* METHOD:Performs Ajax post to create a new package
|
506 |
* Timeout (10000000 = 166 minutes) */
|
507 |
+
Duplicator.Pack.CreateZip = function () {
|
|
|
508 |
var startTime;
|
509 |
var data = {action:'duplicator_package_build', nonce:'<?php echo esc_js($zip_build_nonce); ?>'}
|
510 |
var statusInterval = setInterval(Duplicator.Pack.GetActivePackageStatus, Duplicator.Pack.StatusFrequency);
|
531 |
$('#dup-progress-bar-area').hide();
|
532 |
$('#dup-progress-area, #dup-msg-error').show(200);
|
533 |
var status = xHr.status + ' -' + data.statusText;
|
534 |
+
var response = (xHr.responseText != undefined && xHr.responseText.trim().length > 1)
|
535 |
+
? xHr.responseText.trim()
|
536 |
+
: 'No client side error - see package log file';
|
537 |
$('#dup-msg-error-response-status span.data').html(status)
|
538 |
$('#dup-msg-error-response-text span.data').html(response);
|
539 |
console.log(xHr);
|
540 |
return false;
|
541 |
}
|
542 |
+
|
543 |
if ((data != null) && (typeof (data) != 'undefined') && data.status == 1) {
|
544 |
Duplicator.Pack.WireDownloadLinks(data);
|
545 |
} else {
|
546 |
var message = (typeof (data.error) != 'undefined' && data.error.length) ? data.error :'Error processing package';
|
547 |
Duplicator.Pack.DupArchiveProcessingFailed(message);
|
548 |
}
|
549 |
+
|
550 |
},
|
551 |
error:function (xHr) {
|
552 |
$('#dup-progress-bar-area').hide();
|
553 |
$('#dup-progress-area, #dup-msg-error').show(200);
|
554 |
var status = xHr.status + ' -' + data.statusText;
|
555 |
+
var response = (xHr.responseText != undefined && xHr.responseText.trim().length > 1)
|
556 |
+
? xHr.responseText.trim()
|
557 |
+
: 'No client side error - see package log file';
|
558 |
$('#dup-msg-error-response-status span.data').html(status)
|
559 |
$('#dup-msg-error-response-text span.data').html(response);
|
560 |
console.log(xHr);
|
565 |
|
566 |
/* ----------------------------------------
|
567 |
* METHOD:Performs Ajax post to create a new DupArchive-based package */
|
568 |
+
Duplicator.Pack.CreateDupArchive = function () {
|
|
|
569 |
console.log('Duplicator.Pack.CreateDupArchive');
|
570 |
var data = {action:'duplicator_duparchive_package_build', nonce:'<?php echo esc_js($duparchive_build_nonce); ?>'}
|
571 |
var statusInterval = setInterval(Duplicator.Pack.GetActivePackageStatus, Duplicator.Pack.StatusFrequency);
|
572 |
+
|
573 |
$.ajax({
|
574 |
type:"POST",
|
575 |
timeout:0, // no timeout
|
595 |
}
|
596 |
|
597 |
console.log("CreateDupArchive:AJAX success. Data equals:");
|
|
|
598 |
console.log(data);
|
599 |
// DATA FIELDS
|
600 |
// archive_offset, archive_size, failures, file_index, is_done, timestamp
|
618 |
// Don't stop for non-critical failures - just display those at the end TODO:put these in the log not popup
|
619 |
console.log("CreateDupArchive:archive has completed");
|
620 |
if (data.failures.length > 0) {
|
|
|
621 |
console.log(data.failures);
|
622 |
var errorMessage = "CreateDupArchive:Problems during package creation. These may be non-critical so continue with install.\n------\n";
|
623 |
var len = data.failures.length;
|
637 |
setTimeout(Duplicator.Pack.CreateDupArchive, 500);
|
638 |
}
|
639 |
} else {
|
|
|
640 |
console.log("CreateDupArchive:critical failures present");
|
641 |
// If we get a critical failure it means it's something we can't recover from so no purpose in retrying, just fail immediately.
|
642 |
var errorString = 'Error Processing Step 1<br/>';
|
671 |
|
672 |
/* ----------------------------------------
|
673 |
* METHOD:Retrieves package status and updates UI with build percentage */
|
674 |
+
Duplicator.Pack.GetActivePackageStatus = function () {
|
|
|
675 |
var data = {action:'DUP_CTRL_Package_getActivePackageStatus', nonce:'<?php echo wp_create_nonce('DUP_CTRL_Package_getActivePackageStatus'); ?>'}
|
676 |
console.log('####Duplicator.Pack.GetActivePackageStatus');
|
677 |
|
706 |
return false;
|
707 |
}
|
708 |
|
709 |
+
Duplicator.Pack.PostTransferCleanup = function(statusInterval, startTime) {
|
|
|
710 |
clearInterval(statusInterval);
|
711 |
endTime = new Date().getTime();
|
712 |
var millis = (endTime - startTime);
|
714 |
var seconds = ((millis % 60000) / 1000).toFixed(0);
|
715 |
var status = minutes + ":" + (seconds < 10 ? '0' :'') + seconds;
|
716 |
$('#dup-msg-error-response-time span.data').html(status);
|
|
|
|
|
717 |
};
|
718 |
|
719 |
+
Duplicator.Pack.WireDownloadLinks = function(data) {
|
|
|
720 |
var pack = data.package;
|
721 |
var archive_json = {
|
722 |
filename:pack.Archive.File,
|
735 |
$('#data-time').text(data.runtime || 'unable to read time');
|
736 |
$('#dup-create-new').removeClass('no-display');
|
737 |
$('#dup-packages-btn').removeClass('no-display');
|
738 |
+
|
739 |
//Wire Up Downloads
|
740 |
$('#dup-btn-installer').click(function() {
|
741 |
Duplicator.Pack.DownloadInstaller(installer_json);
|
754 |
}, 700);
|
755 |
return false;
|
756 |
});
|
757 |
+
|
758 |
$('#dup-click-to-copy-installer-name').data('dup-copy-text', data.instDownloadName);
|
759 |
$('#dup-installer-name').data('data-installer-name', data.instDownloadName);
|
760 |
};
|
761 |
|
762 |
+
Duplicator.Pack.HandleDupArchiveInterruption = function (errorText) {
|
|
|
763 |
Duplicator.Pack.DupArchiveFailureCount++;
|
764 |
|
765 |
if (Duplicator.Pack.DupArchiveFailureCount <= Duplicator.Pack.DupArchiveMaxRetries) {
|
774 |
}
|
775 |
};
|
776 |
|
777 |
+
Duplicator.Pack.DupArchiveProcessingFailed = function (errorText) {
|
|
|
778 |
$('#dup-progress-bar-area').hide();
|
779 |
$('#dup-progress-area, #dup-msg-error').show(200);
|
780 |
$('#dup-msg-error-response-text span.data').html(errorText);
|
781 |
+
$('#dup-pack-build-err-info').trigger('click');
|
782 |
};
|
783 |
|
784 |
Duplicator.Pack.GetFailureText = function (failures, onlyCritical)
|
785 |
{
|
786 |
var retVal = '';
|
|
|
787 |
if ((failures !== null) && (typeof failures !== 'undefined')) {
|
788 |
var len = failures.length;
|
789 |
|
824 |
var txt = $('#dup-installer-name').data('data-installer-name');
|
825 |
$('#dup-installer-name').html(txt);
|
826 |
$('#dup-installer-name-help-icon').show();
|
|
|
827 |
};
|
828 |
|
829 |
//Page Init:
|
835 |
Duplicator.Pack.CreateDupArchive();
|
836 |
<?php endif; ?>
|
837 |
});
|
838 |
+
</script>
|
views/settings/import.php
CHANGED
@@ -3,7 +3,6 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
3 |
?>
|
4 |
<style>
|
5 |
div.panel {padding: 20px 5px 10px 10px; text-align: center; }
|
6 |
-
div.sc-note {color:maroon; font-style: italic; line-height:17px; font-size:13px; margin:30px auto 40px auto; max-width: 650px; display:none}
|
7 |
</style>
|
8 |
|
9 |
<div class="panel">
|
@@ -20,13 +19,6 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
20 |
?>
|
21 |
</div>
|
22 |
|
23 |
-
<div class="sc-note">
|
24 |
-
<?php esc_html_e(' Drag and Drop import functionality works with packages created by Duplicator Pro. In the near future, the Duplicator Pro importer '
|
25 |
-
. 'will be enhanced to allow the importing of Duplicator Lite packages. For instructions on how to perform a classic or overwrite install with Duplicator Lite '
|
26 |
-
. 'packages visit the ', 'duplicator'); ?>
|
27 |
-
<a href="https://snapcreek.com/duplicator/docs/quick-start/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=package_built_install_help5&utm_campaign=duplicator_free#install_site" target="_blank"><?php esc_html_e('Quick Start Guide', 'duplicator'); ?></a>.
|
28 |
-
</div>
|
29 |
-
|
30 |
<a class="dup-btn-call-action" href="https://snapcreek.com/duplicator/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=free_tools_imports_checkitout&utm_campaign=duplicator_pro" target="_blank">
|
31 |
<?php esc_html_e('Check It Out!', 'duplicator') ?>
|
32 |
</a>
|
3 |
?>
|
4 |
<style>
|
5 |
div.panel {padding: 20px 5px 10px 10px; text-align: center; }
|
|
|
6 |
</style>
|
7 |
|
8 |
<div class="panel">
|
19 |
?>
|
20 |
</div>
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
<a class="dup-btn-call-action" href="https://snapcreek.com/duplicator/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=free_tools_imports_checkitout&utm_campaign=duplicator_pro" target="_blank">
|
23 |
<?php esc_html_e('Check It Out!', 'duplicator') ?>
|
24 |
</a>
|
views/settings/packages.php
CHANGED
@@ -87,7 +87,7 @@ $installerNameMode = DUP_Settings::Get('installer_name_mode');
|
|
87 |
<hr size="1" />
|
88 |
<table class="form-table">
|
89 |
<tr>
|
90 |
-
<th scope="row"><label><?php esc_html_e("SQL
|
91 |
<td>
|
92 |
<div class="engine-radio <?php echo ($is_shellexec_on) ? '' : 'engine-radio-disabled'; ?>">
|
93 |
<input type="radio" name="package_dbmode" value="mysql" id="package_mysqldump" <?php echo ($package_mysqldump) ? 'checked="checked"' : ''; ?> />
|
87 |
<hr size="1" />
|
88 |
<table class="form-table">
|
89 |
<tr>
|
90 |
+
<th scope="row"><label><?php esc_html_e("SQL Mode", 'duplicator'); ?></label></th>
|
91 |
<td>
|
92 |
<div class="engine-radio <?php echo ($is_shellexec_on) ? '' : 'engine-radio-disabled'; ?>">
|
93 |
<input type="radio" name="package_dbmode" value="mysql" id="package_mysqldump" <?php echo ($package_mysqldump) ? 'checked="checked"' : ''; ?> />
|
views/settings/storage.php
CHANGED
@@ -13,9 +13,9 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
13 |
$action_response = esc_html__("Storage Settings Saved", 'duplicator');
|
14 |
|
15 |
//SAVE RESULTS
|
16 |
-
if (filter_input(INPUT_POST, 'action',
|
17 |
//Nonce Check
|
18 |
-
if (!wp_verify_nonce(filter_input(INPUT_POST, 'dup_storage_settings_save_nonce_field',
|
19 |
die('Invalid token permissions to perform this request.');
|
20 |
}
|
21 |
|
@@ -91,8 +91,8 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
91 |
. "the 'Contents Path'. Upon clicking the save button all files are moved to the new location and the previous path is removed.", 'duplicator');
|
92 |
?><br/>
|
93 |
|
94 |
-
|
95 |
-
<
|
96 |
</p>
|
97 |
</td>
|
98 |
</tr>
|
@@ -129,19 +129,19 @@ function dup_lite_storage_advanced_pro_content()
|
|
129 |
<div style="text-align: center">
|
130 |
<img src="<?php echo esc_url(DUPLICATOR_PLUGIN_URL."assets/img/logo-dpro-300x50.png"); ?>" style="height:50px; width:250px" /><br/>
|
131 |
<?php
|
132 |
-
esc_html_e('Store
|
133 |
echo '<br/>';
|
134 |
esc_html_e('with Duplicator Pro', 'duplicator');
|
135 |
?>
|
136 |
|
137 |
-
<div style="text-align: left; margin:auto; width:
|
138 |
<ul>
|
139 |
-
<li><i class="fab fa-amazon"></i
|
140 |
-
<li><i class="fab fa-dropbox"></i
|
141 |
-
<li><i class="fab fa-google-drive"></i
|
142 |
-
<li><i class="fa fa-cloud fa-sm"></i
|
143 |
-
<li><i class="
|
144 |
-
<li><i class="
|
145 |
</ul>
|
146 |
</div>
|
147 |
<i>
|
13 |
$action_response = esc_html__("Storage Settings Saved", 'duplicator');
|
14 |
|
15 |
//SAVE RESULTS
|
16 |
+
if (filter_input(INPUT_POST, 'action', FILTER_UNSAFE_RAW) === 'save') {
|
17 |
//Nonce Check
|
18 |
+
if (!wp_verify_nonce(filter_input(INPUT_POST, 'dup_storage_settings_save_nonce_field', FILTER_UNSAFE_RAW), 'dup_settings_save')) {
|
19 |
die('Invalid token permissions to perform this request.');
|
20 |
}
|
21 |
|
91 |
. "the 'Contents Path'. Upon clicking the save button all files are moved to the new location and the previous path is removed.", 'duplicator');
|
92 |
?><br/>
|
93 |
|
94 |
+
<i class="fas fa-server fa-sm"></i>
|
95 |
+
<span id="duplicator_advanced_storage_text" class="link-style">[<?php esc_html_e("More Advanced Storage Options...", 'duplicator'); ?>]</span>
|
96 |
</p>
|
97 |
</td>
|
98 |
</tr>
|
129 |
<div style="text-align: center">
|
130 |
<img src="<?php echo esc_url(DUPLICATOR_PLUGIN_URL."assets/img/logo-dpro-300x50.png"); ?>" style="height:50px; width:250px" /><br/>
|
131 |
<?php
|
132 |
+
esc_html_e('Store to Multiple Endpoints', 'duplicator');
|
133 |
echo '<br/>';
|
134 |
esc_html_e('with Duplicator Pro', 'duplicator');
|
135 |
?>
|
136 |
|
137 |
+
<div style="text-align: left; margin:auto; width:200px">
|
138 |
<ul>
|
139 |
+
<li><i class="fab fa-amazon"></i> <?php esc_html_e('Amazon S3', 'duplicator'); ?></li>
|
140 |
+
<li><i class="fab fa-dropbox"></i> <?php esc_html_e(' Dropbox', 'duplicator'); ?></li>
|
141 |
+
<li><i class="fab fa-google-drive"></i> <?php esc_html_e('Google Drive', 'duplicator'); ?></li>
|
142 |
+
<li><i class="fa fa-cloud fa-sm"></i> <?php esc_html_e('One Drive', 'duplicator'); ?></li>
|
143 |
+
<li><i class="fas fa-network-wired"></i> <?php esc_html_e('FTP & SFTP', 'duplicator'); ?></li>
|
144 |
+
<li><i class="fas fa-hdd"></i> <?php esc_html_e('Custom Directory', 'duplicator'); ?></li>
|
145 |
</ul>
|
146 |
</div>
|
147 |
<i>
|
views/tools/diagnostics/inc.settings.php
CHANGED
@@ -193,7 +193,7 @@ SERVER SETTINGS -->
|
|
193 |
</tr>
|
194 |
<tr>
|
195 |
<td><?php esc_html_e("Charset", 'duplicator'); ?></td>
|
196 |
-
<td><?php echo DB_CHARSET ?></td>
|
197 |
</tr>
|
198 |
<tr>
|
199 |
<td><a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout" target="_blank"><?php esc_html_e("Wait Timeout", 'duplicator'); ?></a></td>
|
193 |
</tr>
|
194 |
<tr>
|
195 |
<td><?php esc_html_e("Charset", 'duplicator'); ?></td>
|
196 |
+
<td><?php echo defined('DB_CHARSET') ? DB_CHARSET : 'DB_CHARSET not set' ; ?></td>
|
197 |
</tr>
|
198 |
<tr>
|
199 |
<td><a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout" target="_blank"><?php esc_html_e("Wait Timeout", 'duplicator'); ?></a></td>
|
views/tools/diagnostics/logging.php
CHANGED
@@ -175,7 +175,7 @@ jQuery(document).ready(function($)
|
|
175 |
<tr>
|
176 |
<td id="dup-log-panel-left">
|
177 |
<div class="name">
|
178 |
-
<i class='fa fa-
|
179 |
<i style="cursor: pointer"
|
180 |
data-tooltip-title="<?php esc_attr_e("Host Recommendation:", 'duplicator'); ?>"
|
181 |
data-tooltip="<?php esc_attr_e('Duplicator recommends going with the high performance pro plan or better from our recommended list', 'duplicator'); ?>">
|
175 |
<tr>
|
176 |
<td id="dup-log-panel-left">
|
177 |
<div class="name">
|
178 |
+
<i class='fas fa-file-contract fa-fw'></i> <b><?php echo basename($logurl); ?></b> |
|
179 |
<i style="cursor: pointer"
|
180 |
data-tooltip-title="<?php esc_attr_e("Host Recommendation:", 'duplicator'); ?>"
|
181 |
data-tooltip="<?php esc_attr_e('Duplicator recommends going with the high performance pro plan or better from our recommended list', 'duplicator'); ?>">
|