Image_Optimizer_NAT-2.0-2.2/upload/admin/view/template/module/img_opti.tpl

3662 lines
196 KiB
Smarty

<?php echo $header; ?><?php echo $column_left; ?>
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<button type="submit" form="form-module" data-toggle="tooltip" title="<?php echo $button_save; ?>" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="<?php echo $cancel; ?>" data-toggle="tooltip" title="<?php echo $button_cancel; ?>" class="btn btn-default"><i class="fa fa-reply"></i></a>
</div>
<h1><?php echo $heading_title; ?></h1>
<ul class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><a href="<?php echo $breadcrumb[\'href\']; ?>"><?php echo $breadcrumb[\'text\']; ?></a></li>
<?php } ?>
</ul>
</div>
</div>
<div class="container-fluid">
<?php if (isset($error_warning) && $error_warning) { ?>
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php } ?>
<?php if (isset($success) && $success) { ?>
<div class="alert alert-success alert-dismissible"><i class="fa fa-check-circle"></i> <?php echo $success; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php } ?>
<div class="alert alert-danger"><i class="fa fa-exclamation-triangle"></i> <?php echo $entry_warning; ?></div>
<div class="panel panel-default">
<div class="panel-heading" style="background-color: #2c3e50; color: white;">
<h3 class="panel-title" style="color: white;"><i class="fa fa-cogs"></i> <?php echo $text_edit; ?></h3>
</div>
<div class="panel-body">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-module">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-settings" data-toggle="tab"><i class="fa fa-cog"></i> <?php echo $tab_settings; ?></a></li>
<li><a href="#tab-optimize" data-toggle="tab"><i class="fa fa-compress"></i> <?php echo $tab_optimize; ?></a></li>
<li><a href="#tab-cleaner" data-toggle="tab"><i class="fa fa-trash"></i> <?php echo $tab_cleaner; ?></a></li>
<li><a href="#tab-formats" data-toggle="tab"><i class="fa fa-file-image-o"></i> <?php echo $tab_formats; ?> <span class="badge" style="background:#c0392b; margin-left:4px; font-size:9px; vertical-align:middle; padding:2px 5px;">BETA</span></a></li>
<li><a href="#tab-tools" data-toggle="tab"><i class="fa fa-wrench"></i> <?php echo $tab_tools; ?> <span class="badge" style="background:#c0392b; margin-left:4px; font-size:9px; vertical-align:middle; padding:2px 5px;">BETA</span></a></li>
<li><a href="#tab-cron" data-toggle="tab"><i class="fa fa-clock-o"></i> <?php echo $tab_cron; ?> <span class="badge" style="background:#c0392b; margin-left:4px; font-size:9px; vertical-align:middle; padding:2px 5px;">BETA</span></a></li>
<li><a href="#tab-info" data-toggle="tab"><i class="fa fa-info-circle"></i> <?php echo $tab_info; ?></a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-settings">
<div class="row">
<div class="col-md-2">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6;">
<label><?php echo $entry_status; ?></label>
<select name="module_img_opti_status" class="form-control">
<option value="1" <?php if (isset($module_img_opti_status) && $module_img_opti_status) { ?>selected="selected"<?php } ?>><?php echo $text_status_on; ?></option>
<option value="0" <?php if (!isset($module_img_opti_status) || !$module_img_opti_status) { ?>selected="selected"<?php } ?>><?php echo $text_status_off; ?></option>
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6;">
<label><?php echo $entry_menu_position; ?></label>
<select name="module_img_opti_menu_position" class="form-control">
<option value="module_only" <?php if (isset($module_img_opti_menu_position) && $module_img_opti_menu_position == \'module_only\') { ?>selected="selected"<?php } ?>><?php echo $text_menu_module_only; ?></option>
<option value="header" <?php if (isset($module_img_opti_menu_position) && $module_img_opti_menu_position == \'header\') { ?>selected="selected"<?php } ?>><?php echo $text_menu_header; ?></option>
<option value="sidebar" <?php if (isset($module_img_opti_menu_position) && $module_img_opti_menu_position == \'sidebar\') { ?>selected="selected"<?php } ?>><?php echo $text_menu_sidebar; ?></option>
<option value="both" <?php if (isset($module_img_opti_menu_position) && $module_img_opti_menu_position == \'both\') { ?>selected="selected"<?php } ?>><?php echo $text_menu_both; ?></option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6;">
<label><?php echo $entry_engine; ?></label>
<select name="module_img_opti_engine" class="form-control">
<option value="gd" <?php if (isset($module_img_opti_engine) && $module_img_opti_engine == \'gd\') { ?>selected="selected"<?php } ?>><?php echo $text_engine_gd; ?></option>
<option value="imagick" <?php if (isset($module_img_opti_engine) && $module_img_opti_engine == \'imagick\') { ?>selected="selected"<?php } ?>><?php echo $text_engine_imagick; ?></option>
</select>
</div>
</div>
<div class="col-md-5">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6;">
<label><?php echo $entry_token; ?></label>
<div class="input-group">
<input type="text" name="module_img_opti_token" id="module_token" value="<?php echo $module_img_opti_token; ?>" class="form-control" placeholder="XXXX-XXXX-XXXX-XXXX">
<span class="input-group-btn">
<button type="submit" class="btn btn-info" data-toggle="tooltip" title="<?php echo $button_apply; ?>"><i class="fa fa-refresh"></i></button>
</span>
<span class="input-group-addon">
<?php if (isset($is_licensed) && $is_licensed) { ?><i class="fa fa-check text-success"></i> <?php echo $text_active; ?>
<?php } else { ?><i class="fa fa-times text-danger"></i> <?php echo $text_error; ?><?php } ?>
</span>
</div>
</div>
</div>
</div>
<fieldset style="margin-top: 20px; border: 1px solid #ddd; padding: 15px; border-radius: 4px; background: #fff;">
<legend style="width: auto; padding: 0 10px; font-size: 16px; border: none; font-weight: bold; color: #2980b9;"><?php echo $text_disk_quota_legend; ?></legend>
<div class="alert alert-info" style="margin-bottom: 15px;"><?php echo $text_disk_quota_desc; ?></div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label"><?php echo $entry_disk_quota_total; ?></label>
<input type="number" name="module_img_opti_disk_quota_total" value="<?php echo $module_img_opti_disk_quota_total; ?>" class="form-control" placeholder="20" step="0.1" min="0" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label"><?php echo $entry_disk_quota_used; ?></label>
<input type="number" name="module_img_opti_disk_quota_used" value="<?php echo $module_img_opti_disk_quota_used; ?>" class="form-control" placeholder="7.1" step="0.01" min="0" />
</div>
</div>
</div>
</fieldset>
<fieldset style="margin-top: 20px; border: 1px solid #ddd; padding: 15px; border-radius: 4px; background: #fff;">
<legend style="width: auto; padding: 0 10px; font-size: 16px; border: none; font-weight: bold; color: #2980b9;"><?php echo $text_folder_rules_title; ?></legend>
<div class="alert alert-info" style="margin-bottom: 15px;"><?php echo $text_folder_rules_desc; ?></div>
<div class="table-responsive">
<table id="folder-rules" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<td class="text-left" style="width: 30%;"><?php echo $entry_folder_path; ?></td>
<td class="text-left" style="width: 15%;"><?php echo $entry_jpg_quality; ?></td>
<td class="text-left" style="width: 15%;"><?php echo $entry_webp_quality; ?></td>
<td class="text-left" style="width: 15%;"><?php echo $entry_max_width; ?></td>
<td class="text-left" style="width: 15%;"><?php echo $entry_max_height; ?></td>
<td></td>
</tr>
</thead>
<tbody>
<?php $rule_row = 0 ; ?>
<?php if (isset($module_img_opti_folder_rules) && $module_img_opti_folder_rules) { ?>
<?php foreach ($module_img_opti_folder_rules as $rule) { ?>
<tr id="rule-row<?php echo $rule_row; ?>">
<td class="text-left">
<input type="text" name="module_img_opti_folder_rules[<?php echo $rule_row; ?>][folder]" value="<?php echo $rule[\'folder\']; ?>" placeholder="catalog/banners/" class="form-control" />
</td>
<td class="text-left">
<input type="number" name="module_img_opti_folder_rules[<?php echo $rule_row; ?>][jpg_quality]" value="<?php echo $rule[\'jpg_quality\']; ?>" placeholder="72" min="1" max="100" class="form-control" />
</td>
<td class="text-left">
<input type="number" name="module_img_opti_folder_rules[<?php echo $rule_row; ?>][webp_quality]" value="<?php echo $rule[\'webp_quality\']; ?>" placeholder="80" min="1" max="100" class="form-control" />
</td>
<td class="text-left">
<input type="number" name="module_img_opti_folder_rules[<?php echo $rule_row; ?>][max_width]" value="<?php echo $rule[\'max_width\']; ?>" placeholder="1600" min="0" class="form-control" />
</td>
<td class="text-left">
<input type="number" name="module_img_opti_folder_rules[<?php echo $rule_row; ?>][max_height]" value="<?php echo $rule[\'max_height\']; ?>" placeholder="1600" min="0" class="form-control" />
</td>
<td class="text-left">
<button type="button" onclick="$('#rule-row<?php echo $rule_row; ?>').remove();" data-toggle="tooltip" title="<?php echo $button_remove; ?>" class="btn btn-danger"><i class="fa fa-minus-circle"></i></button>
</td>
</tr>
<?php $rule_row = rule_row + 1 ; ?>
<?php } ?>
<?php } ?>
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td class="text-left">
<button type="button" onclick="addRule();" data-toggle="tooltip" title="<?php echo $button_add_rule; ?>" class="btn btn-primary"><i class="fa fa-plus-circle"></i></button>
</td>
</tr>
</tfoot>
</table>
</div>
</fieldset>
<div style="margin-top: 20px;">
<h4><?php echo $text_tech; ?></h4>
<ul class="list-group">
<li class="list-group-item"><?php echo $text_tech_gd; ?>: <?php echo $gd_enabled ? '<b class="text-success pull-right">' . $text_enabled . '</b>' : '<b class="text-danger pull-right">' . $text_disabled_error . '</b>'; ?></li>
<li class="list-group-item"><?php echo $text_tech_imagick; ?>: <?php echo $imagick_enabled ? '<b class="text-success pull-right">' . $text_supported . '</b>' : '<b class="text-warning pull-right">' . $text_no . '</b>'; ?></li>
<li class="list-group-item"><?php echo $text_tech_webp; ?>: <?php echo $webp_enabled ? '<b class="text-success pull-right">' . $text_supported . '</b>' : '<b class="text-warning pull-right">' . $text_no . '</b>'; ?></li>
</ul>
</div>
<hr style="margin:25px 0;">
<div class="row" style="margin-bottom: 20px; margin-top: 10px;">
<div class="col-md-5">
<div class="panel panel-default" style="border-color:#2c3e50;">
<div class="panel-heading" style="background:#2c3e50; color:#fff; padding:10px 15px;">
<i class="fa fa-pie-chart"></i> <b><?php echo $text_disk_usage; ?></b>
<button type="button" id="btn-load-disk" class="btn btn-xs btn-info pull-right" style="margin-top:-2px;"><i class="fa fa-refresh"></i></button>
</div>
<div class="panel-body" style="padding:15px; text-align:center;">
<canvas id="disk-pie-chart" width="220" height="220" style="max-width:220px;"></canvas>
<div id="disk-legend" style="margin-top:12px; text-align:left; font-size:13px;"></div>
<div id="disk-loading" style="color:#aaa; font-size:13px;"><?php echo $text_click_to_load; ?></div>
<div style="margin-top:15px; text-align:left; border-top:1px solid #eee; padding-top:10px; font-size:12px; color:#555;">
<label style="font-weight:normal; cursor:pointer; margin-bottom:0;">
<input type="checkbox" id="chk-auto-disk" style="vertical-align:middle; margin-top:-2px; margin-right:4px;" /> <?php echo $entry_auto_disk; ?>
</label>
</div>
</div>
</div>
</div>
<div class="col-md-7">
<div class="panel panel-default" style="border-color:#27ae60; margin-bottom:15px;">
<div class="panel-heading" style="background:#27ae60; color:#fff; padding:10px 15px;">
<i class="fa fa-bar-chart"></i> <b><?php echo $text_cumulative_stats; ?></b>
<button type="button" id="btn-reset-stats" class="btn btn-xs btn-danger pull-right" style="margin-top:-2px;" title="<?php echo $text_reset_stats; ?>"><i class="fa fa-trash"></i></button>
</div>
<div class="panel-body" style="padding:15px;">
<div class="row" style="text-align:center;">
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_total_files_opt; ?></div>
<div id="cs-files" style="font-size:26px; font-weight:bold; color:#2c3e50;"><?php echo isset($stats_files) ? $stats_files : '0'; ?></div>
</div>
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_total_saved; ?></div>
<div id="cs-saved" style="font-size:26px; font-weight:bold; color:#27ae60;"><?php echo isset($stats_saved_mb) ? $stats_saved_mb : '0.00'; ?> MB</div>
</div>
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_avg_saving_pct; ?></div>
<div id="cs-pct" style="font-size:26px; font-weight:bold; color:#e67e22;"><?php echo isset($stats_avg_pct) ? $stats_avg_pct : '0.0'; ?>%</div>
</div>
</div>
<hr style="margin:12px 0;">
<div style="font-size:12px; color:#777; text-align:center; display: flex; justify-content: space-between; align-items: center;">
<span><i class="fa fa-database"></i> <?php echo $text_stats_hint; ?></span>
<button type="button" id="btn-reset-stats" class="btn btn-default btn-xs" style="color:#c0392b; border-color:#e74c3c;" title="<?php echo $text_reset_stats; ?>"><i class="fa fa-trash-o"></i> <?php echo $text_reset_stats; ?></button>
</div>
</div>
</div>
<div class="panel panel-default" style="border-color:#8e44ad;">
<div class="panel-heading" style="background:#8e44ad; color:#fff; padding:10px 15px;">
<i class="fa fa-exchange"></i> <b><?php echo $text_export_import; ?></b>
</div>
<div class="panel-body" style="display:flex; align-items:flex-start; gap:20px; flex-wrap:wrap;">
<div>
<a href="index.php?route=module/img_opti/export_settings&token=<?php echo $token; ?>" class="btn btn-primary">
<i class="fa fa-download"></i> <?php echo $button_export_settings; ?>
</a>
<div style="font-size:11px; color:#888; margin-top:5px;"><?php echo $help_export_settings; ?></div>
</div>
<div style="border-left:1px solid #eee; padding-left:20px;">
<label class="btn btn-default" style="margin:0; cursor:pointer;">
<i class="fa fa-upload"></i> <?php echo $button_import_settings; ?>
<input type="file" id="import-settings-file" accept=".json" style="display:none;">
</label>
<span id="import-settings-status" style="margin-left:10px; font-size:13px;"></span>
<div style="font-size:11px; color:#888; margin-top:5px;"><?php echo $help_import_settings; ?></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab-optimize">
<div class="row">
<div class="col-md-5">
<div id="form-opti">
<div class="form-group">
<label><?php echo $entry_targets; ?></label>
<div class="well well-sm" style="height: 180px; overflow: auto; background: #fff; border: 1px solid #ccc;">
<div class="checkbox">
<label><input type="checkbox" name="selected_items[]" value="all" checked="checked"> <b style="color: #d35400;"><?php echo $text_all_catalog; ?></b></label>
</div>
<div class="checkbox" style="margin-left: 15px;">
<label>
<input type="checkbox" name="selected_items[]" value="root_files">
<i class="fa fa-file-image-o" style="color: #3498db;"></i>
<b style="color: #2c3e50;"><?php echo $text_root_files; ?></b>
</label>
</div>
<?php foreach ($catalog_items as $item) { ?>
<div class="checkbox" style="margin-left: 15px;">
<label>
<input type="checkbox" name="selected_items[]" value="<?php echo $item[\'path\']; ?>">
<i class="fa fa-folder" style="color: #f39c12;"></i>
<?php echo $item[\'name\']; ?>
</label>
</div>
<?php } ?>
</div>
</div>
<div class="form-group">
<label><?php echo $entry_mode; ?></label>
<select name="mode" id="input-mode" class="form-control">
<option value="copy"><?php echo $text_copy; ?></option>
<option value="replace"><?php echo $text_replace; ?></option>
</select>
</div>
<div class="form-group" id="folder-group">
<label><?php echo $entry_folder; ?></label>
<input type="text" name="copy_folder" id="copy_folder" value="catalog_new" class="form-control">
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_max_width; ?></label>
<input type="number" name="max_width" value="1600" class="form-control">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_max_height; ?></label>
<input type="number" name="max_height" value="1600" class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_batch; ?></label>
<input type="number" name="batch_size" value="200" class="form-control">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_log_limit; ?></label>
<select id="log_limit" class="form-control">
<option value="50">50</option>
<option value="100" selected="selected">100</option>
<option value="200">200</option>
<option value="500">500</option>
</select>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_threads; ?></label>
<select id="input-threads" class="form-control">
<option value="1" selected>1 (<?php echo $text_threads_optimal; ?>)</option>
<option value="2">2</option>
<option value="4">4</option>
</select>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label><span data-toggle="tooltip" title="<?php echo $help_threshold; ?>" style="cursor:help; border-bottom: 1px dashed #999;"><?php echo $entry_threshold; ?></span></label>
<input type="number" name="size_threshold" value="0" step="1" class="form-control">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_log_level; ?></label>
<select name="module_img_opti_log_level" id="input-log-level" class="form-control">
<option value="changed" <?php if (isset($module_img_opti_log_level) && $module_img_opti_log_level == \'changed\') { ?>selected="selected"<?php } ?>><?php echo $text_log_changed_only; ?></option>
<option value="all" <?php if (isset($module_img_opti_log_level) && $module_img_opti_log_level == \'all\') { ?>selected="selected"<?php } ?>><?php echo $text_log_all; ?></option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_min_savings_bytes; ?></label>
<input type="number" name="module_img_opti_min_savings_bytes" value="<?php echo $module_img_opti_min_savings_bytes; ?>" class="form-control" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_min_savings_percent; ?></label>
<input type="text" name="module_img_opti_min_savings_percent" value="<?php echo $module_img_opti_min_savings_percent; ?>" class="form-control" />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_jpg; ?></label>
<input type="number" name="jpg_quality" value="72" class="form-control">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_png; ?></label>
<input type="number" name="png_quality" value="7" class="form-control">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_webp; ?></label>
<input type="number" name="webp_quality" value="80" class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-10" id="block-start">
<button type="button" id="btn-start" class="btn btn-primary btn-lg btn-block" <?php echo !$gd_enabled ? 'disabled' : ''; ?>><i class="fa fa-play"></i> <?php echo $button_start; ?></button>
</div>
<div class="col-sm-2" id="block-reset-cache">
<button type="button" id="btn-reset-cache" class="btn btn-default btn-lg btn-block" title="<?php echo $text_reset_cache_hint; ?>"><i class="fa fa-eraser"></i></button>
</div>
<div class="col-sm-6" id="block-pause" style="display:none;">
<button type="button" id="btn-pause" class="btn btn-warning btn-lg btn-block"><i class="fa fa-pause"></i> <?php echo $button_pause; ?></button>
</div>
<div class="col-sm-6" id="block-stop" style="display:none;">
<button type="button" id="btn-stop" class="btn btn-danger btn-lg btn-block"><i class="fa fa-stop"></i> <?php echo $button_stop; ?></button>
</div>
</div>
</div>
<div class="well" id="apply-block" style="display:none; margin-top:20px; border: 1px dashed #27ae60;">
<h4 style="color:#27ae60;"><i class="fa fa-check-circle"></i> <?php echo $text_apply_title; ?> <b id="current-copy-folder"></b></h4>
<p><?php echo $text_apply_info; ?></p>
<div class="form-group">
<div class="radio">
<label><input type="radio" name="apply_backup" value="1" checked> <?php echo $entry_apply_backup; ?></label>
</div>
<div class="radio">
<label><input type="radio" name="apply_backup" value="0"> <?php echo $entry_apply_replace; ?></label>
</div>
</div>
<button type="button" id="btn-apply-changes" class="btn btn-success btn-block"><i class="fa fa-refresh"></i> <?php echo $button_apply_main; ?></button>
<button type="button" id="btn-download-copies" class="btn btn-info btn-block" style="margin-top:10px;"><i class="fa fa-download"></i> <?php echo $button_download_zip; ?></button>
<button type="button" id="btn-clear-copies" class="btn btn-default btn-block" style="margin-top:10px;"><i class="fa fa-trash"></i> <?php echo $button_delete_copies; ?></button>
</div>
</div>
<div class="col-md-7">
<h4><?php echo $text_progress; ?> <span id="progress-text">0 / 0</span></h4>
<div class="progress" style="height: 20px;">
<div id="progress-bar" class="progress-bar progress-bar-success progress-bar-striped active" style="width: 0%;"></div>
</div>
<div id="stats-block" style="display:none; background:#222; border:1px solid #444; border-radius:4px; padding:10px 15px; margin-bottom:15px; justify-content:space-between; color:#ddd; font-size:14px;">
<div><?php echo $text_old_size; ?> <b id="stat-old" style="color:#aaa;">0 B</b></div>
<div><?php echo $text_new_size; ?> <b id="stat-new" style="color:#3498db;">0 B</b></div>
<div><?php echo $text_savings; ?> <b id="stat-saved" style="color:#2ecc71; font-size:16px;">0 B (0%)</b></div>
</div>
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:5px; background: #eee; padding: 5px 10px; border-radius: 4px;">
<b style="color:#333;"><i class="fa fa-list"></i> <?php echo $text_detailed_log; ?></b>
<div id="log-pagination" style="display:none;">
<button type="button" id="btn-download-log" class="btn btn-info btn-sm" style="margin-right: 15px;" title="<?php echo $button_download_log; ?>"><i class="fa fa-download"></i> <?php echo $button_download; ?></button>
<button type="button" id="log-prev" class="btn btn-default btn-sm" title="&larr;"><i class="fa fa-chevron-left"></i></button>
<span id="log-page-info" style="margin:0 10px; font-weight:bold; color:#555;"><?php echo $text_page; ?> 1 / 1</span>
<button type="button" id="log-next" class="btn btn-default btn-sm" title="&rarr;"><i class="fa fa-chevron-right"></i></button>
</div>
</div>
<div id="log-window" style="background:#111; color:#ccc; height: 460px; overflow-y:auto; padding:10px; font-family:monospace; border-radius:4px; font-size: 13px;">
<i><?php echo $text_waiting; ?></i>
</div>
</div>
</div>
<div class="row" style="margin-top:20px;">
<div class="col-sm-12 text-right">
<button type="button" id="btn-full-cleanup" class="btn btn-danger btn-xs"><i class="fa fa-eraser"></i> <?php echo $button_full_cleanup; ?></button>
</div>
</div>
</div>
<div class="tab-pane" id="tab-cleaner">
<div class="row">
<div class="col-md-5">
<div class="alert alert-info"><i class="fa fa-info-circle"></i> <?php echo $text_cleaner_info; ?></div>
<div id="form-cleaner">
<div class="form-group">
<label><?php echo $entry_clean_targets; ?></label>
<div class="well well-sm" style="height: 250px; overflow: auto; background: #fff; border: 1px solid #ccc;">
<div class="checkbox">
<label><input type="checkbox" name="clean_items[]" value="all" checked="checked"> <b style="color: #d35400;"><?php echo $text_all_catalog; ?></b></label>
</div>
<div class="checkbox" style="margin-left: 15px;">
<label>
<input type="checkbox" name="clean_items[]" value="root_files">
<i class="fa fa-file-image-o" style="color: #3498db;"></i>
<b style="color: #2c3e50;"><?php echo $text_root_files; ?></b>
</label>
</div>
<?php foreach ($catalog_items as $item) { ?>
<div class="checkbox" style="margin-left: 15px;">
<label>
<input type="checkbox" name="clean_items[]" value="<?php echo $item[\'path\']; ?>">
<i class="fa fa-folder" style="color: #f39c12;"></i>
<?php echo $item[\'name\']; ?>
</label>
</div>
<?php } ?>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<label><input type="checkbox" name="extended_log" value="1" id="extended_log"> <b><?php echo $entry_extended_log; ?></b></label>
</div>
<div class="checkbox">
<label><input type="checkbox" name="process_broken" value="1" id="process_broken"> <b style="color: #e74c3c;"><?php echo $entry_process_broken; ?></b></label>
</div>
</div>
<div class="form-group">
<label><?php echo $entry_log_limit; ?></label>
<select id="cleaner_log_limit" class="form-control">
<option value="50">50</option>
<option value="100">100</option>
<option value="200" selected="selected">200</option>
<option value="500">500</option>
</select>
</div>
<button type="button" id="btn-scan-trash" class="btn btn-primary btn-lg btn-block"><i class="fa fa-search"></i> <?php echo $button_scan_trash; ?></button>
<br>
<div class="row">
<div class="col-sm-4" style="padding-right: 2px; padding-left: 2px;">
<button type="button" id="btn-restore-quarantine" class="btn btn-default btn-block" style="color:#2980b9; border-color:#2980b9; padding: 6px 2px; font-size: 11px;" title="<?php echo $button_restore_quarantine; ?>"><i class="fa fa-reply"></i> <?php echo $button_restore; ?></button>
</div>
<div class="col-sm-4" style="padding-right: 2px; padding-left: 2px;">
<button type="button" id="btn-empty-quarantine" class="btn btn-default btn-block" style="color:#e74c3c; border-color:#e74c3c; padding: 6px 2px; font-size: 11px;" title="<?php echo $button_empty_quarantine; ?>"><i class="fa fa-eraser"></i> <?php echo $button_empty; ?></button>
</div>
<div class="col-sm-4" style="padding-right: 2px; padding-left: 2px;">
<button type="button" id="btn-clear-backups" class="btn btn-default btn-block" style="color:#8e44ad; border-color:#8e44ad; padding: 6px 2px; font-size: 11px;" title="<?php echo $button_clear_backups; ?>"><i class="fa fa-database"></i> <?php echo $button_clear_backups_short; ?></button>
</div>
</div>
</div>
</div>
<div class="col-md-7">
<div id="cleaner-status-box" style="display:none; background:#f9f9f9; padding:15px; border:1px solid #ddd; border-radius:4px; margin-bottom:15px;">
<h4 style="margin-top:0;"><i class="fa fa-pie-chart"></i> <?php echo $text_scan_result; ?></h4>
<p id="cleaner-status-text" style="font-weight:bold; color:#333;"></p>
<div id="cleaner-action-buttons" style="display:none; margin-top:15px;">
<button type="button" id="btn-do-quarantine" class="btn btn-warning"><i class="fa fa-archive"></i> <?php echo $button_quarantine; ?></button>
<button type="button" id="btn-do-delete" class="btn btn-danger pull-right"><i class="fa fa-trash-o"></i> <?php echo $button_delete_trash; ?></button>
</div>
</div>
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:5px; background: #eee; padding: 5px 10px; border-radius: 4px;">
<b style="color:#333;"><i class="fa fa-list"></i> <?php echo $text_detailed_log; ?></b>
<div id="cleaner-log-pagination" style="display:none;">
<button type="button" id="cleaner-btn-download-log" class="btn btn-info btn-sm" style="margin-right: 15px;" title="<?php echo $button_download_log; ?>"><i class="fa fa-download"></i> <?php echo $button_download; ?></button>
<button type="button" id="cleaner-log-prev" class="btn btn-default btn-sm" title="&larr;"><i class="fa fa-chevron-left"></i></button>
<span id="cleaner-log-page-info" style="margin:0 10px; font-weight:bold; color:#555;"><?php echo $text_page; ?> 1 / 1</span>
<button type="button" id="cleaner-log-next" class="btn btn-default btn-sm" title="&rarr;"><i class="fa fa-chevron-right"></i></button>
</div>
</div>
<div id="cleaner-log-window" style="background:#111; color:#e74c3c; height: 380px; overflow-y:auto; padding:10px; font-family:monospace; border-radius:4px; font-size: 13px;">
<i style="color:#777;"><?php echo $text_waiting; ?></i>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab-formats">
<div class="alert alert-info" style="background: linear-gradient(135deg,#1a252f,#2c3e50); color: white; border: none; margin-bottom: 20px;">
<i class="fa fa-file-image-o fa-lg"></i>&nbsp; <b><?php echo $text_formats_title; ?></b> &mdash; <?php echo $text_formats_desc; ?>
</div>
<div class="row">
<div class="col-md-3">
<div class="checkbox" style="background: #fdfdfd; padding: 14px; border: 1px solid #eee; border-radius: 6px; min-height: 140px;">
<label style="font-weight: bold; font-size: 14px;">
<input type="checkbox" name="module_img_opti_support_svg" value="1" <?php if (isset($module_img_opti_support_svg) && $module_img_opti_support_svg) { ?>checked="checked"<?php } ?>>
<?php echo $entry_support_svg; ?>
</label>
<div style="font-size: 12px; color: #666; margin-top: 8px; line-height: 1.4;"><?php echo $help_support_svg; ?></div>
</div>
</div>
<div class="col-md-3">
<div class="checkbox" style="background: #fdfdfd; padding: 14px; border: 1px solid #eee; border-radius: 6px; min-height: 140px;">
<label style="font-weight: bold; font-size: 14px;">
<input type="checkbox" name="module_img_opti_support_webp" value="1" <?php if (isset($module_img_opti_support_webp) && $module_img_opti_support_webp) { ?>checked="checked"<?php } ?>>
<?php echo $entry_support_webp; ?>
</label>
<div style="font-size: 12px; color: #666; margin-top: 8px; line-height: 1.4;"><?php echo $help_support_webp; ?></div>
</div>
</div>
<div class="col-md-3">
<div class="checkbox" style="background: #fffdfd; padding: 14px; border: 1px solid #f5e79e; border-radius: 6px; min-height: 140px;">
<label style="font-weight: bold; font-size: 14px; color: #d35400;">
<input type="checkbox" name="module_img_opti_webp_on_fly" value="1" <?php if (isset($module_img_opti_webp_on_fly) && $module_img_opti_webp_on_fly) { ?>checked="checked"<?php } ?>>
<?php echo $entry_webp_on_fly; ?>
</label>
<div style="font-size: 12px; color: #666; margin-top: 8px; line-height: 1.4;"><?php echo $help_webp_on_fly; ?></div>
</div>
</div>
<div class="col-md-3">
<div class="checkbox" style="background: #fcf8ff; padding: 14px; border: 1px solid #dcd0ff; border-radius: 6px; min-height: 140px;">
<label style="font-weight: bold; font-size: 14px; color: #8e44ad;">
<input type="checkbox" name="module_img_opti_lazy_load" value="1" <?php if (isset($module_img_opti_lazy_load) && $module_img_opti_lazy_load) { ?>checked="checked"<?php } ?>>
<?php echo $entry_lazy_load; ?>
</label>
<div style="font-size: 12px; color: #666; margin-top: 8px; line-height: 1.4;"><?php echo $help_lazy_load; ?></div>
</div>
</div>
</div>
<div class="row" style="margin-top: 20px;">
<div class="col-md-12">
<div style="background: #fffdf5; padding: 16px; border: 1px solid #f39c12; border-radius: 6px;">
<div class="checkbox" style="margin-top: 0; margin-bottom: 8px;">
<label style="font-weight: bold; font-size: 14px; color: #d35400;">
<input type="checkbox" name="module_img_opti_auto_fake_jpg_guard" id="chk-auto-fake-jpg" value="1" <?php if (isset($module_img_opti_auto_fake_jpg_guard) && $module_img_opti_auto_fake_jpg_guard) { ?>checked="checked"<?php } ?>>
<i class="fa fa-shield"></i> <?php echo $entry_auto_fake_jpg_guard; ?>
</label>
</div>
<div style="font-size: 12px; color: #666; line-height: 1.4; margin-bottom: 10px;">
<?php echo $help_auto_fake_jpg_guard; ?>
</div>
<div id="fake-jpg-mode-box" style="<?php if (empty($module_img_opti_auto_fake_jpg_guard)) { ?>display: none;<?php } ?> margin-top: 10px; padding-top: 10px; border-top: 1px dashed #f0c36d; max-width: 600px;">
<label style="font-weight: bold; color: #333; font-size: 13px; margin-bottom: 5px;"><?php echo $entry_fake_jpg_mode; ?></label>
<select name="module_img_opti_fake_jpg_mode" class="form-control input-sm">
<option value="jpg" <?php if (empty($module_img_opti_fake_jpg_mode) || $module_img_opti_fake_jpg_mode == 'jpg') { ?>selected="selected"<?php } ?>><?php echo $text_fake_jpg_mode_jpg; ?></option>
<option value="png" <?php if (isset($module_img_opti_fake_jpg_mode) && $module_img_opti_fake_jpg_mode == 'png') { ?>selected="selected"<?php } ?>><?php echo $text_fake_jpg_mode_png; ?></option>
</select>
</div>
</div>
</div>
</div>
<div class="row" style="margin-top: 20px;">
<div class="col-md-4">
<div class="checkbox" style="background: #fffdf5; padding: 15px; border: 1px solid #f39c12; border-radius: 6px; min-height: 150px; margin-top: 0; margin-bottom: 0;">
<label style="font-weight: bold; font-size: 14px; color: #d35400;">
<input type="checkbox" name="module_img_opti_broken_fallback" value="1" <?php if (isset($module_img_opti_broken_fallback) && $module_img_opti_broken_fallback) { ?>checked="checked"<?php } ?>>
<?php echo $entry_broken_fallback; ?>
</label>
<div style="font-size: 12px; color: #666; margin-top: 8px; line-height: 1.4;"><?php echo $help_broken_fallback; ?></div>
</div>
</div>
<div class="col-md-8">
<div class="form-group" style="background: #fffdf5; padding: 15px; border: 1px solid #f39c12; border-radius: 6px; min-height: 150px; margin-top: 0; margin-bottom: 0;">
<label style="font-weight: bold; font-size: 14px; color: #d35400; margin-bottom: 8px;"><?php echo $entry_fallback_image; ?></label>
<div style="display: flex; align-items: center; gap: 15px;">
<a href="" id="thumb-fallback_image" data-toggle="image" class="img-thumbnail" style="margin-bottom: 0; flex-shrink: 0;"><img src="<?php echo $thumb_fallback_image; ?>" alt="" title="" data-placeholder="<?php echo $placeholder; ?>" /></a>
<input type="hidden" name="module_img_opti_fallback_image" value="<?php echo $module_img_opti_fallback_image; ?>" id="input-fallback_image" />
<div style="font-size: 12px; color: #666; line-height: 1.4;"><?php echo $help_fallback_image; ?></div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab-tools">
<div class="alert alert-info" style="background: #2c3e50; color: white; border: none;"><?php echo $text_tools_desc; ?></div>
<div class="row" style="background: #f4f6f7; padding: 15px; border-radius: 4px; border: 1px solid #dce1e5; margin: 0;">
<div class="col-sm-4">
<label><?php echo $text_tool_select; ?></label>
<select id="tool-selector" class="form-control">
<option value="">---</option>
<optgroup label="<?php echo $text_group_scanners; ?>">
<option value="broken_db"><?php echo $text_tool_broken_db; ?></option>
<option value="broken_files"><?php echo $text_tool_broken_files; ?></option>
<option value="empty_folders"><?php echo $text_tool_empty_folders; ?></option>
<option value="folder_tree"><?php echo $text_tool_folder_tree; ?></option>
<option value="html_broken"><?php echo $text_tool_html_broken; ?></option>
<option value="small_photos"><?php echo $text_tool_small_photos; ?></option>
<option value="duplicates"><?php echo $text_tool_duplicates; ?></option>
<option value="heavy_files"><?php echo $text_tool_heavy_files; ?></option>
<option value="cmyk"><?php echo $text_tool_cmyk; ?></option>
</optgroup>
<optgroup label="<?php echo $text_group_generators; ?>">
<option value="watermark"><?php echo $text_tool_watermark; ?></option>
<option value="placeholders"><?php echo $text_tool_placeholders; ?></option>
<option value="png_jpg"><?php echo $text_tool_png_jpg; ?></option>
<option value="exif"><?php echo $text_tool_exif; ?></option>
<option value="smart_cache"><?php echo $text_tool_smart_cache; ?></option>
</optgroup>
<optgroup label="<?php echo $text_group_experimental; ?>" style="color:#e74c3c;">
<option value="sanitizer"><?php echo $text_tool_sanitizer; ?></option>
<option value="translit"><?php echo $text_tool_translit; ?></option>
<option value="cache_restore"><?php echo $text_tool_cache_restore; ?></option>
</optgroup>
</select>
</div>
<div class="col-sm-8" style="padding-top: 25px;">
<div id="tool-help-text" class="alert alert-warning" style="display: none; padding: 10px; margin-bottom: 10px;"></div>
<button type="button" id="btn-run-tool" class="btn btn-primary" style="display: none;"><i class="fa fa-play"></i> <span class="btn-text"><?php echo $button_run_tool; ?></span></button>
<button type="button" id="btn-fix-tool" class="btn btn-danger" style="display: none; margin-left:10px;"><i class="fa fa-wrench"></i> <span class="btn-text"><?php echo $button_fix_tool; ?></span></button>
</div>
</div>
<div id="tool-container" style="margin-top: 20px;">
<div id="tool-ui-small_photos" class="tool-ui-block" style="display: none;">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_min_width; ?></label>
<input type="number" name="module_img_opti_min_width" value="<?php echo $module_img_opti_min_width; ?>" class="form-control" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_min_height; ?></label>
<input type="number" name="module_img_opti_min_height" value="<?php echo $module_img_opti_min_height; ?>" class="form-control" />
</div>
</div>
</div>
</div>
<div id="tool-ui-watermark" class="tool-ui-block" style="display: none;">
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label class="control-label"><?php echo $entry_wm_status; ?></label>
<select name="module_img_opti_wm_status" class="form-control">
<option value="1" <?php if (isset($module_img_opti_wm_status) && $module_img_opti_wm_status) { ?>selected="selected"<?php } ?>><?php echo $text_enabled; ?></option>
<option value="0" <?php if (!isset($module_img_opti_wm_status) || !$module_img_opti_wm_status) { ?>selected="selected"<?php } ?>><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
<div class="col-sm-4" style="padding-top: 23px;">
<button type="button" id="btn-clear-cache-wm" class="btn btn-warning btn-block" data-loading-text="<i class='fa fa-spinner fa-spin'></i> Cleaning..."><i class="fa fa-eraser"></i> <?php echo $button_clear_cache_wm; ?></button>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="table-wm-rules" style="margin-top: 15px;">
<thead>
<tr style="background:#f8f9fa;">
<th><?php echo $entry_rule_name; ?></th>
<th><?php echo $entry_wm_type; ?></th>
<th><?php echo $entry_wm_targets; ?></th>
<th class="text-center" style="width:100px;"><?php echo $entry_rule_status; ?></th>
<th class="text-right" style="width:200px;"><?php echo $entry_action; ?></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div style="margin-top: 10px; margin-bottom: 20px;">
<button type="button" class="btn btn-primary" id="btn-add-wm-rule"><i class="fa fa-plus-circle"></i> <?php echo $button_add_rule; ?></button>
</div>
</div>
</div>
<textarea name="module_img_opti_wm_rules" id="input-wm-rules" style="display:none;"><?php echo $module_img_opti_wm_rules_json; ?></textarea>
</div>
<div id="tool-ui-placeholders" class="tool-ui-block" style="display: none;">
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="control-label"><?php echo $entry_ph_status; ?></label>
<select name="module_img_opti_ph_status" class="form-control">
<option value="1" <?php if (isset($module_img_opti_ph_status) && $module_img_opti_ph_status) { ?>selected="selected"<?php } ?>><?php echo $text_enabled; ?></option>
<option value="0" <?php if (!isset($module_img_opti_ph_status) || !$module_img_opti_ph_status) { ?>selected="selected"<?php } ?>><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="table-ph-rules" style="margin-top: 15px;">
<thead>
<tr style="background:#f8f9fa;">
<th><?php echo $entry_rule_name; ?></th>
<th><?php echo $entry_wm_targets; ?></th>
<th class="text-center" style="width:100px;"><?php echo $entry_rule_status; ?></th>
<th class="text-right" style="width:200px;"><?php echo $entry_action; ?></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div style="margin-top: 10px; margin-bottom: 20px;">
<button type="button" class="btn btn-primary" id="btn-add-ph-rule"><i class="fa fa-plus-circle"></i> <?php echo $button_add_rule; ?></button>
</div>
</div>
</div>
<textarea name="module_img_opti_ph_rules" id="input-ph-rules" style="display:none;"><?php echo $module_img_opti_ph_rules_json; ?></textarea>
</div>
<div id="tool-ui-sanitizer" class="tool-ui-block" style="display: none;">
<div class="row" style="background: #fff; padding: 15px; border-radius: 4px; border: 1px solid #ddd; margin-bottom: 15px; margin-left: 0; margin-right: 0;">
<div class="col-sm-4">
<div class="checkbox">
<label>
<input type="checkbox" name="module_img_opti_sz_translit" value="1" <?php if (isset($module_img_opti_sz_translit) && $module_img_opti_sz_translit) { ?>checked="checked"<?php } ?> />
<b><?php echo $entry_sz_translit; ?></b>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="module_img_opti_sz_spaces" value="1" <?php if (isset($module_img_opti_sz_spaces) && $module_img_opti_sz_spaces) { ?>checked="checked"<?php } ?> />
<b><?php echo $entry_sz_spaces; ?></b>
</label>
</div>
</div>
<div class="col-sm-4">
<div class="checkbox">
<label>
<input type="checkbox" name="module_img_opti_sz_special" value="1" <?php if (isset($module_img_opti_sz_special) && $module_img_opti_sz_special) { ?>checked="checked"<?php } ?> />
<b><?php echo $entry_sz_special; ?></b>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="module_img_opti_sz_lowercase_name" value="1" <?php if (isset($module_img_opti_sz_lowercase_name) && $module_img_opti_sz_lowercase_name) { ?>checked="checked"<?php } ?> />
<b><?php echo $entry_sz_lowercase_name; ?></b>
</label>
</div>
</div>
<div class="col-sm-4">
<div class="checkbox">
<label>
<input type="checkbox" name="module_img_opti_sz_lowercase_ext" value="1" <?php if (isset($module_img_opti_sz_lowercase_ext) && $module_img_opti_sz_lowercase_ext) { ?>checked="checked"<?php } ?> />
<b><?php echo $entry_sz_lowercase_ext; ?></b>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="module_img_opti_sz_normalize_ext" value="1" <?php if (isset($module_img_opti_sz_normalize_ext) && $module_img_opti_sz_normalize_ext) { ?>checked="checked"<?php } ?> />
<b><?php echo $entry_sz_normalize_ext; ?></b>
</label>
</div>
</div>
</div>
<div class="row" style="margin-top: 10px;">
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_sanitizer_limit; ?></label>
<input type="number" name="module_img_opti_sanitizer_limit" value="<?php echo $module_img_opti_sanitizer_limit; ?>" class="form-control" />
</div>
</div>
</div>
</div>
<div id="tool-ui-heavy_files" class="tool-ui-block" style="display: none;">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_heavy_files_limit; ?></label>
<input type="text" name="module_img_opti_heavy_limit" value="<?php echo $module_img_opti_heavy_limit; ?>" class="form-control" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label><?php echo $entry_heavy_files_min_size; ?> (KB)</label>
<input type="number" name="module_img_opti_heavy_min_size" value="<?php echo $module_img_opti_heavy_min_size; ?>" class="form-control" min="0" />
</div>
</div>
</div>
</div>
<div id="tool-ui-png_jpg" class="tool-ui-block" style="display: none;">
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_png_jpg_limit; ?></label>
<input type="number" name="module_img_opti_png_jpg_limit" value="<?php echo $module_img_opti_png_jpg_limit; ?>" class="form-control" min="1" style="width:120px; display:inline-block;" />
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label><?php echo $entry_png_jpg_min_size; ?> (KB)</label>
<input type="number" name="module_img_opti_png_jpg_min_size" value="<?php echo $module_img_opti_png_jpg_min_size; ?>" class="form-control" min="0" style="width:120px; display:inline-block;" />
</div>
</div>
</div>
</div>
<div id="grid-container" style="display: none; margin-top: 20px;">
<div class="panel panel-default" style="border: 1px solid #2c3e50;">
<div class="panel-heading" style="background-color: #2c3e50; color: white; display: flex; justify-content: space-between; align-items: center; padding: 10px 15px;">
<h4 class="panel-title" style="color: white; margin: 0;"><i class="fa fa-table"></i> <?php echo $text_grid_results; ?></h4>
<div style="display:flex; align-items:center; gap:8px;">
<label style="color:#ccc; margin:0; font-size:12px; white-space:nowrap;"><?php echo $entry_per_page; ?>:</label>
<input type="number" id="grid-per-page" class="form-control input-sm" value="25" min="1" max="9999" style="width:70px; display:inline-block;">
<button type="button" id="btn-grid-download" class="btn btn-info btn-xs"><i class="fa fa-download"></i> CSV</button>
</div>
</div>
<div class="panel-body">
<div id="grid-warnings" style="margin-bottom: 15px;"></div>
<div class="table-responsive">
<table class="table table-bordered table-hover" id="grid-table">
<thead>
<tr id="grid-thead"></tr>
</thead>
<tbody id="grid-tbody"></tbody>
</table>
</div>
<div class="row" style="margin-top: 15px;">
<div class="col-sm-6" id="grid-pagination"></div>
<div class="col-sm-6 text-right" id="grid-bulk-actions" style="display: none;">
<div class="form-inline">
<label style="margin-right: 5px; font-weight: bold; color: #555;"><?php echo $text_bulk_action; ?>:</label>
<select id="grid-bulk-select" class="form-control input-sm" style="margin-right: 5px;"></select>
<button type="button" id="btn-grid-apply-bulk" class="btn btn-warning btn-sm"><?php echo $button_apply; ?></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab-cron">
<div class="alert alert-info" style="background: #2c3e50; color: white; border: none;">
<i class="fa fa-clock-o"></i> <b><?php echo $text_cron_title; ?></b> <?php echo $text_cron_desc; ?><br>
<code style="display:inline-block; margin-top:5px; background:#fff; padding:5px 10px; color:#333;">wget -q -O - "<?php echo str_replace(\'image/catalog\', \'\', $catalog_url); ?>index.php?route=module/img_opti_cron&amp;key=<?php echo $module_img_opti_token; ?>" &gt;/dev/null 2&gt;&amp;1</code>
</div>
<div class="row">
<div class="col-sm-12">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="table-cron-tasks" style="margin-top: 15px;">
<thead>
<tr style="background:#f8f9fa;">
<th><?php echo $entry_cron_task_name; ?></th>
<th><?php echo $text_cron_folder_scan; ?></th>
<th><?php echo $entry_cron_task_summary; ?></th>
<th class="text-center" style="width:100px;"><?php echo $entry_rule_status; ?></th>
<th class="text-right" style="width:200px;"><?php echo $entry_action; ?></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div style="margin-top: 10px; margin-bottom: 20px;">
<button type="button" class="btn btn-primary" id="btn-add-cron-task"><i class="fa fa-plus-circle"></i> <?php echo $button_add_cron_task; ?></button>
</div>
</div>
</div>
<textarea name="module_img_opti_cron_tasks" id="input-cron-tasks" style="display:none;"><?php echo $module_img_opti_cron_tasks_json; ?></textarea>
<div class="panel panel-default">
<div class="panel-heading" style="background:#f39c12; color:#fff;">
<h4 class="panel-title"><i class="fa fa-lightbulb-o"></i> <?php echo $text_cron_recommendations; ?></h4>
</div>
<div class="panel-body">
<?php echo $text_cron_recommendations_desc; ?>
</div>
</div>
</div>
<div class="tab-pane" id="tab-info">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="alert alert-success" style="font-size: 15px; margin-top: 20px; line-height: 1.6; border-left: 5px solid #3498db;">
<h3 style="margin-top: 0; color: #2c3e50;"><i class="fa fa-rocket"></i> <?php echo $text_promo_title; ?></h3>
<p style="color: #333;"><?php echo $text_promo_desc; ?></p>
<p style="color: #333;"><?php echo $text_support; ?> <a href="mailto:info@nat.od.ua">info@nat.od.ua</a></p>
<div style="margin-top: 15px; margin-bottom: 5px;">
<a href="http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html" target="_blank" class="btn btn-primary btn-lg" style="border-radius: 6px; font-weight: bold; background: linear-gradient(135deg, #2980b9, #3498db); border: none; box-shadow: 0 4px 12px rgba(41, 128, 185, 0.3);">
<i class="fa fa-book"></i> <?php echo $button_online_instruction; ?>
</a>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-cogs text-primary"></i> <?php echo $text_mod_cat_opt; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_cat_opt_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-calendar-plus-o text-primary"></i> <?php echo $text_mod_new_arrivals; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_new_arrivals_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fdfdfd; border-color:#bce8f1;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-image text-info"></i> <?php echo $text_mod_img_opt; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_img_opt_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-search text-primary"></i> <?php echo $text_mod_dom_scan; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_dom_scan_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-bar-chart text-primary"></i> <?php echo $text_mod_poll; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_poll_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-exchange text-primary"></i> <?php echo $text_mod_im_ex; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_im_ex_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-database text-primary"></i> <?php echo $text_mod_db_opt; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_db_opt_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-user-secret text-primary"></i> <?php echo $text_mod_admin_tools; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_admin_tools_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-tags text-primary"></i> <?php echo $text_mod_utm_tracker; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_mod_utm_tracker_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-bullhorn text-primary"></i> <?php echo $text_info_title_promo_top_bar; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_info_desc_promo_top_bar; ?></p>
</div>
</div>
</div>
<div class="text-center" style="margin-top: 20px;">
<a href="https://www.opencart.com/index.php?route=marketplace/extension&filter_member=nat.odua" target="_blank" class="btn btn-primary btn-lg"><i class="fa fa-shopping-cart"></i> <?php echo $button_more; ?></a>
<a href="https://opencartforum.com/ru/files/developer/725443-nertyod/" target="_blank" class="btn btn-info btn-lg" style="margin-left: 10px;"><i class="fa fa-comments"></i> <?php echo $button_more_forum; ?></a>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var urlParams = new URLSearchParams(window.location.search);
var tokenParam = urlParams.has('token') ? 'token=' + urlParams.get('token') : 'token=' + urlParams.get('token');
var toolDescriptions = {
'broken_db': '<?php echo $help_tool_broken_db; ?>',
'broken_files': '<?php echo $help_tool_broken_files; ?>',
'empty_folders': '<?php echo $help_tool_empty_folders; ?>',
'folder_tree': '<?php echo $help_tool_folder_tree; ?>',
'html_broken': '<?php echo $help_tool_html_broken; ?>',
'small_photos': '<?php echo $help_tool_small_photos; ?>',
'duplicates': '<?php echo $help_tool_duplicates; ?>',
'watermark': '<?php echo $help_tool_watermark; ?>',
'placeholders': '<?php echo $help_tool_placeholders; ?>',
'png_jpg': '<?php echo $help_tool_png_jpg; ?>',
'exif': '<?php echo $help_tool_exif; ?>',
'smart_cache': '<?php echo $help_tool_smart_cache; ?>',
'translit': '<?php echo $help_tool_translit; ?>',
'sanitizer': '<?php echo $help_tool_sanitizer; ?>',
'cache_restore': '<?php echo $help_tool_cache_restore; ?>',
'cmyk': '<?php echo $help_tool_cmyk; ?>',
'heavy_files': '<?php echo $help_tool_heavy_files; ?>'
};
var gridData = [];
var gridHeaders = [];
var gridPage = 1;
var gridLimit = 25;
var currentTool = '';
function saveScanCache() {
if (gridData && gridData.length > 0) {
sessionStorage.setItem('nat_scan_cache_img_opti', JSON.stringify({
rows: gridData,
headers: gridHeaders,
tool: currentTool,
page: gridPage,
per_page: $('#grid-per-page').val(),
backup_available: $('#grid-warnings').find('.alert-info').length > 0,
quarantine_available: $('#grid-warnings').find('.alert-warning').length > 0
}));
} else {
sessionStorage.removeItem('nat_scan_cache_img_opti');
}
}
function showToolUI(tool) {
$('.tool-ui-block').hide();
if (tool && toolDescriptions[tool]) {
$('#tool-help-text').html('<i class="fa fa-info-circle"></i> ' + toolDescriptions[tool]).show();
} else {
$('#tool-help-text').hide();
}
if (tool) {
if (tool == 'small_photos') {
$('#tool-ui-small_photos').show();
} else if (tool == 'watermark') {
$('#tool-ui-watermark').show();
} else if (tool == 'placeholders') {
$('#tool-ui-placeholders').show();
} else if (tool == 'sanitizer') {
$('#tool-ui-sanitizer').show();
} else if (tool == 'heavy_files') {
$('#tool-ui-heavy_files').show();
} else if (tool == 'png_jpg') {
$('#tool-ui-png_jpg').show();
}
if (tool == 'watermark') {
$('#btn-run-tool').hide();
} else {
$('#btn-run-tool').show().find('.btn-text').text('<?php echo $button_scan_tool; ?>');
}
}
}
function restoreScanCache() {
var cached = sessionStorage.getItem('nat_scan_cache_img_opti');
if (!cached) return;
try {
var data = JSON.parse(cached);
if (data && data.rows && data.headers) {
currentTool = data.tool || '';
gridData = data.rows;
gridHeaders = data.headers;
gridPage = data.page || 1;
if (data.per_page) {
$('#grid-per-page').val(data.per_page);
gridLimit = parseInt(data.per_page, 10) || 25;
}
if (data.tool) {
$('#tool-selector').val(data.tool);
showToolUI(data.tool);
}
var thead = $('#grid-thead');
thead.empty();
thead.append('<th style="width: 1px;" class="text-center"><input type="checkbox" id="grid-select-all" /></th>');
$.each(gridHeaders, function(i, h) {
thead.append('<th>' + h + '</th>');
});
var warnings = $('#grid-warnings');
warnings.empty();
if (data.backup_available) {
warnings.append('<div class="alert alert-info" style="margin-bottom:5px;"><i class="fa fa-database"></i> <?php echo $text_backup_will_be_created; ?></div>');
}
if (data.quarantine_available) {
warnings.append('<div class="alert alert-warning" style="margin-bottom:5px;"><i class="fa fa-archive"></i> <?php echo $text_quarantine_will_be_created; ?></div>');
}
$('#grid-container').show();
renderGrid();
}
} catch (e) {
console.error('Error restoring scan cache', e);
}
}
function updateSelectAllHeaderState() {
var allChecked = true;
var start = (gridPage - 1) * gridLimit;
var end = start + gridLimit;
var sliced = gridData.slice(start, end);
if (sliced.length === 0) {
allChecked = false;
} else {
$.each(sliced, function(i, row) {
if (!row.selected) {
allChecked = false;
return false;
}
});
}
$('#grid-select-all').prop('checked', allChecked);
}
function renderGrid() {
var start = (gridPage - 1) * gridLimit;
var end = start + gridLimit;
var sliced = gridData.slice(start, end);
var tbody = $('#grid-tbody');
tbody.empty();
if (gridData.length === 0) {
tbody.html('<tr><td colspan="' + (gridHeaders.length + 1) + '" class="text-center text-success"><b><?php echo $text_clean_empty; ?></b></td></tr>');
$('#grid-pagination').empty();
$('#grid-bulk-actions').hide();
$('#btn-fix-tool').hide();
return;
}
$('#grid-bulk-actions').show();
$('#btn-fix-tool').show();
var allActions = {};
$.each(gridData, function(i, row) {
if (row.selected === undefined) {
row.selected = true;
}
$.each(row.actions, function(act_key, act_name) {
allActions[act_key] = act_name;
});
});
var bulkSelect = $('#grid-bulk-select');
bulkSelect.empty();
$.each(allActions, function(key, val) {
bulkSelect.append('<option value="' + key + '">' + val + '</option>');
});
$.each(sliced, function(i, row) {
var tr = $('<tr></tr>');
var chk = $('<input type="checkbox" class="grid-row-checkbox" data-id="' + row.id + '" />');
if (row.selected) {
chk.prop('checked', true);
}
tr.append($('<td class="text-center"></td>').append(chk));
var previewHtml = row.preview;
if (currentTool === 'png_jpg' || currentTool === 'watermark') {
var showCompare = false;
if (row.meta && row.meta.width !== undefined && row.meta.height !== undefined) {
if (parseInt(row.meta.width, 10) >= 150 && parseInt(row.meta.height, 10) >= 150) {
showCompare = true;
}
}
if (showCompare) {
previewHtml = '<div style="position:relative; display:inline-block;">' + row.preview +
'<button type="button" class="btn btn-default btn-xs btn-compare-preview" data-id="' + row.id + '" style="position:absolute; bottom:0; right:0; background:rgba(0,0,0,0.6); color:#fff; border:none; padding:2px 4px;" title="<?php echo $text_compare; ?>"><i class="fa fa-eye"></i></button></div>';
}
}
tr.append('<td>' + previewHtml + '</td>');
tr.append('<td>' + row.name + '</td>');
tr.append('<td>' + row.before + '</td>');
tr.append('<td>' + row.after + '</td>');
var select = $('<select class="form-control input-sm grid-action-select" data-id="' + row.id + '"></select>');
$.each(row.actions, function(key, val) {
var opt = $('<option value="' + key + '">' + val + '</option>');
if (row.selected_action === key) {
opt.prop('selected', true);
}
select.append(opt);
});
var td_action = $('<td class="text-right"></td>').append(select);
tr.append(td_action);
tbody.append(tr);
});
updateSelectAllHeaderState();
var totalPages = Math.ceil(gridData.length / gridLimit);
var pagHtml = '';
if (totalPages > 1) {
pagHtml += '<div class="btn-group btn-group-sm">';
if (gridPage > 1) {
pagHtml += '<button type="button" class="btn btn-default btn-grid-page" data-page="' + (gridPage - 1) + '">&larr;</button>';
}
pagHtml += '<button type="button" class="btn btn-default disabled">' + gridPage + ' / ' + totalPages + '</button>';
if (gridPage < totalPages) {
pagHtml += '<button type="button" class="btn btn-default btn-grid-page" data-page="' + (gridPage + 1) + '">&rarr;</button>';
}
pagHtml += '</div>';
}
$('#grid-pagination').html(pagHtml);
}
function changeGridPage(page) {
gridPage = page;
renderGrid();
saveScanCache();
}
$(document).on('click', '.btn-grid-page', function(e) {
e.preventDefault();
var page = parseInt($(this).data('page'), 10);
if (page) {
changeGridPage(page);
}
});
$(document).on('change', '#grid-per-page', function() {
var cached = sessionStorage.getItem('nat_scan_cache_img_opti');
if (cached) {
gridLimit = parseInt($(this).val(), 10) || 25;
gridPage = 1;
renderGrid();
saveScanCache();
} else {
var limit = $(this).val();
window.location = 'index.php?route=module/img_opti&' + tokenParam + '&limit=' + limit;
}
});
$(document).ready(function() {
restoreScanCache();
$('input[value="all"]').on('change', function() {
if ($(this).is(':checked')) {
$(this).closest('.well').find('input[type="checkbox"]').not(this).prop('checked', false);
}
});
$('input[type="checkbox"]').not('input[value="all"]').on('change', function() {
if ($(this).is(':checked')) {
$(this).closest('.well').find('input[value="all"]').prop('checked', false);
}
});
$('#input-mode').on('change', function() {
if ($(this).val() == 'copy') {
$('#folder-group').slideDown();
} else {
$('#folder-group').slideUp();
}
});
$('#wm_type').on('change', function() {
if ($(this).val() == 'text') {
$('#wm_image_wrap').hide();
$('#wm_text_wrap').show();
} else {
$('#wm_image_wrap').show();
$('#wm_text_wrap').hide();
}
});
$('#wm_size_type').on('change', function() {
if ($(this).val() == 'percent') {
$('#wm_size_percent_wrap').slideDown();
} else {
$('#wm_size_percent_wrap').slideUp();
}
});
$('#wm_text_color').on('input', function() {
var val = $(this).val();
if (/^#[0-9a-fA-F]{3,6}$/.test(val)) {
$('#wm_color_preview').css('background', val);
}
});
$('#btn-preview-wm').on('click', function() {
var $btn = $(this).prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i>');
$.ajax({
url: 'index.php?route=module/img_opti/preview_watermark&' + tokenParam,
type: 'post',
data: $('#form-module').serialize(),
dataType: 'json',
success: function(json) {
$btn.prop('disabled', false).html('<i class="fa fa-eye"></i> <?php echo $button_preview_watermark; ?>');
if (json.success && json.preview_url) {
$('#wm-preview-img').attr('src', json.preview_url + '?t=' + Date.now());
$('#wm-preview-container').slideDown();
} else {
alert(json.error || 'Preview failed');
}
},
error: function() {
$btn.prop('disabled', false).html('<i class="fa fa-eye"></i> <?php echo $button_preview_watermark; ?>');
alert('Preview request failed');
}
});
});
$('#cron_quality_override_toggle').on('change', function() {
if ($(this).is(':checked')) {
$('#cron_quality_fields').slideDown();
} else {
$('#cron_quality_fields').slideUp();
}
});
function updateCronFolderHint() {
var mode = $('#input-cron-folder-mode').val();
var checkedCount = $('#cron-folders-container input[type="checkbox"]:checked').length;
var hint = '';
if (mode === 'exclude') {
if (checkedCount === 0) {
hint = '<?php echo $text_cron_folder_hint_exclude_all; ?>';
} else {
hint = '<?php echo $text_cron_folder_hint_exclude_some; ?>'.replace('%d', checkedCount);
}
} else {
if (checkedCount === 0) {
hint = '<span class="text-danger"><?php echo $text_cron_folder_hint_include_none; ?></span>';
} else {
hint = '<?php echo $text_cron_folder_hint_include_some; ?>'.replace('%d', checkedCount);
}
}
$('#cron-folder-hint').html(hint);
}
updateCronFolderHint();
$('#input-cron-folder-mode').on('change', function() {
updateCronFolderHint();
});
$('#cron-folders-container').on('change', 'input[type="checkbox"]', function() {
updateCronFolderHint();
});
$('#btn-cron-select-all').on('click', function() {
$('#cron-folders-container input[type="checkbox"]').prop('checked', true);
updateCronFolderHint();
});
$('#btn-cron-deselect-all').on('click', function() {
$('#cron-folders-container input[type="checkbox"]').prop('checked', false);
updateCronFolderHint();
});
var wmRules = [];
var phRules = [];
try {
wmRules = JSON.parse($('#input-wm-rules').val() || '[]');
} catch (e) {
wmRules = [];
}
try {
phRules = JSON.parse($('#input-ph-rules').val() || '[]');
} catch (e) {
phRules = [];
}
function renderWmRules() {
var tbody = $('#table-wm-rules tbody');
tbody.empty();
$.each(wmRules, function(index, rule) {
var targets = [];
if (rule.target_product) targets.push('Product');
if (rule.target_category) targets.push('Category');
if (rule.target_brand) targets.push('Brand');
if (rule.target_banner) targets.push('Banner');
if (rule.target_blog) targets.push('Blog');
var statusLabel = rule.status ? '<span class="label label-success"><?php echo $text_enabled; ?></span>' : '<span class="label label-danger"><?php echo $text_disabled; ?></span>';
var row = $('<tr>');
row.append($('<td>').text(rule.name || 'Unnamed Rule'));
row.append($('<td>').text(rule.type === 'text' ? '<?php echo $text_wm_text; ?>' : '<?php echo $text_wm_image; ?>'));
row.append($('<td>').text(targets.join(', ')));
row.append($('<td class="text-center">').html(statusLabel));
var actions = $('<td class="text-right">');
actions.append('<button type="button" class="btn btn-default btn-xs" onclick="editWmRule(' + index + ')" style="margin-right:5px;"><i class="fa fa-pencil"></i></button>');
actions.append('<button type="button" class="btn btn-default btn-xs" onclick="moveWmRule(' + index + ', -1)" style="margin-right:5px;"><i class="fa fa-arrow-up"></i></button>');
actions.append('<button type="button" class="btn btn-default btn-xs" onclick="moveWmRule(' + index + ', 1)" style="margin-right:5px;"><i class="fa fa-arrow-down"></i></button>');
actions.append('<button type="button" class="btn btn-danger btn-xs" onclick="deleteWmRule(' + index + ')"><i class="fa fa-trash-o"></i></button>');
row.append(actions);
tbody.append(row);
});
$('#input-wm-rules').val(JSON.stringify(wmRules));
}
function renderPhRules() {
var tbody = $('#table-ph-rules tbody');
tbody.empty();
$.each(phRules, function(index, rule) {
var targets = [];
if (rule.target_product) targets.push('Product');
if (rule.target_category) targets.push('Category');
if (rule.target_brand) targets.push('Brand');
var statusLabel = rule.status ? '<span class="label label-success"><?php echo $text_enabled; ?></span>' : '<span class="label label-danger"><?php echo $text_disabled; ?></span>';
var row = $('<tr>');
row.append($('<td>').text(rule.name || 'Unnamed Rule'));
row.append($('<td>').text(targets.join(', ')));
row.append($('<td class="text-center">').html(statusLabel));
var actions = $('<td class="text-right">');
actions.append('<button type="button" class="btn btn-default btn-xs" onclick="editPhRule(' + index + ')" style="margin-right:5px;"><i class="fa fa-pencil"></i></button>');
actions.append('<button type="button" class="btn btn-default btn-xs" onclick="movePhRule(' + index + ', -1)" style="margin-right:5px;"><i class="fa fa-arrow-up"></i></button>');
actions.append('<button type="button" class="btn btn-default btn-xs" onclick="movePhRule(' + index + ', 1)" style="margin-right:5px;"><i class="fa fa-arrow-down"></i></button>');
actions.append('<button type="button" class="btn btn-danger btn-xs" onclick="deletePhRule(' + index + ')"><i class="fa fa-trash-o"></i></button>');
row.append(actions);
tbody.append(row);
});
$('#input-ph-rules').val(JSON.stringify(phRules));
}
window.deleteWmRule = function(index) {
if (confirm('Are you sure?')) {
wmRules.splice(index, 1);
renderWmRules();
}
};
window.moveWmRule = function(index, dir) {
var target = index + dir;
if (target >= 0 && target < wmRules.length) {
var temp = wmRules[index];
wmRules[index] = wmRules[target];
wmRules[target] = temp;
renderWmRules();
}
};
window.deletePhRule = function(index) {
if (confirm('Are you sure?')) {
phRules.splice(index, 1);
renderPhRules();
}
};
window.movePhRule = function(index, dir) {
var target = index + dir;
if (target >= 0 && target < phRules.length) {
var temp = phRules[index];
phRules[index] = phRules[target];
phRules[target] = temp;
renderPhRules();
}
};
window.editWmRule = function(index) {
var rule = wmRules[index];
$('#wm-rule-index').val(index);
$('#wm-rule-status').val(rule.status ? '1' : '0');
$('#wm-rule-name').val(rule.name || '');
$('#wm-rule-type').val(rule.type || 'image').trigger('change');
$('#input-modal-wm-image').val(rule.image || '');
if (rule.image) {
$('#thumb-modal-wm-image img').attr('src', '../image/' + rule.image);
} else {
$('#thumb-modal-wm-image img').attr('src', '<?php echo $placeholder; ?>');
}
$('#wm-rule-text-val').val(rule.text_val || '');
$('#wm-rule-text-font').val(rule.text_font || '');
$('#wm-rule-text-color').val(rule.text_color || '#ffffff');
$('#modal-wm-color-preview').css('background-color', rule.text_color || '#ffffff');
$('#wm-rule-opacity').val(rule.opacity || '50');
$('#wm-rule-position').val(rule.position || '5');
$('#wm-rule-size-type').val(rule.size_type || 'original').trigger('change');
$('#wm-rule-size-percent').val(rule.size_percent || '20');
$('#wm-rule-angle').val(rule.angle || '0');
$('#wm-rule-corner-radius').val(rule.corner_radius || '0');
$('#wm-rule-target-product').prop('checked', !!rule.target_product);
$('#wm-rule-target-category').prop('checked', !!rule.target_category);
$('#wm-rule-target-brand').prop('checked', !!rule.target_brand);
$('#wm-rule-target-banner').prop('checked', !!rule.target_banner);
$('#wm-rule-target-blog').prop('checked', !!rule.target_blog);
$('#wm-rule-filter-mode').val(rule.filter_mode || 'include');
$('#modal-wm-category-list').empty();
if (rule.categories) {
$.each(rule.categories, function(i, c) {
$('#modal-wm-category-list').append('<div id="modal-wm-category-' + c.id + '"><i class="fa fa-minus-circle"></i> ' + c.name + '<input type="hidden" class="category-id" value="' + c.id + '" data-name="' + c.name + '" /></div>');
});
}
$('#modal-wm-brand-list').empty();
if (rule.brands) {
$.each(rule.brands, function(i, b) {
$('#modal-wm-brand-list').append('<div id="modal-wm-brand-' + b.id + '"><i class="fa fa-minus-circle"></i> ' + b.name + '<input type="hidden" class="brand-id" value="' + b.id + '" data-name="' + b.name + '" /></div>');
});
}
$('#modal-wm-preview-container').hide();
$('#modal-wm-rule').modal('show');
};
window.editPhRule = function(index) {
var rule = phRules[index];
$('#ph-rule-index').val(index);
$('#ph-rule-status').val(rule.status ? '1' : '0');
$('#ph-rule-name').val(rule.name || '');
$('#ph-rule-target-product').prop('checked', !!rule.target_product);
$('#ph-rule-target-category').prop('checked', !!rule.target_category);
$('#ph-rule-target-brand').prop('checked', !!rule.target_brand);
$('#input-modal-ph-image').val(rule.image || '');
if (rule.image) {
$('#thumb-modal-ph-image img').attr('src', '../image/' + rule.image);
} else {
$('#thumb-modal-ph-image img').attr('src', '<?php echo $placeholder; ?>');
}
$('#ph-rule-filter-mode').val(rule.filter_mode || 'exclude');
$('#modal-ph-category-list').empty();
if (rule.categories) {
$.each(rule.categories, function(i, c) {
$('#modal-ph-category-list').append('<div id="modal-ph-category-' + c.id + '"><i class="fa fa-minus-circle"></i> ' + c.name + '<input type="hidden" class="category-id" value="' + c.id + '" data-name="' + c.name + '" /></div>');
});
}
$('#modal-ph-brand-list').empty();
if (rule.brands) {
$.each(rule.brands, function(i, b) {
$('#modal-ph-brand-list').append('<div id="modal-ph-brand-' + b.id + '"><i class="fa fa-minus-circle"></i> ' + b.name + '<input type="hidden" class="brand-id" value="' + b.id + '" data-name="' + b.name + '" /></div>');
});
}
$('#modal-ph-rule').modal('show');
};
renderWmRules();
renderPhRules();
$('#btn-add-wm-rule').on('click', function() {
$('#wm-rule-index').val('');
$('#wm-rule-status').val('1');
$('#wm-rule-name').val('');
$('#wm-rule-type').val('image').trigger('change');
$('#input-modal-wm-image').val('');
$('#thumb-modal-wm-image img').attr('src', '<?php echo $placeholder; ?>');
$('#wm-rule-text-val').val('');
$('#wm-rule-text-font').val('');
$('#wm-rule-text-color').val('#ffffff');
$('#modal-wm-color-preview').css('background-color', '#ffffff');
$('#wm-rule-opacity').val('50');
$('#wm-rule-position').val('5');
$('#wm-rule-size-type').val('original').trigger('change');
$('#wm-rule-size-percent').val('20');
$('#wm-rule-angle').val('0');
$('#wm-rule-corner-radius').val('0');
$('#wm-rule-target-product').prop('checked', true);
$('#wm-rule-target-category').prop('checked', false);
$('#wm-rule-target-brand').prop('checked', false);
$('#wm-rule-target-banner').prop('checked', false);
$('#wm-rule-target-blog').prop('checked', false);
$('#wm-rule-filter-mode').val('exclude');
$('#modal-wm-category-list').empty();
$('#modal-wm-brand-list').empty();
$('#modal-wm-preview-container').hide();
$('#modal-wm-rule').modal('show');
});
$('#btn-add-ph-rule').on('click', function() {
$('#ph-rule-index').val('');
$('#ph-rule-status').val('1');
$('#ph-rule-name').val('');
$('#ph-rule-target-product').prop('checked', true);
$('#ph-rule-target-category').prop('checked', false);
$('#ph-rule-target-brand').prop('checked', false);
$('#input-modal-ph-image').val('');
$('#thumb-modal-ph-image img').attr('src', '<?php echo $placeholder; ?>');
$('#ph-rule-filter-mode').val('exclude');
$('#modal-ph-category-list').empty();
$('#modal-ph-brand-list').empty();
$('#modal-ph-rule').modal('show');
});
$('#wm-rule-type').on('change', function() {
if ($(this).val() === 'text') {
$('.wm-rule-text-group').show();
$('.wm-rule-image-group').hide();
$('.wm-rule-size-percent-group').hide();
} else {
$('.wm-rule-text-group').hide();
$('.wm-rule-image-group').show();
$('#wm-rule-size-type').trigger('change');
}
});
$('#wm-rule-size-type').on('change', function() {
if ($(this).val() === 'percent' && $('#wm-rule-type').val() === 'image') {
$('.wm-rule-size-percent-group').show();
} else {
$('.wm-rule-size-percent-group').hide();
}
});
$('#wm-rule-text-color').on('input', function() {
var color = $(this).val();
if (color.match(/^#[0-9a-fA-F]{6}$/)) {
$('#modal-wm-color-preview').css('background-color', color);
}
});
$('#btn-save-wm-rule').on('click', function() {
var idxVal = $('#wm-rule-index').val();
var index = idxVal === '' ? wmRules.length : parseInt(idxVal, 10);
var categories = [];
$('#modal-wm-category-list input.category-id').each(function() {
categories.push({ id: parseInt($(this).val(), 10), name: $(this).parent().text().trim() });
});
var brands = [];
$('#modal-wm-brand-list input.brand-id').each(function() {
brands.push({ id: parseInt($(this).val(), 10), name: $(this).parent().text().trim() });
});
var rule = {
status: parseInt($('#wm-rule-status').val(), 10),
name: $('#wm-rule-name').val() || 'Unnamed Rule',
type: $('#wm-rule-type').val(),
image: $('#input-modal-wm-image').val(),
text_val: $('#wm-rule-text-val').val(),
text_font: $('#wm-rule-text-font').val(),
text_color: $('#wm-rule-text-color').val(),
opacity: parseInt($('#wm-rule-opacity').val(), 10),
position: $('#wm-rule-position').val(),
size_type: $('#wm-rule-size-type').val(),
size_percent: parseInt($('#wm-rule-size-percent').val(), 10),
angle: parseInt($('#wm-rule-angle').val(), 10),
corner_radius: parseInt($('#wm-rule-corner-radius').val(), 10),
target_product: $('#wm-rule-target-product').is(':checked') ? 1 : 0,
target_category: $('#wm-rule-target-category').is(':checked') ? 1 : 0,
target_brand: $('#wm-rule-target-brand').is(':checked') ? 1 : 0,
target_banner: $('#wm-rule-target-banner').is(':checked') ? 1 : 0,
target_blog: $('#wm-rule-target-blog').is(':checked') ? 1 : 0,
filter_mode: $('#wm-rule-filter-mode').val(),
categories: categories,
brands: brands
};
if (idxVal === '') {
wmRules.push(rule);
} else {
wmRules[index] = rule;
}
$('#modal-wm-rule').modal('hide');
renderWmRules();
});
$('#btn-save-ph-rule').on('click', function() {
var idxVal = $('#ph-rule-index').val();
var index = idxVal === '' ? phRules.length : parseInt(idxVal, 10);
var categories = [];
$('#modal-ph-category-list input.category-id').each(function() {
categories.push({ id: parseInt($(this).val(), 10), name: $(this).parent().text().trim() });
});
var brands = [];
$('#modal-ph-brand-list input.brand-id').each(function() {
brands.push({ id: parseInt($(this).val(), 10), name: $(this).parent().text().trim() });
});
var rule = {
status: parseInt($('#ph-rule-status').val(), 10),
name: $('#ph-rule-name').val() || 'Unnamed Rule',
target_product: $('#ph-rule-target-product').is(':checked') ? 1 : 0,
target_category: $('#ph-rule-target-category').is(':checked') ? 1 : 0,
target_brand: $('#ph-rule-target-brand').is(':checked') ? 1 : 0,
image: $('#input-modal-ph-image').val(),
filter_mode: $('#ph-rule-filter-mode').val(),
categories: categories,
brands: brands
};
if (idxVal === '') {
phRules.push(rule);
} else {
phRules[index] = rule;
}
$('#modal-ph-rule').modal('hide');
renderPhRules();
});
$('#btn-modal-wm-preview').on('click', function() {
var $btn = $(this);
$btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Loading...');
var ruleData = {
module_img_opti_wm_type: $('#wm-rule-type').val(),
module_img_opti_wm_image: $('#input-modal-wm-image').val(),
module_img_opti_wm_text_val: $('#wm-rule-text-val').val(),
module_img_opti_wm_text_font: $('#wm-rule-text-font').val(),
module_img_opti_wm_text_color: $('#wm-rule-text-color').val(),
module_img_opti_wm_opacity: $('#wm-rule-opacity').val(),
module_img_opti_wm_position: $('#wm-rule-position').val(),
module_img_opti_wm_size_type: $('#wm-rule-size-type').val(),
module_img_opti_wm_size_percent: $('#wm-rule-size-percent').val(),
module_img_opti_wm_angle: $('#wm-rule-angle').val(),
module_img_opti_wm_corner_radius: $('#wm-rule-corner-radius').val()
};
$.ajax({
url: 'index.php?route=module/img_opti/preview_watermark&' + tokenParam,
type: 'post',
data: ruleData,
dataType: 'json',
success: function(json) {
$btn.prop('disabled', false).html('<i class="fa fa-eye"></i> <?php echo $button_preview_watermark; ?>');
if (json.error) {
alert(json.error);
} else if (json.preview_url) {
$('#modal-wm-preview-img').attr('src', json.preview_url);
$('#modal-wm-preview-container').slideDown();
}
},
error: function() {
$btn.prop('disabled', false).html('<i class="fa fa-eye"></i> <?php echo $button_preview_watermark; ?>');
}
});
});
$('#input-modal-wm-category').autocomplete({
'source': function(request, response) {
$.ajax({
url: 'index.php?route=module/img_opti/autocomplete_category&' + tokenParam + '&filter_name=' + encodeURIComponent(request),
dataType: 'json',
success: function(json) {
response($.map(json, function(item) {
return { label: item['name'], value: item['category_id'] }
}));
}
});
},
'select': function(item) {
$('#input-modal-wm-category').val('');
$('#modal-wm-category-' + item['value']).remove();
$('#modal-wm-category-list').append('<div id="modal-wm-category-' + item['value'] + '"><i class="fa fa-minus-circle"></i> ' + item['label'] + '<input type="hidden" class="category-id" value="' + item['value'] + '" /></div>');
}
});
$('#modal-wm-category-list').delegate('.fa-minus-circle', 'click', function() {
$(this).parent().remove();
});
$('#input-modal-wm-brand').autocomplete({
'source': function(request, response) {
$.ajax({
url: 'index.php?route=module/img_opti/autocomplete_manufacturer&' + tokenParam + '&filter_name=' + encodeURIComponent(request),
dataType: 'json',
success: function(json) {
response($.map(json, function(item) {
return { label: item['name'], value: item['manufacturer_id'] }
}));
}
});
},
'select': function(item) {
$('#input-modal-wm-brand').val('');
$('#modal-wm-brand-' + item['value']).remove();
$('#modal-wm-brand-list').append('<div id="modal-wm-brand-' + item['value'] + '"><i class="fa fa-minus-circle"></i> ' + item['label'] + '<input type="hidden" class="brand-id" value="' + item['value'] + '" /></div>');
}
});
$('#modal-wm-brand-list').delegate('.fa-minus-circle', 'click', function() {
$(this).parent().remove();
});
$('#input-modal-ph-category').autocomplete({
'source': function(request, response) {
$.ajax({
url: 'index.php?route=module/img_opti/autocomplete_category&' + tokenParam + '&filter_name=' + encodeURIComponent(request),
dataType: 'json',
success: function(json) {
response($.map(json, function(item) {
return { label: item['name'], value: item['category_id'] }
}));
}
});
},
'select': function(item) {
$('#input-modal-ph-category').val('');
$('#modal-ph-category-' + item['value']).remove();
$('#modal-ph-category-list').append('<div id="modal-ph-category-' + item['value'] + '"><i class="fa fa-minus-circle"></i> ' + item['label'] + '<input type="hidden" class="category-id" value="' + item['value'] + '" /></div>');
}
});
$('#modal-ph-category-list').delegate('.fa-minus-circle', 'click', function() {
$(this).parent().remove();
});
$('#input-modal-ph-brand').autocomplete({
'source': function(request, response) {
$.ajax({
url: 'index.php?route=module/img_opti/autocomplete_manufacturer&' + tokenParam + '&filter_name=' + encodeURIComponent(request),
dataType: 'json',
success: function(json) {
response($.map(json, function(item) {
return { label: item['name'], value: item['manufacturer_id'] }
}));
}
});
},
'select': function(item) {
$('#input-modal-ph-brand').val('');
$('#modal-ph-brand-' + item['value']).remove();
$('#modal-ph-brand-list').append('<div id="modal-ph-brand-' + item['value'] + '"><i class="fa fa-minus-circle"></i> ' + item['label'] + '<input type="hidden" class="brand-id" value="' + item['value'] + '" /></div>');
}
});
$('#modal-ph-brand-list').delegate('.fa-minus-circle', 'click', function() {
$(this).parent().remove();
});
var cronTasks = [];
try {
cronTasks = JSON.parse($('#input-cron-tasks').val() || '[]');
} catch(e) {
cronTasks = [];
}
function renderCronTasks() {
var html = '';
if (cronTasks.length > 0) {
$.each(cronTasks, function(index, task) {
var entitiesList = (task.entities || []).join(', ');
var foldersList = '';
if (task.folders && task.folders.length > 0) {
if (task.folder_mode === 'exclude') {
foldersList = 'Scan all except: ' + task.folders.join(', ');
} else {
foldersList = 'Scan only: ' + task.folders.join(', ');
}
} else {
foldersList = task.folder_mode === 'exclude' ? 'Scan all (no exclusions)' : '<span class="text-danger">None selected (scan nothing)</span>';
}
var qualityInfo = '';
if (task.quality_override) {
qualityInfo = 'JPG: ' + task.jpg_quality + '%, WebP: ' + task.webp_quality + '%, Max: ' + task.max_width + 'x' + task.max_height + 'px';
} else {
qualityInfo = 'Use global settings';
}
var statusText = task.status ? '<span class="label label-success"><?php echo $text_enabled; ?></span>' : '<span class="label label-danger"><?php echo $text_disabled; ?></span>';
var escapedTaskName = encodeURIComponent(task.name);
var taskUrl = '<?php echo str_replace(\'image/catalog\', \'\', $catalog_url); ?>index.php?route=module/img_opti_cron&amp;key=<?php echo $module_img_opti_token; ?>&amp;task=' + escapedTaskName;
html += '<tr>';
html += ' <td><b>' + task.name + '</b><br><small class="text-muted">' + entitiesList + '</small></td>';
html += ' <td><small>' + foldersList + '</small></td>';
html += ' <td><small>' + qualityInfo + '</small></td>';
html += ' <td class="text-center">' + statusText + '</td>';
html += ' <td class="text-right">';
html += ' <button type="button" class="btn btn-default btn-xs btn-copy-task-url" data-url="' + taskUrl.replace(/&amp;/g, '&') + '" title="<?php echo $button_copy_cron_url; ?>"><i class="fa fa-copy"></i> <?php echo $button_copy_cron_url; ?></button>';
html += ' <button type="button" class="btn btn-primary btn-xs btn-edit-cron-task" data-index="' + index + '" style="margin-left:5px;"><i class="fa fa-pencil"></i> <?php echo $button_edit; ?></button>';
html += ' <button type="button" class="btn btn-danger btn-xs btn-delete-cron-task" data-index="' + index + '" style="margin-left:5px;"><i class="fa fa-trash"></i> <?php echo $button_delete; ?></button>';
html += ' </td>';
html += '</tr>';
});
} else {
html += '<tr><td colspan="5" class="text-center text-muted">No tasks defined. Please add a cron task.</td></tr>';
}
$('#table-cron-tasks tbody').html(html);
$('#input-cron-tasks').val(JSON.stringify(cronTasks));
$('.btn-copy-task-url').off('click').on('click', function(e) {
e.preventDefault();
var url = $(this).data('url');
var $btn = $(this);
navigator.clipboard.writeText(url).then(function() {
var originalText = $btn.html();
$btn.html('<i class="fa fa-check"></i> Copied!');
setTimeout(function() {
$btn.html(originalText);
}, 2000);
}, function() {
alert('Failed to copy URL: ' + url);
});
});
}
renderCronTasks();
$('#btn-add-cron-task').on('click', function() {
$('#cron-task-index').val('');
$('#cron-task-status').val('1');
$('#cron-task-name').val('');
$('#cron-task-new-only').prop('checked', true);
$('.cron-task-entity').prop('checked', true);
$('#cron-task-folder-mode').val('exclude');
$('.cron-task-folder-checkbox').prop('checked', false);
$('#cron-task-quality-override').prop('checked', false).trigger('change');
$('#cron-task-jpg-quality').val('72');
$('#cron-task-webp-quality').val('80');
$('#cron-task-max-width').val('1600');
$('#cron-task-max-height').val('1600');
updateCronTaskFolderHint();
$('#modal-cron-task').modal('show');
});
$('#cron-task-quality-override').on('change', function() {
if ($(this).is(':checked')) {
$('#cron-task-quality-fields').slideDown();
} else {
$('#cron-task-quality-fields').slideUp();
}
});
$(document).on('click', '.btn-edit-cron-task', function() {
var index = parseInt($(this).data('index'), 10);
var task = cronTasks[index];
if (!task) return;
$('#cron-task-index').val(index);
$('#cron-task-status').val(task.status);
$('#cron-task-name').val(task.name);
$('#cron-task-new-only').prop('checked', task.new_only ? true : false);
$('.cron-task-entity').each(function() {
var val = $(this).val();
$(this).prop('checked', $.inArray(val, task.entities || []) !== -1);
});
$('#cron-task-folder-mode').val(task.folder_mode || 'exclude');
$('.cron-task-folder-checkbox').each(function() {
var val = $(this).val();
$(this).prop('checked', $.inArray(val, task.folders || []) !== -1);
});
$('#cron-task-quality-override').prop('checked', task.quality_override ? true : false);
if (task.quality_override) {
$('#cron-task-quality-fields').show();
} else {
$('#cron-task-quality-fields').hide();
}
$('#cron-task-jpg-quality').val(task.jpg_quality || 72);
$('#cron-task-webp-quality').val(task.webp_quality || 80);
$('#cron-task-max-width').val(task.max_width || 1600);
$('#cron-task-max-height').val(task.max_height || 1600);
updateCronTaskFolderHint();
$('#modal-cron-task').modal('show');
});
$(document).on('click', '.btn-delete-cron-task', function() {
if (confirm('Are you sure you want to delete this cron task?')) {
var index = parseInt($(this).data('index'), 10);
cronTasks.splice(index, 1);
renderCronTasks();
}
});
$('.btn-cron-task-select-all').on('click', function() {
$('.cron-task-folder-checkbox').prop('checked', true);
updateCronTaskFolderHint();
});
$('.btn-cron-task-deselect-all').on('click', function() {
$('.cron-task-folder-checkbox').prop('checked', false);
updateCronTaskFolderHint();
});
$('.cron-task-folder-checkbox, #cron-task-folder-mode').on('change', function() {
updateCronTaskFolderHint();
});
function updateCronTaskFolderHint() {
var mode = $('#cron-task-folder-mode').val();
var checkedCount = $('.cron-task-folder-checkbox:checked').length;
var hint = '';
if (mode === 'exclude') {
if (checkedCount === 0) {
hint = '{{ text_cron_folder_hint_exclude_all|escape("js") }}';
} else {
hint = '{{ text_cron_folder_hint_exclude_some|escape("js") }}'.replace('%d', checkedCount);
}
} else {
if (checkedCount === 0) {
hint = '<span class="text-danger"><i class="fa fa-exclamation-triangle"></i> {{ text_cron_folder_hint_include_none|escape("js") }}</span>';
} else {
hint = '{{ text_cron_folder_hint_include_some|escape("js") }}'.replace('%d', checkedCount);
}
}
$('.cron-task-folder-hint').html(hint);
}
$('#btn-save-cron-task').on('click', function() {
var idxVal = $('#cron-task-index').val();
var index = idxVal === '' ? cronTasks.length : parseInt(idxVal, 10);
var name = $('#cron-task-name').val().trim();
if (!name) {
alert('Please enter a task name.');
return;
}
name = name.replace(/[^a-zA-Z0-9_\-\s]/g, '');
if (!name) {
alert('Task name contains invalid characters.');
return;
}
var duplicate = false;
$.each(cronTasks, function(i, t) {
if (i !== index && t.name.toLowerCase() === name.toLowerCase()) {
duplicate = true;
}
});
if (duplicate) {
alert('A task with this name already exists.');
return;
}
var entities = [];
$('.cron-task-entity:checked').each(function() {
entities.push($(this).val());
});
var folders = [];
$('.cron-task-folder-checkbox:checked').each(function() {
folders.push($(this).val());
});
var rule = {
status: parseInt($('#cron-task-status').val(), 10),
name: name,
new_only: $('#cron-task-new-only').is(':checked') ? 1 : 0,
entities: entities,
folder_mode: $('#cron-task-folder-mode').val(),
folders: folders,
quality_override: $('#cron-task-quality-override').is(':checked') ? 1 : 0,
jpg_quality: parseInt($('#cron-task-jpg-quality').val(), 10) || 72,
webp_quality: parseInt($('#cron-task-webp-quality').val(), 10) || 80,
max_width: parseInt($('#cron-task-max-width').val(), 10) || 1600,
max_height: parseInt($('#cron-task-max-height').val(), 10) || 1600
};
if (idxVal === '') {
cronTasks.push(rule);
} else {
cronTasks[index] = rule;
}
$('#modal-cron-task').modal('hide');
renderCronTasks();
});
$('#tool-selector').on('change', function() {
$('.tool-ui-block').hide();
$('#btn-run-tool, #btn-fix-tool').hide();
$('#grid-container').slideUp();
gridData = [];
var tool = $(this).val();
if (tool && toolDescriptions[tool]) {
$('#tool-help-text').html('<i class="fa fa-info-circle"></i> ' + toolDescriptions[tool]).slideDown();
} else {
$('#tool-help-text').slideUp();
}
if (tool) {
if (tool == 'small_photos') {
$('#tool-ui-small_photos').slideDown();
} else if (tool == 'watermark') {
$('#tool-ui-watermark').slideDown();
} else if (tool == 'placeholders') {
$('#tool-ui-placeholders').slideDown();
} else if (tool == 'sanitizer') {
$('#tool-ui-sanitizer').slideDown();
} else if (tool == 'heavy_files') {
$('#tool-ui-heavy_files').slideDown();
} else if (tool == 'png_jpg') {
$('#tool-ui-png_jpg').slideDown();
}
if (tool == 'watermark') {
$('#btn-run-tool').hide();
} else {
$('#btn-run-tool').show().find('.btn-text').text('<?php echo $button_scan_tool; ?>');
}
}
});
$(document).on('click', '#btn-clear-cache-wm', function(e) {
e.preventDefault();
var $btn = $(this);
$btn.button('loading');
$('.alert-dismissible').remove();
$.ajax({
url: 'index.php?route=module/img_opti/run_tool&' + tokenParam,
type: 'post',
data: {
tool: 'watermark',
action: 'scan'
},
dataType: 'json',
success: function(json) {
$btn.button('reset');
if (json.error) {
$('.breadcrumb').after('<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json.error + ' <button type="button" class="close" data-dismiss="alert">&times;</button></div>');
$('html, body').animate({ scrollTop: 0 }, 'slow');
} else if (json.message !== undefined) {
$('.breadcrumb').after('<div class="alert alert-success alert-dismissible"><i class="fa fa-check-circle"></i> ' + json.message + ' <button type="button" class="close" data-dismiss="alert">&times;</button></div>');
$('html, body').animate({ scrollTop: 0 }, 'slow');
}
},
error: function() {
$btn.button('reset');
}
});
});
$(document).on('change', '#log_limit', function() {
logCurrentPage = 1;
renderLogPage();
});
$(document).on('change', '#cleaner_log_limit', function() {
cleanerCurrentPage = 1;
renderCleanerLogPage();
});
$('#btn-run-tool').on('click', function() {
var tool = $('#tool-selector').val();
if (!tool) return;
var $btn = $(this);
$btn.button('loading');
$('#btn-fix-tool').hide();
$('#grid-container').slideUp();
$('.alert-dismissible').remove();
sessionStorage.removeItem('nat_scan_cache_img_opti');
var formData = $('#form-module').serialize();
formData += '&tool=' + tool + '&action=scan';
$.ajax({
url: 'index.php?route=module/img_opti/run_tool&' + tokenParam,
type: 'post',
data: formData,
dataType: 'json',
success: function(json) {
$btn.button('reset');
if (json.error) {
$('.breadcrumb').after('<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json.error + ' <button type="button" class="close" data-dismiss="alert">&times;</button></div>');
$('html, body').animate({ scrollTop: 0 }, 'slow');
} else {
if (json.rows !== undefined) {
currentTool = tool;
gridData = json.rows;
gridHeaders = json.headers;
gridPage = 1;
var thead = $('#grid-thead');
thead.empty();
thead.append('<th style="width: 1px;" class="text-center"><input type="checkbox" id="grid-select-all" /></th>');
$.each(gridHeaders, function(i, h) {
thead.append('<th>' + h + '</th>');
});
var warnings = $('#grid-warnings');
warnings.empty();
if (json.backup_available) {
warnings.append('<div class="alert alert-info" style="margin-bottom:5px;"><i class="fa fa-database"></i> <?php echo $text_backup_will_be_created; ?></div>');
}
if (json.quarantine_available) {
warnings.append('<div class="alert alert-warning" style="margin-bottom:5px;"><i class="fa fa-archive"></i> <?php echo $text_quarantine_will_be_created; ?></div>');
}
$('#grid-container').slideDown();
renderGrid();
saveScanCache();
} else if (json.message !== undefined) {
$('.breadcrumb').after('<div class="alert alert-success alert-dismissible"><i class="fa fa-check-circle"></i> ' + json.message + ' <button type="button" class="close" data-dismiss="alert">&times;</button></div>');
$('html, body').animate({ scrollTop: 0 }, 'slow');
}
}
},
error: function() {
$btn.button('reset');
}
});
});
$('#btn-fix-tool').on('click', function() {
if (gridData.length === 0) return;
if (!confirm('<?php echo $text_experimental_warn; ?>')) return;
var $btn = $(this);
$btn.button('loading');
$('#btn-run-tool').prop('disabled', true);
var selectedMap = {};
var anyChecked = false;
$.each(gridData, function(i, row) {
if (row.selected) {
selectedMap[row.id] = row.selected_action;
anyChecked = true;
}
});
if (!anyChecked) {
alert('<?php echo $error_empty_selection; ?>');
$btn.button('reset');
$('#btn-run-tool').prop('disabled', false);
return;
}
$.ajax({
url: 'index.php?route=module/img_opti/run_tool&' + tokenParam,
type: 'post',
data: {
tool: currentTool,
action: 'fix',
selected: selectedMap
},
dataType: 'json',
success: function(json) {
$btn.button('reset');
$('#btn-run-tool').prop('disabled', false);
if (json.error) {
alert(json.error);
} else {
alert('<?php echo $text_success_apply; ?>');
$('#grid-container').slideUp();
gridData = [];
sessionStorage.removeItem('nat_scan_cache_img_opti');
renderGrid();
}
},
error: function() {
$btn.button('reset');
$('#btn-run-tool').prop('disabled', false);
}
});
});
$(document).on('change', '.grid-action-select', function() {
var rowId = $(this).data('id');
var val = $(this).val();
$.each(gridData, function(i, row) {
if (row.id === rowId) {
row.selected_action = val;
return false;
}
});
saveScanCache();
});
$(document).on('change', '#grid-select-all', function() {
var checked = $(this).prop('checked');
var start = (gridPage - 1) * gridLimit;
var end = start + gridLimit;
var sliced = gridData.slice(start, end);
$.each(sliced, function(i, row) {
row.selected = checked;
});
$('.grid-row-checkbox').prop('checked', checked);
saveScanCache();
});
$(document).on('change', '.grid-row-checkbox', function() {
var id = $(this).data('id');
var checked = $(this).prop('checked');
$.each(gridData, function(i, row) {
if (row.id == id) {
row.selected = checked;
return false;
}
});
updateSelectAllHeaderState();
saveScanCache();
});
$(document).on('click', '#btn-grid-apply-bulk', function() {
var bulkVal = $('#grid-bulk-select').val();
if (!bulkVal) return;
$.each(gridData, function(i, row) {
if (row.selected && row.actions[bulkVal] !== undefined) {
row.selected_action = bulkVal;
}
});
renderGrid();
saveScanCache();
});
$(document).on('click', '#btn-grid-download', function() {
if (gridData.length === 0) return;
var csv = [];
csv.push(gridHeaders.join(','));
$.each(gridData, function(i, row) {
var line = [
'"' + row.id + '"',
'"' + $('<div>').html(row.name).text().replace(/"/g, '""').trim() + '"',
'"' + $('<div>').html(row.before).text().replace(/"/g, '""').trim() + '"',
'"' + $('<div>').html(row.after).text().replace(/"/g, '""').trim() + '"',
'"' + row.selected_action + '"'
];
csv.push(line.join(','));
});
var blob = new Blob(["\ufeff" + csv.join("\n")], { type: 'text/csv;charset=utf-8;' });
var link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.setAttribute("download", "img_opti_tools_log.csv");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
});
function formatBytesJS(bytes) {
if (bytes === 0) return '0 B';
var k = 1024;
var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
var i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
var totalFiles = 0;
var processedFiles = 0;
var optimizedFiles = 0;
var totalOldBytes = 0;
var totalNewBytes = 0;
var isPaused = false;
var isStopped = false;
var fullLogArray = [];
var logCurrentPage = 1;
var optiParams = '';
function renderLogPage() {
var limit = parseInt($('#log_limit').val(), 10) || 100;
var totalPages = Math.max(1, Math.ceil(fullLogArray.length / limit));
if (logCurrentPage > totalPages) {
logCurrentPage = totalPages;
}
if (logCurrentPage < 1) {
logCurrentPage = 1;
}
$('#log-page-info').text('<?php echo $text_page; ?> ' + logCurrentPage + ' / ' + totalPages);
var pageLogs = fullLogArray.slice((logCurrentPage - 1) * limit, logCurrentPage * limit);
$('#log-window').html(pageLogs.join(''));
if (logCurrentPage === totalPages && !isPaused && !isStopped) {
$('#log-window').scrollTop($('#log-window')[0].scrollHeight);
}
}
$(document).on('click', '#log-prev', function(e) {
e.preventDefault();
if (logCurrentPage > 1) {
logCurrentPage--;
renderLogPage();
}
});
$(document).on('click', '#log-next', function(e) {
e.preventDefault();
var limit = parseInt($('#log_limit').val(), 10) || 100;
if (logCurrentPage < Math.ceil(fullLogArray.length / limit)) {
logCurrentPage++;
renderLogPage();
}
});
$(document).on('click', '#btn-download-log', function(e) {
e.preventDefault();
if (fullLogArray.length === 0) {
alert('<?php echo $error_log_empty; ?>');
return;
}
var plainTextLog = fullLogArray.map(function(html) {
var $temp = $('<div>').html(html);
$temp.find('.btn-compare-opti').remove();
return $temp.text().trim();
}).join('\r\n');
var header = "<?php echo $text_report_header; ?>\r\n<?php echo $text_total_files; ?>" + processedFiles + " / " + totalFiles + " (<?php echo $text_optimized; ?>: " + optimizedFiles + ")\r\n<?php echo $text_savings; ?> " + $('#stat-saved').text() + "\r\n=============================\r\n\r\n";
var blob = new Blob([header + plainTextLog], { type: 'text/plain;charset=utf-8' });
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'img_opti_log.txt';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
});
$(document).on('click', '#btn-start', function(e) {
e.preventDefault();
if ($('#input-mode').val() === 'replace') {
if (!confirm('<?php echo $confirm_replace_mode; ?>')) {
return;
}
}
$('#apply-block').hide();
$('#block-start').hide();
$('#block-pause, #block-stop').show();
$('#btn-pause').prop('disabled', false).html('<i class="fa fa-pause"></i> <?php echo $button_pause; ?>').removeClass('btn-success').addClass('btn-warning');
$('#btn-stop').prop('disabled', false).html('<i class="fa fa-stop"></i> <?php echo $button_stop; ?>');
$('#log-pagination').show();
$('#stats-block').css('display', 'flex');
$('#progress-bar').css('width', '0%').addClass('active progress-bar-striped');
$('#log-window').html('<div><?php echo $text_searching; ?></div>');
isPaused = false;
isStopped = false;
totalFiles = 0;
processedFiles = 0;
optimizedFiles = 0;
totalOldBytes = 0;
totalNewBytes = 0;
fullLogArray.length = 0;
logCurrentPage = 1;
$('#stat-old, #stat-new').text('0 B');
$('#stat-saved').text('0 B (0%)');
$('#progress-text').text('0 / 0');
optiParams = $('#form-opti input, #form-opti select').not('#btn-pause, #btn-stop').serialize();
$('#form-opti input, #form-opti select, #input-threads').not('#btn-pause, #btn-stop').prop('disabled', true);
$.ajax({
url: 'index.php?route=module/img_opti/scan&' + tokenParam,
type: 'post',
data: optiParams,
dataType: 'json',
success: function(json) {
if (json['error']) {
fullLogArray.push('<div class="text-danger">' + json['error'] + '</div>');
renderLogPage();
resetButtons();
} else {
totalFiles = json['total'];
$('#progress-text').text('0 / ' + totalFiles);
fullLogArray.push('<div class="text-info">' + json['success'] + '</div>');
renderLogPage();
if (totalFiles > 0) {
threadsCount = parseInt($('#input-threads').val(), 10) || 1;
activeThreads = 0;
for (var t = 0; t < threadsCount; t++) {
activeThreads++;
processBatch();
}
} else {
resetButtons();
}
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert('<?php echo $error_ajax; ?>' + thrownError);
resetButtons();
}
});
});
$(document).on('click', '#btn-pause', function(e) {
e.preventDefault();
var $btn = $(this);
if (isPaused) {
isPaused = false;
$btn.html('<i class="fa fa-pause"></i> <?php echo $button_pause; ?>').removeClass('btn-success').addClass('btn-warning');
fullLogArray.push('<div style="color:#f39c12; margin:5px 0;"><?php echo $text_resumed; ?></div>');
renderLogPage();
threadsCount = parseInt($('#input-threads').val(), 10) || 1;
activeThreads = 0;
for (var t = 0; t < threadsCount; t++) {
activeThreads++;
processBatch();
}
} else {
isPaused = true;
$btn.html('<i class="fa fa-play"></i> <?php echo $button_continue; ?>').removeClass('btn-warning').addClass('btn-success');
fullLogArray.push('<div style="color:#f39c12; margin:5px 0;"><?php echo $text_paused; ?></div>');
renderLogPage();
}
});
$(document).on('click', '#btn-stop', function(e) {
e.preventDefault();
if (!confirm('<?php echo $confirm_stop; ?>')) return;
isStopped = true;
$('#btn-stop').html('<i class="fa fa-spinner fa-spin"></i> <?php echo $button_stopping; ?>').prop('disabled', true);
$('#btn-pause').prop('disabled', true);
$.ajax({
url: 'index.php?route=module/img_opti/stop&' + tokenParam,
dataType: 'json',
success: function() {
fullLogArray.push('<div class="text-danger" style="margin-top:10px; font-weight:bold; font-size:15px;"><?php echo $text_stopped_user; ?></div>');
renderLogPage();
resetButtons();
$('#progress-bar').removeClass('active progress-bar-striped');
}
});
});
function resetButtons() {
$('#block-pause, #block-stop').hide();
$('#block-start').show();
$('#btn-start').html('<i class="fa fa-play"></i> <?php echo $button_start_new; ?>');
$('#form-opti input, #form-opti select, #input-threads').prop('disabled', false);
}
$(document).on('click', '#btn-reset-cache', function() {
if (!confirm('<?php echo $confirm_reset_cache; ?>')) return;
var $btn = $(this);
$btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i>');
$.ajax({
url: 'index.php?route=module/img_opti/resetCache&' + tokenParam,
type: 'post',
dataType: 'json',
success: function(json) {
$btn.prop('disabled', false).html('<i class="fa fa-eraser"></i>');
if (json['success']) {
alert(json['success']);
}
},
error: function() {
$btn.prop('disabled', false).html('<i class="fa fa-eraser"></i>');
}
});
});
function processBatch() {
if (isPaused || isStopped) {
activeThreads--;
return;
}
$.ajax({
url: 'index.php?route=module/img_opti/process&' + tokenParam,
type: 'post',
data: optiParams,
dataType: 'json',
success: function(json) {
if (isStopped) {
activeThreads--;
return;
}
if (json['log'] && json['log'].length > 0) {
fullLogArray = fullLogArray.concat(json['log']);
logCurrentPage = Math.max(1, Math.ceil(fullLogArray.length / (parseInt($('#log_limit').val(), 10) || 100)));
renderLogPage();
}
if (json['batch_old'] !== undefined) {
totalOldBytes += json['batch_old'];
totalNewBytes += json['batch_new'];
var savedBytes = totalOldBytes - totalNewBytes;
$('#stat-old').text(formatBytesJS(totalOldBytes));
$('#stat-new').text(formatBytesJS(totalNewBytes));
if (savedBytes >= 0) {
$('#stat-saved').css('color', '#2ecc71').text(formatBytesJS(savedBytes) + ' (' + (totalOldBytes > 0 ? ((savedBytes / totalOldBytes) * 100).toFixed(1) : 0) + '%)');
} else {
$('#stat-saved').css('color', '#e74c3c').text('-' + formatBytesJS(Math.abs(savedBytes)) + ' (<?php echo $text_increase; ?>)');
}
// Накопление кумулятивной статистики
$(document).trigger('img_opti_batch_done', [json['batch_old'], json['batch_new'], json['done'] || 1]);
}
processedFiles += json['done'];
optimizedFiles += json['optimized'] || 0;
var percent = totalFiles > 0 ? Math.round((processedFiles / totalFiles) * 100) : 100;
$('#progress-bar').css('width', percent + '%');
$('#progress-text').text(processedFiles + ' / ' + totalFiles + ' (' + percent + '%, <?php echo $text_optimized; ?>: ' + optimizedFiles + ')');
if (!json['finished']) {
if (!isPaused && !isStopped) {
processBatch();
} else {
activeThreads--;
}
} else {
activeThreads--;
if (activeThreads <= 0) {
$('#progress-bar').removeClass('active progress-bar-striped');
fullLogArray.push('<div style="color:#0f0; margin-top:20px; font-weight:bold; font-size:16px;"><?php echo $text_done; ?> (<?php echo $text_optimized; ?>: ' + optimizedFiles + ')</div>');
renderLogPage();
resetButtons();
if ($('#input-mode').val() == 'copy') {
$('#current-copy-folder').text($('#copy_folder').val());
$('#apply-block').slideDown();
}
}
}
},
error: function(xhr) {
if (isStopped) {
activeThreads--;
return;
}
fullLogArray.push('<div class="text-danger" style="margin:5px 0;"><?php echo $error_timeout; ?></div>');
renderLogPage();
setTimeout(function() {
if (!isPaused && !isStopped) {
processBatch();
} else {
activeThreads--;
}
}, 3000);
}
});
}
$(document).on('click', '#btn-apply-changes', function() {
var backup = $('input[name="apply_backup"]:checked').val();
var folder = $('#copy_folder').val();
$.ajax({
url: 'index.php?route=module/img_opti/applyChanges&' + tokenParam,
type: 'post',
data: { backup: backup, copy_folder: folder },
dataType: 'json',
beforeSend: function() { $('#btn-apply-changes').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> <?php echo $text_processing; ?>'); },
success: function(json) {
$('#btn-apply-changes').prop('disabled', false).html('<i class="fa fa-refresh"></i> <?php echo $button_apply_main; ?>');
if (json['error']) alert(json['error']);
if (json['success']) {
alert(json['success']);
$('#apply-block').slideUp();
}
}
});
});
$(document).on('click', '#btn-clear-copies', function() {
if (!confirm('<?php echo $button_delete_copies; ?>?')) return;
clearSpecificTrash();
});
$(document).on('click', '#btn-full-cleanup', function() {
if (!confirm('<?php echo $confirm_full_cleanup; ?>')) return;
clearSpecificTrash();
});
function clearSpecificTrash() {
$.ajax({
url: 'index.php?route=module/img_opti/clearTrash&' + tokenParam,
dataType: 'json',
success: function(json) {
if (json['success']) {
alert(json['success']);
$('#apply-block').slideUp();
}
}
});
}
var cleanerCurrentPage = 1;
var cleanerFullLogArray = [];
function renderCleanerLogPage() {
var limit = parseInt($('#cleaner_log_limit').val(), 10) || 200;
var totalPages = Math.max(1, Math.ceil(cleanerFullLogArray.length / limit));
if (cleanerCurrentPage > totalPages) {
cleanerCurrentPage = totalPages;
}
if (cleanerCurrentPage < 1) {
cleanerCurrentPage = 1;
}
$('#cleaner-log-page-info').text('<?php echo $text_page; ?> ' + cleanerCurrentPage + ' / ' + totalPages);
var pageLogs = cleanerFullLogArray.slice((cleanerCurrentPage - 1) * limit, cleanerCurrentPage * limit);
var dirsInfo = '';
if ($('#cleaner-log-window').find('.scanned-dirs').length > 0) {
dirsInfo = $('#cleaner-log-window').find('.scanned-dirs').prop('outerHTML');
}
$('#cleaner-log-window').html(dirsInfo + pageLogs.join(''));
if (cleanerCurrentPage === totalPages) {
$('#cleaner-log-window').scrollTop($('#cleaner-log-window')[0].scrollHeight);
}
}
$(document).on('click', '#cleaner-log-prev', function(e) {
e.preventDefault();
if (cleanerCurrentPage > 1) {
cleanerCurrentPage--;
renderCleanerLogPage();
}
});
$(document).on('click', '#cleaner-log-next', function(e) {
e.preventDefault();
var limit = parseInt($('#cleaner_log_limit').val(), 10) || 200;
if (cleanerCurrentPage < Math.ceil(cleanerFullLogArray.length / limit)) {
cleanerCurrentPage++;
renderCleanerLogPage();
}
});
$(document).on('click', '#cleaner-btn-download-log', function(e) {
e.preventDefault();
if (cleanerFullLogArray.length === 0) {
alert('<?php echo $error_log_empty; ?>');
return;
}
var plainTextLog = cleanerFullLogArray.map(function(html) {
return $('<div>').html(html).text().trim();
}).join('\r\n');
var header = "<?php echo $text_report_header; ?>\r\n=============================\r\n\r\n";
var blob = new Blob([header + plainTextLog], { type: 'text/plain;charset=utf-8' });
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'img_cleaner_log.txt';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
});
$(document).on('click', '#btn-scan-trash', function(e) {
e.preventDefault();
$('#cleaner-status-box').slideDown();
$('#cleaner-action-buttons').hide();
$('#cleaner-log-pagination').hide();
$('#cleaner-status-text').html('<i class="fa fa-spinner fa-spin"></i> <?php echo $text_building_index; ?><br><small class="text-muted"><?php echo $text_analyzing; ?></small>');
$('#cleaner-log-window').html('');
cleanerFullLogArray = [];
cleanerCurrentPage = 1;
$.ajax({
url: 'index.php?route=module/img_opti/build_index&' + tokenParam,
type: 'post',
data: { module_token: $('#module_token').val() },
dataType: 'json',
success: function(json) {
if (json['error']) {
$('#cleaner-status-text').html('<span class="text-danger">' + json['error'] + '</span>');
return;
}
$('#cleaner-status-text').html('<i class="fa fa-spinner fa-spin"></i> <?php echo $text_comparing; ?>');
$.ajax({
url: 'index.php?route=module/img_opti/scan_trash&' + tokenParam,
type: 'post',
data: $('#form-cleaner :input').serialize() + '&module_token=' + $('#module_token').val(),
dataType: 'json',
success: function(res) {
if (res['error']) {
$('#cleaner-status-text').html('<span class="text-danger">' + res['error'] + '</span>');
return;
}
var dirsHtml = '<div class="scanned-dirs" style="color:#aaa; border-bottom:1px solid #333; margin-bottom:10px; padding-bottom:5px;"><?php echo $text_scanning_dirs; ?><br><b>' + res['scanned_folders'] + '</b></div>';
$('#cleaner-log-window').html(dirsHtml);
if (res['log'] && res['log'].length > 0) {
cleanerFullLogArray = res['log'];
$('#cleaner-log-pagination').show();
renderCleanerLogPage();
}
if (res['total'] > 0) {
$('#cleaner-status-text').html(
'<span style="color:#e74c3c; font-size:15px;"><?php echo $text_trash_files; ?>' + res['total'] + '<br>' +
'<?php echo $text_trash_size; ?>' + formatBytesJS(res['total_bytes']) + '</span>'
);
$('#cleaner-action-buttons').slideDown();
} else {
$('#cleaner-status-text').html('<span style="color:#2ecc71;"><?php echo $text_no_trash; ?></span>');
if (cleanerFullLogArray.length === 0) {
$('#cleaner-log-window').append('<i style="color:#2ecc71;"><?php echo $text_clean_empty; ?></i>');
}
}
}
});
}
});
});
$(document).on('click', '#btn-do-quarantine, #btn-do-delete', function(e) {
e.preventDefault();
var action = $(this).attr('id') === 'btn-do-delete' ? 'delete' : 'quarantine';
if (action === 'delete' && !confirm('<?php echo $confirm_delete; ?>')) return;
$('#cleaner-action-buttons').hide();
$('#cleaner-status-text').html('<i class="fa fa-spinner fa-spin"></i> <?php echo $text_processing; ?>');
cleanerFullLogArray = [];
cleanerCurrentPage = 1;
function processTrashBatch() {
$.ajax({
url: 'index.php?route=module/img_opti/process_trash&' + tokenParam,
type: 'post',
data: { action: action, module_token: $('#module_token').val() },
dataType: 'json',
success: function(json) {
if (json['error']) {
$('#cleaner-status-text').html('<span class="text-danger">' + json['error'] + '</span>');
return;
}
if (json['log'] && json['log'].length > 0) {
cleanerFullLogArray = cleanerFullLogArray.concat(json['log']);
renderCleanerLogPage();
}
if (!json['finished']) {
processTrashBatch();
} else {
var msg = action === 'quarantine' ? '<?php echo $text_quarantine_done; ?>' : '<?php echo $text_deleted_done; ?>';
$('#cleaner-status-text').html('<span style="color:#2ecc71; font-size:15px; font-weight:bold;">' + msg + '</span>');
}
}
});
}
processTrashBatch();
});
$(document).on('click', '#btn-empty-quarantine', function(e) {
e.preventDefault();
if (!confirm('<?php echo $confirm_empty_q; ?>')) return;
$.ajax({
url: 'index.php?route=module/img_opti/empty_quarantine&' + tokenParam,
type: 'post',
data: { module_token: $('#module_token').val() },
dataType: 'json',
success: function(json) {
if (json['error']) {
alert(json['error']);
return;
}
alert('<?php echo $text_quarantine_empty; ?>');
}
});
});
$(document).on('click', '#btn-restore-quarantine', function(e) {
e.preventDefault();
if (!confirm('<?php echo $confirm_restore; ?>')) return;
$('#cleaner-status-box').slideDown();
$('#cleaner-action-buttons').hide();
$('#cleaner-log-pagination').hide();
$('#cleaner-status-text').html('<i class="fa fa-spinner fa-spin"></i> <?php echo $text_restoring; ?>');
cleanerFullLogArray = [];
cleanerCurrentPage = 1;
$('#cleaner-log-window').html('');
$('#cleaner-log-pagination').show();
$.ajax({
url: 'index.php?route=module/img_opti/restore_quarantine&' + tokenParam,
type: 'post',
data: { module_token: $('#module_token').val() },
dataType: 'json',
success: function(json) {
if (json['error']) {
$('#cleaner-status-text').html('<span class="text-danger">' + json['error'] + '</span>');
return;
}
if (json['log'] && json['log'].length > 0) {
cleanerFullLogArray = json['log'];
renderCleanerLogPage();
}
$('#cleaner-status-text').html('<span style="color:#3498db; font-size:15px; font-weight:bold;"><?php echo $text_restore_done; ?></span>');
}
});
});
var activeThreads = 0;
var threadsCount = 1;
var isDragging = false;
var containerWidth = 0;
var imgBefore = new Image();
var imgAfter = new Image();
var loadedCount = 0;
function checkLoaded() {
loadedCount++;
if (loadedCount === 2) {
$('#compare-loader').hide();
$('#compare-container').show();
var maxW = 750;
var maxH = 500;
var origW = imgBefore.width || 500;
var origH = imgBefore.height || 500;
var ratioX = maxW / origW;
var ratioY = maxH / origH;
var ratio = Math.min(ratioX, ratioY, 1);
var w = Math.round(origW * ratio);
var h = Math.round(origH * ratio);
initCompareSlider(w, h);
}
}
function initCompareSlider(width, height) {
var $container = $('#compare-container');
$container.css({
width: width + 'px',
height: height + 'px'
});
containerWidth = width;
var $before = $('.compare-before');
var $after = $('.compare-after');
var $beforeImg = $('#img-before');
var $afterImg = $('#img-after');
var $handle = $('.compare-handle');
$beforeImg.css({ width: width + 'px', height: height + 'px' });
$afterImg.css({ width: width + 'px', height: height + 'px' });
var startX = width / 2;
updateSlider(startX);
$container.off('mousedown touchstart').on('mousedown touchstart', function(e) {
isDragging = true;
moveSlider(e);
});
$(window).off('mousemove touchmove').on('mousemove touchmove', function(e) {
if (!isDragging) return;
moveSlider(e);
});
$(window).off('mouseup touchend').on('mouseup touchend', function() {
isDragging = false;
});
function moveSlider(e) {
var pageX = e.pageX || (e.originalEvent.touches ? e.originalEvent.touches[0].pageX : 0);
var offsetLeft = $container.offset().left;
var x = pageX - offsetLeft;
if (x < 0) x = 0;
if (x > containerWidth) x = containerWidth;
updateSlider(x);
}
function updateSlider(x) {
$after.css('width', (containerWidth - x) + 'px');
$after.css('left', x + 'px');
$afterImg.css('margin-left', '-' + x + 'px');
$handle.css('left', x + 'px');
}
}
$(document).on('click', '.btn-compare-preview, .btn-compare-opti', function(e) {
e.preventDefault();
var id = $(this).data('id') || $(this).data('path');
var tool = $(this).data('id') ? currentTool : 'optimization';
$('#modal-compare').modal('show');
$('#compare-loader').show();
$('#compare-container').hide();
$('#img-before').attr('src', '');
$('#img-after').attr('src', '');
var postData = { id: id, tool: tool };
if ($('input[name="max_width"]').length) postData.max_width = $('input[name="max_width"]').val();
if ($('input[name="max_height"]').length) postData.max_height = $('input[name="max_height"]').val();
if ($('input[name="jpg_quality"]').length) postData.jpg_quality = $('input[name="jpg_quality"]').val();
if ($('input[name="png_quality"]').length) postData.png_quality = $('input[name="png_quality"]').val();
if ($('input[name="webp_quality"]').length) postData.webp_quality = $('input[name="webp_quality"]').val();
$.ajax({
url: 'index.php?route=module/img_opti/compare_preview&' + tokenParam,
type: 'post',
data: postData,
dataType: 'json',
success: function(json) {
if (json['error']) {
alert(json['error']);
$('#modal-compare').modal('hide');
} else {
$('#size-before').text(json['size_before']);
$('#size-after').text(json['size_after']);
$('#saving-percent').text(json['saving'] + '%');
loadedCount = 0;
imgBefore = new Image();
imgBefore.onload = checkLoaded;
imgBefore.src = json['before'];
$('#img-before').attr('src', json['before']);
imgAfter = new Image();
imgAfter.onload = checkLoaded;
imgAfter.src = json['after'];
$('#img-after').attr('src', json['after']);
}
}
});
});
$(document).on('click', '#btn-download-copies', function(e) {
e.preventDefault();
var folder = $('#copy_folder').val();
if (!folder) return;
window.location = 'index.php?route=module/img_opti/download_folder&' + tokenParam + '&folder=' + encodeURIComponent(folder);
setTimeout(function() {
if (confirm('<?php echo $confirm_download_and_delete; ?>')) {
$.ajax({
url: 'index.php?route=module/img_opti/clearTrash&' + tokenParam,
type: 'post',
data: { folder: folder },
dataType: 'json',
success: function(json) {
if (json['success']) {
alert(json['success']);
$('#apply-block').slideUp();
} else if (json['error']) {
alert(json['error']);
}
}
});
}
}, 2000);
});
$(document).on('click', '#btn-clear-backups', function(e) {
e.preventDefault();
if (!confirm('<?php echo $confirm_clear_backups; ?>')) return;
$.ajax({
url: 'index.php?route=module/img_opti/clear_backups&' + tokenParam,
dataType: 'json',
success: function(json) {
if (json['success']) {
alert(json['success']);
} else if (json['error']) {
alert(json['error']);
}
}
});
});
var rule_row = <?php echo isset($rule_row) ? $rule_row : 0; ?>;
function addRule() {
var html = '<tr id="rule-row' + rule_row + '">';
html += ' <td class="text-left"><input type="text" name="module_img_opti_folder_rules[' + rule_row + '][folder]" value="" placeholder="catalog/banners/" class="form-control" /></td>';
html += ' <td class="text-left"><input type="number" name="module_img_opti_folder_rules[' + rule_row + '][jpg_quality]" value="" placeholder="72" min="1" max="100" class="form-control" /></td>';
html += ' <td class="text-left"><input type="number" name="module_img_opti_folder_rules[' + rule_row + '][webp_quality]" value="" placeholder="80" min="1" max="100" class="form-control" /></td>';
html += ' <td class="text-left"><input type="number" name="module_img_opti_folder_rules[' + rule_row + '][max_width]" value="" placeholder="1600" min="0" class="form-control" /></td>';
html += ' <td class="text-left"><input type="number" name="module_img_opti_folder_rules[' + rule_row + '][max_height]" value="" placeholder="1600" min="0" class="form-control" /></td>';
html += ' <td class="text-left"><button type="button" onclick="$(\'#rule-row' + rule_row + '\').remove();" data-toggle="tooltip" title="<?php echo $button_remove; ?>" class="btn btn-danger"><i class="fa fa-minus-circle"></i></button></td>';
html += '</tr>';
$('#folder-rules tbody').append(html);
rule_row++;
}
// ============ DISK PIE CHART ============
function drawDiskPie(data) {
var canvas = document.getElementById('disk-pie-chart');
if (!canvas || !canvas.getContext) return;
var ctx = canvas.getContext('2d');
var total = data.disk_total || 1;
var slices = [
{ label: '<?php echo $text_disk_catalog; ?>', bytes: data.catalog, color: '#3498db' },
{ label: '<?php echo $text_disk_cache; ?>', bytes: data.oc_cache, color: '#e67e22' },
{ label: '<?php echo $text_disk_trash; ?>', bytes: data.module_trash, color: '#e74c3c' },
{ label: '<?php echo $text_disk_other; ?>', bytes: Math.max(0, (total - data.disk_free) - data.catalog - data.oc_cache - data.module_trash), color: '#95a5a6' },
{ label: '<?php echo $text_disk_free; ?>', bytes: data.disk_free, color: '#2ecc71' }
];
var cx = 110, cy = 110, r = 100;
var start = -Math.PI / 2;
ctx.clearRect(0, 0, 220, 220);
slices.forEach(function(s) {
var angle = (s.bytes / total) * 2 * Math.PI;
if (angle < 0.001) return;
ctx.beginPath(); ctx.moveTo(cx, cy);
ctx.arc(cx, cy, r, start, start + angle);
ctx.closePath(); ctx.fillStyle = s.color; ctx.fill();
ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.stroke();
start += angle;
});
var legend = document.getElementById('disk-legend');
legend.innerHTML = slices.map(function(s) {
if (s.bytes <= 0) return '';
return '<div style="margin:3px 0;"><span style="display:inline-block;width:12px;height:12px;background:'+s.color+';border-radius:2px;margin-right:6px;vertical-align:middle;"></span>'
+ '<b>'+s.label+'</b>: '+formatBytesJS(s.bytes)+' ('+(s.bytes/total*100).toFixed(1)+'%)</div>';
}).join('');
$('#disk-loading').hide();
}
$('#btn-load-disk').on('click', function(e, triggerType) {
var isManual = (triggerType !== 'auto');
var btn = $(this).prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i>');
$('#disk-loading').show().text('<?php echo $text_loading; ?>...');
var url = 'index.php?route=module/img_opti/get_disk_stats&' + tokenParam;
if (isManual) {
url += '&refresh=1';
}
$.getJSON(url, function(data) {
if (data.error) { $('#disk-loading').text(data.error); }
else { drawDiskPie(data); }
}).always(function() { btn.prop('disabled', false).html('<i class="fa fa-refresh"></i>'); });
});
// ============ CUMULATIVE STATS ============
function loadCumulativeStats() {
var stored = null;
try { stored = JSON.parse(localStorage.getItem('img_opti_cumulative') || 'null'); } catch(e){}
if (stored && stored.files > 0) {
$('#cs-files').text(stored.files.toLocaleString());
$('#cs-saved').text(formatBytesJS(stored.saved));
var pct = stored.old > 0 ? ((stored.saved / stored.old) * 100).toFixed(1) : 0;
$('#cs-pct').text(pct + '%');
} else {
$('#cs-files').text('0'); $('#cs-saved').text('0 B'); $('#cs-pct').text('0%');
}
}
loadCumulativeStats();
var autoDisk = localStorage.getItem('img_opti_auto_disk');
if (autoDisk === null) {
autoDisk = '1';
}
$('#chk-auto-disk').prop('checked', autoDisk === '1');
$('#chk-auto-disk').on('change', function() {
localStorage.setItem('img_opti_auto_disk', this.checked ? '1' : '0');
});
if (autoDisk === '1') {
$('#btn-load-disk').trigger('click', ['auto']);
}
$(document).on('img_opti_batch_done', function(e, batchOld, batchNew, batchFiles) {
var stored = null;
try { stored = JSON.parse(localStorage.getItem('img_opti_cumulative') || 'null'); } catch(e){}
if (!stored) stored = { files: 0, old: 0, saved: 0 };
stored.files += (batchFiles || 0);
stored.old += (batchOld || 0);
stored.saved += Math.max(0, (batchOld || 0) - (batchNew || 0));
localStorage.setItem('img_opti_cumulative', JSON.stringify(stored));
loadCumulativeStats();
});
$('#btn-reset-stats').on('click', function() {
if (!confirm('<?php echo $text_reset_stats_confirm; ?>')) return;
localStorage.removeItem('img_opti_cumulative');
loadCumulativeStats();
});
// ============ IMPORT SETTINGS ============
$('#import-settings-file').on('change', function() {
var file = this.files[0];
if (!file) return;
var status = $('#import-settings-status');
status.html('<i class="fa fa-spinner fa-spin"></i>');
var fd = new FormData();
fd.append('import_json', file);
$.ajax({
url: 'index.php?route=module/img_opti/import_settings&' + tokenParam,
type: 'POST', data: fd, processData: false, contentType: false, dataType: 'json',
success: function(json) {
if (json.error) status.html('<span class="text-danger"><i class="fa fa-times"></i> ' + json.error + '</span>');
else status.html('<span class="text-success"><i class="fa fa-check"></i> <?php echo $text_import_success; ?></span>');
},
error: function() { status.html('<span class="text-danger"><i class="fa fa-times"></i> Error</span>'); }
});
this.value = '';
});
// ============ PERSIST ACTIVE TAB ============
$(document).ready(function() {
var activeTab = localStorage.getItem('nat_active_tab_img_opti');
if (activeTab) {
$('.nav-tabs').first().find('a[href="' + activeTab + '"]').tab('show');
}
$('.nav-tabs').first().on('shown.bs.tab', 'a[data-toggle="tab"]', function(e) {
localStorage.setItem('nat_active_tab_img_opti', $(e.target).attr('href'));
});
});
</script>
<div class="modal fade" id="modal-compare" tabindex="-1" role="dialog" aria-labelledby="compareModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" style="background: #222; color: #fff;">
<div class="modal-header" style="border-bottom: 1px solid #444;">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" style="color: #fff; opacity: 0.8;"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="compareModalLabel"><i class="fa fa-balance-scale"></i> <?php echo $text_compare_title; ?></h4>
</div>
<div class="modal-body" style="padding: 20px; text-align: center; overflow: hidden; position: relative;">
<div id="compare-loader" style="padding: 50px 0;"><i class="fa fa-spinner fa-spin fa-3x"></i></div>
<div id="compare-container" style="display: none; position: relative; overflow: hidden; margin: 0 auto; user-select: none; -webkit-user-select: none; -moz-user-select: none;">
<div class="compare-img compare-before" style="position: absolute; top:0; left:0; width:100%; height:100%; overflow:hidden;">
<img id="img-before" src="" style="display:block; max-width:none; height:100%; width:100%; pointer-events:none;">
<span class="label label-danger" style="position:absolute; top:10px; left:10px; z-index:10; font-size:12px;"><?php echo $text_compare_before; ?>: <span id="size-before"></span></span>
</div>
<div class="compare-img compare-after" style="position: absolute; top:0; left:0; width:100%; height:100%; overflow:hidden; border-left: 2px solid #3498db;">
<img id="img-after" src="" style="display:block; max-width:none; height:100%; width:100%; pointer-events:none;">
<span class="label label-success" style="position:absolute; top:10px; right:10px; z-index:10; font-size:12px;"><?php echo $text_compare_after; ?>: <span id="size-after"></span> (<span id="saving-percent"></span>)</span>
</div>
<div class="compare-handle" style="position:absolute; top:0; bottom:0; width:4px; background:#3498db; cursor:ew-resize; z-index:20; margin-left:-2px;">
<div style="position:absolute; top:50%; left:50%; margin-top:-20px; margin-left:-20px; width:40px; height:40px; background:#3498db; border-radius:50%; line-height:40px; text-align:center; color:#fff; box-shadow:0 0 10px rgba(0,0,0,0.5);"><i class="fa fa-arrows-h"></i></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal-wm-rule" tabindex="-1" role="dialog" aria-labelledby="modal-wm-rule-title">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="modal-wm-rule-title"><?php echo $text_wm_rule_title; ?></h4>
</div>
<div class="modal-body" style="max-height: calc(100vh - 220px); overflow-y: auto;">
<form id="form-wm-rule" class="form-horizontal">
<input type="hidden" id="wm-rule-index" value="" />
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_rule_status; ?></label>
<div class="col-sm-9">
<select id="wm-rule-status" class="form-control">
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_rule_name; ?></label>
<div class="col-sm-9">
<input type="text" id="wm-rule-name" class="form-control" placeholder="Default Rule" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_type; ?></label>
<div class="col-sm-9">
<select id="wm-rule-type" class="form-control">
<option value="image"><?php echo $text_wm_image; ?></option>
<option value="text"><?php echo $text_wm_text; ?></option>
</select>
</div>
</div>
<div class="form-group wm-rule-image-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_image_path; ?></label>
<div class="col-sm-9">
<a href="" id="thumb-modal-wm-image" data-toggle="image" class="img-thumbnail"><img src="<?php echo $placeholder; ?>" alt="" title="" data-placeholder="<?php echo $placeholder; ?>" /></a>
<input type="hidden" id="input-modal-wm-image" value="" />
</div>
</div>
<div class="form-group wm-rule-text-group" style="display:none;">
<label class="col-sm-3 control-label"><?php echo $entry_wm_text_val; ?></label>
<div class="col-sm-9">
<input type="text" id="wm-rule-text-val" class="form-control" />
</div>
</div>
<div class="form-group wm-rule-text-group" style="display:none;">
<label class="col-sm-3 control-label"><?php echo $entry_wm_text_font; ?></label>
<div class="col-sm-9">
<select id="wm-rule-text-font" class="form-control">
<option value=""><?php echo $text_no_fonts; ?></option>
<?php foreach ($ttf_fonts as $font) { ?>
<option value="<?php echo $font[\'path\']; ?>"><?php echo $font[\'name\']; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group wm-rule-text-group" style="display:none;">
<label class="col-sm-3 control-label"><?php echo $entry_wm_text_color; ?></label>
<div class="col-sm-9">
<div class="input-group">
<span class="input-group-addon" id="modal-wm-color-preview" style="background:#ffffff; width:36px;">&nbsp;</span>
<input type="text" id="wm-rule-text-color" class="form-control" placeholder="#ffffff" maxlength="7"/>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_opacity; ?> (0-100)</label>
<div class="col-sm-9">
<input type="number" id="wm-rule-opacity" class="form-control" min="0" max="100" value="50" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_position; ?></label>
<div class="col-sm-9">
<select id="wm-rule-position" class="form-control">
<option value="1"><?php echo $text_position_1; ?></option>
<option value="2"><?php echo $text_position_2; ?></option>
<option value="3"><?php echo $text_position_3; ?></option>
<option value="4"><?php echo $text_position_4; ?></option>
<option value="5" selected="selected"><?php echo $text_position_5; ?></option>
<option value="6"><?php echo $text_position_6; ?></option>
<option value="7"><?php echo $text_position_7; ?></option>
<option value="8"><?php echo $text_position_8; ?></option>
<option value="9"><?php echo $text_position_9; ?></option>
</select>
</div>
</div>
<div class="form-group wm-rule-image-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_size_type; ?></label>
<div class="col-sm-9">
<select id="wm-rule-size-type" class="form-control">
<option value="original"><?php echo $text_wm_size_original; ?></option>
<option value="percent"><?php echo $text_wm_size_percent; ?></option>
</select>
</div>
</div>
<div class="form-group wm-rule-size-percent-group" style="display:none;">
<label class="col-sm-3 control-label"><?php echo $entry_wm_size_percent; ?></label>
<div class="col-sm-9">
<input type="number" id="wm-rule-size-percent" class="form-control" min="1" max="100" value="20" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_angle; ?></label>
<div class="col-sm-9">
<input type="number" id="wm-rule-angle" class="form-control" min="-360" max="360" value="0" />
</div>
</div>
<div class="form-group wm-rule-image-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_corner_radius; ?></label>
<div class="col-sm-9">
<input type="number" id="wm-rule-corner-radius" class="form-control" min="0" max="200" value="0" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><b><?php echo $entry_wm_targets; ?></b></label>
<div class="col-sm-9">
<div class="well well-sm" style="background:#222; border:1px solid #444; padding:10px; margin-bottom:10px;">
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="wm-rule-target-product" value="1" checked="checked"> <?php echo $text_wm_target_product; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="wm-rule-target-category" value="1"> <?php echo $text_wm_target_category; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="wm-rule-target-brand" value="1"> <?php echo $text_wm_target_brand; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="wm-rule-target-banner" value="1"> <?php echo $text_wm_target_banner; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="wm-rule-target-blog" value="1"> <?php echo $text_wm_target_blog; ?>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_filter_mode; ?></label>
<div class="col-sm-9">
<select id="wm-rule-filter-mode" class="form-control">
<option value="include"><?php echo $text_wm_filter_include; ?></option>
<option value="exclude"><?php echo $text_wm_filter_exclude; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_category; ?></label>
<div class="col-sm-9">
<input type="text" id="input-modal-wm-category" value="" placeholder="Search..." class="form-control" />
<div id="modal-wm-category-list" class="well well-sm" style="height: 100px; overflow: auto; margin-top: 5px;">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_brand; ?></label>
<div class="col-sm-9">
<input type="text" id="input-modal-wm-brand" value="" placeholder="Search..." class="form-control" />
<div id="modal-wm-brand-list" class="well well-sm" style="height: 100px; overflow: auto; margin-top: 5px;">
</div>
</div>
</div>
<div class="form-group" style="margin-top:10px;">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-9">
<button type="button" id="btn-modal-wm-preview" class="btn btn-info"><i class="fa fa-eye"></i> <?php echo $button_preview_watermark; ?></button>
<div id="modal-wm-preview-container" style="display:none; margin-top:15px; text-align:center; border:2px dashed #2c3e50; padding:15px; border-radius:4px; background:#f8f9fa;">
<div style="font-weight:bold; color:#2c3e50; margin-bottom:8px;"><i class="fa fa-image"></i> <?php echo $text_wm_preview_title; ?></div>
<img id="modal-wm-preview-img" src="" style="max-width:100%; max-height:300px; border:2px solid #2c3e50; border-radius:4px;" />
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><?php echo $button_close; ?></button>
<button type="button" class="btn btn-primary" id="btn-save-wm-rule"><?php echo $button_save; ?></button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal-ph-rule" tabindex="-1" role="dialog" aria-labelledby="modal-ph-rule-title">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="modal-ph-rule-title"><?php echo $text_ph_rule_title; ?></h4>
</div>
<div class="modal-body" style="max-height: calc(100vh - 220px); overflow-y: auto;">
<form id="form-ph-rule" class="form-horizontal">
<input type="hidden" id="ph-rule-index" value="" />
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_rule_status; ?></label>
<div class="col-sm-9">
<select id="ph-rule-status" class="form-control">
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_rule_name; ?></label>
<div class="col-sm-9">
<input type="text" id="ph-rule-name" class="form-control" placeholder="Products Placeholder" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><b><?php echo $entry_wm_targets; ?></b></label>
<div class="col-sm-9">
<div class="well well-sm" style="background:#222; border:1px solid #444; padding:10px; margin-bottom:10px;">
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="ph-rule-target-product" value="1" checked="checked"> <?php echo $text_wm_target_product; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="ph-rule-target-category" value="1"> <?php echo $text_wm_target_category; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" id="ph-rule-target-brand" value="1"> <?php echo $text_wm_target_brand; ?>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_ph_image; ?></label>
<div class="col-sm-9">
<a href="" id="thumb-modal-ph-image" data-toggle="image" class="img-thumbnail"><img src="<?php echo $placeholder; ?>" alt="" title="" data-placeholder="<?php echo $placeholder; ?>" /></a>
<input type="hidden" id="input-modal-ph-image" value="" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_filter_mode; ?></label>
<div class="col-sm-9">
<select id="ph-rule-filter-mode" class="form-control">
<option value="include"><?php echo $text_wm_filter_include; ?></option>
<option value="exclude" selected="selected"><?php echo $text_wm_filter_exclude; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_category; ?></label>
<div class="col-sm-9">
<input type="text" id="input-modal-ph-category" value="" placeholder="Search..." class="form-control" />
<div id="modal-ph-category-list" class="well well-sm" style="height: 100px; overflow: auto; margin-top: 5px;">
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_wm_brand; ?></label>
<div class="col-sm-9">
<input type="text" id="input-modal-ph-brand" value="" placeholder="Search..." class="form-control" />
<div id="modal-ph-brand-list" class="well well-sm" style="height: 100px; overflow: auto; margin-top: 5px;">
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><?php echo $button_close; ?></button>
<button type="button" class="btn btn-primary" id="btn-save-ph-rule"><?php echo $button_save; ?></button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal-cron-task" tabindex="-1" role="dialog" aria-labelledby="modal-cron-task-title">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="modal-cron-task-title"><?php echo $entry_cron_task_name; ?></h4>
</div>
<div class="modal-body" style="max-height: calc(100vh - 220px); overflow-y: auto;">
<form id="form-cron-task" class="form-horizontal">
<input type="hidden" id="cron-task-index" value="" />
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_rule_status; ?></label>
<div class="col-sm-9">
<select id="cron-task-status" class="form-control">
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_cron_task_name; ?></label>
<div class="col-sm-9">
<input type="text" id="cron-task-name" class="form-control" placeholder="Default Task" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-9">
<div class="checkbox">
<label>
<input type="checkbox" id="cron-task-new-only" value="1" checked="checked"> <b><?php echo $entry_cron_new_only; ?></b>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><b><?php echo $text_cron_entities; ?></b></label>
<div class="col-sm-9">
<div class="well well-sm" style="background:#222; border:1px solid #444; padding:10px; margin-bottom:10px;">
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" class="cron-task-entity" value="product" checked="checked"> <?php echo $text_cron_entity_product; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" class="cron-task-entity" value="category" checked="checked"> <?php echo $text_cron_entity_category; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" class="cron-task-entity" value="manufacturer" checked="checked"> <?php echo $text_cron_entity_manufacturer; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" class="cron-task-entity" value="banner" checked="checked"> <?php echo $text_cron_entity_banner; ?>
</label>
<label class="checkbox-inline" style="color:#fff; margin-left:0; margin-right:15px;">
<input type="checkbox" class="cron-task-entity" value="blog" checked="checked"> <?php echo $text_cron_entity_blog; ?>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_cron_folder_mode; ?></label>
<div class="col-sm-9">
<select id="cron-task-folder-mode" class="form-control">
<option value="exclude"><?php echo $text_cron_folder_mode_exclude; ?></option>
<option value="include"><?php echo $text_cron_folder_mode_include; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $text_cron_folder_scan; ?></label>
<div class="col-sm-9">
<div style="margin-bottom: 10px;">
<button type="button" class="btn btn-default btn-xs btn-cron-task-select-all"><i class="fa fa-check-square-o"></i> <?php echo $button_select_all; ?></button>
<button type="button" class="btn btn-default btn-xs btn-cron-task-deselect-all" style="margin-left: 5px;"><i class="fa fa-square-o"></i> <?php echo $button_deselect_all; ?></button>
</div>
<div class="cron-task-folders-container" style="max-height:200px; overflow-y:auto; padding:5px; border:1px solid #ddd; border-radius:4px; background:#fafafa;">
<?php if (isset($cron_folders_list) && $cron_folders_list) { ?>
<?php foreach ($cron_folders_list as $folder) { ?>
<div class="checkbox" style="margin-top: 5px; margin-bottom: 5px;">
<label>
<input type="checkbox" class="cron-task-folder-checkbox" value="<?php echo $folder; ?>"> <i class="fa fa-folder" style="color:#f39c12;"></i> <?php echo $folder; ?>
</label>
</div>
<?php } ?>
<?php } ?>
</div>
<div class="cron-task-folder-hint help-block" style="margin-top: 8px; font-weight: bold; color: #337ab7;"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-9">
<div class="checkbox">
<label>
<input type="checkbox" id="cron-task-quality-override" value="1"> <b><?php echo $text_cron_quality_override; ?></b>
</label>
</div>
</div>
</div>
<div id="cron-task-quality-fields" style="display:none;">
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_cron_jpg_quality; ?></label>
<div class="col-sm-9">
<input type="number" id="cron-task-jpg-quality" class="form-control" min="1" max="100" value="72" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_cron_webp_quality; ?></label>
<div class="col-sm-9">
<input type="number" id="cron-task-webp-quality" class="form-control" min="1" max="100" value="80" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_cron_max_width; ?></label>
<div class="col-sm-9">
<input type="number" id="cron-task-max-width" class="form-control" min="0" value="1600" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo $entry_cron_max_height; ?></label>
<div class="col-sm-9">
<input type="number" id="cron-task-max-height" class="form-control" min="0" value="1600" />
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><?php echo $button_close; ?></button>
<button type="button" class="btn btn-primary" id="btn-save-cron-task"><?php echo $button_save; ?></button>
</div>
</div>
</div>
</div>
<style>
#compare-container {
box-shadow: 0 0 20px rgba(0,0,0,0.8);
border-radius: 4px;
border: 1px solid #444;
}
.compare-img img {
object-fit: contain;
}
</style>
<?php echo $footer; ?>