Version Description
Download this release
Release Info
Developer | cory@lamle.org |
Plugin | Duplicator – WordPress Migration Plugin |
Version | 1.1.6 |
Comparing to | |
See all releases |
Code changes from version 1.1.4 to 1.1.6
- assets/css/style.css +20 -21
- assets/js/javascript.php +4 -5
- define.php +1 -1
- duplicator.php +1 -1
- installer/build/ajax.step1.php +8 -0
- installer/build/ajax.step2.php +11 -10
- installer/build/classes/class.utils.php +24 -26
- readme.txt +1 -1
- uninstall.php +0 -6
- views/help/gopro.php +10 -9
- views/help/help.php +6 -8
- views/packages/main/new1.base.php +3 -6
- views/packages/main/new1.inc.form.php +21 -14
- views/tools/cleanup.php +1 -1
assets/css/style.css
CHANGED
@@ -11,29 +11,30 @@ fieldset {border:1px solid gray; padding:0px 5px 5px 5px; }
|
|
11 |
label {font-size:13px}
|
12 |
.no-select {user-select:none; -o-user-select:none; -moz-user-select:none; -khtml-user-select:none; -webkit-user-select:none;}
|
13 |
hr {border:0; border-top:1px solid #ddd; border-bottom:1px solid #fafafa; margin:10px 0px 2px 0px;}
|
14 |
-
i[data-tooltip].fa-question-circle {cursor:pointer; color
|
15 |
i[data-tooltip].fa-lightbulb-o {cursor:pointer; color:gray}
|
16 |
|
17 |
-
/*
|
18 |
-
|
19 |
-
div.dup-box-title {font-size:15px; padding:10px 0 0 15px; font-weight:bold; cursor:pointer; height:28px; margin:0px; }
|
20 |
-
div.dup-box-title:hover {background-color:#FCFCFC;}
|
21 |
-
div.dup-box-arrow {text-decoration:none!important; float:right; width:27px; height:30px; font-size:16px; cursor:pointer; padding:1px 0px 0px 0px; white-space:nowrap}
|
22 |
-
div.dup-box-panel {padding:10px 15px 10px 15px; border-top:1px solid #EEEEEE; margin:-1px 0px 0px 0px;}
|
23 |
|
24 |
-
/*
|
25 |
-
div.dup-
|
26 |
-
div.dup-
|
27 |
-
div.dup-
|
|
|
|
|
28 |
|
29 |
-
/*PANELS:
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
div.dup-box-title-fancy {
|
31 |
-
|
32 |
-
background
|
33 |
-
background
|
34 |
-
background:-ms-linear-gradient(top, #eeeeee 0%,#e0e0e0 100%);
|
35 |
-
background:linear-gradient(to bottom, #eeeeee 0%,#e0e0e0 100%);
|
36 |
-
filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#e0e0e0',GradientType=0 );
|
37 |
}
|
38 |
|
39 |
/*INFO-BOX:Simple box with no title */
|
@@ -48,9 +49,6 @@ div#dup-progress-bar-area h2 {margin-bottom:15px}
|
|
48 |
div.dup-hdr-success {color:#196512; font-size:20px; font-weight:bold}
|
49 |
div.dup-hdr-error {color:#A62426; font-size:20px; font-weight:bold}
|
50 |
|
51 |
-
/*================================================
|
52 |
-
JQUERY UI:Overrides */
|
53 |
-
.ui-tabs-hide {display:none !important} /*fix for WP 3.5 setting */
|
54 |
|
55 |
/*================================================
|
56 |
PARSLEY:Overrides*/
|
@@ -59,6 +57,7 @@ input.parsley-error, textarea.parsley-error {
|
|
59 |
background-color:#F2DEDE !important;
|
60 |
border:1px solid #EED3D7 !important;
|
61 |
}
|
|
|
62 |
ul.parsley-error-list {margin:1px 0px -7px 0px}
|
63 |
|
64 |
|
11 |
label {font-size:13px}
|
12 |
.no-select {user-select:none; -o-user-select:none; -moz-user-select:none; -khtml-user-select:none; -webkit-user-select:none;}
|
13 |
hr {border:0; border-top:1px solid #ddd; border-bottom:1px solid #fafafa; margin:10px 0px 2px 0px;}
|
14 |
+
i[data-tooltip].fa-question-circle {cursor:pointer; color:#C3C3C3}
|
15 |
i[data-tooltip].fa-lightbulb-o {cursor:pointer; color:gray}
|
16 |
|
17 |
+
/*TABS*/
|
18 |
+
ul.category-tabs li {cursor: pointer}
|
|
|
|
|
|
|
|
|
19 |
|
20 |
+
/*BOXES: Expandable sections */
|
21 |
+
div.dup-box {padding:0px; display: block; background-color: #fff; border: 1px solid #e5e5e5; box-shadow: 0 1px 1px rgba(0,0,0,.04);}
|
22 |
+
div.dup-box-title {font-size: 16px; padding: 10px 0 0 10px; font-weight: bold; cursor: pointer; height:27px; margin:0px; }
|
23 |
+
div.dup-box-title:hover {background-color: #FCFCFC;}
|
24 |
+
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}
|
25 |
+
div.dup-box-panel {padding:10px 15px 10px 15px; border-top:1px solid #EEEEEE; margin:-1px 0 0 0;}
|
26 |
|
27 |
+
/*PANELS: Boxes that do not exapand */
|
28 |
+
div.dup-panel {padding:0px; display: block; background-color: #fff; border: 1px solid #e5e5e5; box-shadow: 0 1px 1px rgba(0,0,0,.04);}
|
29 |
+
div.dup-panel-title {font-size: 14px; padding: 10px 0 0 15px; font-weight: 600; height:28px; margin:0px; }
|
30 |
+
div.dup-panel-panel {padding:10px 15px 10px 15px; border-top:1px solid #EEEEEE; margin:-1px 0 0 0;}
|
31 |
+
|
32 |
+
/*PANELS: Fancy */
|
33 |
+
div.dup-box-fancy {border-radius: 4px; border:1px solid #E1E1E1; margin: 1px 0 1px 0}
|
34 |
div.dup-box-title-fancy {
|
35 |
+
padding:5px 2px 5px 8px; height:18px;
|
36 |
+
background: #eeeeee;
|
37 |
+
background: linear-gradient(to bottom, #eeeeee 0%,#e0e0e0 100%);
|
|
|
|
|
|
|
38 |
}
|
39 |
|
40 |
/*INFO-BOX:Simple box with no title */
|
49 |
div.dup-hdr-success {color:#196512; font-size:20px; font-weight:bold}
|
50 |
div.dup-hdr-error {color:#A62426; font-size:20px; font-weight:bold}
|
51 |
|
|
|
|
|
|
|
52 |
|
53 |
/*================================================
|
54 |
PARSLEY:Overrides*/
|
57 |
background-color:#F2DEDE !important;
|
58 |
border:1px solid #EED3D7 !important;
|
59 |
}
|
60 |
+
div.qtip-content {line-height:16px}
|
61 |
ul.parsley-error-list {margin:1px 0px -7px 0px}
|
62 |
|
63 |
|
assets/js/javascript.php
CHANGED
@@ -109,7 +109,7 @@ Duplicator.UI.ToggleMetaBox = function()
|
|
109 |
jQuery(document).ready(function($)
|
110 |
{
|
111 |
|
112 |
-
//INIT:
|
113 |
$("div[data-dup-tabs='true']").each(function () {
|
114 |
|
115 |
//Load Tab Setup
|
@@ -119,11 +119,10 @@ jQuery(document).ready(function($)
|
|
119 |
var $pnls = $root.children('div');
|
120 |
|
121 |
//Apply Styles
|
122 |
-
$lblKids.css('cursor', 'pointer')
|
123 |
$root.addClass('categorydiv');
|
124 |
$lblRoot.addClass('category-tabs');
|
125 |
$pnls.addClass('tabs-panel').css('display', 'none');
|
126 |
-
$lblKids.eq(0).addClass('tabs');
|
127 |
$pnls.eq(0).show();
|
128 |
|
129 |
//Attach Events
|
@@ -133,8 +132,8 @@ jQuery(document).ready(function($)
|
|
133 |
var $pnls = $(evt.target).parent().parent().children('div');
|
134 |
var index = ($(evt.target).index());
|
135 |
|
136 |
-
$lbls.removeClass('tabs');
|
137 |
-
$lbls.eq(index).addClass('tabs');
|
138 |
$pnls.hide();
|
139 |
$pnls.eq(index).show();
|
140 |
});
|
109 |
jQuery(document).ready(function($)
|
110 |
{
|
111 |
|
112 |
+
//INIT: Tabs
|
113 |
$("div[data-dup-tabs='true']").each(function () {
|
114 |
|
115 |
//Load Tab Setup
|
119 |
var $pnls = $root.children('div');
|
120 |
|
121 |
//Apply Styles
|
|
|
122 |
$root.addClass('categorydiv');
|
123 |
$lblRoot.addClass('category-tabs');
|
124 |
$pnls.addClass('tabs-panel').css('display', 'none');
|
125 |
+
$lblKids.eq(0).addClass('tabs').css('font-weight', 'bold');
|
126 |
$pnls.eq(0).show();
|
127 |
|
128 |
//Attach Events
|
132 |
var $pnls = $(evt.target).parent().parent().children('div');
|
133 |
var index = ($(evt.target).index());
|
134 |
|
135 |
+
$lbls.removeClass('tabs').css('font-weight', 'normal');
|
136 |
+
$lbls.eq(index).addClass('tabs').css('font-weight', 'bold');
|
137 |
$pnls.hide();
|
138 |
$pnls.eq(index).show();
|
139 |
});
|
define.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
if (function_exists('plugin_dir_url')) {
|
4 |
|
5 |
|
6 |
-
define('DUPLICATOR_VERSION', '1.1.
|
7 |
define("DUPLICATOR_HOMEPAGE", "http://lifeinthegrid.com/labs/duplicator");
|
8 |
define("DUPLICATOR_GIVELINK", "http://lifeinthegrid.com/partner");
|
9 |
define("DUPLICATOR_HELPLINK", "http://lifeinthegrid.com/duplicator-docs");
|
3 |
if (function_exists('plugin_dir_url')) {
|
4 |
|
5 |
|
6 |
+
define('DUPLICATOR_VERSION', '1.1.6');
|
7 |
define("DUPLICATOR_HOMEPAGE", "http://lifeinthegrid.com/labs/duplicator");
|
8 |
define("DUPLICATOR_GIVELINK", "http://lifeinthegrid.com/partner");
|
9 |
define("DUPLICATOR_HELPLINK", "http://lifeinthegrid.com/duplicator-docs");
|
duplicator.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Duplicator
|
4 |
Plugin URI: http://www.lifeinthegrid.com/duplicator/
|
5 |
Description: Create a backup of your WordPress files and database. Duplicate and move an entire site from one location to another in a few steps. Create a full snapshot of your site at any point in time.
|
6 |
-
Version: 1.1.
|
7 |
Author: LifeInTheGrid
|
8 |
Author URI: http://www.lifeinthegrid.com
|
9 |
Text Domain: duplicator
|
3 |
Plugin Name: Duplicator
|
4 |
Plugin URI: http://www.lifeinthegrid.com/duplicator/
|
5 |
Description: Create a backup of your WordPress files and database. Duplicate and move an entire site from one location to another in a few steps. Create a full snapshot of your site at any point in time.
|
6 |
+
Version: 1.1.6
|
7 |
Author: LifeInTheGrid
|
8 |
Author URI: http://www.lifeinthegrid.com
|
9 |
Text Domain: duplicator
|
installer/build/ajax.step1.php
CHANGED
@@ -225,6 +225,14 @@ if (! $_POST['cache_path']) {
|
|
225 |
array_push($replace, "'WPCACHEHOME', ''");
|
226 |
}
|
227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
$wpconfig = preg_replace($patterns, $replace, $wpconfig);
|
229 |
file_put_contents('wp-config.php', $wpconfig);
|
230 |
$wpconfig = null;
|
225 |
array_push($replace, "'WPCACHEHOME', ''");
|
226 |
}
|
227 |
|
228 |
+
if (! is_writable("{$root_path}/wp-config.php") )
|
229 |
+
{
|
230 |
+
chmod("{$root_path}/wp-config.php", 0644)
|
231 |
+
? DUPX_Log::Info('File Permission Update: wp-config.php set to 0644')
|
232 |
+
: DUPX_Log::Error('Unable to update file permissions and write to wp-config.php. Please visit the online FAQ for setting file permissions and work with your hosting provider or server administrator to enable this installer.php script to write to the wp-config.php file.');
|
233 |
+
}
|
234 |
+
|
235 |
+
|
236 |
$wpconfig = preg_replace($patterns, $replace, $wpconfig);
|
237 |
file_put_contents('wp-config.php', $wpconfig);
|
238 |
$wpconfig = null;
|
installer/build/ajax.step2.php
CHANGED
@@ -188,6 +188,9 @@ $mu_newDomain = parse_url($_POST['url_new']);
|
|
188 |
$mu_oldDomain = parse_url($_POST['url_old']);
|
189 |
$mu_newDomainHost = $mu_newDomain['host'];
|
190 |
$mu_oldDomainHost = $mu_oldDomain['host'];
|
|
|
|
|
|
|
191 |
$mu_updates = @mysqli_query($dbh, "UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
|
192 |
if ($mu_updates) {
|
193 |
DUPX_Log::Info("Update MU table blogs: domain {$mu_newDomainHost} ");
|
@@ -195,21 +198,19 @@ if ($mu_updates) {
|
|
195 |
DUPX_Log::Info("UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
|
196 |
}
|
197 |
|
198 |
-
|
199 |
/*UPDATE WP-CONFIG FILE */
|
200 |
-
$patterns = array("/'WP_HOME
|
201 |
-
"/'WP_SITEURL
|
202 |
-
"/'DOMAIN_CURRENT_SITE
|
203 |
-
|
204 |
-
$replace
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
$config_file = @file_get_contents('wp-config.php', true);
|
209 |
$config_file = preg_replace($patterns, $replace, $config_file);
|
210 |
file_put_contents('wp-config.php', $config_file);
|
211 |
|
212 |
-
|
213 |
//Create Snapshots directory
|
214 |
if (!file_exists(DUPLICATOR_SSDIR_NAME)) {
|
215 |
mkdir(DUPLICATOR_SSDIR_NAME, 0755);
|
188 |
$mu_oldDomain = parse_url($_POST['url_old']);
|
189 |
$mu_newDomainHost = $mu_newDomain['host'];
|
190 |
$mu_oldDomainHost = $mu_oldDomain['host'];
|
191 |
+
$mu_newUrlPath = parse_url($_POST['url_new'], PHP_URL_PATH);
|
192 |
+
$mu_oldUrlPath = parse_url($_POST['url_old'], PHP_URL_PATH);
|
193 |
+
|
194 |
$mu_updates = @mysqli_query($dbh, "UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
|
195 |
if ($mu_updates) {
|
196 |
DUPX_Log::Info("Update MU table blogs: domain {$mu_newDomainHost} ");
|
198 |
DUPX_Log::Info("UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
|
199 |
}
|
200 |
|
|
|
201 |
/*UPDATE WP-CONFIG FILE */
|
202 |
+
$patterns = array("/('|\")WP_HOME.*?\)\s*;/",
|
203 |
+
"/('|\")WP_SITEURL.*?\)\s*;/",
|
204 |
+
"/('|\")DOMAIN_CURRENT_SITE.*?\)\s*;/",
|
205 |
+
"/('|\")PATH_CURRENT_SITE.*?\)\s*;/");
|
206 |
+
$replace = array("'WP_HOME', '{$_POST['url_new']}');",
|
207 |
+
"'WP_SITEURL', '{$_POST['url_new']}');",
|
208 |
+
"'DOMAIN_CURRENT_SITE', {$mu_newDomainHost}');",
|
209 |
+
"'PATH_CURRENT_SITE', {$mu_newUrlPath}');");
|
210 |
$config_file = @file_get_contents('wp-config.php', true);
|
211 |
$config_file = preg_replace($patterns, $replace, $config_file);
|
212 |
file_put_contents('wp-config.php', $config_file);
|
213 |
|
|
|
214 |
//Create Snapshots directory
|
215 |
if (!file_exists(DUPLICATOR_SSDIR_NAME)) {
|
216 |
mkdir(DUPLICATOR_SSDIR_NAME, 0755);
|
installer/build/classes/class.utils.php
CHANGED
@@ -11,18 +11,17 @@ if (! defined('DUPLICATOR_INIT')) {
|
|
11 |
/** * *****************************************************
|
12 |
* CLASS::DupUtil
|
13 |
* Various Static Utility methods for working with the installer */
|
14 |
-
class DupUtil
|
|
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
/** METHOD: GET_MICROTIME
|
19 |
* Get current microtime as a float. Can be used for simple profiling.
|
20 |
*/
|
21 |
static public function get_microtime() {
|
22 |
return microtime(true);
|
23 |
}
|
24 |
|
25 |
-
/**
|
26 |
* Return a string with the elapsed time.
|
27 |
* Order of $end and $start can be switched.
|
28 |
*/
|
@@ -30,7 +29,7 @@ class DupUtil {
|
|
30 |
return sprintf("%.4f sec.", abs($end - $start));
|
31 |
}
|
32 |
|
33 |
-
/**
|
34 |
* @param string $string Thing that needs escaping
|
35 |
* @param bool $echo Do we echo or return?
|
36 |
* @return string Escaped string.
|
@@ -43,7 +42,7 @@ class DupUtil {
|
|
43 |
return $output;
|
44 |
}
|
45 |
|
46 |
-
/**
|
47 |
* Count the tables in a given database
|
48 |
* @param string $_POST['dbname'] Database to count tables in
|
49 |
*/
|
@@ -53,7 +52,7 @@ class DupUtil {
|
|
53 |
return is_null($row) ? 0 : $row[0];
|
54 |
}
|
55 |
|
56 |
-
/**
|
57 |
* Returns the table count
|
58 |
* @param string $conn A valid link resource
|
59 |
* @param string $table_name A valid table name
|
@@ -68,7 +67,7 @@ class DupUtil {
|
|
68 |
}
|
69 |
}
|
70 |
|
71 |
-
/**
|
72 |
* Adds a slash to the end of a path
|
73 |
* @param string $path A path
|
74 |
*/
|
@@ -80,7 +79,7 @@ class DupUtil {
|
|
80 |
return $path;
|
81 |
}
|
82 |
|
83 |
-
/**
|
84 |
* Makes path safe for any OS
|
85 |
* Paths should ALWAYS READ be "/"
|
86 |
* uni: /home/path/file.xt
|
@@ -95,7 +94,7 @@ class DupUtil {
|
|
95 |
return str_replace("/", "\\", $path);
|
96 |
}
|
97 |
|
98 |
-
/**
|
99 |
* PHP_SAPI for fcgi requires a data flush of at least 256
|
100 |
* bytes every 40 seconds or else it forces a script hault
|
101 |
*/
|
@@ -104,7 +103,7 @@ class DupUtil {
|
|
104 |
@flush();
|
105 |
}
|
106 |
|
107 |
-
/**
|
108 |
* A safe method used to copy larger files
|
109 |
* @param string $source The path to the file being copied
|
110 |
* @param string $destination The path to the file being made
|
@@ -122,7 +121,7 @@ class DupUtil {
|
|
122 |
fclose($sp);
|
123 |
}
|
124 |
|
125 |
-
/**
|
126 |
* Finds a string in a file and returns true if found
|
127 |
* @param array $list A list of strings to search for
|
128 |
* @param string $haystack The string to search in
|
@@ -153,7 +152,7 @@ class DupUtil {
|
|
153 |
return array();
|
154 |
}
|
155 |
|
156 |
-
/**
|
157 |
* Returns the tables for a database
|
158 |
* @param conn $dbh A database connection handle
|
159 |
* @return array $list A list of all table names
|
@@ -261,7 +260,6 @@ class DupUtil {
|
|
261 |
}
|
262 |
|
263 |
/**
|
264 |
-
* READABLE_BYTESIZE
|
265 |
* Display human readable byte sizes
|
266 |
* @param string $size The size in bytes
|
267 |
*/
|
@@ -277,7 +275,6 @@ class DupUtil {
|
|
277 |
}
|
278 |
|
279 |
/**
|
280 |
-
* PREG_REPLACEMENT_QUOTE
|
281 |
* The characters that are special in the replacement value of preg_replace are not the
|
282 |
* same characters that are special in the pattern
|
283 |
* @param string $str The string to replace on
|
@@ -288,30 +285,31 @@ class DupUtil {
|
|
288 |
|
289 |
|
290 |
/**
|
291 |
-
* IS_WEB_CONNECTED
|
292 |
* Check to see if the internet is accessable
|
|
|
|
|
293 |
* @param string $url A url e.g without prefix "ajax.googleapis.com"
|
294 |
* @param string $port A valid port number
|
295 |
* @return bool
|
296 |
*/
|
297 |
-
static
|
298 |
-
|
|
|
|
|
|
|
299 |
$port = isset($port) && is_integer($port) ? $port : 80;
|
300 |
-
$connected = @fsockopen($url, $port); //website and port
|
301 |
if ($connected){
|
302 |
-
$is_conn = true;
|
303 |
@fclose($connected);
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
return $is_conn;
|
308 |
} else {
|
309 |
return false;
|
310 |
}
|
311 |
}
|
312 |
|
313 |
/**
|
314 |
-
* GET_ZIP_FILES
|
315 |
* Returns an array of zip files found in the current directory
|
316 |
* @return array of zip files
|
317 |
*/
|
11 |
/** * *****************************************************
|
12 |
* CLASS::DupUtil
|
13 |
* Various Static Utility methods for working with the installer */
|
14 |
+
class DupUtil
|
15 |
+
{
|
16 |
|
17 |
+
/**
|
|
|
|
|
18 |
* Get current microtime as a float. Can be used for simple profiling.
|
19 |
*/
|
20 |
static public function get_microtime() {
|
21 |
return microtime(true);
|
22 |
}
|
23 |
|
24 |
+
/**
|
25 |
* Return a string with the elapsed time.
|
26 |
* Order of $end and $start can be switched.
|
27 |
*/
|
29 |
return sprintf("%.4f sec.", abs($end - $start));
|
30 |
}
|
31 |
|
32 |
+
/**
|
33 |
* @param string $string Thing that needs escaping
|
34 |
* @param bool $echo Do we echo or return?
|
35 |
* @return string Escaped string.
|
42 |
return $output;
|
43 |
}
|
44 |
|
45 |
+
/**
|
46 |
* Count the tables in a given database
|
47 |
* @param string $_POST['dbname'] Database to count tables in
|
48 |
*/
|
52 |
return is_null($row) ? 0 : $row[0];
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
* Returns the table count
|
57 |
* @param string $conn A valid link resource
|
58 |
* @param string $table_name A valid table name
|
67 |
}
|
68 |
}
|
69 |
|
70 |
+
/**
|
71 |
* Adds a slash to the end of a path
|
72 |
* @param string $path A path
|
73 |
*/
|
79 |
return $path;
|
80 |
}
|
81 |
|
82 |
+
/**
|
83 |
* Makes path safe for any OS
|
84 |
* Paths should ALWAYS READ be "/"
|
85 |
* uni: /home/path/file.xt
|
94 |
return str_replace("/", "\\", $path);
|
95 |
}
|
96 |
|
97 |
+
/**
|
98 |
* PHP_SAPI for fcgi requires a data flush of at least 256
|
99 |
* bytes every 40 seconds or else it forces a script hault
|
100 |
*/
|
103 |
@flush();
|
104 |
}
|
105 |
|
106 |
+
/**
|
107 |
* A safe method used to copy larger files
|
108 |
* @param string $source The path to the file being copied
|
109 |
* @param string $destination The path to the file being made
|
121 |
fclose($sp);
|
122 |
}
|
123 |
|
124 |
+
/**
|
125 |
* Finds a string in a file and returns true if found
|
126 |
* @param array $list A list of strings to search for
|
127 |
* @param string $haystack The string to search in
|
152 |
return array();
|
153 |
}
|
154 |
|
155 |
+
/**
|
156 |
* Returns the tables for a database
|
157 |
* @param conn $dbh A database connection handle
|
158 |
* @return array $list A list of all table names
|
260 |
}
|
261 |
|
262 |
/**
|
|
|
263 |
* Display human readable byte sizes
|
264 |
* @param string $size The size in bytes
|
265 |
*/
|
275 |
}
|
276 |
|
277 |
/**
|
|
|
278 |
* The characters that are special in the replacement value of preg_replace are not the
|
279 |
* same characters that are special in the pattern
|
280 |
* @param string $str The string to replace on
|
285 |
|
286 |
|
287 |
/**
|
|
|
288 |
* Check to see if the internet is accessable
|
289 |
+
* NOTE: fsocketopen on windows doesn't seem to honor $timeout setting.
|
290 |
+
*
|
291 |
* @param string $url A url e.g without prefix "ajax.googleapis.com"
|
292 |
* @param string $port A valid port number
|
293 |
* @return bool
|
294 |
*/
|
295 |
+
public static function is_url_active($url, $port, $timeout=5)
|
296 |
+
{
|
297 |
+
if (function_exists('fsockopen'))
|
298 |
+
{
|
299 |
+
@ini_set("default_socket_timeout", 5);
|
300 |
$port = isset($port) && is_integer($port) ? $port : 80;
|
301 |
+
$connected = @fsockopen($url, $port, $errno, $errstr, $timeout); //website and port
|
302 |
if ($connected){
|
|
|
303 |
@fclose($connected);
|
304 |
+
return true;
|
305 |
+
}
|
306 |
+
return false;
|
|
|
307 |
} else {
|
308 |
return false;
|
309 |
}
|
310 |
}
|
311 |
|
312 |
/**
|
|
|
313 |
* Returns an array of zip files found in the current directory
|
314 |
* @return array of zip files
|
315 |
*/
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: www.lifeinthegrid.com/partner
|
|
4 |
Tags: backup, restore, move, migrate, localhost, synchronize, duplicate, clone, automate, niche
|
5 |
Requires at least: 3.9
|
6 |
Tested up to: 4.4.2
|
7 |
-
Stable tag: 1.1.
|
8 |
License: GPLv2
|
9 |
|
10 |
Duplicate, clone, backup, move and transfer an entire site from one location to another.
|
4 |
Tags: backup, restore, move, migrate, localhost, synchronize, duplicate, clone, automate, niche
|
5 |
Requires at least: 3.9
|
6 |
Tested up to: 4.4.2
|
7 |
+
Stable tag: 1.1.6
|
8 |
License: GPLv2
|
9 |
|
10 |
Duplicate, clone, backup, move and transfer an entire site from one location to another.
|
uninstall.php
CHANGED
@@ -1,12 +1,6 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Fired when the plugin is uninstalled.
|
4 |
-
*
|
5 |
-
* @package Duplicator
|
6 |
-
* @author Cory Lamle
|
7 |
-
* @license GPL-2.0+
|
8 |
-
* @link http://lifeinthegrid.com
|
9 |
-
* @copyright 2013 LifeInTheGrid.com
|
10 |
*/
|
11 |
|
12 |
// If uninstall not called from WordPress, then exit
|
1 |
<?php
|
2 |
/**
|
3 |
* Fired when the plugin is uninstalled.
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
*/
|
5 |
|
6 |
// If uninstall not called from WordPress, then exit
|
views/help/gopro.php
CHANGED
@@ -92,6 +92,14 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
|
|
92 |
</td>
|
93 |
<td class="check-column"></td>
|
94 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
</tr>
|
96 |
<tr>
|
97 |
<td class="feature-column"><?php _e('Scheduled Backups', 'duplicator') ?></td>
|
@@ -99,7 +107,7 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
|
|
99 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
100 |
</tr>
|
101 |
<tr>
|
102 |
-
<td class="feature-column"><?php _e('
|
103 |
<td class="check-column"></td>
|
104 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
105 |
</tr>
|
@@ -108,14 +116,7 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
|
|
108 |
<td class="check-column"></td>
|
109 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
110 |
</tr>
|
111 |
-
|
112 |
-
<td class="feature-column">
|
113 |
-
<img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/cpanel-48.png" style="width:16px; height:12px" />
|
114 |
-
<?php _e('cPanel Connectivity', 'duplicator') ?>
|
115 |
-
</td>
|
116 |
-
<td class="check-column"></td>
|
117 |
-
<td class="check-column"><i class="fa fa-check"></i></td>
|
118 |
-
</tr-->
|
119 |
<tr>
|
120 |
<td class="feature-column"><?php _e('Email Alerts', 'duplicator') ?></td>
|
121 |
<td class="check-column"></td>
|
92 |
</td>
|
93 |
<td class="check-column"></td>
|
94 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
95 |
+
</tr>
|
96 |
+
<tr>
|
97 |
+
<td class="feature-column">
|
98 |
+
<img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/cpanel-48.png" style="width:16px; height:12px" />
|
99 |
+
<?php _e('cPanel Database API', 'duplicator') ?>
|
100 |
+
</td>
|
101 |
+
<td class="check-column"></td>
|
102 |
+
<td class="check-column"><i class="fa fa-check"></i></td>
|
103 |
</tr>
|
104 |
<tr>
|
105 |
<td class="feature-column"><?php _e('Scheduled Backups', 'duplicator') ?></td>
|
107 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
108 |
</tr>
|
109 |
<tr>
|
110 |
+
<td class="feature-column"><?php _e('Larger Package Support', 'duplicator') ?></td>
|
111 |
<td class="check-column"></td>
|
112 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
113 |
</tr>
|
116 |
<td class="check-column"></td>
|
117 |
<td class="check-column"><i class="fa fa-check"></i></td>
|
118 |
</tr>
|
119 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
<tr>
|
121 |
<td class="feature-column"><?php _e('Email Alerts', 'duplicator') ?></td>
|
122 |
<td class="check-column"></td>
|
views/help/help.php
CHANGED
@@ -38,7 +38,6 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
|
|
38 |
_e("Migrating WordPress is a complex process and the logic to make all the magic happen smoothly may not work quickly with every site. With over 30,000 plugins and a very complex server eco-system some migrations may run into issues. This is why the Duplicator includes a detailed knowledgebase that can help with many common issues. Resources to additional support, approved hosting, and alternatives to fit your needs can be found below.", 'duplicator');
|
39 |
?>
|
40 |
</td>
|
41 |
-
|
42 |
</tr>
|
43 |
</table>
|
44 |
<br/><br/>
|
@@ -70,11 +69,13 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
|
|
70 |
</div>
|
71 |
<div class="dup-support-hlp-txt">
|
72 |
<?php _e("Get Help From IT Professionals", 'duplicator'); ?>
|
73 |
-
<br
|
74 |
-
<div class="dup-support-txts-links">
|
75 |
-
<button class="button button-primary button-large" onclick="Duplicator.OpenSupportWindow();
|
76 |
-
|
|
|
77 |
</div>
|
|
|
78 |
</div>
|
79 |
</div>
|
80 |
<br style="clear:both" /><br/><br/>
|
@@ -111,9 +112,6 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
|
|
111 |
</div>
|
112 |
</div>
|
113 |
</div>
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
</div>
|
118 |
</div><br/><br/><br/><br/>
|
119 |
|
38 |
_e("Migrating WordPress is a complex process and the logic to make all the magic happen smoothly may not work quickly with every site. With over 30,000 plugins and a very complex server eco-system some migrations may run into issues. This is why the Duplicator includes a detailed knowledgebase that can help with many common issues. Resources to additional support, approved hosting, and alternatives to fit your needs can be found below.", 'duplicator');
|
39 |
?>
|
40 |
</td>
|
|
|
41 |
</tr>
|
42 |
</table>
|
43 |
<br/><br/>
|
69 |
</div>
|
70 |
<div class="dup-support-hlp-txt">
|
71 |
<?php _e("Get Help From IT Professionals", 'duplicator'); ?>
|
72 |
+
<br/>
|
73 |
+
<div class="dup-support-txts-links" style="margin:10px 0 10px 0">
|
74 |
+
<button class="button button-primary button-large" onclick="Duplicator.OpenSupportWindow();return false;">
|
75 |
+
<?php _e('Get Support!', 'duplicator') ?>
|
76 |
+
</button> <br/>
|
77 |
</div>
|
78 |
+
<small>Pro Users <a href="https://snapcreek.com/ticket" target="_blank">Support Here</a></small>
|
79 |
</div>
|
80 |
</div>
|
81 |
<br style="clear:both" /><br/><br/>
|
112 |
</div>
|
113 |
</div>
|
114 |
</div>
|
|
|
|
|
|
|
115 |
</div>
|
116 |
</div><br/><br/><br/><br/>
|
117 |
|
views/packages/main/new1.base.php
CHANGED
@@ -18,8 +18,6 @@ if (isset($_POST['action']))
|
|
18 |
DUP_Util::InitSnapshotDirectory();
|
19 |
|
20 |
$Package = DUP_Package::GetActive();
|
21 |
-
//RSR REMOVED $package_hash = $Package->MakeHash();
|
22 |
-
|
23 |
$dup_tests = array();
|
24 |
$dup_tests = DUP_Server::GetRequirements();
|
25 |
$default_name = DUP_Package::GetDefaultName();
|
@@ -77,12 +75,11 @@ TOOL BAR: STEPS -->
|
|
77 |
|
78 |
<!-- ============================
|
79 |
SYSTEM REQUIREMENTS -->
|
80 |
-
<div class="dup-box">
|
81 |
<div class="dup-box-title dup-box-title-fancy">
|
82 |
-
<i class="fa fa-check-square-o"></i>
|
83 |
<?php
|
84 |
-
|
85 |
-
|
86 |
?>
|
87 |
<div class="dup-box-arrow"></div>
|
88 |
</div>
|
18 |
DUP_Util::InitSnapshotDirectory();
|
19 |
|
20 |
$Package = DUP_Package::GetActive();
|
|
|
|
|
21 |
$dup_tests = array();
|
22 |
$dup_tests = DUP_Server::GetRequirements();
|
23 |
$default_name = DUP_Package::GetDefaultName();
|
75 |
|
76 |
<!-- ============================
|
77 |
SYSTEM REQUIREMENTS -->
|
78 |
+
<div class="dup-box dup-box-fancy">
|
79 |
<div class="dup-box-title dup-box-title-fancy">
|
|
|
80 |
<?php
|
81 |
+
_e("Requirements:", 'duplicator');
|
82 |
+
echo ($dup_tests['Success']) ? ' <div class="dup-sys-pass">Pass</div>' : ' <div class="dup-sys-fail">Fail</div>';
|
83 |
?>
|
84 |
<div class="dup-box-arrow"></div>
|
85 |
</div>
|
views/packages/main/new1.inc.form.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
form#dup-form-opts fieldset {border-radius:4px; border-top:1px solid #dfdfdf; line-height:20px}
|
7 |
form#dup-form-opts fieldset{padding:10px 15px 15px 15px; min-height:275px; margin:0 10px 10px 10px}
|
8 |
form#dup-form-opts textarea, input[type="text"] {width:100%}
|
9 |
-
form#dup-form-opts textarea#filter-dirs {height:
|
10 |
form#dup-form-opts textarea#filter-exts {height:27px}
|
11 |
textarea#package_notes {height:37px;}
|
12 |
div.dup-notes-add {float:right; margin:-4px 2px 4px 0;}
|
@@ -16,13 +16,14 @@
|
|
16 |
form#dup-form-opts div.tabs-panel{max-height:550px; padding:10px; min-height:280px}
|
17 |
form#dup-form-opts ul li.tabs{font-weight:bold}
|
18 |
ul.category-tabs li {padding:4px 15px 4px 15px}
|
19 |
-
select#archive-format {min-width:100px; margin:1px
|
20 |
span#dup-archive-filter-file {color:#A62426; display:none}
|
21 |
span#dup-archive-filter-db {color:#A62426; display:none}
|
22 |
-
div#dup-file-filter-items, div#dup-db-filter-items {padding:
|
23 |
-
|
|
|
24 |
div.dup-quick-links {font-size:11px; float:right; display:inline-block; margin-top:2px; font-style:italic}
|
25 |
-
div.dup-tabs-opts-help {font-style:italic; font-size:11px; margin:10px
|
26 |
table#dup-dbtables td {padding:1px 15px 1px 4px}
|
27 |
table.dbmysql-compatibility td{padding:2px 20px 2px 2px}
|
28 |
div.dup-store-pro {font-size:12px; font-style:italic;}
|
@@ -35,12 +36,13 @@
|
|
35 |
div.dup-installer-header-2 {font-weight:bold; border-bottom:1px solid #dfdfdf; padding-bottom:2px; width:100%}
|
36 |
label.chk-labels {display:inline-block; margin-top:1px}
|
37 |
table.dup-installer-tbl {width:95%; margin-left:20px}
|
|
|
|
|
|
|
38 |
</style>
|
39 |
|
40 |
<form id="dup-form-opts" method="post" action="?page=duplicator&tab=new2" data-validate="parsley">
|
41 |
<input type="hidden" id="dup-form-opts-action" name="action" value="">
|
42 |
-
<!-- RSR Removed the following -->
|
43 |
-
<!-- <input type="hidden" id="dup-form-opts-hash" name="package-hash" value="<?php echo $package_hash; ?>">-->
|
44 |
<div>
|
45 |
<label for="package-name"><b><?php _e('Name', 'duplicator') ?>:</b> </label>
|
46 |
<div class="dup-notes-add">
|
@@ -117,14 +119,14 @@ ARCHIVE -->
|
|
117 |
<input type="hidden" name="archive-format" value="ZIP" />
|
118 |
|
119 |
<!-- NESTED TABS -->
|
120 |
-
<div
|
121 |
-
<ul
|
122 |
-
<li
|
123 |
<li><?php _e('Database', 'duplicator') ?></li>
|
124 |
</ul>
|
125 |
|
126 |
<!-- TAB1:PACKAGE -->
|
127 |
-
<div
|
128 |
<!-- FILTERS -->
|
129 |
<?php
|
130 |
$uploads = wp_upload_dir();
|
@@ -133,6 +135,11 @@ ARCHIVE -->
|
|
133 |
<div class="dup-enable-filters">
|
134 |
<input type="checkbox" id="filter-on" name="filter-on" onclick="Duplicator.Pack.ToggleFileFilters()" <?php echo ($Package->Archive->FilterOn) ? "checked='checked'" :""; ?> />
|
135 |
<label for="filter-on"><?php _e("Enable File Filters", 'duplicator') ?></label>
|
|
|
|
|
|
|
|
|
|
|
136 |
</div>
|
137 |
|
138 |
<div id="dup-file-filter-items">
|
@@ -169,7 +176,7 @@ ARCHIVE -->
|
|
169 |
</div>
|
170 |
|
171 |
<!-- TAB2: DATABASE -->
|
172 |
-
<div
|
173 |
<div class="dup-enable-filters">
|
174 |
<table>
|
175 |
<tr>
|
@@ -349,14 +356,14 @@ INSTALLER -->
|
|
349 |
<?php _e("The installer can have these fields pre-filled at install time.", 'duplicator'); ?> <b><?php _e('All values are optional.', 'duplicator'); ?></b>
|
350 |
</div>
|
351 |
|
352 |
-
<div style="padding:10px 0 0 12px;
|
353 |
<span class="dup-pro-text">
|
354 |
<img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/cpanel-48.png" style="width:16px; height:12px" />
|
355 |
<?php _e("Connect to a cPanel database with.", 'duplicator'); ?>
|
356 |
<a href="http://snapcreek.com/duplicator/?free-file-filters" target="_blank"><?php _e('Professional', 'duplicator');?></a>
|
357 |
<i class="fa fa-lightbulb-o"
|
358 |
data-tooltip-title="<?php DUP_Util::_e("cPanel Access:"); ?>"
|
359 |
-
data-tooltip="<?php DUP_Util::_e('If your server supports cPanel API access then you can create new databases and select existing ones with Duplicator Professional.'); ?>">
|
360 |
</i>
|
361 |
</span>
|
362 |
</div>
|
6 |
form#dup-form-opts fieldset {border-radius:4px; border-top:1px solid #dfdfdf; line-height:20px}
|
7 |
form#dup-form-opts fieldset{padding:10px 15px 15px 15px; min-height:275px; margin:0 10px 10px 10px}
|
8 |
form#dup-form-opts textarea, input[type="text"] {width:100%}
|
9 |
+
form#dup-form-opts textarea#filter-dirs {height:85px}
|
10 |
form#dup-form-opts textarea#filter-exts {height:27px}
|
11 |
textarea#package_notes {height:37px;}
|
12 |
div.dup-notes-add {float:right; margin:-4px 2px 4px 0;}
|
16 |
form#dup-form-opts div.tabs-panel{max-height:550px; padding:10px; min-height:280px}
|
17 |
form#dup-form-opts ul li.tabs{font-weight:bold}
|
18 |
ul.category-tabs li {padding:4px 15px 4px 15px}
|
19 |
+
select#archive-format {min-width:100px; margin:1px 0 4px 0}
|
20 |
span#dup-archive-filter-file {color:#A62426; display:none}
|
21 |
span#dup-archive-filter-db {color:#A62426; display:none}
|
22 |
+
div#dup-file-filter-items, div#dup-db-filter-items {padding:5px 0;}
|
23 |
+
div#dup-db-filter-items {font-stretch:ultra-condensed; font-family:Calibri; }
|
24 |
+
label.dup-enable-filters {display:inline-block; margin:-5px 0 5px 0}
|
25 |
div.dup-quick-links {font-size:11px; float:right; display:inline-block; margin-top:2px; font-style:italic}
|
26 |
+
div.dup-tabs-opts-help {font-style:italic; font-size:11px; margin:10px 0 0 10px; color:#777}
|
27 |
table#dup-dbtables td {padding:1px 15px 1px 4px}
|
28 |
table.dbmysql-compatibility td{padding:2px 20px 2px 2px}
|
29 |
div.dup-store-pro {font-size:12px; font-style:italic;}
|
36 |
div.dup-installer-header-2 {font-weight:bold; border-bottom:1px solid #dfdfdf; padding-bottom:2px; width:100%}
|
37 |
label.chk-labels {display:inline-block; margin-top:1px}
|
38 |
table.dup-installer-tbl {width:95%; margin-left:20px}
|
39 |
+
|
40 |
+
/*TABS*/
|
41 |
+
ul.add-menu-item-tabs li, ul.category-tabs li {padding:3px 30px 5px}
|
42 |
</style>
|
43 |
|
44 |
<form id="dup-form-opts" method="post" action="?page=duplicator&tab=new2" data-validate="parsley">
|
45 |
<input type="hidden" id="dup-form-opts-action" name="action" value="">
|
|
|
|
|
46 |
<div>
|
47 |
<label for="package-name"><b><?php _e('Name', 'duplicator') ?>:</b> </label>
|
48 |
<div class="dup-notes-add">
|
119 |
<input type="hidden" name="archive-format" value="ZIP" />
|
120 |
|
121 |
<!-- NESTED TABS -->
|
122 |
+
<div data-dup-tabs='true'>
|
123 |
+
<ul>
|
124 |
+
<li><?php _e('Files', 'duplicator') ?></li>
|
125 |
<li><?php _e('Database', 'duplicator') ?></li>
|
126 |
</ul>
|
127 |
|
128 |
<!-- TAB1:PACKAGE -->
|
129 |
+
<div>
|
130 |
<!-- FILTERS -->
|
131 |
<?php
|
132 |
$uploads = wp_upload_dir();
|
135 |
<div class="dup-enable-filters">
|
136 |
<input type="checkbox" id="filter-on" name="filter-on" onclick="Duplicator.Pack.ToggleFileFilters()" <?php echo ($Package->Archive->FilterOn) ? "checked='checked'" :""; ?> />
|
137 |
<label for="filter-on"><?php _e("Enable File Filters", 'duplicator') ?></label>
|
138 |
+
<i class="fa fa-question-circle"
|
139 |
+
data-tooltip-title="<?php _e("File Filters:", 'duplicator'); ?>"
|
140 |
+
data-tooltip="<?php _e('File filters allow you to ignore directories and file extensions. When creating a package only include the data you '
|
141 |
+
. 'want and need. This helps to improve the overall archive build time and keep your backups simple and clean.', 'duplicator'); ?>">
|
142 |
+
</i>
|
143 |
</div>
|
144 |
|
145 |
<div id="dup-file-filter-items">
|
176 |
</div>
|
177 |
|
178 |
<!-- TAB2: DATABASE -->
|
179 |
+
<div>
|
180 |
<div class="dup-enable-filters">
|
181 |
<table>
|
182 |
<tr>
|
356 |
<?php _e("The installer can have these fields pre-filled at install time.", 'duplicator'); ?> <b><?php _e('All values are optional.', 'duplicator'); ?></b>
|
357 |
</div>
|
358 |
|
359 |
+
<div style="padding:10px 0 0 12px;">
|
360 |
<span class="dup-pro-text">
|
361 |
<img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/cpanel-48.png" style="width:16px; height:12px" />
|
362 |
<?php _e("Connect to a cPanel database with.", 'duplicator'); ?>
|
363 |
<a href="http://snapcreek.com/duplicator/?free-file-filters" target="_blank"><?php _e('Professional', 'duplicator');?></a>
|
364 |
<i class="fa fa-lightbulb-o"
|
365 |
data-tooltip-title="<?php DUP_Util::_e("cPanel Access:"); ?>"
|
366 |
+
data-tooltip="<?php DUP_Util::_e('If your server supports cPanel API access then you can create new databases and select existing ones with Duplicator Professional at install time.'); ?>">
|
367 |
</i>
|
368 |
</span>
|
369 |
</div>
|
views/tools/cleanup.php
CHANGED
@@ -96,7 +96,7 @@
|
|
96 |
<?php endif; ?>
|
97 |
|
98 |
|
99 |
-
<
|
100 |
<table class="dup-reset-opts">
|
101 |
<tr style="vertical-align:text-top">
|
102 |
<td>
|
96 |
<?php endif; ?>
|
97 |
|
98 |
|
99 |
+
<h2><?php DUP_Util::_e('Data Cleanup')?><hr size="1"/></h2>
|
100 |
<table class="dup-reset-opts">
|
101 |
<tr style="vertical-align:text-top">
|
102 |
<td>
|