backup
This commit is contained in:
1 parent
c8bcfe6bd6
commit
9c277e6db8
18 files changed
+2506
-671
No files matched your search
@@ -1,215 +1,357 @@
|
||||
|
||||
{* views/templates/admin/configure.tpl *}
|
||||
{*
|
||||
* @author EcomZone
|
||||
* @copyright EcomZone
|
||||
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
|
||||
*}
|
||||
|
||||
<div class="panel">
|
||||
<h3><i class="icon icon-cogs"></i> {l s='EcomZone Configuration' mod='ecomzone'}</h3>
|
||||
<form method="post" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">{l s='API Token' mod='ecomzone'}</label>
|
||||
<div class="col-lg-6">
|
||||
<input type="text" name="ECOMZONE_API_TOKEN"
|
||||
value="{$ECOMZONE_API_TOKEN|escape:'html':'UTF-8'}"
|
||||
class="form-control" />
|
||||
|
||||
<form id="configuration_form" class="defaultForm form-horizontal" action="{$current_url}" method="post">
|
||||
<input type="hidden" name="token" value="{$token}" />
|
||||
<div class="panel">
|
||||
<div class="form-wrapper">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">{l s='API URL' mod='ecomzone'}</label>
|
||||
<div class="col-lg-9">
|
||||
<input type="text" name="ECOMZONE_API_URL" value="{$ECOMZONE_API_URL|escape:'html':'UTF-8'}" class="form-control" required="required" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">{l s='API Token' mod='ecomzone'}</label>
|
||||
<div class="col-lg-9">
|
||||
<input type="text" name="ECOMZONE_API_TOKEN" value="{$ECOMZONE_API_TOKEN|escape:'html':'UTF-8'}" class="form-control" required="required" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-footer">
|
||||
<button type="submit" name="submitEcomZoneModule" class="btn btn-default pull-right">
|
||||
<i class="process-icon-save"></i> {l s='Save' mod='ecomzone'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="panel">
|
||||
<h3>{l s='Product Synchronization' mod='ecomzone'}</h3>
|
||||
<div class="form-wrapper">
|
||||
<p>{l s='Last synchronization:' mod='ecomzone'} <strong>{if $ECOMZONE_LAST_SYNC}{$ECOMZONE_LAST_SYNC}{else}{l s='Never' mod='ecomzone'}{/if}</strong></p>
|
||||
|
||||
<form action="{$current_url}" method="post" class="form-horizontal" id="sync-form">
|
||||
<input type="hidden" name="token" value="{$token}" />
|
||||
<div class="form-group">
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
<button type="submit" name="syncProducts" class="btn btn-primary" id="sync-button">
|
||||
<i class="process-icon-refresh"></i> {l s='Synchronize Products Now' mod='ecomzone'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">{l s='Last Sync' mod='ecomzone'}</label>
|
||||
<div class="col-lg-6">
|
||||
<p class="form-control-static">
|
||||
{if $ECOMZONE_LAST_SYNC}
|
||||
{$ECOMZONE_LAST_SYNC|escape:'html':'UTF-8'}
|
||||
{else}
|
||||
{l s='Never' mod='ecomzone'}
|
||||
{/if}
|
||||
<div id="sync-progress" style="display: none;">
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" style="width: 0%;">
|
||||
0%
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-center">
|
||||
<span id="sync-status">{l s='Processing...' mod='ecomzone'}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-footer">
|
||||
<button type="submit" name="submitEcomZoneModule" class="btn btn-default pull-right">
|
||||
<i class="process-icon-save"></i> {l s='Save' mod='ecomzone'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<h3>{l s='Product Preview' mod='ecomzone'}</h3>
|
||||
<div class="form-wrapper">
|
||||
<form action="{$current_url}" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{$token}" />
|
||||
<div class="form-group">
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
<button type="submit" name="fetchProducts" class="btn btn-default">
|
||||
<i class="process-icon-preview"></i> {l s='Preview Available Products' mod='ecomzone'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{if isset($API_PRODUCTS) && $API_PRODUCTS}
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{l s='SKU' mod='ecomzone'}</th>
|
||||
<th>{l s='Name' mod='ecomzone'}</th>
|
||||
<th>{l s='Price' mod='ecomzone'}</th>
|
||||
<th>{l s='Stock' mod='ecomzone'}</th>
|
||||
<th>{l s='Status' mod='ecomzone'}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach from=$API_PRODUCTS item=product}
|
||||
<tr>
|
||||
<td>{$product.sku|escape:'html':'UTF-8'}</td>
|
||||
<td>{$product.product_name|escape:'html':'UTF-8'}</td>
|
||||
<td>{$product.product_price|escape:'html':'UTF-8'}</td>
|
||||
<td>{$product.stock|escape:'html':'UTF-8'}</td>
|
||||
<td>
|
||||
{if isset($product.sync_status)}
|
||||
<span class="badge badge-{if $product.sync_status == 'success'}success{elseif $product.sync_status == 'error'}danger{else}info{/if}">
|
||||
{$product.sync_status|escape:'html':'UTF-8'}
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{if isset($PAGINATION)}
|
||||
<div class="text-center">
|
||||
<ul class="pagination">
|
||||
{for $page=1 to $PAGINATION.total_pages}
|
||||
<li {if $page == $PAGINATION.current_page}class="active"{/if}>
|
||||
<a href="{$current_url}&token={$token}&page={$page}">{$page}</a>
|
||||
</li>
|
||||
{/for}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if isset($SYNC_PROGRESS)}
|
||||
<div class="panel">
|
||||
<h3><i class="icon icon-cloud-download"></i> {l s='Product Import' mod='ecomzone'}</h3>
|
||||
<h3><i class="icon icon-refresh"></i> {l s='Sync Progress' mod='ecomzone'}</h3>
|
||||
<div class="panel-body">
|
||||
<form method="post" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
<button type="submit" name="fetchProducts" class="btn btn-primary">
|
||||
<i class="process-icon-download"></i> {l s='Fetch Products' mod='ecomzone'}
|
||||
</button>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" style="width: {$SYNC_PROGRESS.percentage}%;">
|
||||
{$SYNC_PROGRESS.percentage}%
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<p class="text-center">
|
||||
{l s='Processed:' mod='ecomzone'} {$SYNC_PROGRESS.processed} / {$SYNC_PROGRESS.total}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($API_PRODUCTS) && $API_PRODUCTS}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{l s='SKU' mod='ecomzone'}</th>
|
||||
<th>{l s='Name' mod='ecomzone'}</th>
|
||||
<th>{l s='Price' mod='ecomzone'}</th>
|
||||
<th>{l s='Stock' mod='ecomzone'}</th>
|
||||
<th class="text-right">{l s='Actions' mod='ecomzone'}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach from=$API_PRODUCTS item=product}
|
||||
<tr>
|
||||
<td>{$product.sku|escape:'html':'UTF-8'}</td>
|
||||
<td>{$product.product_name|escape:'html':'UTF-8'}</td>
|
||||
<td>{$product.product_price|escape:'html':'UTF-8'}</td>
|
||||
<td>{$product.stock|escape:'html':'UTF-8'}</td>
|
||||
<td class="text-right">
|
||||
<form method="post" style="display:inline;">
|
||||
<input type="hidden" name="import_sku"
|
||||
value="{$product.sku|escape:'html':'UTF-8'}" />
|
||||
<button type="submit" name="importSingleProduct"
|
||||
class="btn btn-xs btn-primary"
|
||||
title="{l s='Import this product' mod='ecomzone'}">
|
||||
<i class="icon-download"></i> {l s='Import' mod='ecomzone'}
|
||||
<div class="panel">
|
||||
<h3><i class="icon icon-list"></i> {l s='Recent Activity Log' mod='ecomzone'}</h3>
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{l s='Time' mod='ecomzone'}</th>
|
||||
<th>{l s='Level' mod='ecomzone'}</th>
|
||||
<th>{l s='Message' mod='ecomzone'}</th>
|
||||
<th>{l s='Details' mod='ecomzone'}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{if isset($ACTIVITY_LOG) && $ACTIVITY_LOG}
|
||||
{foreach from=$ACTIVITY_LOG item=log}
|
||||
<tr class="{if $log.level == 'ERROR'}danger{elseif $log.level == 'WARNING'}warning{/if}">
|
||||
<td>{$log.timestamp|escape:'html':'UTF-8'}</td>
|
||||
<td><span class="badge badge-{if $log.level == 'ERROR'}danger{elseif $log.level == 'WARNING'}warning{else}info{/if}">{$log.level|escape:'html':'UTF-8'}</span></td>
|
||||
<td>{$log.message|escape:'html':'UTF-8'}</td>
|
||||
<td>
|
||||
{if $log.details}
|
||||
<button type="button" class="btn btn-xs btn-default" data-toggle="popover" data-content="{$log.details|escape:'html':'UTF-8'}">
|
||||
<i class="icon-info-circle"></i>
|
||||
</button>
|
||||
</form>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{if isset($PAGINATION)}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<ul class="pagination">
|
||||
{if $PAGINATION.current_page > 1}
|
||||
<li>
|
||||
<a href="{$current_url|escape:'html':'UTF-8'}&page=1" title="{l s='First page' mod='ecomzone'}">
|
||||
<i class="icon-double-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{$current_url|escape:'html':'UTF-8'}&page={$PAGINATION.current_page-1}"
|
||||
title="{l s='Previous page' mod='ecomzone'}">
|
||||
<i class="icon-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
{assign var=p value=$PAGINATION.current_page-2}
|
||||
{if $p < 1}
|
||||
{assign var=p value=1}
|
||||
{/if}
|
||||
{assign var=stop value=$p+4}
|
||||
{if $stop > $PAGINATION.total_pages}
|
||||
{assign var=stop value=$PAGINATION.total_pages}
|
||||
{assign var=p value=$stop-4}
|
||||
{if $p < 1}
|
||||
{assign var=p value=1}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{while $p <= $stop}
|
||||
<li {if $p == $PAGINATION.current_page}class="active"{/if}>
|
||||
<a href="{$current_url|escape:'html':'UTF-8'}&page={$p}">{$p}</a>
|
||||
</li>
|
||||
{assign var=p value=$p+1}
|
||||
{/while}
|
||||
|
||||
{if $PAGINATION.current_page < $PAGINATION.total_pages}
|
||||
<li>
|
||||
<a href="{$current_url|escape:'html':'UTF-8'}&page={$PAGINATION.current_page+1}"
|
||||
title="{l s='Next page' mod='ecomzone'}">
|
||||
<i class="icon-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{$current_url|escape:'html':'UTF-8'}&page={$PAGINATION.total_pages}"
|
||||
title="{l s='Last page' mod='ecomzone'}">
|
||||
<i class="icon-double-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<h3><i class="icon icon-clock-o"></i> {l s='Automatic Sync' mod='ecomzone'}</h3>
|
||||
<div class="panel-body">
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">{l s='Cron URL' mod='ecomzone'}</label>
|
||||
<div class="col-lg-9">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" readonly="readonly"
|
||||
value="{$shop_url}modules/ecomzone/cron.php?token={$ECOMZONE_CRON_TOKEN|escape:'html':'UTF-8'}" />
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" onclick="selectText(this.parentElement.previousElementSibling)">
|
||||
<i class="icon-copy"></i> {l s='Copy' mod='ecomzone'}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<p class="help-block">
|
||||
{l s='Add this URL to your server\'s crontab to run every 24 hours.' mod='ecomzone'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center">{l s='No activity logs available' mod='ecomzone'}</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if isset($ECOMZONE_LOGS) && $ECOMZONE_LOGS}
|
||||
<div class="panel">
|
||||
<h3><i class="icon icon-list"></i> {l s='Recent Logs' mod='ecomzone'}</h3>
|
||||
<div class="panel-body">
|
||||
<div class="log-container" style="max-height: 400px; overflow-y: auto;">
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
{foreach from=$ECOMZONE_LOGS item=log}
|
||||
<tr>
|
||||
<td style="font-family: monospace;">{$log|escape:'html':'UTF-8'}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<script type="text/javascript">
|
||||
function selectText(element) {
|
||||
element.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
showSuccessMessage('{l s='Copied to clipboard!' mod='ecomzone'}');
|
||||
} catch (err) {
|
||||
showErrorMessage('{l s='Failed to copy. Please copy manually.' mod='ecomzone'}');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
.log-container {
|
||||
background: #f8f8f8;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
.progress {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.log-container table {
|
||||
margin-bottom: 0;
|
||||
.badge-success {
|
||||
background-color: #72C279;
|
||||
}
|
||||
.input-group .form-control {
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
.badge-warning {
|
||||
background-color: #fbbb22;
|
||||
}
|
||||
.badge-danger {
|
||||
background-color: #E08F95;
|
||||
}
|
||||
.badge-info {
|
||||
background-color: #25B9D7;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('[data-toggle="popover"]').popover({
|
||||
placement: 'left',
|
||||
trigger: 'click'
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
var syncInProgress = false;
|
||||
var currentRequest = null;
|
||||
|
||||
function showErrorMessage(message) {
|
||||
if (typeof $.growl !== 'undefined') {
|
||||
$.growl.error({ message: message });
|
||||
} else {
|
||||
alert(message);
|
||||
}
|
||||
}
|
||||
|
||||
function showSuccessMessage(message) {
|
||||
if (typeof $.growl !== 'undefined') {
|
||||
$.growl.notice({ message: message });
|
||||
}
|
||||
}
|
||||
|
||||
function handleAjaxError(xhr, status, error) {
|
||||
var errorMessage = '{l s='Connection error' mod='ecomzone'}';
|
||||
|
||||
if (xhr.responseText) {
|
||||
try {
|
||||
var response = JSON.parse(xhr.responseText);
|
||||
if (response.error) {
|
||||
errorMessage = response.error;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to parse error response:', e);
|
||||
}
|
||||
}
|
||||
|
||||
showErrorMessage(errorMessage);
|
||||
syncInProgress = false;
|
||||
$('#sync-button').prop('disabled', false);
|
||||
$('#sync-progress').hide();
|
||||
}
|
||||
|
||||
function updateProgress(progress) {
|
||||
if (!progress) return;
|
||||
|
||||
$('#sync-progress').show();
|
||||
$('.progress-bar').css('width', progress.percentage + '%').text(progress.percentage + '%');
|
||||
$('#sync-status').text('{l s='Processed:' mod='ecomzone'} ' + progress.processed + ' / ' + progress.total);
|
||||
}
|
||||
|
||||
function continueSyncProcess() {
|
||||
if (!syncInProgress) return false;
|
||||
|
||||
if (currentRequest) {
|
||||
currentRequest.abort();
|
||||
}
|
||||
|
||||
currentRequest = $.ajax({
|
||||
url: '{$current_url|escape:'javascript':'UTF-8'}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
ajax: 1,
|
||||
action: 'continueSyncProducts',
|
||||
token: '{$token|escape:'javascript':'UTF-8'}'
|
||||
},
|
||||
success: function(result) {
|
||||
if (!result) {
|
||||
showErrorMessage('{l s='Invalid server response' mod='ecomzone'}');
|
||||
syncInProgress = false;
|
||||
$('#sync-button').prop('disabled', false);
|
||||
$('#sync-progress').hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
updateProgress(result.progress);
|
||||
if (!result.progress.is_complete) {
|
||||
setTimeout(continueSyncProcess, 1000);
|
||||
} else {
|
||||
syncInProgress = false;
|
||||
$('#sync-button').prop('disabled', false);
|
||||
showSuccessMessage('{l s='Synchronization completed successfully' mod='ecomzone'}');
|
||||
window.location.reload();
|
||||
}
|
||||
} else {
|
||||
showErrorMessage(result.error || '{l s='Sync failed' mod='ecomzone'}');
|
||||
syncInProgress = false;
|
||||
$('#sync-button').prop('disabled', false);
|
||||
$('#sync-progress').hide();
|
||||
}
|
||||
},
|
||||
error: handleAjaxError
|
||||
});
|
||||
}
|
||||
|
||||
$('#sync-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
if (syncInProgress) return false;
|
||||
|
||||
syncInProgress = true;
|
||||
$('#sync-button').prop('disabled', true);
|
||||
$('#sync-progress').show();
|
||||
|
||||
if (currentRequest) {
|
||||
currentRequest.abort();
|
||||
}
|
||||
|
||||
currentRequest = $.ajax({
|
||||
url: $(this).attr('action'),
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: $(this).serialize() + '&ajax=1&syncProducts=1',
|
||||
success: function(result) {
|
||||
if (!result) {
|
||||
showErrorMessage('{l s='Invalid server response' mod='ecomzone'}');
|
||||
syncInProgress = false;
|
||||
$('#sync-button').prop('disabled', false);
|
||||
$('#sync-progress').hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
updateProgress(result.progress);
|
||||
if (!result.progress.is_complete) {
|
||||
setTimeout(continueSyncProcess, 1000);
|
||||
} else {
|
||||
syncInProgress = false;
|
||||
$('#sync-button').prop('disabled', false);
|
||||
showSuccessMessage('{l s='Synchronization completed successfully' mod='ecomzone'}');
|
||||
window.location.reload();
|
||||
}
|
||||
} else {
|
||||
showErrorMessage(result.error || '{l s='Sync failed' mod='ecomzone'}');
|
||||
syncInProgress = false;
|
||||
$('#sync-button').prop('disabled', false);
|
||||
$('#sync-progress').hide();
|
||||
}
|
||||
},
|
||||
error: handleAjaxError
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$(window).on('beforeunload', function() {
|
||||
if (currentRequest) {
|
||||
currentRequest.abort();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in new issue
Block a user