| 1 |
<?php |
| 2 |
if (!defined('ABSPATH')) { |
| 3 |
exit; |
| 4 |
} |
| 5 |
$ufg_loader_title = __('Loading Import / Export Dashboard...', 'filter-gallery'); |
| 6 |
$ufg_loader_subtitle = __('Please wait while settings configurations load', 'filter-gallery'); |
| 7 |
require_once 'loader.php'; |
| 8 |
?> |
| 9 |
<div class="wrap ufg-docs-page" style="margin: 32px 20px 0 10px;"> |
| 10 |
<style> |
| 11 |
.ufg-docs-page * { box-sizing: border-box; } |
| 12 |
html { scroll-behavior: smooth; } |
| 13 |
.ufg-docs-page .max-w-7xl { max-width: 80rem; margin-left: auto; margin-right: auto; } |
| 14 |
.ufg-docs-page .flex { display: flex; } |
| 15 |
.ufg-docs-page .flex-col { flex-direction: column; } |
| 16 |
.ufg-docs-page .items-center { align-items: center; } |
| 17 |
.ufg-docs-page .justify-between { justify-content: space-between; } |
| 18 |
.ufg-docs-page .grid { display: grid; grid-template-columns: 1fr; gap: 2rem; } |
| 19 |
.ufg-docs-page .gap-6 { gap: 1.5rem; } |
| 20 |
@media (min-width: 1024px) { |
| 21 |
.ufg-docs-page .lg\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } |
| 22 |
.ufg-docs-page .lg\:flex-row { flex-direction: row; } |
| 23 |
} |
| 24 |
.ufg-docs-page .bg-white { background-color: #ffffff; } |
| 25 |
.ufg-docs-page .rounded-2xl { border-radius: 1rem; } |
| 26 |
.ufg-docs-page .rounded-3xl { border-radius: 1.5rem; } |
| 27 |
.ufg-docs-page .shadow-sm { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); } |
| 28 |
.ufg-docs-page .p-6 { padding: 1.5rem; } |
| 29 |
.ufg-docs-page .p-8 { padding: 2rem; } |
| 30 |
.ufg-docs-page .border { border: 1px solid #e2e8f0; } |
| 31 |
.ufg-docs-page .text-gray-900 { color: #1a202c; } |
| 32 |
.ufg-docs-page .text-gray-600 { color: #4a5568; } |
| 33 |
.ufg-docs-page .text-blue-600 { color: #2563eb; } |
| 34 |
.ufg-docs-page .font-black { font-weight: 900; } |
| 35 |
.ufg-docs-page .font-bold { font-weight: 700; } |
| 36 |
.ufg-docs-page .font-medium { font-weight: 500; } |
| 37 |
.ufg-docs-page .tracking-tight { letter-spacing: -0.025em; } |
| 38 |
.ufg-docs-page .no-underline { text-decoration: none; } |
| 39 |
.ufg-docs-page .space-y-4 > * + * { margin-top: 1rem; } |
| 40 |
.ufg-docs-page .space-y-6 > * + * { margin-top: 1.5rem; } |
| 41 |
.ufg-docs-page .space-x-5 > * + * { margin-left: 1.25rem; } |
| 42 |
|
| 43 |
/* Header Icon */ |
| 44 |
.ufg-header-icon { |
| 45 |
width: 56px; |
| 46 |
height: 56px; |
| 47 |
background: #2563eb; |
| 48 |
display: flex; |
| 49 |
align-items: center; |
| 50 |
justify-content: center; |
| 51 |
border-radius: 16px; |
| 52 |
color: white; |
| 53 |
box-shadow: 0 4px 14px 0 rgba(37, 99, 235, 0.39); |
| 54 |
} |
| 55 |
|
| 56 |
/* Specific UI elements */ |
| 57 |
.ufg-btn-primary { |
| 58 |
background: #2563eb; color: white; padding: 10px 20px; border-radius: 8px; font-weight: 700; font-size: 14px; text-transform: uppercase; letter-spacing: 1px; display: inline-flex; align-items: center; box-shadow: 0 4px 10px rgba(37, 99, 235, 0.3); border: none; cursor: pointer; transition: all 0.2s; |
| 59 |
} |
| 60 |
.ufg-btn-primary:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 6px 14px rgba(37, 99, 235, 0.4); } |
| 61 |
.ufg-btn-primary:disabled { opacity: 0.6; cursor: not-allowed; box-shadow: none; transform: none; } |
| 62 |
|
| 63 |
.ufg-ie-gallery-list { |
| 64 |
max-height: 250px; |
| 65 |
overflow-y: auto; |
| 66 |
border: 1px solid #e2e8f0; |
| 67 |
border-radius: 12px; |
| 68 |
padding: 12px; |
| 69 |
background: #f8fafc; |
| 70 |
margin-bottom: 24px; |
| 71 |
} |
| 72 |
.ufg-ie-gallery-item, .ufg-ie-select-all { |
| 73 |
display: flex; |
| 74 |
align-items: center; |
| 75 |
gap: 12px; |
| 76 |
padding: 10px 14px; |
| 77 |
border-radius: 8px; |
| 78 |
cursor: pointer; |
| 79 |
transition: background 0.15s; |
| 80 |
} |
| 81 |
.ufg-ie-gallery-item:hover { background: #e2e8f0; } |
| 82 |
.ufg-ie-gallery-item code { color: #718096; font-size: 12px; background: transparent; padding: 0; } |
| 83 |
.ufg-ie-select-all { border-bottom: 1px solid #e2e8f0; margin-bottom: 6px; padding-bottom: 14px; font-weight: 700; } |
| 84 |
.ufg-ie-empty { color: #a0aec0; text-align: center; padding: 30px; } |
| 85 |
|
| 86 |
.ufg-ie-upload-area { |
| 87 |
border: 2px dashed #cbd5e0; |
| 88 |
border-radius: 16px; |
| 89 |
padding: 40px 20px; |
| 90 |
text-align: center; |
| 91 |
margin-bottom: 24px; |
| 92 |
transition: all 0.2s; |
| 93 |
cursor: pointer; |
| 94 |
background: #f8fafc; |
| 95 |
} |
| 96 |
.ufg-ie-upload-area.dragover { border-color: #2563eb; background: #ebf8ff; } |
| 97 |
.ufg-ie-upload-area .dashicons { display: block; margin: 0 auto 12px; color: #a0aec0; font-size: 48px; width: 48px; height: 48px; } |
| 98 |
.ufg-ie-filename { color: #2563eb; font-weight: 700; margin-top: 12px; } |
| 99 |
.ufg-ie-import-options { margin-bottom: 24px; padding: 14px 16px; background: #edf2f7; border-radius: 8px; font-weight: 500; font-size: 14px; color: #4a5568; } |
| 100 |
|
| 101 |
.ufg-ie-status { |
| 102 |
margin-top: 32px; |
| 103 |
background: #ffffff; |
| 104 |
border: 1px solid #e2e8f0; |
| 105 |
border-radius: 1.5rem; |
| 106 |
padding: 2rem; |
| 107 |
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); |
| 108 |
} |
| 109 |
.ufg-ie-progress-bar { |
| 110 |
height: 12px; |
| 111 |
background: #edf2f7; |
| 112 |
border-radius: 6px; |
| 113 |
overflow: hidden; |
| 114 |
margin: 16px 0 24px; |
| 115 |
} |
| 116 |
.ufg-ie-progress-fill { |
| 117 |
height: 100%; |
| 118 |
background: linear-gradient(90deg, #2563eb, #60a5fa); |
| 119 |
border-radius: 6px; |
| 120 |
transition: width 0.3s ease; |
| 121 |
} |
| 122 |
.ufg-ie-log { |
| 123 |
max-height: 250px; |
| 124 |
overflow-y: auto; |
| 125 |
font-family: 'JetBrains Mono', monospace, Consolas; |
| 126 |
font-size: 13px; |
| 127 |
color: #4a5568; |
| 128 |
line-height: 1.8; |
| 129 |
padding: 16px; |
| 130 |
background: #f8fafc; |
| 131 |
border-radius: 12px; |
| 132 |
border: 1px solid #e2e8f0; |
| 133 |
} |
| 134 |
.ufg-ie-log .success { color: #16a34a; font-weight: 600; } |
| 135 |
.ufg-ie-log .error { color: #dc2626; font-weight: 600; } |
| 136 |
.ufg-ie-log .warning { color: #d97706; } |
| 137 |
.ufg-ie-log .info { color: #2563eb; } |
| 138 |
|
| 139 |
input[type="checkbox"] { width: 18px; height: 18px; border-radius: 4px; border-color: #cbd5e0; } |
| 140 |
input[type="checkbox"]:checked { background-color: #2563eb; border-color: #2563eb; } |
| 141 |
</style> |
| 142 |
|
| 143 |
<div class="max-w-7xl"> |
| 144 |
<!-- Header --> |
| 145 |
<div class="flex flex-col lg:flex-row lg:items-center justify-between mb-10 flex-wrap gap-6" style="border-bottom: 2px solid #edf2f7; padding-bottom: 32px;"> |
| 146 |
<div class="flex items-center space-x-5"> |
| 147 |
<div class="ufg-header-icon"> |
| 148 |
<span class="dashicons dashicons-update" style="font-size: 32px; width: 32px; height: 32px; transform: rotate(90deg);"></span> |
| 149 |
</div> |
| 150 |
<div> |
| 151 |
<h1 class="font-black text-gray-900 tracking-tight" style="font-size: 42px; margin: 0; line-height: 1;">Import / Export <span style="font-size: 14px; background: #2563eb; color: white; padding: 4px 8px; border-radius: 6px; vertical-align: middle; margin-left: 10px;">v<?php echo esc_html(UFG_VERSION); ?></span></h1> |
| 152 |
<p class="text-gray-600 font-medium" style="margin-top: 8px; font-size: 16px;">Transfer your filterable galleries seamlessly between WordPress sites.</p> |
| 153 |
</div> |
| 154 |
</div> |
| 155 |
|
| 156 |
<div class="flex items-center gap-4 flex-wrap"> |
| 157 |
<a href="<?php echo esc_url(admin_url('admin.php?page=filter-gallery-pro')); ?>" class="no-underline ufg-btn-primary" style="background: #1a202c; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);"> |
| 158 |
Back to Dashboard |
| 159 |
</a> |
| 160 |
</div> |
| 161 |
</div> |
| 162 |
|
| 163 |
<div class="grid lg:grid-cols-2 gap-6"> |
| 164 |
<!-- EXPORT SECTION --> |
| 165 |
<div class="bg-white border rounded-3xl p-8 shadow-sm"> |
| 166 |
<h2 class="font-black text-gray-900" style="font-size: 28px; margin: 0 0 16px 0;">Export Galleries</h2> |
| 167 |
<p class="text-gray-600 font-medium mb-6">Select galleries to export. The exported JSON file will include all gallery settings, filters, and image URLs.</p> |
| 168 |
|
| 169 |
<div class="ufg-ie-gallery-list" id="ufg-export-gallery-list"> |
| 170 |
<?php |
| 171 |
global $wpdb; |
| 172 |
$ufg_gallery_key = "ufg_gallery_"; |
| 173 |
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- direct query is required here to scan for option patterns for gallery export |
| 174 |
$ufg_all_galleries = $wpdb->get_results( |
| 175 |
$wpdb->prepare( |
| 176 |
"SELECT option_name FROM `{$wpdb->prefix}options` WHERE `option_name` LIKE %s ORDER BY option_id ASC", |
| 177 |
'%' . $wpdb->esc_like($ufg_gallery_key) . '%' |
| 178 |
) |
| 179 |
); |
| 180 |
if (!empty($ufg_all_galleries)) { |
| 181 |
echo '<label class="ufg-ie-select-all"><input type="checkbox" id="ufg-export-select-all"> Select All</label>'; |
| 182 |
foreach ($ufg_all_galleries as $gallery) { |
| 183 |
$option_name = $gallery->option_name; |
| 184 |
$underscore_pos = strrpos($option_name, '_'); |
| 185 |
$gallery_id = substr($option_name, ($underscore_pos + 1)); |
| 186 |
$details = get_option("ufg_details_" . $gallery_id); |
| 187 |
$gallery_name = isset($details['gallery_name']) ? $details['gallery_name'] : 'Gallery #' . $gallery_id; |
| 188 |
echo '<label class="ufg-ie-gallery-item">'; |
| 189 |
echo '<input type="checkbox" name="ufg_export_ids[]" value="' . intval($gallery_id) . '"> '; |
| 190 |
echo '<span>' . esc_html($gallery_name) . ' <code>[ufg id="' . intval($gallery_id) . '"]</code></span>'; |
| 191 |
echo '</label>'; |
| 192 |
} |
| 193 |
} else { |
| 194 |
echo '<p class="ufg-ie-empty">No galleries found.</p>'; |
| 195 |
} |
| 196 |
?> |
| 197 |
</div> |
| 198 |
<button type="button" id="ufg-export-btn" class="ufg-btn-primary" <?php echo empty($ufg_all_galleries) ? 'disabled' : ''; ?>> |
| 199 |
<span class="dashicons dashicons-download" style="margin-right:8px; line-height: 1.3;"></span> Export Selected |
| 200 |
</button> |
| 201 |
</div> |
| 202 |
|
| 203 |
<!-- IMPORT SECTION --> |
| 204 |
<div class="bg-white border rounded-3xl p-8 shadow-sm"> |
| 205 |
<h2 class="font-black text-gray-900" style="font-size: 28px; margin: 0 0 16px 0;">Import Galleries</h2> |
| 206 |
<p class="text-gray-600 font-medium mb-6">Upload a previously exported JSON file to import galleries. Images will be downloaded automatically.</p> |
| 207 |
|
| 208 |
<div class="ufg-ie-upload-area" id="ufg-import-drop-zone"> |
| 209 |
<div> |
| 210 |
<span class="dashicons dashicons-media-default"></span> |
| 211 |
<p class="font-bold text-gray-900" style="font-size: 16px; margin: 10px 0 6px;">Drag & drop your .json file here</p> |
| 212 |
<p class="text-gray-600 font-medium" style="margin-bottom: 16px;">or click to browse</p> |
| 213 |
<label class="ufg-btn-primary" style="background:#cbd5e0; color:#1a202c; box-shadow:none; padding:8px 16px; font-size:12px;" for="ufg-import-file">Choose File</label> |
| 214 |
<input type="file" id="ufg-import-file" accept=".json" style="display:none;"> |
| 215 |
<p class="ufg-ie-filename" id="ufg-import-filename"></p> |
| 216 |
</div> |
| 217 |
</div> |
| 218 |
|
| 219 |
<div class="ufg-ie-import-options" id="ufg-import-options" style="display:none;"> |
| 220 |
<label class="flex items-center cursor-pointer gap-2"> |
| 221 |
<input type="checkbox" id="ufg-import-skip-images" value="1"> |
| 222 |
Skip image download (only import settings & filters) |
| 223 |
</label> |
| 224 |
</div> |
| 225 |
|
| 226 |
<button type="button" id="ufg-import-btn" class="ufg-btn-primary" disabled> |
| 227 |
<span class="dashicons dashicons-upload" style="margin-right:8px; line-height: 1.3;"></span> Import Galleries |
| 228 |
</button> |
| 229 |
</div> |
| 230 |
</div> |
| 231 |
|
| 232 |
<!-- STATUS / LOG --> |
| 233 |
<div class="ufg-ie-status" id="ufg-ie-status" style="display:none;"> |
| 234 |
<h3 class="font-black text-gray-900" id="ufg-ie-status-title" style="margin:0 0 8px; font-size: 20px;">Processing...</h3> |
| 235 |
<div class="ufg-ie-progress-bar"> |
| 236 |
<div class="ufg-ie-progress-fill" id="ufg-ie-progress-fill" style="width:0%"></div> |
| 237 |
</div> |
| 238 |
<div class="ufg-ie-log" id="ufg-ie-log"></div> |
| 239 |
</div> |
| 240 |
</div> |
| 241 |
</div> |
| 242 |
|
| 243 |
<script> |
| 244 |
jQuery(document).ready(function($) { |
| 245 |
|
| 246 |
// Select All toggle |
| 247 |
$('#ufg-export-select-all').on('change', function() { |
| 248 |
$('input[name="ufg_export_ids[]"]').prop('checked', $(this).is(':checked')); |
| 249 |
}); |
| 250 |
|
| 251 |
// EXPORT |
| 252 |
$('#ufg-export-btn').on('click', function() { |
| 253 |
var ids = []; |
| 254 |
$('input[name="ufg_export_ids[]"]:checked').each(function() { |
| 255 |
ids.push($(this).val()); |
| 256 |
}); |
| 257 |
if (ids.length === 0) { |
| 258 |
alert('Please select at least one gallery to export.'); |
| 259 |
return; |
| 260 |
} |
| 261 |
var $btn = $(this); |
| 262 |
$btn.prop('disabled', true).html('<span class="dashicons dashicons-update-alt" style="margin-right:8px; line-height: 1.3;"></span> Exporting...'); |
| 263 |
showStatus('Exporting ' + ids.length + ' gallery(ies)...'); |
| 264 |
addLog('Starting export for gallery IDs: ' + ids.join(', '), 'info'); |
| 265 |
|
| 266 |
$.ajax({ |
| 267 |
url: ajaxurl, |
| 268 |
type: 'POST', |
| 269 |
data: { |
| 270 |
action: 'ufg_export_galleries', |
| 271 |
nonce: '<?php echo esc_js(wp_create_nonce("ufg-import-export")); ?>', |
| 272 |
gallery_ids: ids |
| 273 |
}, |
| 274 |
success: function(response) { |
| 275 |
if (response.success) { |
| 276 |
// Trigger download |
| 277 |
var blob = new Blob([JSON.stringify(response.data, null, 2)], {type: 'application/json'}); |
| 278 |
var url = URL.createObjectURL(blob); |
| 279 |
var a = document.createElement('a'); |
| 280 |
var date = new Date().toISOString().slice(0,10); |
| 281 |
a.href = url; |
| 282 |
a.download = 'filter-gallery-export-' + date + '.json'; |
| 283 |
document.body.appendChild(a); |
| 284 |
a.click(); |
| 285 |
document.body.removeChild(a); |
| 286 |
URL.revokeObjectURL(url); |
| 287 |
addLog('Export completed! ' + response.data.galleries.length + ' gallery(ies) exported.', 'success'); |
| 288 |
setProgress(100); |
| 289 |
} else { |
| 290 |
addLog('Export failed: ' + (response.data || 'Unknown error'), 'error'); |
| 291 |
} |
| 292 |
$btn.prop('disabled', false).html('<span class="dashicons dashicons-download" style="margin-right:8px; line-height: 1.3;"></span> Export Selected'); |
| 293 |
}, |
| 294 |
error: function(xhr, status, err) { |
| 295 |
addLog('Export request failed: ' + err, 'error'); |
| 296 |
$btn.prop('disabled', false).html('<span class="dashicons dashicons-download" style="margin-right:8px; line-height: 1.3;"></span> Export Selected'); |
| 297 |
} |
| 298 |
}); |
| 299 |
}); |
| 300 |
|
| 301 |
// IMPORT — File handling |
| 302 |
var importFile = null; |
| 303 |
|
| 304 |
$('#ufg-import-drop-zone').on('click', function(e) { |
| 305 |
if(e.target.tagName.toLowerCase() !== 'label' && e.target.tagName.toLowerCase() !== 'input') { |
| 306 |
$('#ufg-import-file').click(); |
| 307 |
} |
| 308 |
}); |
| 309 |
|
| 310 |
$('#ufg-import-file').on('change', function(e) { |
| 311 |
if (e.target.files.length) { |
| 312 |
setImportFile(e.target.files[0]); |
| 313 |
} |
| 314 |
}); |
| 315 |
|
| 316 |
$('#ufg-import-drop-zone').on('dragover', function(e) { |
| 317 |
e.preventDefault(); |
| 318 |
$(this).addClass('dragover'); |
| 319 |
}).on('dragleave drop', function(e) { |
| 320 |
e.preventDefault(); |
| 321 |
$(this).removeClass('dragover'); |
| 322 |
if (e.type === 'drop' && e.originalEvent.dataTransfer.files.length) { |
| 323 |
setImportFile(e.originalEvent.dataTransfer.files[0]); |
| 324 |
} |
| 325 |
}); |
| 326 |
|
| 327 |
function setImportFile(file) { |
| 328 |
if (!file.name.endsWith('.json')) { |
| 329 |
alert('Please select a valid .json file.'); |
| 330 |
return; |
| 331 |
} |
| 332 |
importFile = file; |
| 333 |
$('#ufg-import-filename').text('Selected: ' + file.name + ' (' + formatBytes(file.size) + ')'); |
| 334 |
$('#ufg-import-btn').prop('disabled', false); |
| 335 |
$('#ufg-import-options').slideDown(200); |
| 336 |
} |
| 337 |
|
| 338 |
function formatBytes(bytes) { |
| 339 |
if (bytes < 1024) return bytes + ' B'; |
| 340 |
if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB'; |
| 341 |
return (bytes / 1048576).toFixed(1) + ' MB'; |
| 342 |
} |
| 343 |
|
| 344 |
// IMPORT — Process |
| 345 |
$('#ufg-import-btn').on('click', function() { |
| 346 |
if (!importFile) return; |
| 347 |
var $btn = $(this); |
| 348 |
$btn.prop('disabled', true).html('<span class="dashicons dashicons-update-alt" style="margin-right:8px; line-height: 1.3;"></span> Reading file...'); |
| 349 |
showStatus('Importing galleries...'); |
| 350 |
|
| 351 |
var reader = new FileReader(); |
| 352 |
reader.onload = function(e) { |
| 353 |
try { |
| 354 |
var data = JSON.parse(e.target.result); |
| 355 |
} catch (err) { |
| 356 |
addLog('Invalid JSON file: ' + err.message, 'error'); |
| 357 |
$btn.prop('disabled', false).html('<span class="dashicons dashicons-upload" style="margin-right:8px; line-height: 1.3;"></span> Import Galleries'); |
| 358 |
return; |
| 359 |
} |
| 360 |
|
| 361 |
if (!data.plugin || data.plugin !== 'filter-gallery-pro' || !data.galleries) { |
| 362 |
addLog('This file is not a valid Filter Gallery Pro export.', 'error'); |
| 363 |
$btn.prop('disabled', false).html('<span class="dashicons dashicons-upload" style="margin-right:8px; line-height: 1.3;"></span> Import Galleries'); |
| 364 |
return; |
| 365 |
} |
| 366 |
|
| 367 |
addLog('Found ' + data.galleries.length + ' gallery(ies) in export file (v' + data.version + ' from ' + data.source_url + ')', 'info'); |
| 368 |
$btn.html('<span class="dashicons dashicons-update-alt" style="margin-right:8px; line-height: 1.3;"></span> Importing...'); |
| 369 |
|
| 370 |
var skipImages = $('#ufg-import-skip-images').is(':checked') ? 1 : 0; |
| 371 |
|
| 372 |
// Import galleries one by one |
| 373 |
importNext(data.galleries, 0, skipImages, $btn); |
| 374 |
}; |
| 375 |
reader.readAsText(importFile); |
| 376 |
}); |
| 377 |
|
| 378 |
function importNext(galleries, idx, skipImages, $btn) { |
| 379 |
if (idx >= galleries.length) { |
| 380 |
addLog('All ' + galleries.length + ' gallery(ies) imported successfully!', 'success'); |
| 381 |
setProgress(100); |
| 382 |
$btn.prop('disabled', false).html('<span class="dashicons dashicons-upload" style="margin-right:8px; line-height: 1.3;"></span> Import Galleries'); |
| 383 |
return; |
| 384 |
} |
| 385 |
|
| 386 |
var g = galleries[idx]; |
| 387 |
var pct = Math.round(((idx) / galleries.length) * 100); |
| 388 |
setProgress(pct); |
| 389 |
var gName = (g.details && g.details.gallery_name) ? g.details.gallery_name : 'Gallery #' + g.original_id; |
| 390 |
addLog('Importing "' + gName + '" (' + (idx + 1) + '/' + galleries.length + ')...', 'info'); |
| 391 |
|
| 392 |
$.ajax({ |
| 393 |
url: ajaxurl, |
| 394 |
type: 'POST', |
| 395 |
data: { |
| 396 |
action: 'ufg_import_gallery', |
| 397 |
nonce: '<?php echo esc_js(wp_create_nonce("ufg-import-export")); ?>', |
| 398 |
gallery_data: JSON.stringify(g), |
| 399 |
skip_images: skipImages |
| 400 |
}, |
| 401 |
timeout: 120000, |
| 402 |
success: function(response) { |
| 403 |
if (response.success) { |
| 404 |
addLog('✓ "' + gName + '" imported as gallery #' + response.data.new_id + |
| 405 |
(response.data.images_imported > 0 ? ' (' + response.data.images_imported + ' images)' : "") + |
| 406 |
(response.data.images_failed > 0 ? ' (' + response.data.images_failed + ' images failed)' : ""), |
| 407 |
response.data.images_failed > 0 ? 'warning' : 'success' |
| 408 |
); |
| 409 |
} else { |
| 410 |
addLog('✗ Failed to import "' + gName + '": ' + (response.data || 'Unknown error'), 'error'); |
| 411 |
} |
| 412 |
importNext(galleries, idx + 1, skipImages, $btn); |
| 413 |
}, |
| 414 |
error: function(xhr, status, err) { |
| 415 |
addLog('✗ Request failed for "' + gName + '": ' + err, 'error'); |
| 416 |
importNext(galleries, idx + 1, skipImages, $btn); |
| 417 |
} |
| 418 |
}); |
| 419 |
} |
| 420 |
|
| 421 |
function showStatus(title) { |
| 422 |
$('#ufg-ie-status').slideDown(300); |
| 423 |
$('#ufg-ie-status-title').text(title); |
| 424 |
$('#ufg-ie-log').empty(); |
| 425 |
setProgress(0); |
| 426 |
} |
| 427 |
function addLog(msg, cls) { |
| 428 |
$('#ufg-ie-log').append('<div class="' + (cls || '') + '">' + msg + '</div>'); |
| 429 |
$('#ufg-ie-log').scrollTop($('#ufg-ie-log')[0].scrollHeight); |
| 430 |
} |
| 431 |
function setProgress(pct) { |
| 432 |
$('#ufg-ie-progress-fill').css('width', pct + '%'); |
| 433 |
} |
| 434 |
}); |
| 435 |
</script> |
| 436 |
|