Add X13 WebP module for image conversion to next-generation formats

- Implemented the X13Webp class with core functionalities for converting images to WebP format.
- Added support for different PHP versions and defined constants for versioning.
- Included translation strings for various user interface elements and messages.
- Created XML file for module versioning.
This commit is contained in:
2025-09-12 00:41:29 +02:00
parent fa0f4b590b
commit 9003eede2d
247 changed files with 55597 additions and 1 deletions

View File

@@ -0,0 +1,240 @@
<button id="x13webpTestButton" class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseTestCompression" aria-expanded="false" aria-controls="collapseTestCompression">
<i class="icon icon-photo" aria-hidden="true"></i> {l s='Test conversion' mod='x13webp'}
</button>
<div class="collapse" id="collapseTestCompression">
<div class="card" id="x13webp-products-search-wrapper">
<label class="control-label">{l s='Search product' mod='x13webp'}</label>
<input type="text" class="form-control" name="x13webp-search-product" id="x13webp-search-product" autocomplete="off">
<div id="x13webp-products-output">
<ul></ul>
</div>
</div>
<div id="x13webp-test-images-wrapper">
<div class="row hidden">
<div class="col-lg-6">
<div class="x13webp-image image-before">
<h4 class="title">{l s='Original images (before)' mod='x13webp'}</h4>
<h5 class="size"><strong><span class="kb">XXX KB</span> ({l s='image quality' mod='x13webp'}: <span class="percent"></span>%)</strong></h5>
<div class="image"></div>
</div>
</div>
<div class="col-lg-6">
<div class="x13webp-image image-after">
<h4 class="title">{l s='After compressed' mod='x13webp'}</h4>
<h5 class="size"><strong><span class="kb">KB</span> ({l s='image quality' mod='x13webp'}: <span class="percent"></span>%)</strong></h5>
<div class="image">
<div class="preloader"></div>
</div>
</div>
</div>
<div class="col-lg-12">
<button type="button" class="btn btn-default" id="x13webp-convert-image">{l s='Reconvert image' mod='x13webp'}</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(() => {
$('#x13webp-search-product').on('input', function(e){
if(e.keyCode == 13) {
e.preventDefault();
e.stopPropagation();
return false;
}
doX13AjaxSearch(this);
});
$(document).bind('click', function (e) {
if (!$(e.target).parents('#x13webp-products-search-wrapper').length && $('#x13webp-products-output ul').hasClass('active')) {
$('#x13webp-products-output ul').removeClass('active');
}
});
$('#x13webp-search-product').on('click', function () {
if ($('#x13webp-products-output ul').html() != '' && !$('#x13webp-products-output ul').hasClass('active')) {
$('#x13webp-products-output ul').addClass('active');
} else if($(this).val().length){
doX13AjaxSearch(this);
}
});
$('#x13webp-convert-image').on('click', function(){
if(!$(this).hasClass('disabled')){
$(this).addClass('disabled');
tryX13ConvertImage();
}
});
});
const doX13AjaxSearch = (input) => {
$.ajax({
url: "{$params.search_products_url}",
method: 'POST',
data: {
q: $(input).val(),
limit: 15
}
}).done((resp) => {
if(resp.length){
let row = '';
const products = JSON.parse(resp);
$(products).each(function(){
let ref = this.ref ? ' (ref: '+this.ref+')' : '';
row += '<li data-id_product="'+this.id+'">';
row += '<img src="'+this.image+'"><span>'+this.name+ref+'</span>';
row += '</li>';
});
$('#x13webp-products-output ul').html(row);
if (!$('#x13webp-products-output ul').hasClass('active')) {
$('#x13webp-products-output ul').addClass('active');
}
initX13ProductsClick();
} else {
$('#x13webp-products-output ul').removeClass('active')
}
});
};
const ajaxGetProductImage = (id_product) => {
let image = false;
$.ajax({
url: '{$params.product_image_url}',
method: 'POST',
async: false,
data: {
id_product
}
}).done((resp) => {
if(resp.length){
image = JSON.parse(resp);
}
});
return image;
}
const initX13ProductsClick = () => {
$('#x13webp-products-output ul li').on('click', function(){
$('#x13webp-test-images-wrapper .alert').remove();
$('#x13webp-test-images-wrapper .row').addClass('hidden');
$('#x13webp-test-images-wrapper .image-after .image a').remove();
$('#x13webp-test-images-wrapper .image-before .image a').remove();
$('#x13webp-products-output ul').html('').removeClass('active');
const img = ajaxGetProductImage($(this).data('id_product'));
const img_wrapper = $('#x13webp-test-images-wrapper .image-before .image');
if(!img.error){
img_wrapper
.data('id_product', $(this).data('id_product'))
.html('<a data-lightbox="conversion-test" href="'+img.url+'"><img src="'+img.url+'"/></a>');
img_wrapper.siblings('.size').find('.kb').text(img.size).siblings('.percent').text('100');
$('#x13webp-test-images-wrapper .row').removeClass('hidden');
tryX13ConvertImage();
} else {
$('#x13webp-test-images-wrapper').prepend('<div class="alert alert-danger">'+img.error+'</div>');
}
});
};
const tryX13ConvertImage = () => {
const form = $('#x13webp-test-images-wrapper').closest('form').get(0);
let data = new FormData(form);
data.append('test_conversion', 1);
data.append('id_product', $('#x13webp-test-images-wrapper .image-before .image').data('id_product'));
$.ajax({
url: '{$params.convert_image_url}',
method: 'POST',
data,
processData: false,
contentType: false,
beforeSend: function(){
$('#x13webp-test-images-wrapper .image-after .preloader').addClass('active');
$('#x13webp-test-images-wrapper .image-after a').remove();
$('#x13webp-test-images-wrapper').find('.alert').remove();
}
}).done((resp) => {
if(resp.length){
const output = JSON.parse(resp);
if(output.success && output.image_url.length){
$('#x13webp-test-images-wrapper .image-after .image')
.append('<a data-lightbox="conversion-test" href="'+output.image_url+'"><img src="'+output.image_url+'"></a>')
.siblings('.size')
.find('.kb')
.text(output.image_size)
.siblings('.percent')
.text(output.image_quality);
} else {
const error = output.error.length ? output.error : "{l s='A problem occured...' mod='x13webp'}";
$('#x13webp-test-images-wrapper').prepend('<div class="alert alert-danger">'+error+'</div>');
}
}
$('#x13webp-convert-image').removeClass('disabled');
$('#x13webp-test-images-wrapper .image-after .preloader').removeClass('active');
});
}
</script>

View File

@@ -0,0 +1,281 @@
{extends file="helpers/form/form.tpl"}
{block name="script"}
$(document).ready(function() {
$('.rangeslider').each(function(){
const rangeslider_input = $(this).closest('.row').find('.rangeslider-input');
const rangeslider = $(this).slider({
value: rangeslider_input.val()
}).on('slide', function(event, ui){
rangeslider_input.val(ui.value);
});
$(rangeslider_input).on("input", function() {
this.value = this.value.replace(/\D/g,'');
if (this.value < 0) this.value = 0;
if (this.value > 100) this.value = 100;
rangeslider.slider( "option", "value", this.value);
});
});
$('.iframe-upload').fancybox({
'width' : 900,
'height' : 600,
'type' : 'iframe',
'autoScale' : false,
'autoDimensions': false,
'fitToView' : false,
'autoSize' : false,
onUpdate : function() {
$('.fancybox-iframe').contents().find('a.link').data('field_id', $(this.element).data("input-name"));
$('.fancybox-iframe').contents().find('a.link').attr('data-field_id', $(this.element).data("input-name"));
},
afterShow: function() {
$('.fancybox-iframe').contents().find('a.link').data('field_id', $(this.element).data("input-name"));
$('.fancybox-iframe').contents().find('a.link').attr('data-field_id', $(this.element).data("input-name"));
},
helpers: {
overlay: {
locked: false
}
}
});
handleFieldDependencies();
let $fieldDependencies = getFieldDependencies();
for (let i = 0; i < $fieldDependencies.length; i++) {
$(document).off($fieldDependencies[i]).on('change', '[name="'+ $fieldDependencies[i] +'"]', function () {
handleFieldDependencies($fieldDependencies[i]);
}).bind(i);
}
function getFieldDependencies()
{
let fieldDependencies = [];
$('.depends-on').each(function (index, node) {
var $element = $(node);
var $classes = $element.prop('class').split(/\s+/);
for (var i = 0; i < $classes.length; i++) {
let current = $classes[i];
if (current.includes('depends-field')) {
let parts = current.replace('depends-field-', '').split(':');
fieldDependencies.push(parts[0]);
}
}
});
return fieldDependencies;
}
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
function handleFieldDependencies(specificFieldName)
{
let specificField = specificFieldName || false;
$('.depends-on').each(function (index, node) {
var $element = $(node);
var $classes = $element.prop('class').split(/\s+/);
let $method = 'match';
let $fieldName = false,
$fieldValue = false,
$fieldType = false,
$currentValue;
if ($element.hasClass('depends-on-multiple')) {
$fieldValue = [];
$fieldName = [];
$fieldType = [];
}
for (var i = 0; i < $classes.length; i++) {
let current = $classes[i];
if (current.includes('depends-where')) {
if (current == 'depends-where-is-not') {
$method = 'not_match';
}
}
if (current.includes('depends-field')) {
let parts = current.replace('depends-field-', '').split(':');
let $nameOfTheField = parts[0];
let $valueOfTheField = parts[1].split('--');
if ($element.hasClass('depends-on-multiple')) {
$fieldName.push($nameOfTheField);
$fieldValue.push($valueOfTheField);
} else {
$fieldName = $nameOfTheField;
$fieldValue = $valueOfTheField;
}
if($('input[name="'+ $nameOfTheField +'"]').length > 0){
$typeOfTheField = $('input[name="'+ $nameOfTheField +'"]').attr('type');
}else if($('textarea[name="'+ $nameOfTheField +'"]').length == 1){
$typeOfTheField = 'textarea';
}else if($('select[name="'+ $nameOfTheField +'"]').length == 1){
$typeOfTheField = 'select';
}
if ($element.hasClass('depends-on-multiple')) {
$fieldType.push($typeOfTheField);
} else {
$fieldType = $typeOfTheField;
}
}
}
if ($element.hasClass('depends-on-multiple')) {
var showBasedOnMultiple = true;
for (var i = 0; i < $fieldName.length; i++) {
if ($fieldType[i] == 'checkbox' || $fieldType[i] == 'radio'){
$currentValue = $('[name="'+ $fieldName[i] +'"]:checked').val();
} else {
$currentValue = $('[name="'+ $fieldName[i] +'"]').val();
}
$searchedValues = $fieldValue[i];
if ($method == 'match') {
if (!inArray($currentValue, $searchedValues)) {
showBasedOnMultiple = false;
}
}
if ($method == 'not_match') {
if (inArray($currentValue, $searchedValues)) {
showBasedOnMultiple = false;
}
}
}
if (showBasedOnMultiple) {
$element.show();
} else {
$element.hide();
}
} else {
if (specificField && specificField != $fieldName) {
return;
}
if ($fieldType == 'checkbox' || $fieldType == 'radio'){
$currentValue = $('[name="'+ $fieldName +'"]:checked').val();
} else {
$currentValue = $('[name="'+ $fieldName +'"]').val();
}
if ($method == 'not_match' && $fieldName && $fieldValue) {
if ($fieldValue.includes($currentValue)) {
$element.hide();
} else {
$element.show();
}
}
if ($method == 'match' && $fieldName && $fieldValue) {
if ($fieldValue.includes($currentValue)) {
$element.show();
} else {
$element.hide();
}
}
}
});
}
});
{/block}
{* {block name="label"}
{if isset($input.errors) && !empty($input.errors)}
<div class="col-lg-12">
<div class="alert alert-danger">{$input.errors}</div>
</div>
{/if}
{$smarty.block.parent}
{/block} *}
{block name="input"}
{if $input.type == 'file_lang'}
<div class="row">
{foreach from=$languages item=language}
{if $languages|count > 1}
<div class="translatable-field lang-{$language.id_lang|escape:'UTF-8'}" {if $language.id_lang != $defaultFormLanguage}style="display:none"{/if}>
{/if}
<div class="col-lg-9">
{*$fields_value|d*}
{if isset($fields_value['image']) && $fields_value['image'][$language.id_lang] != ''}
<img src="{$image_baseurl|escape:'UTF-8'}{$language.iso_code|escape:'UTF-8'}/{$fields_value['image'][$language.id_lang]|escape:'UTF-8'}" class="img-thumbnail" /><br><br>
{/if}
<input id="{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}" type="file" name="{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}" class="hide" />
<div class="dummyfile input-group">
<span class="input-group-addon"><i class="icon-file"></i></span>
<input id="{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}-name" type="text" class="disabled" name="filename" readonly />
<span class="input-group-btn">
<button id="{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}-selectbutton" type="button" name="submitAddAttachments" class="btn btn-default">
<i class="icon-folder-open"></i> {l s='Choose a file' mod='X13Webp'}
</button>
</span>
</div>
</div>
{if $languages|count > 1}
<div class="col-lg-2">
<button type="button" class="btn btn-default dropdown-toggle" tabindex="-1" data-toggle="dropdown">
{$language.iso_code|escape:'UTF-8'}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{foreach from=$languages item=lang}
<li><a href="javascript:hideOtherLanguage({$lang.id_lang|escape:'UTF-8'});" tabindex="-1">{$lang.name}</a></li>
{/foreach}
</ul>
</div>
{/if}
{if $languages|count > 1}
</div>
{/if}
<script>
$(document).ready(function() {
$('#{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}-selectbutton').click(function(e) {
$('#{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}').trigger('click');
});
$('#{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}').change(function(e) {
var val = $(this).val();
var file = val.split(/[\\/]/);
$('#{$input.name|escape:'UTF-8'}_{$language.id_lang|escape:'UTF-8'}-name').val(file[file.length - 1]);
});
});
</script>
{/foreach}
</div>
{elseif $input.type == 'selectImage'}
<input name="{$input.name|escape:'html':'UTF-8'}" id="{$input.name|escape:'html':'UTF-8'}" value="{$fields_value[$input.name]|escape:'html':'UTF-8'}" type="text" />
<p>
<a href="filemanager/dialog.php?type=1&amp;field_id={$input.name|escape:'html':'UTF-8'}" class="btn btn-default iframe-upload" data-input-name="{$input.name|escape:'html':'UTF-8'}" type="button">{l s='Image selector' mod='X13Webp'} <i class="icon-angle-right"></i></a>
</p>
{elseif $input.type == 'rangeSlider'}
<div class="row" class="rangeslider-row">
<div class="col-lg-1">
<input class="rangeslider-input" type="text" name="{$input.name|escape:'html':'UTF-8'}" value="{$fields_value[$input.name]|escape:'html':'UTF-8'}">
</div>
<div class="col-lg-6">
<div class="rangeslider" style="margin-top:12px;"></div>
</div>
</div>
{elseif $input.type == 'radio'}
{foreach $input.values as $value}
<div class="radio {if isset($input.class)}{$input.class}{/if}">
{strip}
<label>
<input type="radio" name="{$input.name}" id="{$value.id}" value="{$value.value|escape:'html':'UTF-8'}"{if $fields_value[$input.name] == $value.value} checked="checked"{/if}{if (isset($input.disabled) && $input.disabled) or (isset($value.disabled) && $value.disabled)} disabled="disabled"{/if}/>
{$value.label}
</label>
{/strip}
</div>
{if isset($value.p) && $value.p}<p class="help-block">{$value.p}</p>{/if}
{/foreach}
{elseif $input.type == 'converTest'}
{include file='./conversion_test.tpl' params=$input.vars}
{elseif $input.type == 'readonly'}
<input class="form-control" type="text" value="{$input.default}" readonly>
{else}
{$smarty.block.parent}
{/if}
{/block}

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,92 @@
<div class="panel" id="conversion-fieldset">
<div class="panel-heading">
<i class="icon-cogs"></i> {l s='Delete unnecessary photos' mod='x13webp'}
</div>
<div class="form-horizontal">
<div class="form-wrapper">
<div class="form-group">
<label class="control-label col-lg-4">{l s='Delete product images that are not correctly assigned to products' mod='x13webp'}</label>
<div class="col-lg-8">
<a
href="{$x13webp_clean_product_images_url}"
class="x13webp-button-confirm btn btn-danger"
id="x13webp-clean-product-images"
data-confirm="{l s='Are you sure you want to clean product images?' mod='x13webp'}"
>
<i class="icon-trash"></i>
{l s='Delete' mod='x13webp'}
</a>
<p class="help-block">{l s='Removes invalid photos from the img/p/ folder - those that are not assigned to products in the database' mod='x13webp'}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">{l s='Delete images from the img/tmp/ folder' mod='x13webp'}</label>
<div class="col-lg-8">
<a
href="{$x13webp_clean_tmp_url}"
class="x13webp-button-confirm btn btn-danger"
id="x13webp-clean-tmp-folder"
data-confirm="{l s='Are you sure you want to clean tmp folder?' mod='x13webp'}"
>
<i class="icon-trash"></i>
{l s='Delete' mod='x13webp'}
</a>
<p class="help-block">{l s='Deletes photos from the temporary folder, which PrestaShop will regenerate if needed' mod='x13webp'}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">{l s='Delete images that are not correctly assigned to image types' mod='x13webp'}</label>
<div class="col-lg-8">
<form action="{$x13webp_clean_image_types_url}" method="POST">
<select name="type" class="fixed-width-xl">
<option value="products">{l s='Products' mod='x13webp'}</option>
<option value="categories">{l s='Categories' mod='x13webp'}</option>
<option value="manufacturers">{l s='Manufacturers' mod='x13webp'}</option>
<option value="suppliers">{l s='Suppliers' mod='x13webp'}</option>
<option value="stores">{l s='Stores' mod='x13webp'}</option>
</select>
<br>
<button
type="submit"
class="x13webp-button-confirm btn btn-danger"
id="x13webp-submit-unnecessary-images"
data-confirm="{l s='Are you sure you want to delete unnecessary images?' mod='x13webp'}"
>
<i class="icon-trash"></i>
{l s='Delete' mod='x13webp'}
</button>
</form>
<p class="help-block">{l s='Delete images whose format has been removed from the database' mod='x13webp'}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">{l s='Delete all WebP images' mod='x13webp'}</label>
<div class="col-lg-8">
<div id="x13webp-delete-all-wrapper">
<p class="help-block {if $x13webp_images_exists}hidden{/if}">{l s='There are no images to delete' mod='x13webp'}</p>
<button
type="button"
class="x13webp-button-confirm btn btn-danger {if !$x13webp_images_exists}hidden{/if}"
id="x13webp-delete-all-webp"
data-confirm="{l s='Are you sure you want to delete all WebP images?' mod='x13webp'}"
>
<i class="icon-trash"></i> {l s='Delete' mod='x13webp'}
</button>
<p class="help-block">{l s='Delete all images WebP that have been generated in this module' mod='x13webp'}</p>
</div>
</div>
<div class="col-lg-12">
<div id="x13webp-logs-delete-all" class="hidden"></div>
</div>
</div>
</div>
</div>
</div>
<script>
</script>

View File

@@ -0,0 +1,68 @@
<div class="panel" id="conversion-fieldset">
<div class="panel-heading">
<i class="icon-cogs"></i> {l s='Conversion process' mod='x13webp'}
</div>
<div class="row">
<div class="col-lg-3"></div>
<div class="col-lg-6">
<select name="{$x13webp_select.name}" class="form-control" id="x13webp_image_format">
<option value="webp" {if $x13webp_select.value == 'webp'}selected{/if}>{l s='Generate only WebP' mod='x13webp'}</option>
<option value="jpg" {if $x13webp_select.value == 'jpg'}selected{/if}>{l s='Generate only JPG' mod='x13webp'}</option>
<option value="all" {if $x13webp_select.value == 'all'}selected{/if}>{l s='Generate WebP and JPG' mod='x13webp'}</option>
</select>
</div>
<div class="col-lg-3"></div>
</div>
{if $types}
<ul class="nav nav-tabs" id="form-tabs">
{foreach from=$types item=item name=type}
<li class="{if $smarty.foreach.type.first}active{/if}" data-toggle="tooltip" data-original-title="{l s='The tab has been locked until the photos were generated' mod='x13webp'}">
<a
data-toggle="tab"
href="#tab-x13wepb-{$item.val}"
data-fieldset="{$item.val}"
data-toggle="tab"
class="{if $item.has_types}has_types{/if} {if $x13webp_select.value == 'jpg' && !$item.has_types}disabled{/if}"
>{$item.name}</a>
</li>
{/foreach}
</ul>
<div class="tab-content panel">
{foreach from=$types item=item name=types}
<div class="tab-pane {if $smarty.foreach.types.first}active{/if}" id="tab-x13wepb-{$item.val}">
{if $item.val == 'others'}
{if $is_ps_176}
{include file="module:x13webp/views/templates/admin/file_manager.tpl" progress_item=$item}
{else}
{include file="./file_manager.tpl" progress_item=$item}
{/if}
{else}
{if $is_ps_176}
{include file="module:x13webp/views/templates/admin/conversion_progress.tpl" progress_item=$item}
{else}
{include file="./conversion_progress.tpl" progress_item=$item}
{/if}
{/if}
</div>
{/foreach}
</div>
{if $warning_exists}
<div class="text-center">
<button class="btn btn-warning" id="regenerate-warnings">{l s='Re-generate images that have an error' mod='x13webp'}</button>
</div>
{/if}
<div class="x13webp-log-wrapper hidden">
<div class="button">
<button type="button" class="btn btn-warning hidden" id="x13webp-log-warning" data-toggle="warnings" data-text="{l s='Show all logs' mod='x13webp'}">{l s='Show warnings only' mod='x13webp'}</button>
</div>
<div class="x13webp-log-info"></div>
</div>
{/if}
</div>

View File

@@ -0,0 +1,55 @@
<form>
<table class="table progress-item-table">
<thead>
<tr>
<th width="15%">{l s='Image type' mod='x13webp'}</th>
<th width="15%">{l s='Actions' mod='x13webp'}</th>
<th width="15%" class="text-right">{l s='Status' mod='x13webp'}</th>
<th width="55%">{l s='Progress' mod='x13webp'}</th>
</tr>
</thead>
<tbody>
{if $progress_item.types}
{foreach from=$progress_item.types item=type}
{if $is_ps_176}
{include file="module:x13webp/views/templates/admin/progress_item.tpl" progress_item=$progress_item image_type=$type.name image_name=$type.name}
{else}
{include file="./progress_item.tpl" progress_item=$progress_item image_type=$type.name image_name=$type.name}
{/if}
{/foreach}
{else}
{if $is_ps_176}
{include file="module:x13webp/views/templates/admin/progress_item.tpl" progress_item=$progress_item image_type='all' image_name=$progress_item.types_info}
{else}
{include file="./progress_item.tpl" progress_item=$progress_item image_type='all' image_name=$progress_item.types_info}
{/if}
{/if}
</tbody>
</table>
{if $progress_item.allowed}
{if $progress_item.types}
<div class="bottom-button-conversion-progress" data-type="{$progress_item.val}">
<div class="bottom-buttons-wrapper" data-toggle="tooltip" data-original-title="{l s='Buttons were disabled during the conversion process' mod='x13webp'}">
<div class="tooltip-wrapper" data-toggle="tooltip" data-original-title="{l s='Button has been disabled as all images have already been generated' mod='x13webp'}">
<button type="button" class="btn btn-success btn-start-conversion" disabled>
<i class="icon icon-play" aria-hidden="true"></i> {l s='Generate all images' mod='x13webp'}
</button>
</div>
<button type="button" class="btn btn-warning btn-pause-conversion hidden" disabled>
<i class="icon icon-pause" aria-hidden="true"></i> {l s='Stop generating images' mod='x13webp'}
</button>
<button type="button" class="btn btn-secondary btn-refresh-conversion" disabled>
<i class="icon icon-refresh" aria-hidden="true"></i> {l s='Re-generate all images' mod='x13webp'}
</button>
</div>
</div>
{/if}
{else}
<div class="alert alert-warning" style="margin-top:15px;">{l s='This item is not allowed to generate' mod='x13webp'}</div>
{/if}
</form>

View File

@@ -0,0 +1,93 @@
<div class="list-files">
<div class="files-preloader"></div>
</div>
{* {if $tree}
<div class="list-files hidden">
<ul>
{foreach from=$tree item=file}
<li data-file="{$file.name}" {if $file.type == 'dir'}class="dir" {/if}>
<p {if $file.exists && $file.type == 'dir'}data-toggle="tooltip" title="{l s='No image in this folder' mod='x13webp'}"{/if}>
{if $file.type == 'dir'}
<span class="state"><i class="icon-folder"></i></span>
{/if}
<input type="checkbox" name="others_item" value="{$file.name}" {if $file.exists}disabled {if $file.type != 'dir'}checked{/if}{/if}>
{$file.name}
</p>
</li>
{/foreach}
</ul>
</div>
{/if} *}
<form>
<table class="table progress-item-table">
<thead>
<tr>
<th width="15%">{l s='Image type' mod='x13webp'}</th>
<th width="15%">{l s='Actions' mod='x13webp'}</th>
<th width="15%" class="text-right">{l s='Status' mod='x13webp'}</th>
<th width="55%">{l s='Progress' mod='x13webp'}</th>
</tr>
</thead>
<tbody>
{if !$progress_item.types}
<tr data-image_type="all">
<td>
<strong>{$progress_item.types_info}</strong>
</td>
<td class="progress-button" data-image_type="all" data-type="{$progress_item.val}">
{if $progress_item.allowed}
<div class="tooltip-wrapper" data-toggle="tooltip" data-original-title="{l s='You have to select an image if you want to generate images' mod='x13webp'}">
<button type="button" class="btn btn-success btn-sm btn-item-start-others" disabled><i class="icon icon-play" aria-hidden="true"></i></button>
</div>
<button type="button" class="btn btn-warning btn-sm hidden btn-item-pause-others" disabled><i class="icon icon-pause" aria-hidden="true"></i></button>
<button type="button" class="btn btn-secondary btn-sm btn-item-refresh-others" disabled><i class="icon icon-refresh" aria-hidden="true"></i></button>
{/if}
</td>
<td class="text-right images-done-wrapper">
<div class="preloader active"></div>
<div class="images-done-total" data-format="webp">
<span class="done">0</span>
/
<span class="total">0</span>
</div>
</td>
<td class="progress-td">
<div class="progress" data-image_type="all" data-format="webp">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="0">
<span class="progress-text">WebP</span>
<span class="progressbar-inner hidden-sm-down">0%</span>
</div>
</div>
</td>
</tr>
{/if}
</tbody>
</table>
{if $progress_item.allowed}
{if $progress_item.types}
<div class="bottom-button-conversion-progress" data-type="{$progress_item.val}">
<button type="button" class="btn btn-success btn-start-conversion" disabled>
<i class="icon icon-play" aria-hidden="true"></i> {l s='Generate all images' mod='x13webp'}
</button>
<button type="button" class="btn btn-warning btn-pause-conversion hidden" disabled>
<i class="icon icon-pause" aria-hidden="true"></i> {l s='Stop generating images' mod='x13webp'}
</button>
<button type="button" class="btn btn-secondary btn-refresh-conversion" disabled>
<i class="icon icon-refresh" aria-hidden="true"></i> {l s='Re-generate all images' mod='x13webp'}
</button>
</div>
{/if}
{else}
<div class="alert alert-warning" style="margin-top:15px;">{l s='This item is not allowed to generate' mod='x13webp'}</div>
{/if}
</form>

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,20 @@
<ul id="module_x13lookbook_toolbar" class="hidden">
{foreach from=$module_toolbar_buttons item=btn key=k}
<li>
<a id="module-header-desc-{$module_name}-{if isset($btn.imgclass)}{$btn.imgclass|escape}{else}{$k}{/if}"
class="toolbar_btn {if isset($btn.target) && $btn.target} _blank{/if} pointer"{if isset($btn.href)} href="{$btn.href|escape}"{/if}
title="{if isset($btn.help)}{$btn.help}{else}{$btn.desc|escape}{/if}"{if isset($btn.js) && $btn.js} onclick="{$btn.js}"{/if}{if isset($btn.modal_target) && $btn.modal_target} data-target="{$btn.modal_target}" data-toggle="modal"{/if}{if isset($btn.help)} data-toggle="tooltip" data-placement="bottom"{/if}>
<i
class="{if isset($btn.icon)}{$btn.icon|escape}{else}process-icon-{if isset($btn.imgclass)}{$btn.imgclass|escape}{else}{$k}{/if}{/if}{if isset($btn.class)} {$btn.class|escape}{/if}"></i>
<div{if isset($btn.force_desc) && $btn.force_desc == true } class="locked"{/if}>{$btn.desc|escape}</div>
</a>
</li>
{/foreach}
</ul>
<script>
$( document ).ready(function() {
$('#module_x13lookbook_toolbar li').prependTo('.toolbarBox .btn-toolbar .nav');
$('.toolbarBox .btn-toolbar .nav li>a#desc-module-update').parent().remove();
});
</script>

View File

@@ -0,0 +1,49 @@
<tr data-image_type="{$image_type}" class="tr-format-{$x13webp_select.value}">
<td>
<strong>{$image_name}</strong>
</td>
<td class="progress-button" data-image_type="{$image_type}" data-type="{$progress_item.val}">
<div class="progress-button-wrapper" data-toggle="tooltip" data-original-title="{l s='Buttons were disabled during the conversion process' mod='x13webp'}">
{if $progress_item.allowed}
<div class="tooltip-wrapper" data-toggle="tooltip" data-original-title="{l s='Button has benn disabled bacause all images have already been generated' mod='x13webp'}">
<button type="button" class="btn btn-success btn-sm btn-item-start" disabled><i class="icon icon-play" aria-hidden="true"></i></button>
</div>
<button type="button" class="btn btn-warning btn-sm hidden btn-item-pause" disabled><i class="icon icon-pause" aria-hidden="true"></i></button>
<button type="button" class="btn btn-secondary btn-sm btn-item-refresh" disabled><i class="icon icon-refresh" aria-hidden="true"></i></button>
{/if}
</div>
</td>
<td class="text-right">
<div class="images-done-wrapper">
<div class="preloader active"></div>
<div class="images-done-total" data-format="webp">
<span class="done">0</span>
/
<span class="total">0</span>
</div>
{if $progress_item.has_types && $image_type != 'main'}
<div class="images-done-total" data-format="jpg">
<span class="done">0</span>
/
<span class="total">0</span>
</div>
{/if}
</div>
</td>
<td class="progress-td">
<div class="progress" data-image_type="{$image_type}" data-format="webp">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="0">
<span class="progress-text">WebP</span>
<span class="progressbar-inner hidden-sm-down">0%</span>
</div>
</div>
{if $progress_item.has_types && $image_type != 'main'}
<div class="progress" data-image_type="{$image_type}" data-format="jpg">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="0">
<span class="progress-text">JPG</span>
<span class="progressbar-inner hidden-sm-down">0%</span>
</div>
</div>
{/if}
</td>
</tr>