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

3672 lines
197 KiB
Smarty
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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" style="padding: 3px 8px; background: #f8f9fa;">
<input type="color" id="wm-rule-text-color-picker" value="#ffffff" style="width: 28px; height: 24px; border: none; padding: 0; cursor: pointer; background: transparent; vertical-align: middle;" />
</span>
<input type="text" id="wm-rule-text-color" class="form-control" placeholder="#ffffff" maxlength="7" value="#ffffff" />
</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">
<div style="margin-bottom: 10px;">
<label style="font-weight:bold; margin-right:8px; display:inline-block; vertical-align:middle;">Фон прев'ю / Фон превью / Preview BG:</label>
<div class="btn-group" data-toggle="buttons" id="wm-preview-bg-switcher">
<label class="btn btn-default active" style="padding: 4px 10px; font-size: 12px;"><input type="radio" name="wm_preview_bg" value="product" checked="checked"> 🖼 Товар / Item</label>
<label class="btn btn-default" style="padding: 4px 10px; font-size: 12px;"><input type="radio" name="wm_preview_bg" value="white"> Білий / Белый</label>
<label class="btn btn-default" style="padding: 4px 10px; font-size: 12px;"><input type="radio" name="wm_preview_bg" value="transparent"> 🏁 Сітка / Сетка</label>
</div>
</div>
<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; ?>