This commit is contained in:
2025-03-21 20:24:43 +01:00
parent 224398df90
commit f34c9162d4
12427 changed files with 5329941 additions and 373384 deletions

View File

@@ -0,0 +1,208 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
{extends file="helpers/form/form.tpl"}
{block name="input_row"}
{if $input.type == 'alert_info'}
<div class="alert alert-info">{$input.text|escape:'quotes':'UTF-8'}</div>
{elseif $input.type == 'alert_warn'}
<div class="alert alert-warning">{$input.text|escape:'quotes':'UTF-8'}</div>
{elseif $input.type == 'alert_error'}
<div class="alert alert-danger">{$input.text|escape:'quotes':'UTF-8'}</div>
{elseif $input.type == 'logs'}
<a href="#" onclick="$('#{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}').toggle()"><i class="material-icons">bug_report</i><span style="vertical-align: super;">{l s='See logs' mod='pagecache'}</span></a>
<div class="panel" id="{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}" style="display: none">
<div class="pre">
{foreach $input.logs as $log}
<div class="log_{$log->type|escape:'html':'UTF-8'}"><b>{$log->date|escape:'html':'UTF-8'} &gt;</b> {$log->msg|escape:'html':'UTF-8'}</div>
{/foreach}
</div>
</div>
{elseif $input.type == 'converters_report'}
<div class="alert {$input.typeAlert|escape:'html':'UTF-8'}">{$input.text|escape:'quotes':'UTF-8'}
<a class="btntoggle" data-toggle="collapse" href="#collapseConverters" role="button" aria-expanded="false" aria-controls="collapseConverters">
{l s='Details' mod='pagecache'}
</a>
<div class="collapse" id="collapseConverters">
<div class="alert alert-info" style="margin-top: 0.5rem;">
<b>{l s='The following errors or warnings can be ignored.' mod='pagecache'}</b>
{l s='They simply show how the compressor was selected in your store.' mod='pagecache'}
</div>
{foreach $input.values as $key => $value}
{if is_array($value) && $key !== 'firstActiveConverter'}
<div class="reportHead alert alert-{if !$value.disabled}success{else}warning{/if}">{$value.label|escape:'quotes':'UTF-8'}{if !$value.disabled} ({$value.duration_ms|intval}ms){/if}
<a class="btntoggle" data-toggle="collapse" href="#collapse{$value.id|escape:'html':'UTF-8'}" role="button" aria-expanded="false" aria-controls="collapse{$value.id|escape:'html':'UTF-8'}">
{l s='Details' mod='pagecache'}
</a>
</div>
<div class="collapse report" id="collapse{$value.id|escape:'html':'UTF-8'}">
{if isset($value.error) && $value.error}<div class="alert alert-warning">{$value.error|escape:'html':'UTF-8'}</div>{/if}
{$value.log|escape:'quotes':'UTF-8'}
</div>
{/if}
{/foreach}
</div>
</div>
{elseif $input.type == 'check_header_vary'}
<script type="application/javascript">
function jprestaIsCrossDomain(urlToFetch) {
let currentUrl = new URL(window.location.href);
let otherUrl = new URL(urlToFetch);
return currentUrl.host !== otherUrl.host;
}
function jprestaContainsAccept(val) {
if (!val) {
return false;
}
let vals = val.split(',');
for (let i = 0; i < vals.length; i++) {
if(vals[i].trim().toLowerCase() === 'accept') {
return true;
}
}
return false;
}
try {
$.ajax({
url: '{$input.url_to_test|escape:'javascript':'UTF-8'}', cache: false, headers: { 'Accept': 'image/webp,*/*' }, complete: function (jqXHR) {
console.log(jqXHR);
if (jqXHR.status >= 200 && jqXHR.status < 300) {
// Get the raw header string
let allHeaders = jqXHR.getAllResponseHeaders();
// Convert the header string into an array
// of individual headers
let allHeadersArray = allHeaders.trim().split(/[\r\n]+/);
// Create a map of header names to values
let allHeadersMap = [];
allHeadersArray.forEach(function (line) {
let parts = line.split(': ');
let headerName = parts.shift().toLowerCase();
let headerValue = parts.join(': ').toLowerCase();
allHeadersMap[headerName] = headerValue;
});
if (!('vary' in allHeadersMap) && jprestaIsCrossDomain('{$input.url_to_test|escape:'javascript':'UTF-8'}')) {
$('#vary_check_dontknow').show();
}
else if (!('vary' in allHeadersMap) || !jprestaContainsAccept(allHeadersMap['vary'])) {
$('#vary_check_error').show();
}
else {
$('#vary_check_ok').show();
}
}
else {
console.log("Speed pack cannot analyze HTTP headers: status=" + jqXHR.status + " " + jqXHR.statusText);
}
}
});
}
catch (e) {
console.error("Speed pack cannot analyze HTTP headers: " + e.message, e);
}
</script>
<div id="vary_check_error" class="alert alert-warning" style="display: none">
{$input.text_error|escape:'quotes':'UTF-8'}
<pre>
location ~ (.+)\.(png|jpe?g)$ {
add_header Vary Accept;
}
</pre>
</div>
<div id="vary_check_ok" class="alert alert-success" style="display: none">
{$input.text_ok|escape:'quotes':'UTF-8'}
</div>
<div id="vary_check_dontknow" class="alert alert-default" style="display: none">
{$input.text_dontknow|escape:'quotes':'UTF-8'}
</div>
{else}
{$smarty.block.parent}
{/if}
{/block}
{block name="input"}
{if $input.type == 'integer'}
{if isset($input.prefix) || isset($input.suffix)}
<div class="input-group{if isset($input.class)} {$input.class|escape:'html':'UTF-8'}{/if}">
{/if}
{if isset($input.prefix)}
<span class="input-group-addon">{$input.prefix|escape:'html':'UTF-8'}</span>
{/if}
<input type="number"
id="{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}"
name="{$input.name|escape:'html':'UTF-8'}"
class="form-control text-right{if isset($input.class)} {$input.class|escape:'html':'UTF-8'}{/if}"
value="{$fields_value[$input.name]|intval}"
{if isset($input.size)} size="{$input.size|intval}"{/if}
{if isset($input.max)} max="{$input.max|intval}"{/if}
{if isset($input.min)} min="{$input.min|intval}"{/if}
{if isset($input.readonly) && $input.readonly} readonly="readonly"{/if}
{if isset($input.disabled) && $input.disabled} disabled="disabled"{/if}
{if isset($input.required) && $input.required} required="required" {/if}
{if isset($input.placeholder) && $input.placeholder} placeholder="{$input.placeholder|escape:'html':'UTF-8'}"{/if} />
{if isset($input.suffix)}
<span class="input-group-addon">{$input.suffix|escape:'html':'UTF-8'}</span>
{/if}
{if isset($input.maxchar) || isset($input.prefix) || isset($input.suffix)}
</div>
{/if}
{/if}
{if $input.type == 'webp_slider_quality'}
{assign var='value_text' value=$fields_value[$input.name]}
<style type="text/css">
.ui-slider .ui-slider-handle {
height: 1.5rem;
width: 2.5rem;
top: -0.5rem;
text-align: center;
line-height: 1.4rem;
margin-left: -.1rem;
}
</style>
<script type="application/javascript">
$(function() {
let inputField = $("#{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}");
let cursor = $("#cursor{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}");
$( "#slider{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}" ).slider({
{if isset($input.min)}min: {$input.min|intval},{/if}
{if isset($input.max)}max: {$input.max|intval},{/if}
{if isset($input.step)}step: {$input.step|intval},{/if}
animate: "fast",
{if isset($input.disabled) && $input.disabled}disabled: true,{/if}
value: {$value_text|escape:'html':'UTF-8'},
slide: function(event, ui) {
inputField.val(ui.value);
cursor.text(ui.value {if isset($input.unit)} + "{$input.unit|escape:'html':'UTF-8'}"{/if});
},
change: function (event, ui) {
$('#afterSlider').attr('src', '{$input.after.url|escape:'html':'UTF-8'}&quality=' + ui.value);
}
});
// Initialize the slider
$("#beforeAfterSlider").twentytwenty({ before_label: 'JPG', after_label: 'WEBP' });
} );
</script>
<div style="width: {$input.before.width|intval}px;{if isset($input.disabled) && $input.disabled}display:none{/if}" id="beforeAfterSlider" class='twentytwenty-container'>
<img id="beforeSlider" {if isset($input.before.width)}width="{$input.before.width|intval}px"{/if} {if isset($input.before.height)}height="{$input.before.height|intval}px"{/if} src="{$input.before.url|escape:'html':'UTF-8'}">
<img id="afterSlider" {if isset($input.after.width)}width="{$input.before.width|intval}px"{/if} {if isset($input.after.height)}height="{$input.before.height|intval}px"{/if} src="{$input.after.url|escape:'html':'UTF-8'}&quality={$input.after.quality|intval}">
</div>
<input type="hidden"
name="{$input.name|escape:'html':'UTF-8'}"
id="{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}"
value="{$value_text|escape:'html':'UTF-8'}"
/>
<div style="width: {$input.before.width|intval}px; margin: 1rem 0;" id="slider{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}">
<div id="cursor{if isset($input.id)}{$input.id|escape:'html':'UTF-8'}{else}{$input.name|escape:'html':'UTF-8'}{/if}" class="ui-slider-handle">{$value_text|escape:'html':'UTF-8'}{if isset($input.unit)}&nbsp;{$input.unit|escape:'html':'UTF-8'}{/if}</div>
</div>
{else}
{$smarty.block.parent}
{/if}
{/block}

View File

@@ -0,0 +1,19 @@
<?php
/**
* This file protect the directory
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*/
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,19 @@
<?php
/**
* This file protect the directory
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*/
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,19 @@
<?php
/**
* This file protect the directory
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*/
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,12 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<ul>
{foreach $urls as $url}
<li style="line-height: 2rem;"><span class="cron_url">{$url|escape:'html':'UTF-8'}</span></li>
{/foreach}
</ul>

View File

@@ -0,0 +1,177 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="row">
<div class="col-md-12">
<div class="panel">
<h3>
{if $avec_bootstrap}<i class="icon-gear"></i>{else}<img width="16" height="16" src="../img/admin/AdminPreferences.gif"/>{/if}&nbsp;{l s='Cache key settings' mod='pagecache'}
</h3>
<form id="pagecache_form_cachekey" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="cachekey"/>
<fieldset>
<div style="clear: both;">
<div class="row form-group">
<div class="col-lg-12">
<h4>{l s='Devices' mod='pagecache'}</h4>
</div>
<div id="pagecache_depend_on_device_auto">
<label class="control-label col-lg-3">
{l s='Create separate cache for desktop and mobile' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_depend_on_device_auto"
id="pagecache_depend_on_device_auto_on" value="1"
{if $pagecache_depend_on_device_auto}checked{/if}>
<label for="pagecache_depend_on_device_auto_on"
class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_depend_on_device_auto"
id="pagecache_depend_on_device_auto_off" value="0"
{if !$pagecache_depend_on_device_auto}checked{/if}>
<label for="pagecache_depend_on_device_auto_off"
class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='If you know that your mobile version is the same as the desktop version then you can disable this option' mod='pagecache'}
</div>
</div>
</div>
<div id="pagecache_tablet_is_mobile">
<label class="control-label col-lg-3">
{l s='Tablet are considered as mobile' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_tablet_is_mobile"
id="pagecache_tablet_is_mobile_on" value="1"
{if $pagecache_tablet_is_mobile}checked{/if}>
<label for="pagecache_tablet_is_mobile_on"
class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_tablet_is_mobile"
id="pagecache_tablet_is_mobile_off" value="0"
{if !$pagecache_tablet_is_mobile}checked{/if}>
<label for="pagecache_tablet_is_mobile_off"
class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Set to true if your theme display the mobile site for tablet devices' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="row form-group">
<div class="col-lg-12">
<h4>{l s='CSS & JS' mod='pagecache'}</h4>
</div>
<div id="pagecache_depend_on_css_js">
<label class="control-label col-lg-3">
{l s='Insert CSS and JS version in cache key' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_depend_on_css_js" id="pagecache_depend_on_css_js_on"
value="1" {if $pagecache_depend_on_css_js}checked{/if}>
<label for="pagecache_depend_on_css_js_on"
class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_depend_on_css_js" id="pagecache_depend_on_css_js_off"
value="0" {if !$pagecache_depend_on_css_js}checked{/if}>
<label for="pagecache_depend_on_css_js_off"
class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Only enable this option if the styles disappear when the cache is enabled' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="row form-group">
<div class="col-lg-12">
<h4>{l s='Countries' mod='pagecache'}</h4>
</div>
<div class="col-lg-12">
<div class="alert alert-info">{l s='The module automatically detects countries with specific prices rules. Any country with a specific price rule need a specific cache, this is why you cannot uncheck it. When there is no specific price rule you may display specific informations for a country (not detected by the module), this is why you can force the country to have a specific cache.' mod='pagecache'}</div>
</div>
<div id="pagecache_depend_on_css_js">
<label class="control-label col-lg-3">
{l s='Select countries that need a specific cache' mod='pagecache'}
</label>
<div class="col-lg-9">
{if count($pagecache_cache_key_countries) === 0}
<i>{l s='No country are enabled on the shop' mod='pagecache'}</i>
{/if}
{foreach $pagecache_cache_key_countries as $id_country => $country_conf}
<span style="margin-right: 1rem;white-space: nowrap;">
<input type="checkbox"
style="vertical-align: middle; margin: 0 2px;"
id="pagecache_cachekey_countries_{$id_country|escape:'html':'UTF-8'}"
name="pagecache_cachekey_countries[{$id_country|escape:'html':'UTF-8'}]"
{if $country_conf.has_impact}disabled="disabled" {/if}
{if $country_conf.specific_cache}checked="checked" {/if}
value="true">
<label for="pagecache_cachekey_countries_{$id_country|escape:'html':'UTF-8'}">{$country_conf.name|escape:'html':'UTF-8'}</label>
</span>
{/foreach}
</div>
</div>
</div>
<div class="row form-group">
<div class="col-lg-12">
<h4>{l s='User groups' mod='pagecache'}</h4>
</div>
<div class="col-lg-12">
<div class="alert alert-info">{l s='The module automatically detects user groups with specific prices rules. Any user group with a specific price rule need a specific cache, this is why you cannot uncheck it. When there is no specific price rule you may display specific informations for a user group (not detected by the module), this is why you can force the user group to have a specific cache.' mod='pagecache'}</div>
</div>
<div id="pagecache_depend_on_css_js">
<label class="control-label col-lg-3">
{l s='Select user groups that need a specific cache' mod='pagecache'}
</label>
<div class="col-lg-9">
{if count($pagecache_cache_key_usergroups) === 0}
<i>{l s='No user group are enabled on the shop' mod='pagecache'}</i>
{/if}
{foreach $pagecache_cache_key_usergroups as $id_group => $group_conf}
<span style="margin-right: 1rem;white-space: nowrap;">
<input type="checkbox"
style="vertical-align: middle; margin: 0 2px;"
id="pagecache_cachekey_usergroups_{$id_group|escape:'html':'UTF-8'}"
name="pagecache_cachekey_usergroups[{$id_group|escape:'html':'UTF-8'}]"
{if $group_conf.has_impact_as_default}disabled="disabled" {/if}
{if $group_conf.specific_cache}checked="checked" {/if}
value="true">
<label for="pagecache_cachekey_usergroups_{$id_group|escape:'html':'UTF-8'}">{$group_conf.name|escape:'html':'UTF-8'}</label>
</span>
{/foreach}
</div>
</div>
</div>
</div>
<div class="bootstrap">
<button type="submit" value="1" id="submitModuleCacheKey" name="submitModuleCacheKey"
class="btn btn-default pull-right">
<i class="process-icon-save"></i> {l s='Save' mod='pagecache'}
</button>
</div>
</fieldset>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,63 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-link"></i>{else}<img width="16" height="16" src="../img/admin/subdomain.gif" alt=""/>{/if}&nbsp;{l s='API (URLs to clear the cache)' mod='pagecache'}</h3>
<form id="pagecache_form_cron" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="cron"/>
<fieldset>
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-info" style="display: block;">&nbsp;{l s='Here you will find URLs to clear the cache from a script (you can do it manually in the statistics table). Be aware that the cache cleans itself continuously, these URLs are only for users modifying the database not with Prestashop (hooks are not called).' mod='pagecache'}</div></div>
{else}
<div class="hint clear" style="display: block;">&nbsp;{l s='Here you will find URLs to clear the cache from a script (you can do it manually in the statistics table). Be aware that the cache cleans itself continuously, these URLs are only for users modifying the database not with Prestashop (hooks are not called).' mod='pagecache'}</div>
{/if}
<p>{l s='People who want to clear cache can use the following URLs (one per shop, returns 200 if OK, 404 if there is an error): ' mod='pagecache'}</p>
<ul>
{foreach $pagecache_cron_urls as $controller_name => $cron_url}
<li><pre>{$cron_url|escape:'javascript':'UTF-8'}</pre></li>
{/foreach}
</ul>
<p>
{l s='To refresh cache of a specific product add "&product=<product\'s ids separated by commas>", for a category add "&category=<category\'s ids separated by commas>", for home page add "&index", etc.' mod='pagecache'}
{l s='Available controller (type of page) are' mod='pagecache'}
</p>
<ul>
<li>index (no IDs)</li>
<li>category</li>
<li>product</li>
<li>cms</li>
<li>newproducts (no IDs)</li>
<li>bestsales (no IDs)</li>
<li>supplier</li>
<li>manufacturer</li>
<li>contact (no IDs)</li>
<li>pricesdrop (no IDs)</li>
<li>sitemap (no IDs)</li>
</ul>
<p>
{l s='When you refresh the cache of a product, or a category, etc. then the pages that have a link to this product or category will also be refreshed except if you add this parameter in the URL' mod='pagecache'}:
<pre>&delete_linking_pages=0</pre>
</p>
</fieldset>
</form>
<h4>{l s='Purge of the cache' mod='pagecache'}</h4>
<p>{l s='As we explained above the cache cleans itself continously but it can be a good thing to purge the cache once a week with this URL.' mod='pagecache'}</p>
<p>{l s='A purge will delete all obsolete datas from the cache, it will not decrease the hit rate.' mod='pagecache'}</p>
<ul>
{foreach $pagecache_cron_urls as $controller_name => $cron_url}
<li><pre>{$cron_url|escape:'javascript':'UTF-8'}&purge</pre></li>
{/foreach}
</ul>
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-info" style="display: block;">&nbsp;{l s='If you subscribed to the JPresta-Cache-Warmer service, the purge is processed automatically; there\'s no need to schedule a CRON job.' mod='pagecache'}</div></div>
{else}
<div class="hint clear" style="display: block;">&nbsp;{l s='If you subscribed to the JPresta-Cache-Warmer service, the purge is processed automatically; there\'s no need to schedule a CRON job.' mod='pagecache'}</div>
{/if}
</div>

View File

@@ -0,0 +1,362 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<script type="application/javascript">
$(document).ready(function () {
$.fn.dataTable.ext.errMode = 'none';
let datasTable = $('#datasTable')
.on('error.dt', function (e, settings, techNote, message) {
console.error('Page Cache - Cannot display cache datas: ', message);
})
.DataTable({
processing: true,
serverSide: true,
searching: true,
ajax: '{$pagecache_datas_url|escape:'javascript':'UTF-8'}',
columns: [
{ orderable: false },
{ },
{ orderable: false, width: '5rem' },
{ orderable: false, width: '3rem' },
{ width: '7rem' },
{ width: '3rem' },
{ width: '3rem' },
],
order: [],
language: {
processing: "{l s='Loading datas...' mod='pagecache'}",
search: "{l s='Search' mod='pagecache'}:",
lengthMenu: "{l s='Showing _MENU_ rows' mod='pagecache'}",
info: "{l s='Showing _START_ to _END_ of _TOTAL_ rows' mod='pagecache'}",
infoEmpty: "{l s='Showing 0 to 0 of 0 row' mod='pagecache'}",
infoFiltered: "{l s='Filtered of _MAX_ rows' mod='pagecache'}",
infoPostFix: "",
loadingRecords: "{l s='Loading datas...' mod='pagecache'}",
zeroRecords: "{l s='No data to display' mod='pagecache'}",
emptyTable: "{l s='No data to display' mod='pagecache'}",
paginate: {
first: "{l s='First' mod='pagecache'}",
previous: "{l s='Previous' mod='pagecache'}",
next: "{l s='Next' mod='pagecache'}",
last: "{l s='Last' mod='pagecache'}"
},
aria: {
sortAscending: ": {l s='Click to sort ascending' mod='pagecache'}",
sortDescending: ": {l s='Click to sort descending' mod='pagecache'}"
}
},
dom: 'Bfrtip',
lengthMenu: [
[ 10, 25, 50, 100 ],
[ '10 {l s='rows' mod='pagecache'}', '25 {l s='rows' mod='pagecache'}', '50 {l s='rows' mod='pagecache'}', '100 {l s='rows' mod='pagecache'}' ]
],
buttons: [
'pageLength'
],
});
let datasContextsTable = $('#datasContextsTable')
.on('error.dt', function (e, settings, techNote, message) {
console.error('Page Cache - Cannot display contexts datas: ', message);
})
.DataTable({
processing: true,
serverSide: true,
searching: true,
ajax: '{$pagecache_datas_url|escape:'javascript':'UTF-8'}&type=contexts',
columns: [
{ orderable: false },
{ orderable: false },
{ },
{ },
{ },
{ orderable: false },
],
order: [],
language: {
processing: "{l s='Loading datas...' mod='pagecache'}",
search: "{l s='Search' mod='pagecache'}:",
lengthMenu: "{l s='Showing _MENU_ rows' mod='pagecache'}",
info: "{l s='Showing _START_ to _END_ of _TOTAL_ rows' mod='pagecache'}",
infoEmpty: "{l s='Showing 0 to 0 of 0 row' mod='pagecache'}",
infoFiltered: "{l s='Filtered of _MAX_ rows' mod='pagecache'}",
infoPostFix: "",
loadingRecords: "{l s='Loading datas...' mod='pagecache'}",
zeroRecords: "{l s='No data to display' mod='pagecache'}",
emptyTable: "{l s='No data to display' mod='pagecache'}",
paginate: {
first: "{l s='First' mod='pagecache'}",
previous: "{l s='Previous' mod='pagecache'}",
next: "{l s='Next' mod='pagecache'}",
last: "{l s='Last' mod='pagecache'}"
},
aria: {
sortAscending: ": {l s='Click to sort ascending' mod='pagecache'}",
sortDescending: ": {l s='Click to sort descending' mod='pagecache'}"
}
},
dom: 'Bfrtip',
lengthMenu: [
[ 10, 25, 50, 100 ],
[ '10 {l s='rows' mod='pagecache'}', '25 {l s='rows' mod='pagecache'}', '50 {l s='rows' mod='pagecache'}', '100 {l s='rows' mod='pagecache'}' ]
],
buttons: [
'pageLength'
],
});
$('#searchObject').on('keyup', function () {
datasTable
.columns(3)
.search(this.value, false, false, false)
.draw();
});
$('#searchContext').on('change', function () {
datasTable
.columns(1)
.search(this.value, false, false, true)
.draw();
});
$('#searchController').on('change', function () {
datasTable
.columns(2)
.search(this.value, false, false, true)
.draw();
});
$('#searchURL').on('change', function () {
datasTable
.columns(0)
.search(this.value, false, true, true)
.draw();
});
$('#searchContextDevice,#searchContextLang,#searchContextCur,#searchContextCountry,#searchContextSpecs,#searchContextGroups').on('change', function () {
datasContextsTable
.search('id_device=' + $('#searchContextDevice').val() + ',id_lang=' + $('#searchContextLang').val() + ',id_currency=' + $('#searchContextCur').val() + ',id_country=' + $('#searchContextCountry').val() + ',id_specs=' + $('#searchContextSpecs').val() + ',id_group=' + $('#searchContextGroups').val())
.draw();
});
$('#refreshDatas').on('click', function () {
datasTable.ajax.reload();
});
$('#clearCacheDatas').on('click', function () {
let parameters = datasTable.ajax.params();
parameters.clear = true;
$.ajax({ url: datasTable.ajax.url(), method: 'post', data: parameters,
success: function(response) {
datasTable.ajax.reload();
},
error: function(result, status, error) {
console.log(result + ' - ' + status + ' - ' + error);
}});
});
});
</script>
<style>
.dataTables_processing {
border: 2px solid orange;
border-radius: 5px;
padding: 0 !important;
line-height: 3rem;
height: auto !important;
z-index: 99;
font-weight: bold;
}
.bootstrap .label-default {
border: 1px solid #999;
background-color: transparent;
padding: 0 2px;
}
#datasTable tr td:nth-child(n+3),#datasTable th,
#datasContextsTable th, #datasContextsTable tr td:nth-child(n+3){
text-align: center;
}
#datasTable tr td:last-child {
text-align: right;
}
#datasTable_filter {
display: none;
}
#datasTable span.label {
cursor: help;
padding: 0px 2px;
margin-right: 1px;
}
{if !$avec_bootstrap}tfoot input,tfoot select { width:95%; }{/if}
#datasContextsTable_filter {
display: none;
}
</style>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-line-chart"></i>{else}<img width="16" height="16" src="../img/admin/AdminStats.gif" alt=""/>{/if}&nbsp;{l s='Cached pages' mod='pagecache'}</h3>
<div class="alert alert-info">{l s='Here you can browse all cached pages. This can be usefull to debug.' mod='pagecache'}</div>
<fieldset class="cachemanagement">
<table id="datasTable" class="display cell-border compact stripe" style="width:100%">
<colgroup>
<col width="*">
<col width="*">
<col width="0*">
<col width="0*">
<col width="0*">
<col width="0*">
<col width="0*">
</colgroup>
<thead>
<tr>
<th>{l s='URL' mod='pagecache'}</th>
<th>{l s='Context' mod='pagecache'}</th>
<th>{l s='Controller' mod='pagecache'}</th>
<th>{l s='ID' mod='pagecache'}</th>
<th>{l s='Last generation' mod='pagecache'}</th>
<th>{l s='Cleared' mod='pagecache'}</th>
<th>{l s='Hit/Missed' mod='pagecache'}</th>
</tr>
</thead>
<tbody>
<tr><td>-</td><td>-</td><td>--------------</td><td>----</td><td>----/--/-- --:--:--</td><td>-</td><td>- / - (--%)</td></tr>
<tr><td>-</td><td>-</td><td>--------------</td><td>----</td><td>----/--/-- --:--:--</td><td>-</td><td>- / - (--%)</td></tr>
<tr><td>-</td><td>-</td><td>--------------</td><td>----</td><td>----/--/-- --:--:--</td><td>-</td><td>- / - (--%)</td></tr>
</tbody>
<tfoot>
<tr>
<th><input type="text" name="searchURL" id="searchURL" placeholder="{l s='Find in URL (click outside to trigger the search)' mod='pagecache'}" style="padding:4px"></th>
<th>
<select name="searchContext" id="searchContext" style="padding:4px">
<option></option>
{foreach $pagecache_contexts as $context}
<option value="{$context.id|intval}">#{$context.id|intval}</option>
{/foreach}
</select>
</th>
<th>
<select name="searchController" id="searchController" style="padding:4px">
<option></option>
{foreach $managed_controllers as $controller_name => $controller}
<option value="{$controller['id']|intval}">{$controller_name|escape:'html':'UTF-8'}</option>
{/foreach}
</select>
</th>
<th><input type="text" name="searchObject" id="searchObject" placeholder="{l s='Exact ID' mod='pagecache'}" style="text-align: center; padding:4px"></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
<div style="margin-top: 5px">
<div class="alert alert-info">
<strong>{l s='Reset cache (with stats)' mod='pagecache'}:</strong> {l s='This will delete all files of the cache and clear all database tables' mod='pagecache'}
<br/>
<strong>{l s='Clear cache (only files)' mod='pagecache'}:</strong> {l s='This will delete all files of the cache (not stats). If you filtered the table above then it will only delete files listed in the table within the limit of 1000 files.' mod='pagecache'}
<br/>
<strong>{l s='Purge cache (with stats)' mod='pagecache'}:</strong> {l s='This will remove from stats deleted cache older than 24H (and so probably not used anymore)' mod='pagecache'}
</div>
<form id="pagecache_form_datas" action="{$request_uri|escape:'html':'UTF-8'}#tabdatas" method="post">
<input type="hidden" name="submitModule" value="true"/>
<button type="submit" value="1" id="submitModuleResetDatas" name="submitModuleResetDatas"
class="btn btn-danger pull-right">
<i class="process-icon-delete"></i> {l s='Reset cache (with stats)' mod='pagecache'}
</button>
<button type="button" id="clearCacheDatas" class="btn btn-warning pull-right">
<i class="process-icon-delete"></i> {l s='Clear cache (only files)' mod='pagecache'}
</button>
<button type="submit" value="1" id="submitModulePurgeDatas" name="submitModulePurgeDatas"
class="btn btn-warning pull-right">
<i class="process-icon-delete"></i> {l s='Purge cache (with stats)' mod='pagecache'}
</button>
<button type="button" id="refreshDatas" class="btn btn-default pull-right">
<i class="process-icon-refresh"></i> {l s='Refresh' mod='pagecache'}
</button>
</form>
</div>
</fieldset>
</div>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-database"></i>{else}<img width="16" height="16" src="../img/admin/AdminStats.gif" alt=""/>{/if}&nbsp;{l s='Contexts' mod='pagecache'}</h3>
<fieldset class="cachemanagement">
<div class="alert alert-info">{l s='Here you can see which contexts are used on your shop, this is useful to know which ones you should warmup with the cache-warmer.' mod='pagecache'}</div>
<table id="datasContextsTable" class="display cell-border compact stripe" style="width:100%">
<thead>
<tr>
<th>{l s='UUID' mod='pagecache'}</th>
<th>{l s='Context' mod='pagecache'}</th>
<th>{l s='Number of visit' mod='pagecache'}</th>
<th>{l s='Hit rate' mod='pagecache'}</th>
<th>{l s='Visit of bots/crawlers' mod='pagecache'}</th>
<th>{l s='Cleared' mod='pagecache'}</th>
</tr>
</thead>
<tbody>
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
</tbody>
<tfoot>
<tr>
<th colspan="6">
{l s='Filters' mod='pagecache'}&nbsp;:
<select name="searchContextDevice" id="searchContextDevice" style="width:auto; display: inline-block">
<option value="0">{l s='All devices' mod='pagecache'}</option>
<option value="3">{l s='Mobile' mod='pagecache'}</option>
<option value="1">{l s='Desktop' mod='pagecache'}</option>
</select>
<select name="searchContextLang" id="searchContextLang" style="width:auto; display: inline-block">
<option value="0">{l s='All languages' mod='pagecache'}</option>
{foreach $pagecache_contexts_languages as $row}
<option value="{$row@key|intval}">#{$row@key|intval} - {$row|escape:'html':'UTF-8'}</option>
{/foreach}
</select>
<select name="searchContextCur" id="searchContextCur" style="width:auto; display: inline-block">
<option value="0">{l s='All currencies' mod='pagecache'}</option>
{foreach $pagecache_contexts_currencies as $row}
<option value="{$row@key|intval}">#{$row@key|intval} - {$row|escape:'html':'UTF-8'}</option>
{/foreach}
</select>
<select name="searchContextCountry" id="searchContextCountry" style="width:auto; display: inline-block">
<option value="0">{l s='All countries' mod='pagecache'}</option>
{foreach $pagecache_contexts_countries as $row}
<option value="{$row@key|intval}">#{$row@key|intval} - {$row|escape:'html':'UTF-8'}</option>
{/foreach}
</select>
<select name="searchContextGroups" id="searchContextGroups" style="width:auto; display: inline-block">
<option value="-1">{l s='All user groups' mod='pagecache'}</option>
{foreach $pagecache_contexts_groups as $row}
<option value="{$row@key|intval}">#{$row@key|intval} - {$row|escape:'html':'UTF-8'}</option>
{/foreach}
</select>
<select name="searchContextSpecs" id="searchContextSpecs" style="width:auto; display: inline-block">
<option value="0">{l s='All specific contexts' mod='pagecache'}</option>
<option value="null">{l s='By default' mod='pagecache'}</option>
{foreach $pagecache_contexts_specs as $row}
<option value="{$row@key|intval}">#{$row@key|intval}</option>
{/foreach}
</select>
</th>
</tr>
</tfoot>
</table>
</fieldset>
</div>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-database"></i>{else}<img width="16" height="16" src="../img/admin/AdminStats.gif" alt=""/>{/if}&nbsp;{l s='Database' mod='pagecache'}</h3>
<fieldset class="cachemanagement">
<div class="alert alert-info">{l s='Tables can consumme a lot of space but they are all optimized and stores only necessary informations. This is mainly used by the automatic refresment of the cache.' mod='pagecache'}</div>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>{l s='Table' mod='pagecache'}</th>
<th>{l s='Row count' mod='pagecache'}</th>
<th>{l s='Size in MB' mod='pagecache'}</th>
</tr>
</thead>
<tbody>
{foreach $pagecache_datas_dbinfos as $row}
<tr>
{foreach $row as $col}
<td>{$col|escape:'html':'UTF-8'}</td>
{/foreach}
</tr>
{/foreach}
</tbody>
</table>
</fieldset>
</div>

View File

@@ -0,0 +1,10 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div style="position: static;padding: 10px;top: 0;width: 100%;background-color: orange;color: white;text-align: center;">
{l s='WARNING! This is the HTML stored into the cache. All other resources like images, javascript and styles are the "live" ones. Also dynamic modules are displayed with your context.' mod='pagecache'}
</div>

View File

@@ -0,0 +1,47 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
#{$id_context|intval} :
{if isset($flag_lang)}
<span class="label label-default" title="Language"><img src="../img/l/{$flag_lang|intval}.jpg" width="16" height="11"/></span>
{/if}
{if isset($flag_currency)}
<span class="label label-default" title="Currency">{$flag_currency|escape:'html':'UTF-8'}</span>
{/if}
{if isset($flag_country)}
<span class="label label-default" title="Country">{$flag_country|escape:'html':'UTF-8'}</span>
{/if}
{if isset($flag_device)}
{if $isPs17}
<span class="label label-default" title="{$flag_device|escape:'html':'UTF-8'} device"><i class="icon-{$flag_device|escape:'html':'UTF-8'}"></i></span>
{else}
<span class="label label-default" title="{$flag_device|escape:'html':'UTF-8'} device">{$flag_device|escape:'html':'UTF-8'}</span>
{/if}
{/if}
{if isset($flag_group)}
{if $isPs17}
<span class="label label-default" title="User groups"><i class="icon-users"></i> {$flag_group|escape:'html':'UTF-8'}</span>
{else}
<span class="label label-default" title="User groups">Groups: {$flag_group|escape:'html':'UTF-8'}</span>
{/if}
{/if}
{if isset($flag_tax_manager)}
<span class="label label-default specifics">Tax: #{$flag_tax_manager|escape:'html':'UTF-8'}
<div class="pc_specifics"><b>Taxes applied in this cache</b><br/>{$flag_tax_manager_more|escape:'html':'UTF-8'}</div>
</span>
{/if}
{if isset($flag_specifics)}
<span class="label label-default specifics">Specifics: #{$flag_specifics|escape:'html':'UTF-8'}
<div class="pc_specifics"><b>Some specific keys added by some modules</b><br/>{$flag_specifics_more|escape:'html':'UTF-8'}</div>
</span>
{/if}
{if isset($flag_v_css)}
<span class="label label-default" title="JS version to avoid the use of obsolete styles">CSS v{$flag_v_css|escape:'html':'UTF-8'}</span>
{/if}
{if isset($flag_v_js)}
<span class="label label-default" title="JS version to avoid the use of obsolete javascript">JS v{$flag_v_js|escape:'html':'UTF-8'}</span>
{/if}

View File

@@ -0,0 +1,14 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
{if $deleted}
{if $isPs17}
<i class="icon-check"></i>
{else}
X
{/if}
{/if}

View File

@@ -0,0 +1,9 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<span style="color:green">{$count_hit|intval}</span>&nbsp;/&nbsp;<span style="color:red">{$count_missed|intval}</span>
({$count_percent|escape:'html':'UTF-8'}%)

View File

@@ -0,0 +1,9 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<span style="cursor:help" title="Age: {$age|escape:'html':'UTF-8'} - Time to live: {$ttl_msg|escape:'html':'UTF-8'}">{$last_gen|escape:'html':'UTF-8'}</span>
<div style="border-bottom: 2px solid {$color|escape:'html':'UTF-8'};width: {$percent|intval}%;"></div>

View File

@@ -0,0 +1,50 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<a class="cacheurl" href="{$url|escape:'html':'UTF-8'}" title="{$url|escape:'html':'UTF-8'}" target="_blank">{$url|escape:'html':'UTF-8'}</a>
{if isset($url_cached)}
<a class="cacheurl" href="{$url_cached|escape:'html':'UTF-8'}" title="See the cached version" target="_blank"><i class="icon-database"></i></a>
{/if}
{if isset($flag_lang)}
<span class="label label-default" title="Language"><img src="../img/l/{$flag_lang|intval}.jpg" width="16" height="11"/></span>
{/if}
{if isset($flag_currency)}
<span class="label label-default" title="Currency">{$flag_currency|escape:'html':'UTF-8'}</span>
{/if}
{if isset($flag_country)}
<span class="label label-default" title="Country">{$flag_country|escape:'html':'UTF-8'}</span>
{/if}
{if isset($flag_device)}
{if $isPs17}
<span class="label label-default" title="{$flag_device|escape:'html':'UTF-8'} device"><i class="icon-{$flag_device|escape:'html':'UTF-8'}"></i></span>
{else}
<span class="label label-default" title="{$flag_device|escape:'html':'UTF-8'} device">{$flag_device|escape:'html':'UTF-8'}</span>
{/if}
{/if}
{if isset($flag_group)}
{if $isPs17}
<span class="label label-default" title="User groups"><i class="icon-users"></i> {$flag_group|escape:'html':'UTF-8'}</span>
{else}
<span class="label label-default" title="User groups">Groups: {$flag_group|escape:'html':'UTF-8'}</span>
{/if}
{/if}
{if isset($flag_tax_manager)}
<span class="label label-default specifics" title="Taxes applied in this cache">Tax: #{$flag_tax_manager|escape:'html':'UTF-8'}
<div class="pc_specifics">{$flag_tax_manager_more|escape:'html':'UTF-8'}</div>
</span>
{/if}
{if isset($flag_specifics)}
<span class="label label-default specifics" title="Some specific keys added by some modules">Specifics: #{$flag_specifics|escape:'html':'UTF-8'}
<div class="pc_specifics"><b>Some specific keys added by some modules</b><br/>{$flag_specifics_more|escape:'html':'UTF-8'}</div>
</span>
{/if}
{if isset($flag_v_css)}
<span class="label label-default" title="JS version to avoid the use of obsolete styles">CSS v{$flag_v_css|escape:'html':'UTF-8'}</span>
{/if}
{if isset($flag_v_js)}
<span class="label label-default" title="JS version to avoid the use of obsolete javascript">JS v{$flag_v_js|escape:'html':'UTF-8'}</span>
{/if}

View File

@@ -0,0 +1,30 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<table class="table">
<tbody>
{foreach $systemInfos->getAll() as $key => $labelValue}
<tr>
<td style="font-weight: bold">{$labelValue['label']|escape:'html':'UTF-8'}</td>
<td>{$labelValue['value']|escape:'html':'UTF-8'}</td>
</tr>
{/foreach}
</tbody>
</table>
{if $op_cache}
<form id="pagecache_form_resetopcache" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="diagnostic"/>
<fieldset style="margin: 10px 0">
<div class="bootstrap">
<button type="submit" id="submitModuleResetOpcache" name="submitModuleResetOpcache" class="btn btn-warning">
<i class="process-icon-delete"></i> {l s='Reset OP Cache' mod='pagecache'}
</button>
</div>
</fieldset>
</form>
{/if}

View File

@@ -0,0 +1,171 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-user-md"></i>{else}<img width="16" height="16" src="../img/admin/binoculars.png" alt=""/>{/if}&nbsp;{l s='Configuration' mod='pagecache'} ({$diagnostic_count|escape:'html':'UTF-8'})</h3>
<form id="pagecache_form_diagnostic" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="diagnostic"/>
<fieldset>
{if $diagnostic_count == 0}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24"/> {l s='Everything is good!' mod='pagecache'}
{/if}
{foreach $diagnostic['error'] as $diagMsg}
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-danger" style="display: block;">&nbsp;{$diagMsg['msg']|escape:'html':'UTF-8'}.{if array_key_exists('link', $diagMsg)} <a href="{$diagMsg['link']|escape:'html':'UTF-8'}">{$diagMsg['link_title']|escape:'html':'UTF-8'}.</a>{/if}</div></div>
{else}
<div class="error clear" style="display: block;">&nbsp;{$diagMsg['msg']|escape:'html':'UTF-8'}.{if array_key_exists('link', $diagMsg)} <a href="{$diagMsg['link']|escape:'html':'UTF-8'}">{$diagMsg['link_title']|escape:'html':'UTF-8'}.</a>{/if}</div>
{/if}
{/foreach}
{foreach $diagnostic['warn'] as $diagMsg}
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-warning" style="display: block;">&nbsp;{$diagMsg['msg']|escape:'html':'UTF-8'}.{if array_key_exists('link', $diagMsg)} <a href="{$diagMsg['link']|escape:'html':'UTF-8'}">{$diagMsg['link_title']|escape:'html':'UTF-8'}.</a>{/if}</div></div>
{else}
<div class="warn clear" style="display: block;">&nbsp;{$diagMsg['msg']|escape:'html':'UTF-8'}.{if array_key_exists('link', $diagMsg)} <a href="{$diagMsg['link']|escape:'html':'UTF-8'}">{$diagMsg['link_title']|escape:'html':'UTF-8'}.</a>{/if}</div>
{/if}
{/foreach}
{foreach $diagnostic['info'] as $diagMsg}
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-info" style="display: block;">&nbsp;{$diagMsg['msg']|escape:'html':'UTF-8'}.{if array_key_exists('link', $diagMsg)} <a href="{$diagMsg['link']|escape:'html':'UTF-8'}">{$diagMsg['link_title']|escape:'html':'UTF-8'}.</a>{/if}</div></div>
{else}
<div class="hint clear" style="display: block;">&nbsp;{$diagMsg['msg']|escape:'html':'UTF-8'}.{if array_key_exists('link', $diagMsg)} <a href="{$diagMsg['link']|escape:'html':'UTF-8'}">{$diagMsg['link_title']|escape:'html':'UTF-8'}.</a>{/if}</div>
{/if}
{/foreach}
</fieldset>
</form>
</div>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-desktop"></i>{else}<img width="16" height="16" src="../img/admin/informations.png" alt=""/>{/if}&nbsp;{l s='System informations' mod='pagecache'}</h3>
{include file='./get-content-tab-diagnostic-infos.tpl' systemInfos=$systemInfos}
</div>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-exclamation-triangle"></i>{else}<img width="16" height="16" src="../img/admin/error.png" alt=""/>{/if}&nbsp;{l s='Slower modules' mod='pagecache'}</h3>
{if $avec_bootstrap}
<div class="bootstrap">
<div class="alert alert-info" style="display: block;">
{l s='This table shows you the slower modules that could slow down your shop' mod='pagecache'}
</div>
{if $pagecache_profiling_not_available}
<div class="alert alert-warning" style="display: block;">
&nbsp;{l s='This tools is only available from Prestashop 1.7' mod='pagecache'}
</div>
{else}
{if !$module_enabled}
<div class="alert alert-warning" style="display: block;">
&nbsp;{l s='This tools is not available if the module or if the shop is not enabled' mod='pagecache'}
</div>
{/if}
{if $pagecache_profiling_max_reached}
<div class="alert alert-warning" style="display: block;">
{l s='To preserve performances, the profiling has been suspended because it reaches the maximum number of records' mod='pagecache'}: {$pagecache_profiling_max|escape:'html':'UTF-8'}
</div>
{/if}
{/if}
</div>
{else}
<div class="hint clear">
<div>
{l s='This table shows you the slower modules that could slow down your shop' mod='pagecache'}
</div>
</div>
{if $pagecache_profiling_not_available}
<div class="warn clear" style="display: block;">&nbsp;{l s='This tools is only available from Prestashop 1.7' mod='pagecache'}</div>
{else}
{if !$module_enabled}
<div class="warn clear" style="display: block;">&nbsp;{l s='This tools is not available if the module or if the shop is not enabled' mod='pagecache'}</div>
{/if}
{if $pagecache_profiling_max_reached}
<div class="warn clear" style="display: block;">&nbsp;{l s='To preserve performances, the profiling has been suspended because it reaches the maximum number of records' mod='pagecache'}: {$pagecache_profiling_max|escape:'html':'UTF-8'}</div>
{/if}
{/if}
{/if}
{if $module_enabled && !$pagecache_profiling_not_available}
<form id="pagecache_form_profiling" action="{$request_uri|escape:'html':'UTF-8'}" method="post" class="form-inline">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="diagnostic"/>
<fieldset style="margin: 10px 0">
{if $pagecache_profiling}
<div class="form-group">
<label for="pagecache_profiling_min_ms">{l s='Only record modules that last more than' mod='pagecache'}</label>
<div class="input-group">
<input type="number" min="0" style="text-align:right" class="form-control" id="pagecache_profiling_min_ms" name="pagecache_profiling_min_ms" value="{$pagecache_profiling_min_ms|escape:'html':'UTF-8'}">
<div class="input-group-addon">ms</div>
</div>
</div>
<button type="submit" id="submitModuleProfilingMinMs" name="submitModuleProfilingMinMs" value="1" class="btn btn-default">{l s='Save' mod='pagecache'}</button>
{/if}
</fieldset>
<fieldset style="margin: 10px 0">
<div class="bootstrap">
<button type="submit" value="1" id="submitModuleOnOffProfiling" name="submitModuleOnOffProfiling"
class="btn btn-default">
<i class="process-icon-off"
style="color:{if $pagecache_profiling}red{else}rgb(139, 201, 84){/if}"></i> {if $pagecache_profiling}{l s='Disable profiling' mod='pagecache'}{else}{l s='Enable profiling' mod='pagecache'}{/if}
</button>
{if $pagecache_profiling}
<button type="submit" value="1" id="submitModuleResetProfiling" name="submitModuleResetProfiling"
class="btn btn-default">
<i class="process-icon-delete"
style="color:orange"></i> {l s='Clear profiling datas' mod='pagecache'}
</button>
<button type="button" value="1" id="submitModuleRefreshProfiling" name="submitModuleRefreshProfiling"
class="btn btn-default" onclick="$('#profilingTable').DataTable().ajax.reload();return false;">
<i class="process-icon-refresh"></i> {l s='Refresh' mod='pagecache'}
</button>
{/if}
</div>
</fieldset>
</form>
{if $pagecache_profiling}
<script type="application/javascript">
$(document).ready(function () {
$('#profilingTable').DataTable({
processing: true,
serverSide: true,
searching: false,
ajax: '{$pagecache_profiling_datas_url|escape:'javascript':'UTF-8'}',
language: {
processing: "{l s='Loading datas...' mod='pagecache'}",
search: "{l s='Search...' mod='pagecache'}:",
lengthMenu: "{l s='Showing _MENU_ rows' mod='pagecache'}",
info: "{l s='Showing _START_ to _END_ of _TOTAL_ rows' mod='pagecache'}",
infoEmpty: "{l s='Showing 0 to 0 of 0 row' mod='pagecache'}",
infoFiltered: "{l s='Filtered of _MAX_ rows' mod='pagecache'}",
infoPostFix: "",
loadingRecords: "{l s='Loading datas...' mod='pagecache'}",
zeroRecords: "{l s='No module to display' mod='pagecache'}",
emptyTable: "{l s='No module to display' mod='pagecache'}",
paginate: {
first: "{l s='First' mod='pagecache'}",
previous: "{l s='Previous' mod='pagecache'}",
next: "{l s='Next' mod='pagecache'}",
last: "{l s='Last' mod='pagecache'}"
},
aria: {
sortAscending: ": {l s='Click to sort ascending' mod='pagecache'}",
sortDescending: ": {l s='Click to sort descending' mod='pagecache'}"
}
}
});
});
</script>
<table id="profilingTable" class="display cell-border compact stripe" style="width:100%">
<thead>
<tr>
<th>{l s='Module' mod='pagecache'}</th>
<th>{l s='Code' mod='pagecache'}</th>
<th>{l s='Execution date' mod='pagecache'}</th>
<th>{l s='Duration' mod='pagecache'}</th>
</tr>
</thead>
</table>
{/if}
{/if}
</div>

View File

@@ -0,0 +1,186 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
{if $avec_bootstrap}
{assign var=logo value='logo.png'}
{else}
{assign var=logo value='logo.gif'}
{/if}
<script type="text/javascript">
function addWidget(widgetDisplayName, widgetName, hookName, emptyBox, widgetVersion, widgetAuthor, widgetDescription, widgetId) {
$("#widgetTables").append("<tr>" +
"<td><img width=\"32\" src=\"../modules/"+widgetName+"/logo.png\" title=\""+widgetName+" #"+widgetId+" - "+widgetDescription+"\"/> "+widgetDisplayName+" <small class=\"text-muted\">&nbsp;-&nbsp;v"+widgetVersion+"</small><small class=\"text-muted\">&nbsp;-&nbsp;"+widgetAuthor+"</small></td>" +
"<td style=\"text-align: center\">"+hookName+"</td>" +
"<td style=\"text-align: center\"><input" + (emptyBox ? " checked" : "") + " disabled type=\"checkbox\"/></td>" +
"<td><button type=\"button\" onclick=\"removeWidget(\'"+widgetName+"\', \'"+hookName+"\'); this.closest(\'tr\').remove();\"><i class=\"icon-remove\"></i> {l s='Remove' mod='pagecache'}</button><input type=\"hidden\" name=\"pagecache_dynwidgets[]\" value=\""+widgetName+"|"+hookName+"|"+(emptyBox ? "1" : "0")+"\"/></td></tr>");
}
function removeWidget(widgetName, hookName) {
}
$(function() {
$("#dynhook_filter").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#dynhooks_table > tbody > tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
});
});
});
</script>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-puzzle-piece"></i>{else}<img width="16" height="16" src="../img/admin/tab-plugins.gif" alt=""/>{/if}&nbsp;{l s='Dynamic modules and widgets' mod='pagecache'}</h3>
<form id="pagecache_form_dynhooks" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="dynhooks"/>
<fieldset>
<div style="clear: both;">
{if !$pagecache_debug}
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-warning" style="display: block;">&nbsp;{l s='To be able to modify dynamic modules and widgets you must go back in "test mode" in first tab' mod='pagecache'}</div></div>
{else}
<div class="warn clear" style="display: block;">&nbsp;{l s='To be able to modify dynamic modules and widgets you must go back in "test mode" in first tab' mod='pagecache'}</div>
{/if}
{/if}
<p>{l s='You cannot exclude a module from the cache but you can set it as dynamic. A dynamic module will be displayed in "anonymous mode" in the cache, then a background request will refresh it in order to display it with the context of the current visitor.' mod='pagecache'}</p>
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-info" style="display: block;">&nbsp;{l s='Note that dynamic module Ajax call are done all at once (one HTTP request)' mod='pagecache'}</div></div>
{else}
<div class="hint clear" style="display: block;">&nbsp;{l s='Note that dynamic module Ajax call are done all at once (one HTTP request)' mod='pagecache'}</div>
{/if}
<br/><h4 id="tabdynhooksmodules">{l s='Dynamic modules' mod='pagecache'}</h4>
<input type="text" id="dynhook_filter" placeholder="{l s='Filter' mod='pagecache'}" style="margin: 5px 0; width: 200px"/>
<table id="dynhooks_table" class="table table-bordered table-striped">
<thead>
<tr>
<th width="40%">{l s='Module' mod='pagecache'}</th>
<th width="60%">{l s='Hooks' mod='pagecache'}</th>
</tr>
</thead>
<tbody>
{assign var=indexRow value=0}
{foreach $modules_hooks as $module_name => $moduleInfos}
<tr>
<td style="vertical-align: top">
<img width="32" src="../modules/{$module_name|escape:'html':'UTF-8'}/logo.png" title="{$module_name|escape:'html':'UTF-8'} #{$moduleInfos['id_module']|intval} - {$moduleInfos['description']|escape:'html':'UTF-8'}" />
{$moduleInfos['display_name']|escape:'html':'UTF-8'}
{if $moduleInfos['version']}
<small class="text-muted">&nbsp;-&nbsp;v{$moduleInfos['version']|escape:'html':'UTF-8'}</small>
{/if}
{if $moduleInfos['author']}
<small class="text-muted">&nbsp;-&nbsp;{$moduleInfos['author']|escape:'html':'UTF-8'}</small>
{/if}
</td>
<td>
<table class="table">
<colgroup>
<col width="0*">
<col width="*">
<col width="0*">
<col width="50%">
</colgroup>
{foreach $moduleInfos['hooks'] as $hook_name => $hook_infos}
<tr>
<td width="15"><input {if $hook_infos['dyn_is_checked']}checked{/if} {if !$pagecache_debug}disabled{/if} type="checkbox" name="pagecache_hooks[]" id="dyn{$indexRow|escape:'html':'UTF-8'}" value="{$hook_name|escape:'html':'UTF-8'}|{$module_name|escape:'html':'UTF-8'}" onclick="$('.emptyspan{$indexRow|escape:'html':'UTF-8'}').toggle();"/></td>
<td><label for="dyn{$indexRow|escape:'html':'UTF-8'}">{$hook_name|escape:'html':'UTF-8'}</label></td>
<td width="15">
<span {if !$hook_infos['dyn_is_checked']}style="display:none"{/if} class="emptyspan{$indexRow|escape:'html':'UTF-8'}">
<input {if $hook_infos['empty_option_checked']}checked{/if} {if !$pagecache_debug}disabled{/if} type="checkbox" name="pagecache_hooks_empty_{$hook_name|escape:'html':'UTF-8'}_{$module_name|escape:'html':'UTF-8'}" id="emptyoption{$indexRow|escape:'html':'UTF-8'}" value="1"/>
</span>
</td>
<td>
<span {if !$hook_infos['dyn_is_checked']}style="display:none"{/if} class="emptyspan{$indexRow|escape:'html':'UTF-8'}">
<label class="t" for="emptyoption{$indexRow|escape:'html':'UTF-8'}">{l s='Display nothing in cache' mod='pagecache'}</label>
</span>
</td>
</tr>
{assign var=indexRow value=$indexRow+1}
{/foreach}
</table>
</td>
</tr>
{/foreach}
</tbody>
</table>
<h4 id="tabdynhookswidgets" style="margin-top: 20px">{l s='Dynamic widgets' mod='pagecache'}</h4>
<input type="hidden" name="pcdynwidgets" value=""/>
<p>{l s='Widgets are modules that can be displayed anywhere in the theme; they do not need any hook. This feature has been added in Prestashop 1.7. A widget can be displayed with an optional "hookName" that is used to choose a specific template.' mod='pagecache'}</p>
<p>{l s='Here you can specify which widget must be refreshed dynamically (is relative to the current visitor).' mod='pagecache'}</p>
<table style="margin: 15px">
<tr>
<td style="padding-right: 5px"><label for="widgetName" style="float:inherit">{l s='Widget' mod='pagecache'}</label></td>
<td><label for="widgetHookName" style="float:inherit; padding-left: 20px">{l s='Hook name (optional)' mod='pagecache'}</label></td>
</tr>
<tr>
<td style="padding-right: 5px">
<select {if !$pagecache_debug}disabled{/if} name="widgetName" id="widgetName" style="width: 200px">
{foreach $widgets as $widget_name => $widget_infos}
<option value="{$widget_name|escape:'html':'UTF-8'}" data-version="{$widget_infos['version']|escape:'html':'UTF-8'}" data-author="{$widget_infos['author']|escape:'html':'UTF-8'}" data-description="{$widget_infos['description']|escape:'html':'UTF-8'}" data-id="{$widget_infos['id_module']|escape:'html':'UTF-8'}">{$widget_infos['display_name']|escape:'html':'UTF-8'} ({$widget_name|escape:'html':'UTF-8'})</option>
{/foreach}
</select>
</td>
<td style="padding-right: 5px">
<input {if !$pagecache_debug}disabled{/if} id="widgetHookName" name="widgetHookName" style="width: 200px;" value="" type="text"/>
</td>
<td style="padding-right: 5px">
<div class="checkbox"><label for="widgetEmptyBox"><input {if !$pagecache_debug}disabled{/if} id="widgetEmptyBox" name="widgetEmptybox" value="1" type="checkbox"/>{l s='Display nothing in cache' mod='pagecache'}</label></div>
</td>
<td>
<button {if !$pagecache_debug}disabled{/if} type="button" onclick="addWidget($('#widgetName option:selected').text(), $('#widgetName').val(), $('#widgetHookName').val(), $('#widgetEmptyBox').is(':checked'), $('#widgetName option:selected').data('version'), $('#widgetName option:selected').data('author'), $('#widgetName option:selected').data('description'), $('#widgetName option:selected').data('id'))" class="btn btn-default"><i class="icon-plus"></i> {l s='Add' mod='pagecache'}</button>
</td>
</tr>
</table>
<div class="bootstrap">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr><th>{l s='Widget' mod='pagecache'}</th><th style="text-align: center">{l s='Hook name' mod='pagecache'}</th><th style="text-align: center">{l s='Display nothing in cache' mod='pagecache'}</th><th></th></tr>
</thead>
<tbody id="widgetTables">
{foreach $dynamic_widgets as $widgetInfos}
<tr>
<td>
<img width="32" src="../modules/{$widgetInfos['name']|escape:'html':'UTF-8'}/logo.png" title="{$widgetInfos['name']|escape:'html':'UTF-8'} #{$widgetInfos['id_module']|intval} - {$widgetInfos['description']|escape:'html':'UTF-8'}" />
{$widgetInfos['display_name']|escape:'html':'UTF-8'}
{if $widgetInfos['version']}
<small class="text-muted">&nbsp;-&nbsp;v{$widgetInfos['version']|escape:'html':'UTF-8'}</small>
{/if}
{if $widgetInfos['author']}
<small class="text-muted">&nbsp;-&nbsp;{$widgetInfos['author']|escape:'html':'UTF-8'}</small>
{/if}
</td>
<td style="text-align: center">{$widgetInfos['hook']|escape:'html':'UTF-8'}</td>
<td style="text-align: center"><input {if $widgetInfos['empty_box']}checked{/if} disabled type="checkbox"/></td>
<td>{if $pagecache_debug}<button type="button" onclick="removeWidget('{$widgetInfos['name']|escape:'html':'UTF-8'}', '{$widgetInfos['hook']|escape:'html':'UTF-8'}'); this.closest('tr').remove();"><i class="icon-remove"></i> {l s='Remove' mod='pagecache'}</button><input type="hidden" name="pagecache_dynwidgets[]" value="{$widgetInfos['name']|escape:'html':'UTF-8'}|{$widgetInfos['hook']|escape:'html':'UTF-8'}|{$widgetInfos['empty_box']|intval}"/>{/if}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<h4 id="tabdynhooksjs" style="margin-top: 20px">{l s='Javascript to execute' mod='pagecache'}</h4>
<div id="cfgadvanced">
<p>{l s='Here you can modify javascript code that is executed after dynamic modules and widgets have been displayed on the page.' mod='pagecache'}</p>
<p>{l s='If you meet problems with your theme, ask your theme designer what javascript you should add here.' mod='pagecache'}</p>
<textarea {if !$pagecache_debug}disabled{/if} name="cfgadvancedjs" style="width:95%" rows="20">{$pagecache_cfgadvancedjs|escape:'html':'UTF-8'}</textarea>
</div>
</div>
<br/>
<div class="bootstrap">
<button type="submit" value="1" id="submitModuleDynhooks" name="submitModuleDynhooks" class="btn btn-default pull-right" {if !$pagecache_debug}disabled{/if}>
<i class="process-icon-save"></i> {l s='Save' mod='pagecache'}
</button>
</div>
</fieldset>
</form>
</div>

View File

@@ -0,0 +1,538 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="row" id="dashboard">
{if $latest_version}
<div class="col-md-12">
<div class="panel" style="font-size: 0.9rem;">
<h3 class="panel-heading" style="color: #59c763">{if $avec_bootstrap}<i class="icon-star" style="color: #59c763"></i>{else}<img width="16" height="16" src="../img/admin/asterisk.gif" alt=""/>{/if} {l s='New version %s is now available!' mod='pagecache' sprintf=[$latest_version['version']]}</h3>
<p>{l s='Version %s has been published, check the changelogs to know what is new.' mod='pagecache' sprintf=[$latest_version['version']]}</p>
{if !$latest_version['upgrade_link']}
{if $pagecache_seller == 'addons'}
<p>
{l s='Publishing all versions to Addons is very time consuming so I created a free module to allow you to upgrade to the latest version very easily (one click). Find how it works and download it here:' mod='pagecache'}
<a href="{$jpresta_shop_url|escape:'html':'UTF-8'}{l s='/en/prestashop-modules/20-jpresta-easy-upgrade.html' mod='pagecache'}" target="_blank">{$jpresta_shop_url|escape:'html':'UTF-8'}{l s='/en/prestashop-modules/20-jpresta-easy-upgrade.html' mod='pagecache'}</a>
</p>
{else}
<p>
{l s='To make your life easier I created a free module to allow you to upgrade to the latest version in one click. Find how it works and download it here:' mod='pagecache'}
<a href="{$jpresta_shop_url|escape:'html':'UTF-8'}{l s='/en/prestashop-modules/20-jpresta-easy-upgrade.html' mod='pagecache'}" target="_blank">{$jpresta_shop_url|escape:'html':'UTF-8'}{l s='/en/prestashop-modules/20-jpresta-easy-upgrade.html' mod='pagecache'}</a>
</p>
{/if}
{/if}
<p>{l s='Using the latest version is always recommended because it may fix a bug or make the cache more efficient or even faster!' mod='pagecache'}</p>
{if $latest_version['upgrade_link']}
<a href="{$latest_version['upgrade_link']|escape:'html':'UTF-8'}" class="btn btn-primary">{l s='Upgrade with JPresta Easy Upgrade' mod='pagecache'}...</a>
{else}
<a href="{$jpresta_shop_url|escape:'html':'UTF-8'}{l s='/en/prestashop-modules/20-jpresta-easy-upgrade.html' mod='pagecache'}" target="_blank" class="btn btn-primary">{l s='Download JPresta Easy Upgrade' mod='pagecache'}...</a>
{/if}
{if $latest_version['changelogs']}
<a data-toggle="collapse" href="#changelogs" role="button" aria-expanded="false" aria-controls="changelogs" class="btn btn-default">{l s='See changelogs' mod='pagecache'}</a>
<div id="changelogs" class="collapse changelogs" style="border: 1px solid #ccc; border-radius: 3px; padding: 0.5rem; margin-top: 0.5rem; max-height: 200px; overflow: auto;">
{foreach from=$latest_version['changelogs'] key=versionLogs item=logs}
{$versionLogs|escape:'html':'UTF-8'}
<ul>
{foreach from=$logs item=log}
<li>{$log|escape:'html':'UTF-8'}</li>
{/foreach}
</ul>
{/foreach}
</div>
{/if}
</div>
</div>
{/if}
<div class="{if $pagecache_debug}col-md-12{else}col-md-12 col-lg-6{/if}">
<div class="panel">
<h3 class="panel-heading">{if $avec_bootstrap}<i class="icon-wrench"></i>{else}<img width="16" height="16" src="../img/admin/prefs.gif" alt=""/>{/if} {l s='Installation' mod='pagecache'}</h3>
<form id="pagecache_form_install" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="install"/>
<input type="hidden" name="pagecache_disable_tokens" value="false" id="pagecache_disable_tokens"/>
<fieldset>
<div style="clear: both;">
{if $pagecache_debug}
<input type="hidden" name="pagecache_install_step" id="pagecache_install_step" value="{$cur_step + 1|escape:'html':'UTF-8'}"/>
<input type="hidden" name="pagecache_disable_loggedin" id="pagecache_disable_loggedin" value="0"/>
<input type="hidden" name="pagecache_seller" id="pagecache_seller" value="{$pagecache_seller|escape:'html':'UTF-8'}"/>
<input type="hidden" name="pagecache_autoconf" id="pagecache_autoconf" value="false"/>
{if $cur_step > $INSTALL_STEP_INSTALL}
<div class="installstep">{l s='Congratulations!' mod='pagecache'} {$module_displayName|escape:'html':'UTF-8'} {l s='is currently installed in' mod='pagecache'} <b>{l s='test mode' mod='pagecache'}</b>{l s=', that means it\'s not yet activated to your visitors.' mod='pagecache'}</div>
{/if}
<div class="installstep">{l s='To complete the installation, please follow these steps:' mod='pagecache'}
{* INSTALL STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_INSTALL}stepok{elseif $cur_step < $INSTALL_STEP_INSTALL}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_INSTALL}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_INSTALL}
<span>{$INSTALL_STEP_INSTALL|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Install the module and enable test mode' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_INSTALL}
<div class="stepdesc"><ol><li>{l s='Resolve displayed errors above' mod='pagecache'}</li></ol></div>
{/if}
</div>
{* BUY FROM STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_BUY_FROM}stepok{elseif $cur_step < $INSTALL_STEP_BUY_FROM}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_BUY_FROM}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_BUY_FROM}
<span>{$INSTALL_STEP_BUY_FROM|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Tell us where did you buy the module' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_BUY_FROM}
<div class="stepdesc">
<ol>
<li>{l s='In order to display correct links for support just tell us where you bought ' mod='pagecache'}{$module_displayName|escape:'html':'UTF-8'}</li>
</ol>
<a href="#" class="okbtn" onclick="$('#pagecache_seller').val('addons');$('#pagecache_form_install').submit();return false;">{l s='Prestashop Addons' mod='pagecache'}</a>
<a href="#" class="okbtn" onclick="$('#pagecache_seller').val('jpresta');$('#pagecache_form_install').submit();return false;">{l s='JPresta.com' mod='pagecache'}</a>
</div>
{/if}
</div>
{* IN ACTION STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_IN_ACTION}stepok{elseif $cur_step < $INSTALL_STEP_IN_ACTION}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_IN_ACTION}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_IN_ACTION}
<span>{$INSTALL_STEP_IN_ACTION|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Check that the module is well installed' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_IN_ACTION}
<div class="stepdesc">
<ol>
<li><a href="{$shop_link_debug|escape:'html':'UTF-8'}" target="_blank">{l s='Click here to browse your site in test mode' mod='pagecache'}</a></li>
<li>{l s='You must see a box displayed in bottom left corner of your store' mod='pagecache'}</li>
<li>{l s='You must be able to play with these buttons' mod='pagecache'} &nbsp;&nbsp;<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/on.png" alt="" width="16" height="16" /><img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/reload.png" alt="" width="16" height="16" /><img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/trash.png" alt="" width="16" height="16" /><img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/close.png" alt="" width="16" height="16" /></li>
</ol>
<a href="#" class="okbtn" onclick="$('#pagecache_form_install').submit();return false;">{l s='OK, I validate this step' mod='pagecache'}</a>
<a href="#" class="kobtn" onclick="$('#helpINSTALL_STEP_IN_ACTION').toggle();return false;">{l s='No, I\'m having trouble' mod='pagecache'}</a>
<div class="stephelp" id="helpINSTALL_STEP_IN_ACTION">
<ol>
<li>{l s='Reset the module and see if it\'s better' mod='pagecache'}</li>
<li>{l s='If, after resetting the module, you are still having trouble,' mod='pagecache'} <a href="{$contact_url|escape:'html':'UTF-8'}" target="_blank">{l s='contact us here' mod='pagecache'}</a></li>
</ol>
</div>
</div>
{/if}
</div>
{* AUTOCONF STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_AUTOCONF}stepok{elseif $cur_step < $INSTALL_STEP_AUTOCONF}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_AUTOCONF}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_AUTOCONF}
<span>{$INSTALL_STEP_AUTOCONF|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Auto-configuration of known modules' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_AUTOCONF}
<div class="stepdesc">
<p>
<i>{l s='Contact our server to request the configuration of know modules so it\'s faster and easier for you' mod='pagecache'}</i>
</p>
{if !empty($pagecache_cfgadvancedjs)}
<div class="bootstrap">
<div class="alert alert-info" style="display: block;">&nbsp;{l s='Warning: this will erase the current configuration of Page Cache' mod='pagecache'}</div>
</div>
<button class="okbtn" onclick="if (confirm('{l s='Warning: this will erase the current configuration of Page Cache' js='true' mod='pagecache'}')){ $('#pagecache_autoconf').val('true');$('#pagecache_form_install').submit();$(this).prop('disabled', 'true');};return false;">{l s='Auto-configuration' mod='pagecache'}</button>
{else}
<button class="okbtn" onclick="$('#pagecache_autoconf').val('true');$('#pagecache_form_install').submit();$(this).prop('disabled', 'true');return false;">{l s='Auto-configuration' mod='pagecache'}</button>
{/if}
<a href="#" class="kobtn" onclick="$('#pagecache_autoconf').val('false');$('#pagecache_form_install').submit();return false;">{l s='Continue manually' mod='pagecache'}</a>
</div>
{/if}
</div>
{* CART STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_CART}stepok{elseif $cur_step < $INSTALL_STEP_CART}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_CART}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_CART}
<span>{$INSTALL_STEP_CART|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Check that the cart is working good' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_CART}
<div class="stepdesc">
<ol>
<li><a href="{$shop_link_debug|escape:'html':'UTF-8'}" target="_blank">{l s='Click here to browse your site in test mode' mod='pagecache'}</a></li>
<li>{l s='Check that you can add products into the cart as usual' mod='pagecache'}</li>
<li>{l s='Once you have a product in your cart, display an other page and see if cart still contains the products you added' mod='pagecache'}</li>
</ol>
<a href="#" class="okbtn" onclick="$('#pagecache_form_install').submit();return false;">{l s='OK, I validate this step' mod='pagecache'}</a>
<a href="#" class="kobtn" onclick="$('#helpINSTALL_STEP_CART').toggle();return false;">{l s='No, I\'m having trouble' mod='pagecache'}</a>
<div class="stephelp" id="helpINSTALL_STEP_CART">
<ol>
<li>{l s='When you display an other page, check that you have the parameter dbgpagecache=1 in the URL. If not, just add it.' mod='pagecache'}</li>
<li>{l s='When refreshing the cart, PageCache may remove some "mouse over" behaviours. To set them back you can execute some javascript after all dynamics modules have been displayed.' mod='pagecache'} <a href="#tabdynhooksjs" onclick="displayTab('dynhooks');return true;">{l s='Go in "Dynamic modules" tab in Javascript form.' mod='pagecache'}</a></li>
<li>{l s='If you cannot make it work,' mod='pagecache'} <a href="{$contact_url|escape:'html':'UTF-8'}" target="_blank">{l s='contact us here' mod='pagecache'}</a></li>
</ol>
</div>
</div>
{/if}
</div>
{* LOGGED_IN STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_LOGGED_IN}stepok{elseif $cur_step < $INSTALL_STEP_LOGGED_IN}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_LOGGED_IN}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_LOGGED_IN}
<span>{$INSTALL_STEP_LOGGED_IN|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Check that logged in users are recognized' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_LOGGED_IN}
<div class="stepdesc">
<ol>
{if $pagecache_skiplogged}
{if $avec_bootstrap}
<div class="bootstrap">
<div class="alert alert-info" style="display: block;">&nbsp;{l s='Cache is disabled for logged in users so this step should be OK now, but you should check this out anyway ;-)' mod='pagecache'}
<br/>{l s='If you want you can' mod='pagecache'} <a href="#" class="browsebtn" onclick="$('#pagecache_disable_loggedin').val(-1);$('#pagecache_form_install').submit();return false;">{l s='reactivate cache for logged in users' mod='pagecache'}</a>
</div>
</div>
{else}
<div class="hint clear" style="display: block;">&nbsp;{l s='Cache is disabled for logged in users so this step should be OK now, but you should check this out anyway ;-)' mod='pagecache'}
<br/>{l s='If you want you can' mod='pagecache'} <a href="#" class="browsebtn" onclick="$('#pagecache_disable_loggedin').val(-1);$('#pagecache_form_install').submit();return false;">{l s='reactivate cache for logged in users' mod='pagecache'}</a>
</div>
{/if}
{/if}
<li><a href="{$shop_link_debug|escape:'html':'UTF-8'}" target="_blank">{l s='Click here to browse your site in test mode' mod='pagecache'}</a></li>
<li>{l s='You must see the "sign in" link when you are not logged in' mod='pagecache'}</li>
<li>{l s='You must see the the user name when you are logged in' mod='pagecache'}</li>
<li>{l s='Of course it depends on your theme so just check that being logged in or not has the same behaviour with PageCache' mod='pagecache'}</li>
</ol>
<a href="#" class="okbtn" onclick="$('#pagecache_form_install').submit();return false;">{l s='OK, I validate this step' mod='pagecache'}</a>
<a href="#" class="kobtn" onclick="$('#helpINSTALL_STEP_LOGGED_IN').toggle();return false;">{l s='No, I\'m having trouble' mod='pagecache'}</a>
<div class="stephelp" id="helpINSTALL_STEP_LOGGED_IN">
{if !$pagecache_skiplogged}
<ol>
<li>{l s='Make sure that module displaying user informations or sign in links are set as "dynamic".' mod='pagecache'}</li>
<li>{l s='Your theme may be uncompatible with this feature, specially if these informations are "hard coded" in theme without using a module. In this case just disable PageCache for logged in users.' mod='pagecache'}</li>
</ol>
<a href="#" class="browsebtn" onclick="$('#pagecache_disable_loggedin').val(1);$('#pagecache_form_install').submit();return false;">{l s='Disable cache for logged in users' mod='pagecache'}</a>
{else}
<ol>
<li>{l s='Still having problem? Then ' mod='pagecache'} <a href="{$contact_url|escape:'html':'UTF-8'}" target="_blank">{l s='contact us here' mod='pagecache'}</a></li>
</ol>
{/if}
</div>
</div>
{/if}
</div>
{* EU_COOKIE STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_EU_COOKIE}stepok{elseif $cur_step < $INSTALL_STEP_EU_COOKIE}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_EU_COOKIE}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_EU_COOKIE}
<span>{$INSTALL_STEP_EU_COOKIE|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Check your european law module if any' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_EU_COOKIE}
<div class="stepdesc">
<ol>
<li><a href="{$shop_link_debug|escape:'html':'UTF-8'}" target="_blank">{l s='Click here to browse your site in test mode' mod='pagecache'}</a></li>
<li>{l s='Remove your cookies, reset the cache, then display a page' mod='pagecache'}</li>
<li>{l s='You should see the cookie law message; click to hide it' mod='pagecache'}</li>
<li>{l s='Reload the page, you should not see the message again' mod='pagecache'}</li>
</ol>
<a href="#" class="okbtn" onclick="$('#pagecache_form_install').submit();return false;">{l s='OK, I validate this step' mod='pagecache'}</a>
<a href="#" class="kobtn" onclick="$('#helpINSTALL_STEP_EU_COOKIE').toggle();return false;">{l s='No, I\'m having trouble' mod='pagecache'}</a>
<div class="stephelp" id="helpINSTALL_STEP_EU_COOKIE">
<ol>
<li>{l s='Make sure you have the latest version of the module' mod='pagecache'}</li>
<li>{l s='Still having problem? Then ' mod='pagecache'} <a href="{$contact_url|escape:'html':'UTF-8'}" target="_blank">{l s='contact us here' mod='pagecache'}</a></li>
</ol>
</div>
</div>
{/if}
</div>
{* VALIDATE STEP *}
<div class="step {if $cur_step > $INSTALL_STEP_VALIDATE}stepok{elseif $cur_step < $INSTALL_STEP_VALIDATE}steptodo{/if}">
{if $cur_step > $INSTALL_STEP_VALIDATE}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="24" height="24" />
{elseif $cur_step < $INSTALL_STEP_VALIDATE}
<span>{$INSTALL_STEP_VALIDATE|escape:'html':'UTF-8'}</span>
{else}
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/curstep.gif" alt="todo" width="24" height="24" />
{/if}
{l s='Push in production mode' mod='pagecache'}
{if $cur_step == $INSTALL_STEP_VALIDATE}
<div class="stepdesc">
<ol>
<li><a href="{$shop_link_debug|escape:'html':'UTF-8'}" target="_blank">{l s='Click here to browse your site in test mode' mod='pagecache'}</a></li>
<li>{l s='You can do more tests and once your are ready...' mod='pagecache'}</li>
</ol>
<a href="#" class="okbtn" onclick="$('#pagecache_form_install').submit();return false;">{l s='Enable PageCache for my customers!' mod='pagecache'}</a>
<a href="#" class="kobtn" onclick="$('#helpINSTALL_STEP_VALIDATE').toggle();return false;">{l s='No, I\'m having trouble' mod='pagecache'}</a>
<div class="stephelp" id="helpINSTALL_STEP_VALIDATE">
<ol>
<li>{l s='Make sure that the problem you have does not occur if you disable PageCache module' mod='pagecache'}</li>
<li>{l s='If your problem is only occuring with PageCache enabled, then' mod='pagecache'} <a href="{$contact_url|escape:'html':'UTF-8'}" target="_blank">{l s='contact us here' mod='pagecache'}</a></li>
</ol>
</div>
</div>
{/if}
</div>
<div class="bootstrap actions">
<button type="submit" value="1" onclick="$('#pagecache_install_step').val({$INSTALL_STEP_BUY_FROM|escape:'html':'UTF-8'}); return true;" id="submitModuleRestartInstall" name="submitModuleRestartInstall" class="btn btn-default">
<i class="process-icon-cancel" style="color:red"></i> {l s='Restart from first step' mod='pagecache'}
</button>
{if $cur_step !== $INSTALL_STEP_VALIDATE}
<button type="submit" value="1" onclick="$('#pagecache_install_step').val({$INSTALL_STEP_VALIDATE|escape:'html':'UTF-8'}); return true;" id="submitModuleGoToProd" name="submitModuleGoToProd" class="btn btn-default">
<i class="process-icon-next" style="color: #59C763"></i> {l s='Validate all steps' mod='pagecache'}
</button>
{/if}
</div>
</div>
{else}
<input type="hidden" name="pagecache_install_step" id="pagecache_install_step" value="{$INSTALL_STEP_BACK_TO_TEST|escape:'html':'UTF-8'}"/>
<div class="installstep"><img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/check.png" alt="ok" width="20" height="20" /> {l s='Congratulations!' mod='pagecache'} {$module_displayName|escape:'html':'UTF-8'} {l s='is currently installed in' mod='pagecache'} <b>{l s='production mode' mod='pagecache'}</b>{if $pagecache_skiplogged}{l s=' for not logged in users' mod='pagecache'}{/if}{l s=', that means your site is now faster than ever!' mod='pagecache'}
</div>
<div class="installstep">{l s='If you are having trouble, ' mod='pagecache'}<a href="#" class="browsebtn" onclick="$('#pagecache_form_install').submit();return false;">{l s='go back to test mode' mod='pagecache'}</a></div>
{/if}
<button type="submit" value="1" id="submitModuleClearCache" name="submitModuleClearCache" class="btn btn-default" style="display:none">
<i class="process-icon-delete" style="color:orange"></i> {l s='Clear cache' mod='pagecache'}
</button>
<ul style="display:none">
<li id="desc-module-clearcache-li">
<a id="desc-module-clearcache" class="toolbar_btn" href="#" onclick="$('#submitModuleClearCache').click(); return false;" style="color:white; background-color: #FFA500FF">
<i class="process-icon-delete"></i>
<div>{l s='Clear cache' mod='pagecache'}</div>
</a>
</li>
</ul>
</div>
</fieldset>
</form>
</div>
{if !$pagecache_debug}
<div class="panel">
<h3 class="panel-heading">{if $avec_bootstrap}<i class="icon-dashboard"></i>{else}<img width="16" height="16" src="../img/admin/stats.gif" alt=""/>{/if} {l s='Cache performance' mod='pagecache'}</h3>
<label for="hitrate">{l s='Hit rate' mod='pagecache'}</label>
<div id="hitrate" class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="{$performances.percent_hit|intval}" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em; width: {$performances.percent_hit|intval}%;">
{$performances.percent_hit|escape:'html':'UTF-8'}%
</div>
</div>
<p>{l s='This represents the rate of visitors getting the cached page, which mean the fast way. Higher is better! Don\'t worry, it is normal to get a low rate at the beginning.' mod='pagecache'}</p>
<p>{l s='You can improve this rate by using JPresta Cache Warmer' mod='pagecache'}.</p>
{if $performances.count_total > 0}
<div id="used_cache_chart" class='chart with-transitions' style="height: 400px">
<svg></svg>
</div>
<p>{l s='These metrics are based on %d visits since %s' sprintf=[$performances.count_total|intval,$performances.start_date|date_format:"%Y-%m-%d %H:%M:%S"] mod='pagecache'}</p>
<p>{l s='These metrics are flushed when you go in the statistics tab and click on' mod='pagecache'} "{l s='Reset cache (with stats)' mod='pagecache'}".</p>
{/if}
</div>
{/if}
</div>
{if !$pagecache_debug}
<div class="col-md-12 col-lg-6">
<div class="panel">
<h3 class="panel-heading">{if $avec_bootstrap}<i class="icon-dashboard"></i>{else}<img width="16" height="16" src="../img/admin/stats.gif" alt=""/>{/if} {l s='TTFB' mod='pagecache'}</h3>
<p>{l s='The TTFB is the real one computed by the browser of your visitors' mod='pagecache'}</p>
{if $pagecache_statsttfb}
<select id="perf_controller" name="perf_controller">
<option value="all">{l s='All pages' mod='pagecache'}</option>
{foreach $managed_controllers as $controller_name => $controller}
<option value="{$controller_name|escape:'javascript':'UTF-8'}">{$controller['title']|escape:'html':'UTF-8'}</option>
{/foreach}
</select>
<div id="ttfb_chart" class='chart with-transitions' style="height: 400px">
<svg></svg>
</div>
<p id="perf_infos"></p>
<p>{l s='You may see holes in lines or dates without data, this happens when no visits was recorded on that date for that type of page and that type of cache' mod='pagecache'}.</p>
{else}
<div class="alert alert-info">{l s='Statistics about TTFB have been disabled in "Advanced mode" > "Options"' mod='pagecache'}</div>
{/if}
</div>
</div>
{/if}
</div>
<script type="application/javascript">
var chart_ttfb = null;
$(document).ready(function () {
let used_cache_datas = [
{
"label": "{l s='Cache not available' mod='pagecache'}",
"value": {$performances.percent_missed|escape:'javascript':'UTF-8'}
},
{
"label": "{l s='Server cache' mod='pagecache'}",
"value": {$performances.percent_hit_server|escape:'javascript':'UTF-8'}
},
{
"label": "{l s='Static cache' mod='pagecache'}",
"value": {$performances.percent_hit_static|escape:'javascript':'UTF-8'}
},
{
"label": "{l s='Browser cache' mod='pagecache'}",
"value": {$performances.percent_hit_browser|escape:'javascript':'UTF-8'}
},
{
"label": "{l s='Back/forward cache' mod='pagecache'}",
"value": {$performances.percent_hit_bfcache|escape:'javascript':'UTF-8'}
},
];
//Donut chart example
if (typeof nv !== 'undefined') {
nv.addGraph(function () {
let chart_visits = nv.models.pieChart()
.x(function (d) {
return d.label
})
.y(function (d) {
return d.value
})
.color(['#ce720b', '#007e00', '#00bd00', '#00da00', '#00ff00'])
.donut(true) //Turn on Donut mode. Makes pie chart look tasty!
.donutRatio(0.25) //Configure how big you want the donut hole size to be.
.tooltipContent(function (key, y, e, graph) {
return '<b>' + y + ' %' + '</b>';
});
d3.select("#used_cache_chart svg")
.datum(used_cache_datas)
.transition().duration(500)
.call(chart_visits);
//Update the chart when window resizes.
nv.utils.windowResize(function () {
chart_visits.update()
});
return chart_visits;
});
let initGraph = function () {
d3.json('{$pagecache_datas_url|escape:'javascript':'UTF-8'}&type=ttfb&controller_name=' + $('#perf_controller').val() + '&_=' + Date.now(), function (datasInfos) {
nv.addGraph(function () {
let data = datasInfos['datas'];
if (datasInfos['total_count'] > 0) {
let msg = "{l s='These metrics are based on _TTFB_VISIT_ visits since _TTFB_START_' mod='pagecache'}.";
$('#perf_infos').html(msg.replace('_TTFB_START_', datasInfos['start_date']).replace('_TTFB_VISIT_', datasInfos['total_count']));
} else {
$('#perf_infos').html('');
}
chart_ttfb = nv.models.lineChart()
.margin({
left: 80,
bottom: 80,
right: 5
}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
.noData("{l s='No metric available yet, reload the page once your shop get some visitors' mod='pagecache'}");
;
let maxTtfb = 0;
$.each(data, function (i, rowType) {
$.each(rowType['values'], function (j, value) {
maxTtfb = Math.max(maxTtfb, value['y']);
});
});
// X axis
let midnight = new Date();
midnight.setHours(0);
midnight.setMinutes(0);
midnight.setSeconds(0);
midnight.setMilliseconds(0);
let startDate = new Date(midnight.getTime());
startDate.setDate(midnight.getDate() - 14);
let endDate = new Date(midnight.getTime());
endDate.setDate(midnight.getDate() + 1);
chart_ttfb.forceX([startDate.getTime() / 1000, endDate.getTime() / 1000]);
let tickValues = [];
for (let i = 0; i < 15; i++) {
tickValues[i] = (startDate.getTime() / 1000 + 86400 * i);
}
chart_ttfb.xAxis.axisLabel('Day').rotateLabels(-45).showMaxMin(false).tickValues(tickValues).tickFormat(function (d) {
let date = new Date(d * 1000);
return d3.time.format('%m-%d')(date);
});
// Y axis
chart_ttfb.forceY([0, Math.ceil(maxTtfb / 100) * 100]);
chart_ttfb.yAxis.axisLabel('TTFB (ms)');
d3.select('#ttfb_chart svg') //Select the <svg> element you want to render the chart in.
.datum(data) //Populate the <svg> element with chart data...
.call(chart_ttfb); //Finally, render the chart!
// Update the chart when window resizes.
nv.utils.windowResize(function () {
chart_ttfb.update()
});
return chart_ttfb;
});
});
}
let redrawGraph = function () {
console.log('Refresh chart for controller: ' + $('#perf_controller').val());
d3.json('{$pagecache_datas_url|escape:'javascript':'UTF-8'}&type=ttfb&controller_name=' + $('#perf_controller').val() + '&_=' + Date.now(), function (datasInfos) {
let data = datasInfos['datas'];
if (datasInfos['total_count'] > 0) {
let msg = "{l s='These metrics are based on _TTFB_VISIT_ visits since _TTFB_START_' mod='pagecache'}";
$('#perf_infos').html(msg.replace('_TTFB_START_', datasInfos['start_date']).replace('_TTFB_VISIT_', datasInfos['total_count']));
} else {
$('#perf_infos').html('');
}
let maxTtfb = 0;
$.each(data, function (i, rowType) {
$.each(rowType['values'], function (j, value) {
maxTtfb = Math.max(maxTtfb, value['y']);
});
});
chart_ttfb.forceY([0, Math.ceil(maxTtfb / 100) * 100]);
d3.select('#ttfb_chart svg > *').remove();
d3.select('#ttfb_chart svg').datum(data).transition().duration(500).call(chart_ttfb);
});
};
$('#perf_controller').change(function () {
redrawGraph();
});
initGraph();
}
});
</script>

View File

@@ -0,0 +1,13 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-fire"></i>{else}<img width="16" height="16" src="../img/admin/quick.gif" alt=""/>{/if}&nbsp;{l s='JPresta Cache Warmer' mod='pagecache'}</h3>
<p>{l s="JPresta Cache Warmer is a service that creates bots to browse your site in order to generate the cache, so when human visitors display your shop they get the cached pages, which are faster." mod='pagecache'}</p>
<p>{l s="To use the JPresta Cache Warmer service, you must sign in or create your account on jpresta.com, copy your JPresta Account Key and attach it to this Prestashop instance." mod='pagecache'}</p>
<a href="#tablicense" class="btn btn-primary" onclick="displayTab('license');"><i class="icon-sign-in"></i>&nbsp;{l s='Attach my JPresta Account Key' mod='pagecache'}</a>
</div>

View File

@@ -0,0 +1,13 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
{if !$maybe_a_clone}
<iframe loading="lazy" src="{$jpresta_api_url_cw|escape:'html':'UTF-8'}?page=report&nogutter{if $is_multistores}&multistores{/if}&ps_token={$jpresta_ps_token|escape:'url':'UTF-8'}&jpresta_account_key={$jpresta_account_key|escape:'url':'UTF-8'}&shop_url={$pagecache_cron_base|escape:'url':'UTF-8'}&shop_url_cw={$pagecache_cw_url|escape:'url':'UTF-8'}&shop_name={$shop_name|escape:'url':'UTF-8'}&ps_version={$prestashop_version|escape:'url':'UTF-8'}&module_name={$module_name|escape:'url':'UTF-8'}&module_version={$module_version|escape:'url':'UTF-8'}"
style="width: 100%; height: 1500px; border: none"></iframe>
{else}
{include file='./get-content-tab-license.tpl'}
{/if}

View File

@@ -0,0 +1,310 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<style>
.show-on-auto {
display: none;
}
.hide-on-auto {
display: block;
}
.cw_create_auto .show-on-auto {
display: block;
}
.cw_create_auto .hide-on-auto {
display: none;
}
</style>
<script type="application/javascript">
function jprestaUpdateCount() {
let pages_count = 0;
$('[name="warmup_controllers[]"]:checked').each(function () {
pages_count += $(this).data('page-count');
});
let contexts_count = $('#contexts tbody tr').length - 1;
$('#pages_count').html(pages_count);
$('#contexts_count').html(contexts_count);
$('#total_pages_count').html(pages_count * contexts_count);
$('#total_pages_count').removeClass('cachewarmer_count_warn').removeClass('cachewarmer_count_danger');
if (pages_count * contexts_count > 100000) {
if (pages_count * contexts_count > 200000) {
$('#total_pages_count').addClass('cachewarmer_count_danger');
}
else {
$('#total_pages_count').addClass('cachewarmer_count_warn');
}
}
}
function jprestaDeleteContexts(elt) {
$(elt).parents('tr').remove();
jprestaUpdateCount();
}
function jprestaAddContexts() {
let newIndex = 0;
$('#contexts tbody tr').each(function() {
if ($(this).data('context-index')) {
newIndex = Math.max(newIndex, $(this).data('context-index'));
}
});
newIndex++;
let html = $('#contexts tbody tr:first-child').clone().html();
$('<tr data-context-index="' + newIndex + '">' + html.replaceAll(' disabled="disabled"', '').replaceAll('XXX', newIndex) + '</tr>').appendTo('#contexts tbody');
jprestaUpdateCount();
}
$(function() {
jprestaUpdateCount();
$('[name=pagecache_cw_create_auto]').on('change', function() {
if ($('#pagecache_cw_create_auto_on').is(':checked')) {
$('#panelCw').addClass('cw_create_auto');
}
else {
$('#panelCw').removeClass('cw_create_auto');
}
});
});
</script>
<div id="panelCw" class="panel{if $pagecache_cw_contexts->contexts_auto|default:false} cw_create_auto{/if}" style="margin-bottom: 10px">
<h3><a href="{$pagecache_cw_url|escape:'html':'UTF-8'}" target="_blank">{if $avec_bootstrap}<i class="icon-gear"></i>{else}<img width="16" height="16" src="../img/admin/AdminPreferences.gif" alt=""/>{/if}</a>
&nbsp;{l s='Cache Warmer settings' mod='pagecache'}
</h3>
{if count($pagecache_cw_contexts->specifics) > 0}
<form id="pagecache_form_cachewarmer" action="{$request_uri|escape:'html':'UTF-8'}#tabcachewarmer-settings" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="cachewarmer-settings"/>
<input type="hidden" name="cachewarmer_id_shop" value="{$pagecache_cw_contexts->id_shop|intval}"/>
<fieldset>
<div class="bootstrap">
<div class="row">
<div class="col-md-12">
<div class="bootstrap">
<div class="alert alert-info" style="display: block;">&nbsp;<b>{l s='These settings will be used by the cache warmer service if you subscribed to it. See below for more informations.' mod='pagecache'}</b>
</div>
</div>
<p>{l s='The cache warmer browses your site in different contexts so all visitors will get a page on which the cache is available.' mod='pagecache'}</p>
<p>{l s='The more you have contexts, the more the warm-up will be long and the cache will consumme resources (database and hard disk).' mod='pagecache'}</p>
<p>{l s='The purpose of these settings is to select which contexts you want to warm-up.' mod='pagecache'}</p>
</div>
</div>
<div class="row" style="margin-top: 1rem">
<div class="col-md-12">
<h4>{l s='Pages to warmup' mod='pagecache'}</h4>
{foreach $managed_controllers as $controller_name => $controller}
{if $controller['warmer']}
<span style="margin-right: 1rem;white-space: nowrap;">
<input type="checkbox"
onchange="jprestaUpdateCount()"
style="vertical-align: middle; margin: 0 2px;"
id="warmup_page_{$controller_name|escape:'html':'UTF-8'}"
name="warmup_controllers[]"
{if isset($pagecache_cw_contexts->controllers[$controller_name]) && $pagecache_cw_contexts->controllers[$controller_name]['checked']}checked="checked" {/if}
{if isset($pagecache_cw_contexts->controllers[$controller_name]) && $pagecache_cw_contexts->controllers[$controller_name]['disabled']}disabled="disabled" {/if}
value="{$controller_name|escape:'html':'UTF-8'}"
data-page-count="{if isset($pagecache_cw_contexts->controllers[$controller_name])}{$pagecache_cw_contexts->controllers[$controller_name]['count']|intval}{else}0{/if}"
>
<label for="warmup_page_{$controller_name|escape:'html':'UTF-8'}" {if isset($pagecache_cw_contexts->controllers[$controller_name]) && $pagecache_cw_contexts->controllers[$controller_name]['count'] != null}title="About {$pagecache_cw_contexts->controllers[$controller_name]['count']|intval} page(s)"{/if}>{$controller['title']|escape:'html':'UTF-8'}</label>
</span>
{/if}
{/foreach}
<div style="margin-top: 1rem;font-weight: bold; font-size: 0.9rem; text-transform: uppercase;">{l s='Options' mod='pagecache'}:</div>
<div class="row" style="margin-top: 0.4rem;">
<div class="col-md-3">
<label
for="pagecache_cw_filter_products_cats_ids">{l s='Only warmup products of these categories' mod='pagecache'}</label>
</div>
<div class="col-md-9">
<input type="text"
name="pagecache_cw_filter_products_cats_ids"
id="pagecache_cw_filter_products_cats_ids"
value="{$pagecache_cw_contexts->filter_products_cats_ids|default:''|escape:'html':'UTF-8'}"
>
<div>{l s='Comma separated list of categories\' IDs. Leave empty to warmup all products.' mod='pagecache'}</div>
</div>
</div>
</div>
</div>
<div class="row" style="margin-top: 1rem">
<div class="col-md-12">
<h4>{l s='Contexts to warmup' mod='pagecache'}</h4>
<div class="alert alert-info">
<p>
{l s='We recommend you to let the module generates contexts to warmup. They are generated depending on the statistics of your shop to generate the cache of the most viewed pages in priority. Creating contexts manually can be less efficient but you can do it if you need.' mod='pagecache'}
</p>
</div>
<div class="row" style="margin-bottom: 1rem">
<div class="col-md-12">
<div class="form-group">
<label class="control-label col-lg-3" for="">{l s='How to create contexts to warmup?' mod='pagecache'}</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-xxl">
<input type="radio" name="pagecache_cw_create_auto" id="pagecache_cw_create_auto_on" value="1" {if $pagecache_cw_contexts->contexts_auto|default:0}checked{/if}>
<label for="pagecache_cw_create_auto_on" class="radioCheck">{l s='Automatically' mod='pagecache'}</label>
<input type="radio" name="pagecache_cw_create_auto" id="pagecache_cw_create_auto_off" value="0" {if !$pagecache_cw_contexts->contexts_auto|default:0}checked{/if}>
<label for="pagecache_cw_create_auto_off" class="radioCheck">{l s='Manually' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
<p class="help-block">
{l s='We highly recommend to create contexts automatically' mod='pagecache'}
</p>
</div>
</div>
</div>
</div>
<div class="hide-on-auto">
<div class="alert alert-info">
<p>
{l s='Please, create all contexts that you want to warmup' mod='pagecache'}
</p>
<hr>
<p><strong>{if $avec_bootstrap}<i class="icon-flag"></i>{else}<img width="16" height="16" src="../img/admin/world.gif" alt=""/>{/if}&nbsp;{l s='Languages' mod='pagecache'}</strong>&nbsp;:&nbsp;
{l s='Available languages are the ones enabled for this shop' mod='pagecache'}
</p>
<p><strong>{if $avec_bootstrap}<i class="icon-money"></i>{else}<img width="16" height="16" src="../img/admin/money.gif" alt=""/>{/if}&nbsp;{l s='Currencies' mod='pagecache'}</strong>&nbsp;:&nbsp;
{l s='Available currencies are the ones enabled for this shop' mod='pagecache'}
</p>
<p><strong>{if $avec_bootstrap}<i class="icon-desktop"></i>{else}<img width="16" height="16" src="../img/admin/metatags.gif" alt=""/>{/if}&nbsp;{l s='Devices' mod='pagecache'}</strong>&nbsp;:&nbsp;
{l s="You can only select 'mobile' if you enabled the option 'Create separate cache for desktop and mobile' in advanced mode, in menu Cache Key > Devices" mod='pagecache'}
</p>
<p><strong>{if $avec_bootstrap}<i class="icon-map-marker"></i>{else}<img width="16" height="16" src="../img/admin/world.gif" alt=""/>{/if}&nbsp;{l s='Countries' mod='pagecache'}</strong>&nbsp;:&nbsp;
{l s='Available countries are the ones you selected in advanced mode, in menu Cache Key > Countries' mod='pagecache'}
</p>
<p><strong>{if $avec_bootstrap}<i class="icon-users"></i>{else}<img width="16" height="16" src="../img/admin/group.gif" alt=""/>{/if}&nbsp;{l s='User groups combinations' mod='pagecache'}</strong>&nbsp;:&nbsp;
{l s="Available user groups are the ones currently used by the cache. To add a user group or a user group combination you just need to connect to the shop with a corresponding customer account when the cache is enabled. If you still don't find it, that means this user group or user group combination does not need a specific cache. More informations in advanced mode, in menu Cache Key > User groups" mod='pagecache'}
</p>
<p><strong>{if $avec_bootstrap}<i class="icon-cogs"></i>{else}<img width="16" height="16" src="../img/admin/cogs.gif" alt=""/>{/if}&nbsp;{l s='Specifics' mod='pagecache'}</strong>&nbsp;:&nbsp;
{l s='Specifics are mostly used for RGPD law; it creates different cache for visitor accepting cookies or not. The list is based on current cache statistics.' mod='pagecache'}
</p>
</div>
<table id="contexts" class="table table-striped table-hover">
<thead>
<tr>
<th><a onclick="jprestaAddContexts(); return false;" class="btn btn-xs btn-primary" href="#"><i class="icon-plus"></i></a></th>
<th>{if $avec_bootstrap}<i class="icon-flag"></i>{else}<img width="16" height="16" src="../img/admin/world.gif" alt=""/>{/if}&nbsp;{l s='Languages' mod='pagecache'}</th>
<th>{if $avec_bootstrap}<i class="icon-money"></i>{else}<img width="16" height="16" src="../img/admin/money.gif" alt=""/>{/if}&nbsp;{l s='Currencies' mod='pagecache'}</th>
<th>{if $avec_bootstrap}<i class="icon-desktop"></i>{else}<img width="16" height="16" src="../img/admin/metatags.gif" alt=""/>{/if}&nbsp;{l s='Devices' mod='pagecache'}</th>
<th>{if $avec_bootstrap}<i class="icon-flag"></i>{else}<img width="16" height="16" src="../img/admin/world.gif" alt=""/>{/if}&nbsp;{l s='Countries' mod='pagecache'}</th>
<th>{if $avec_bootstrap}<i class="icon-users"></i>{else}<img width="16" height="16" src="../img/admin/group.gif" alt=""/>{/if}&nbsp;{l s='User groups' mod='pagecache'}</th>
<th>{if $avec_bootstrap}<i class="icon-cogs"></i>{else}<img width="16" height="16" src="../img/admin/cogs.gif" alt=""/>{/if}&nbsp;{l s='Specifics' mod='pagecache'}</th>
</tr>
</thead>
<tbody>
<tr style="display:none">
<td><a onclick="jprestaDeleteContexts(this); return false;" class="btn btn-xs btn-primary deletecontext" href="#"><i class="icon-trash"></i></a></td>
<td>
<select name="contexts[XXX][language]" disabled="disabled">
{foreach $pagecache_cw_contexts->languages as $context}
<option value="{$context['value']|escape:'html':'UTF-8'}">{$context['label']|escape:'html':'UTF-8'}{if isset($context['count'])} ({$context['count']|intval}){/if}</option>
{/foreach}
</select>
</td>
<td>
<select name="contexts[XXX][currency]" disabled="disabled">
{foreach $pagecache_cw_contexts->currencies as $context}
<option value="{$context['value']|escape:'html':'UTF-8'}">{$context['label']|escape:'html':'UTF-8'}{if isset($context['count'])} ({$context['count']|intval}){/if}</option>
{/foreach}
</select>
</td>
<td>
<select name="contexts[XXX][device]" disabled="disabled">
{foreach $pagecache_cw_contexts->devices as $context}
<option value="{$context['value']|escape:'html':'UTF-8'}">{$context['label']|escape:'html':'UTF-8'}{if isset($context['count'])} ({$context['count']|intval}){/if}</option>
{/foreach}
</select>
</td>
<td>
<select name="contexts[XXX][country]" disabled="disabled">
{foreach $pagecache_cw_contexts->countries as $context}
<option value="{$context['value']|escape:'html':'UTF-8'}">{$context['label']|escape:'html':'UTF-8'}{if isset($context['count'])} ({$context['count']|intval}){/if}</option>
{/foreach}
</select>
</td>
<td>
<select name="contexts[XXX][group]" disabled="disabled">
{foreach $pagecache_cw_contexts->groups as $context}
<option value="{$context['value']|escape:'html':'UTF-8'}">{$context['label']|escape:'html':'UTF-8'}{if isset($context['count'])} ({$context['count']|intval}){/if}</option>
{/foreach}
</select>
</td>
<td>
<select name="contexts[XXX][specifics]" disabled="disabled">
{foreach $pagecache_cw_contexts->specifics as $context}
<option value="{$context['value']|escape:'html':'UTF-8'}">{$context['label']|escape:'html':'UTF-8'}{if isset($context['count'])} ({$context['count']|intval}){/if}</option>
{/foreach}
</select>
</td>
</tr>
{foreach $pagecache_cw_contexts->contexts as $index => $context}
<tr data-context-index="{$index|intval}">
<input type="hidden" name="contexts[{$index|intval}][language]" value="{$context['language']|default:''|escape:'html':'UTF-8'}">
<input type="hidden" name="contexts[{$index|intval}][currency]" value="{$context['currency']|default:''|escape:'html':'UTF-8'}">
<input type="hidden" name="contexts[{$index|intval}][device]" value="{$context['device']|default:''|escape:'html':'UTF-8'}">
<input type="hidden" name="contexts[{$index|intval}][country]" value="{$context['country']|default:''|escape:'html':'UTF-8'}">
<input type="hidden" name="contexts[{$index|intval}][group]" value="{$context['group']|default:''|escape:'html':'UTF-8'}">
<input type="hidden" name="contexts[{$index|intval}][specifics]" value="{$context['specifics']|default:''|escape:'html':'UTF-8'}">
<td><a onclick="jprestaDeleteContexts(this); return false;" class="btn btn-xs btn-primary" href="#"><i class="icon-trash"></i></a></td>
<td>{$pagecache_cw_contexts->languages[$context['language']]['label']|default:''|escape:'html':'UTF-8'}</td>
<td>{$pagecache_cw_contexts->currencies[$context['currency']]['label']|default:''|escape:'html':'UTF-8'}</td>
<td>{$pagecache_cw_contexts->devices[$context['device']]['label']|default:''|escape:'html':'UTF-8'}</td>
<td>{$pagecache_cw_contexts->countries[$context['country']]['label']|default:''|escape:'html':'UTF-8'}</td>
<td>{$pagecache_cw_contexts->groups[$context['group']]['label']|default:''|escape:'html':'UTF-8'}</td>
<td>{$pagecache_cw_contexts->specifics[$context['specifics']]['label']|default:''|escape:'html':'UTF-8'}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
</div>
<div class="row" style="margin-top: 1rem">
<div class="col-md-12">
<h4>{l s='Total pages to warmup' mod='pagecache'}</h4>
<div class="show-on-auto">
<div class="bootstrap">
<div class="alert alert-info" style="display: block;">&nbsp;{l s='When contexts are automatically created the number of pages to warm up will be adapted to your subscription plan' mod='pagecache'}
</div>
</div>
</div>
<div class="hide-on-auto">
<div class="bootstrap">
<div class="alert alert-info" style="display: block;">&nbsp;{l s='Try to have less than 100000 pages to warmup or it will be too long to be processed by the cache-warmer in a single day' mod='pagecache'}
</div>
</div>
<table class="table" style="width: initial">
<tbody>
<tr>
<td>{l s='Estimated number of pages per context' mod='pagecache'}</td>
<td id="pages_count" class="cachewarmer_count"></td>
</tr>
<tr>
<td>{l s='Number of context' mod='pagecache'}</td>
<td id="contexts_count" class="cachewarmer_count"></td>
</tr>
<tr>
<td>{l s='Total pages to warmup' mod='pagecache'}</td>
<td id="total_pages_count" class="cachewarmer_count"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<button type="submit" value="1" id="submitModuleCacheWarmerSettings" name="submitModuleCacheWarmerSettings"
class="btn btn-default pull-right">
<i class="process-icon-save"></i> {l s='Save' mod='pagecache'}
</button>
</div>
</fieldset>
</form>
{else}
<div class="alert alert-warning">
{l s='Before setting the pages that you want to warmup, you, or your visitors, need to browse your shop a little bit. Why? So the module know the different contexts that can be used on your shop. So, you just have to browse different pages of your store and reload this page.' mod='pagecache'}
</div>
{/if}
</div>

View File

@@ -0,0 +1,13 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
{if !$maybe_a_clone}
<iframe loading="lazy" src="{$jpresta_api_url_cw|escape:'html':'UTF-8'}?page=status&nogutter{if $is_multistores}&multistores{/if}&ps_token={$jpresta_ps_token|escape:'url':'UTF-8'}&jpresta_account_key={$jpresta_account_key|escape:'url':'UTF-8'}&shop_url={$pagecache_cron_base|escape:'url':'UTF-8'}&shop_url_cw={$pagecache_cw_url|escape:'url':'UTF-8'}&shop_name={$shop_name|escape:'url':'UTF-8'}&ps_version={$prestashop_version|escape:'url':'UTF-8'}&module_name={$module_name|escape:'url':'UTF-8'}&module_version={$module_version|escape:'url':'UTF-8'}"
style="width: 100%; height: 1500px; border: none"></iframe>
{else}
{include file='./get-content-tab-license.tpl'}
{/if}

View File

@@ -0,0 +1,17 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
{if !isset($jpresta_account_key) || !$jpresta_account_key}
{include file='./get-content-tab-jpresta-account-key.tpl'}
{/if}
{if !$maybe_a_clone}
<iframe id="jprestaCacheWamer"
src="{$jpresta_api_url_cw|escape:'html':'UTF-8'}?nogutter{if $is_multistores}&multistores{/if}&ps_token={$jpresta_ps_token|escape:'url':'UTF-8'}&jpresta_account_key={$jpresta_account_key|escape:'url':'UTF-8'}&shop_url={$pagecache_cron_base|escape:'url':'UTF-8'}&shop_url_cw={$pagecache_cw_url|escape:'url':'UTF-8'}&shop_name={$shop_name|escape:'url':'UTF-8'}&ps_version={$prestashop_version|escape:'url':'UTF-8'}&module_name={$module_name|escape:'url':'UTF-8'}&module_version={$module_version|escape:'url':'UTF-8'}"
style="width: 100%; height: 1500px; border: none"></iframe>
{else}
{include file='./get-content-tab-license.tpl'}
{/if}

View File

@@ -0,0 +1,113 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
{if !$jpresta_account_key}
<script type="application/javascript">
function refreshSubmitModuleJakStatus() {
if ($('#jprestaAccountKey').val().length >= 20 && $('input[name=prestashopType]:checked').length > 0) {
$('#submitModuleJak').removeAttr('disabled');
$('#cannotValidate').hide();
}
else {
$('#submitModuleJak').attr('disabled', '1');
$('#cannotValidate').show();
}
}
$(document).ready(function() {
refreshSubmitModuleJakStatus();
$('input').on('keyup keypress blur change', refreshSubmitModuleJakStatus);
});
</script>
<style type="text/css">
button:disabled {
cursor: not-allowed;
pointer-events: all !important;
}
</style>
{/if}
<div class="row">
<div class="col-md-12">
<div class="panel">
<h3 class="panel-heading"><img height="20" src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/logo-jpresta.png" alt=""/>&nbsp;{l s='JPresta account' mod='pagecache'}</h3>
{if $pagecache_clone_detected}
<div class="alert alert-danger">
<strong>{l s='This Prestashop instance seems to be a clone of an other Prestahop.' mod='pagecache'}</strong>
<p>
{l s='Clones are allowed but can messes up your JPresta-Cache-Warmer subscription so please, just tell us if it is a clone or not.' mod='pagecache'}
</p>
<p>
{l s='This message can be displayed if you modified your database connexion or the URL of your shop. If so then just click on "No, it is the same Prestashop".' mod='pagecache'}
</p>
<form id="confirmClone" method="post" action="{$request_uri|escape:'html':'UTF-8'}" class="form-inline">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="license"/>
<div style="text-align: left; margin: 10px 0 0 0;">
<button type="submit" id="submitModuleConfirmClone" name="submitModuleConfirmClone" class="btn btn-secondary">{l s='Yes, it is a clone' mod='pagecache'}</button>
<button type="submit" id="submitModuleNotAClone" name="submitModuleNotAClone" class="btn btn-secondary">{l s='No, it is the same Prestashop' mod='pagecache'}</button>
</div>
</form>
</div>
{/if}
{if !$jpresta_account_key}
<p>{l s="To use the JPresta Cache Warmer service, you must create an account on jpresta.com and attach your JPresta Account Key to this Prestashop instance." mod='pagecache'}</p>
<form method="post" action="{$request_uri|escape:'html':'UTF-8'}" class="form-inline">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="license"/>
<div style="margin: 10px 0">
{l s='This Prestashop instance is: ' mod='pagecache'}
<label class="radio-inline" style="margin-left: 10px">
<input type="radio" name="prestashopType" id="prestashopType1" value="prod"> {l s='a live site with real customers' mod='pagecache'}
</label>
<label class="radio-inline" style="margin-left: 10px">
<input type="radio" name="prestashopType" id="prestashopType2" value="test"> {l s='for test only' mod='pagecache'}
</label>
</div>
<div class="form-group">
<input type="text" style="width:20rem" class="form-control" id="jprestaAccountKey" name="jprestaAccountKey" placeholder="{l s='Example: JPRESTA-AB12YZ89XX00' mod='pagecache'}">
</div>
<button type="submit" id="submitModuleJak" name="submitModuleJak" class="btn btn-primary"><i class="icon-sign-in"></i>&nbsp;{l s='Attach my JPresta Account Key' mod='pagecache'}</button>
<div class="alert alert-warning" style="margin-top: 10px" id="cannotValidate">
{l s='In order to validate, select the type of Prestashop instance and fill in the JPresta Account Key' mod='pagecache'}
</div>
</form>
{else}
<p>
<input type="text" style="width:20rem;display: inline-block" class="form-control" name="jprestaAccountKey" readonly disabled value="{$jpresta_account_key|escape:'url':'UTF-8'}">
<i class="icon-check" style="font-size: 1.5rem; margin: 0 6px; color: green;"></i>
<a href="#" onclick="$('#confirmDetach').toggle()">{l s='detach' mod='pagecache'}</a>
</p>
<p>{l s="Congratulation, the module is attached to your JPresta Account." mod='pagecache'}</p>
<form id="confirmDetach" style="display: none" method="post" action="{$request_uri|escape:'html':'UTF-8'}" class="form-inline">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="license"/>
{l s="If you detach your JPresta Account your Cache Warmer subscription (if any) will be suspended" mod='pagecache'}
<div style="text-align: center; margin: 10px 0 0 0;">
<button type="submit" id="submitModuleJakDetach" name="submitModuleJakDetach" class="btn btn-danger"><i class="icon-sign-out"></i>&nbsp;{l s='I confirm, detach my JPresta Account' mod='pagecache'}</button>
</div>
</form>
{/if}
{if $advanced_mode}
<div style="border-top: 1px dotted #dbe6e9; margin-top: 1rem; padding-top: 0.5rem;">
<strong>{l s='Advanced mode' mod='pagecache'}:</strong>
{l s='In case of troubles with license key, if you cloned your shop for exemple, you can recompute the ID of this Prestashop instance by clicking on the following button:' mod='pagecache'}
<form method="post" action="{$request_uri|escape:'html':'UTF-8'}" class="form-inline">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="license"/>
<button type="submit" id="submitModuleJakReset" name="submitModuleJakReset" class="btn btn-sm btn-danger">{l s='Recompute the ID of this Prestashop instance' mod='pagecache'}</button>
</form>
</div>
{/if}
</div>
</div>
</div>
{if $jpresta_ps_token && $jpresta_account_key && !$maybe_a_clone}
<iframe loading="lazy" src="{$jpresta_api_url_licenses|escape:'html':'UTF-8'}?nogutter&ps_token={$jpresta_ps_token|escape:'url':'UTF-8'}&jpresta_account_key={$jpresta_account_key|escape:'url':'UTF-8'}&shop_url={$pagecache_cron_base|escape:'url':'UTF-8'}&shop_url_cw={$pagecache_cw_url|escape:'url':'UTF-8'}&shop_name={$shop_name|escape:'url':'UTF-8'}&ps_version={$prestashop_version|escape:'url':'UTF-8'}&module_name={$module_name|escape:'url':'UTF-8'}&module_version={$module_version|escape:'url':'UTF-8'}"
style="width: 100%; height: 1500px; border: none"></iframe>
{/if}

View File

@@ -0,0 +1,392 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-gear"></i>{else}<img width="16" height="16" src="../img/admin/AdminPreferences.gif" alt=""/>{/if}&nbsp;{l s='Options' mod='pagecache'}</h3>
<form id="pagecache_form_options" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="options"/>
<fieldset>
<div style="clear: both;">
<div class="form-group">
<div id="pagecache_skiplogged">
<label class="control-label col-lg-3">
{l s='Cache for logged in users' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_skiplogged" id="pagecache_skiplogged_on" value="0" {if !$pagecache_skiplogged}checked{/if}>
<label for="pagecache_skiplogged_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_skiplogged" id="pagecache_skiplogged_off" value="1" {if $pagecache_skiplogged}checked{/if}>
<label for="pagecache_skiplogged_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Enable cache for visitors that are logged in (recommended)' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_cache_customizable">
<label class="control-label col-lg-3">
{l s='Cache customizable products' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_cache_customizable" id="pagecache_cache_customizable_on" value="1" {if $pagecache_cache_customizable}checked{/if}>
<label for="pagecache_cache_customizable_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_cache_customizable" id="pagecache_cache_customizable_off" value="0" {if !$pagecache_cache_customizable}checked{/if}>
<label for="pagecache_cache_customizable_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Here you can force the customizable products to be cached but make sure that customizations of visitors are not stored into the cache.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_normalize_urls">
<label class="control-label col-lg-3">
{l s='Normalize URLs' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_normalize_urls" id="pagecache_normalize_urls_on" value="1" {if $pagecache_normalize_urls}checked{/if}>
<label for="pagecache_normalize_urls_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_normalize_urls" id="pagecache_normalize_urls_off" value="0" {if !$pagecache_normalize_urls}checked{/if}>
<label for="pagecache_normalize_urls_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Avoid same page linked with different URLs to use different cache. Should only be disabled when you have a lot of links in a page (> 500).' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_logout_nocache">
<label class="control-label col-lg-3">
{l s='Force no cache at logout' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_logout_nocache" id="pagecache_logout_nocache_on" value="1" {if $pagecache_logout_nocache}checked{/if}>
<label for="pagecache_logout_nocache_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_logout_nocache" id="pagecache_logout_nocache_off" value="0" {if !$pagecache_logout_nocache}checked{/if}>
<label for="pagecache_logout_nocache_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Add a "nocache" parameter in the URL after logout to avoid the browser cache to be used.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_logs_debug">
<label class="control-label col-lg-3">
{l s='Enable logs' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_logs" id="pagecache_logs_debug_2" value="2" {if $pagecache_logs > 0}checked{/if}>
<label for="pagecache_logs_debug_2" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
{*<input type="radio" name="pagecache_logs" id="pagecache_logs_debug_1" value="1" {if $pagecache_logs == 1}checked{/if}>
<label for="pagecache_logs_debug_1" class="radioCheck">{l s='Info' mod='pagecache'}</label>*}
<input type="radio" name="pagecache_logs" id="pagecache_logs_debug_0" value="0" {if $pagecache_logs == 0}checked{/if}>
<label for="pagecache_logs_debug_0" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Logs informations into the Prestashop logger. You should only enable it to debug or understand how the cache works.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_logs_debug">
<label class="control-label col-lg-3">
{l s='Ignored URL parameters' mod='pagecache'}
</label>
<div class="col-lg-9">
<input type="text" name="pagecache_ignored_params" id="pagecache_ignored_params" value="{$pagecache_ignored_params|escape:'html':'UTF-8'}" size="100">
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='URL parameters are used to identify a unique page content. Some URL parameters do not affect page content like tracking parameters for analytics (utm_source, utm_campaign, etc.) so we can ignore them. You can set a comma separated list of these parameters here.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_always_infosbox">
<label class="control-label col-lg-3">
{l s='Always display infos box' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_always_infosbox" id="pagecache_always_infosbox_on" value="1" {if $pagecache_always_infosbox}checked{/if}>
<label for="pagecache_always_infosbox_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_always_infosbox" id="pagecache_always_infosbox_off" value="0" {if !$pagecache_always_infosbox}checked{/if}>
<label for="pagecache_always_infosbox_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Only used for demo' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_exec_header_hook">
<label class="control-label col-lg-3">
{l s='Executes "header" hook in dynamic modules request' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_exec_header_hook" id="pagecache_exec_header_hook_on" value="1" {if $pagecache_exec_header_hook}checked{/if}>
<label for="pagecache_exec_header_hook_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_exec_header_hook" id="pagecache_exec_header_hook_off" value="0" {if !$pagecache_exec_header_hook}checked{/if}>
<label for="pagecache_exec_header_hook_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='If checked, the header hook will be executed so javascript variables added in this hook by other modules will be refreshed' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_use_dispatcher_hook">
<label class="control-label col-lg-3">
{l s='Check cache in "dispatcher" hook' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_use_dispatcher_hook" id="pagecache_use_dispatcher_hook_on" value="1" {if $pagecache_use_dispatcher_hook}checked{/if}>
<label for="pagecache_use_dispatcher_hook_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_use_dispatcher_hook" id="pagecache_use_dispatcher_hook_off" value="0" {if !$pagecache_use_dispatcher_hook}checked{/if}>
<label for="pagecache_use_dispatcher_hook_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='If checked, the cache will be checked in dispatcher hook (not dispatcherBefore) which is slower but compatible with some modules like securitypro' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_product_refreshEveryX">
<label class="control-label col-lg-3">
{l s='Refresh product page every X sales' mod='pagecache'}
</label>
<div class="col-lg-9">
{l s='Every' mod='pagecache'}
<select style="display: inline-block; width: fit-content;" name="pagecache_product_refreshEveryX" class="form-control">
<option value="1" {if $pagecache_product_refreshEveryX == 1} selected{/if}>1</option>
<option value="5" {if $pagecache_product_refreshEveryX == 5} selected{/if}>5</option>
<option value="10" {if $pagecache_product_refreshEveryX == 10} selected{/if}>10</option>
<option value="50" {if $pagecache_product_refreshEveryX == 50} selected{/if}>50</option>
<option value="100" {if $pagecache_product_refreshEveryX == 100} selected{/if}>100</option>
</select>
{l s='sales' mod='pagecache'}
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='When stock is not displayed on product page then you can set how often the cache of the product page should be refreshed when the quantity is greater than the quantity that displays a "last items..."' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_instockisadd">
<label class="control-label col-lg-3">
{l s='Back in stock refreshes like new product' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_instockisadd" id="pagecache_instockisadd_on" value="1" {if $pagecache_instockisadd}checked{/if}>
<label for="pagecache_instockisadd_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_instockisadd" id="pagecache_instockisadd_off" value="0" {if !$pagecache_instockisadd}checked{/if}>
<label for="pagecache_instockisadd_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='When a product is back in stock the cache will be refreshed like if the product was a new one' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_max_exec_time">
<label class="control-label col-lg-3">
{l s='Max execution time in seconds' mod='pagecache'}
</label>
<div class="col-lg-9">
<input type="number" name="pagecache_max_exec_time" id="pagecache_max_exec_time" value="{$pagecache_max_exec_time|escape:'html':'UTF-8'}" max="480" min="1">
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Used by the cache warmer to split the list of URLs to browse if it takes much time to generate. Must be between 1s and 480s, we recommend 30s.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_maxrows">
<label class="control-label col-lg-3">
{l s='Max pages in cache' mod='pagecache'}
</label>
<div class="col-lg-9">
<input type="number" name="pagecache_maxrows" id="pagecache_maxrows" value="{$pagecache_maxrows|escape:'html':'UTF-8'}" min="0">
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Let this value to 0 until you have a really good reason to limit the number of rows into the cache' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_ignore_before_pattern">
<label class="control-label col-lg-3">
{l s='Ignore backlinks before this string' mod='pagecache'}
</label>
<div class="col-lg-9">
<input type="text" name="pagecache_ignore_before_pattern" id="pagecache_ignore_before_pattern" value="{$pagecache_ignore_before_pattern|escape:'html':'UTF-8'}">
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Usefull to ignore links of a mega menu (for exemple) that are not necessary for automatic refreshment. This will decrease the size of the backlinks table (jm_pagecache_bl). Exemple: </header>.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_ignore_after_pattern">
<label class="control-label col-lg-3">
{l s='Ignore backlinks after this string' mod='pagecache'}
</label>
<div class="col-lg-9">
<input type="text" name="pagecache_ignore_after_pattern" id="pagecache_ignore_after_pattern" value="{$pagecache_ignore_after_pattern|escape:'html':'UTF-8'}">
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Usefull to ignore links of a side mobile menu (for exemple) that are not necessary for automatic refreshment. This will decrease the size of the backlinks table (jm_pagecache_bl). Exemple: </footer>.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_ignore_url_regex">
<label class="control-label col-lg-3">
{l s='Ignore URLs matching this regex' mod='pagecache'}
</label>
<div class="col-lg-9">
<input type="text" name="pagecache_ignore_url_regex" id="pagecache_ignore_url_regex" value="{$pagecache_ignore_url_regex|escape:'html':'UTF-8'}">
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='You can avoid some pages to be cached. Setup a regular expression that will match URLs that must not be cached. Read https://www.php.net/manual/en/reference.pcre.pattern.syntax.php for more informations. Use https://regex101.com/ to test your regular expression.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_currencies_to_cache">
<label class="control-label col-lg-3">
{l s='Currencies to cache' mod='pagecache'}
</label>
<div class="col-lg-9">
{if count($pagecache_currencies_to_cache) === 0}
<i>{l s='No currency are enabled on the shop' mod='pagecache'}</i>
{/if}
{foreach $pagecache_currencies_to_cache as $cur_iso_code => $cur_state}
<span style="margin-right: 1rem;white-space: nowrap;">
<input type="checkbox"
style="vertical-align: middle; margin: 0 2px;"
id="pagecache_currencies_to_cache_{$cur_iso_code|escape:'html':'UTF-8'}"
name="pagecache_currencies_to_cache[]"
{if $cur_state}checked="checked" {/if}
value="{$cur_iso_code|escape:'html':'UTF-8'}">
<label for="pagecache_currencies_to_cache_{$cur_iso_code|escape:'html':'UTF-8'}">{$cur_iso_code|escape:'html':'UTF-8'}</label>
</span>
{/foreach}
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Here you can avoid some currencies to be cached, usefull when the rate changes everyday.' mod='pagecache'}
</div>
</div>
</div>
</div>
<div class="form-group">
<div id="pagecache_statsttfb">
<label class="control-label col-lg-3">
{l s='Enable statistics on TTFB' mod='pagecache'}
</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="pagecache_statsttfb" id="pagecache_statsttfb_on" value="1" {if $pagecache_statsttfb}checked{/if}>
<label for="pagecache_statsttfb_on" class="radioCheck">{l s='Yes' mod='pagecache'}</label>
<input type="radio" name="pagecache_statsttfb" id="pagecache_statsttfb_off" value="0" {if !$pagecache_statsttfb}checked{/if}>
<label for="pagecache_statsttfb_off" class="radioCheck">{l s='No' mod='pagecache'}</label>
<a class="slide-button btn"></a>
</span>
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="help-block">
{l s='Store statistics on TTFB, recommended if you subscribed to the cache-warmer but you should disable it if you have a large amount of visitors every day' mod='pagecache'}
</div>
</div>
</div>
</div>
</div>
<div class="bootstrap">
<button type="submit" value="1" id="submitModuleOptions" name="submitModuleOptions" class="btn btn-default pull-right">
<i class="process-icon-save"></i> {l s='Save' mod='pagecache'}
</button>
</div>
</fieldset>
</form>
</div>

View File

@@ -0,0 +1,68 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-sitemap"></i>{else}<img width="16" height="16" src="../img/admin/multishop_config.png" alt=""/>{/if}&nbsp;{l s='Multistore' mod='pagecache'}</h3>
<form id="pagecache_form_shopsinfos" action="{$request_uri|escape:'html':'UTF-8'}" method="post" onsubmit='return confirm("{l s='WARNING! This will replace the configuration of selected shops, are you sure?' mod='pagecache'}");'>
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="shopsinfos"/>
<fieldset>
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-info" style="display: block;">&nbsp;{l s='It is usually a pain to configure all shops so here you can copy the configuration of the current shop to other shops.' mod='pagecache'}</div></div>
{else}
<div class="hint clear" style="display: block;">&nbsp;{l s='It is usually a pain to configure all shops so here you can copy the configuration of the current shop to other shops.' mod='pagecache'}</div>
{/if}
<table id="shopsinfosTable" class="table table-bordered table-striped">
<colgroup>
<col width="0*">
<col width="0*">
<col width="*">
<col width="0*">
<col width="0*">
<col width="0*">
</colgroup>
<thead>
<tr>
<th></th>
<th style="text-align: center">{l s='ID' d='Admin.Global'}</th>
<th>{l s='Name' d='Admin.Global'}</th>
<th style="text-align: center">{l s='Theme' mod='pagecache'}</th>
<th style="text-align: center">{l s='Status' d='Admin.Global'}</th>
<th style="text-align: center">{l s='Settings' d='Admin.Global'}</th>
</tr>
</thead>
<tbody>
{foreach $pagecache_shopsinfos as $shopinfos}
<tr>
<td style="text-align: center">{if !$shopinfos['is_current']}<input type="checkbox" name="id_shops[]" value="{$shopinfos['id_shop']|intval}">{else}({l s='Current shop' mod='pagecache'}){/if}</td>
<td style="text-align: center">{$shopinfos['id_shop']|intval}</td>
<td>{$shopinfos['name']|escape:'html':'UTF-8'}</td>
<td style="text-align: center">{$shopinfos['theme_name']|escape:'html':'UTF-8'}</td>
<td style="text-align: center">
{if $shopinfos['module_enabled']}
<i class="material-icons" style="color: green">check</i>
{else}
<i class="material-icons" style="color: red">clear</i>
{/if}
</td>
<td style="text-align: center">
{if $shopinfos['module_install_step'] == 9}
<i class="material-icons" style="color: green">check</i>
{else}
{$shopinfos['module_install_step']|intval} / 9
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
<button type="submit" id="submitModuleShopsinfos" name="submitModuleShopsinfos" class="btn btn-primary pull-right">
<i class="process-icon-duplicate"></i> {l s='Copy configuration to selected shops' mod='pagecache'}
</button>
</fieldset>
</form>
</div>

View File

@@ -0,0 +1,155 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<script type="text/javascript">
var slidersServer = [];
var slidersBrowser = [];
function onSliderChange(value, controller) {
switch (value) {
case 0:
text = "{l s='Disabled' mod='pagecache'}";
break;
case 1:
text = "{l s='1 day' mod='pagecache'}";
break;
case 10:
text = "{l s='To infinity...' mod='pagecache'}";
break;
case 8:
value = 14;
text = value + " {l s='days' mod='pagecache'}";
break;
case 9:
value = 30;
text = value + " {l s='days' mod='pagecache'}";
break;
default:
text = value + " {l s='days' mod='pagecache'}";
break;
}
$("#pc"+controller+"SliderVal").text(text);
if (value === 0) {
// ULTIMATE
if (slidersBrowser[controller]) { slidersBrowser[controller].setValue(0); onBrowserSliderChange(0, controller+"2"); slidersBrowser[controller].disable(); }
// ULTIMATE£
$("#pc"+controller).parent().find(".slider-handle").css("background-color", "gray").css("background-image", "none");
}
else {
// ULTIMATE
if (slidersBrowser[controller]) slidersBrowser[controller].enable();
// ULTIMATE£
$("#pc"+controller).parent().find(".slider-handle").css("background-image", "linear-gradient(to bottom,#149bdf 0,#0480be 100%);");
}
}
function onBrowserSliderChange(value, controller) {
switch (value) {
case 0:
text = "{l s='Disabled' mod='pagecache'}";
break;
default:
text = value + " {l s='minutes' mod='pagecache'}";
break;
}
$("#pc"+controller+"SliderVal").text(text);
if (value === 0) {
$("#pc"+controller).parent().find(".slider-handle").css("background-color", "gray").css("background-image", "none");
}
else {
$("#pc"+controller).parent().find(".slider-handle").css("background-image", "linear-gradient(to bottom,#149bdf 0,#0480be 100%);");
}
}
$( document ).ready(function() {
{*ULTIMATE*}
slidersBrowser["static"] = new Slider('#pcstatic2');
slidersBrowser["static"].setValue({$pagecache_static_expires|intval|default:'0'});
onBrowserSliderChange({$pagecache_static_expires|intval|default:'0'}, "static2");
$("#pcstatic2").on("change", function(slideEvt) { onBrowserSliderChange(slideEvt.value.newValue, "static2"); });
{*ULTIMATE£*}
{foreach $managed_controllers as $controller_name => $controller}
slidersServer["{$controller_name|escape:'javascript':'UTF-8'}"] = new Slider('#pc{$controller_name|escape:'javascript':'UTF-8'}');
slidersServer["{$controller_name|escape:'javascript':'UTF-8'}"].setValue({$controller['timeout']|default:'0'});
{*ULTIMATE*}
slidersBrowser["{$controller_name|escape:'javascript':'UTF-8'}"] = new Slider('#pc{$controller_name|escape:'javascript':'UTF-8'}2');
slidersBrowser["{$controller_name|escape:'javascript':'UTF-8'}"].setValue({$controller['expires']|default:'0'});
{*ULTIMATE£*}
onSliderChange({$controller['timeout']|escape:'html':'UTF-8'|default:'0'}, "{$controller_name|escape:'javascript':'UTF-8'}");
{*ULTIMATE*}
onBrowserSliderChange({$controller['expires']|escape:'html':'UTF-8'|default:'0'}, "{$controller_name|escape:'javascript':'UTF-8'}2");
{*ULTIMATE£*}
$("#pc{$controller_name|escape:'javascript':'UTF-8'}").on("change", function(slideEvt) { onSliderChange(slideEvt.value.newValue, "{$controller_name|escape:'javascript':'UTF-8'}"); });
{*ULTIMATE*}
$("#pc{$controller_name|escape:'javascript':'UTF-8'}2").on("change", function(slideEvt) { onBrowserSliderChange(slideEvt.value.newValue, "{$controller_name|escape:'javascript':'UTF-8'}2"); });
{*ULTIMATE£*}
{/foreach}
});
</script>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-time"></i>{else}<img width="16" height="16" src="../img/admin/time.gif" alt=""/>{/if}&nbsp;{l s='Pages & timeouts' mod='pagecache'}</h3>
<form id="pagecache_form_timeouts" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="timeouts"/>
<fieldset>
<div style="clear: both;">
{if $avec_bootstrap}
<div class="bootstrap"><div class="alert alert-info" style="display: block;">
<dl>
<dt>{l s='Server cache maximum duration' mod='pagecache'}</dt>
<dd>{l s='Server cache is automatically refreshed when you modify prices, descriptions, stocks, etc. (not when you do modifications in theme, modules, CSS, etc.) so here you set the maximum age of the cache if there is no modification.' mod='pagecache'}</dd>
<dt>{l s='Browser cache duration' mod='pagecache'}</dt>
<dd>{l s='Browser cache cannot be refreshed (except if the visitor refreshes the page in the browser) so here you set the maximum age of the cache whatever modifications are done in back office. This is why it is limited to 60 minutes.' mod='pagecache'}</dd>
</dl>
</div></div>
{else}
<div class="hint clear" style="display: block;">
<dl>
<dt>{l s='Server cache maximum duration' mod='pagecache'}</dt>
<dd>{l s='Server cache is automatically refreshed when you modify prices, descriptions, stocks, etc. (not when you do modifications in theme, modules, CSS, etc.) so here you set the maximum age of the cache if there is no modification.' mod='pagecache'}</dd>
<dt>{l s='Browser cache duration' mod='pagecache'}</dt>
<dd>{l s='Browser cache cannot be refreshed (except if the visitor refreshes the page in the browser) so here you set the maximum age of the cache whatever modifications are done in back office. This is why it is limited to 60 minutes.' mod='pagecache'}</dd>
</dl>
</div>
{/if}
{*ULTIMATE*}
<h4>{l s='When using Prestashop Static cache' mod='pagecache'}</h4>
<div>
{l s='When the static cache is used it is not possible to know what kind of page is requested and so the browser cache duration must be the same for all cached pages' mod='pagecache'}:
</div>
<table>
<tr class="first">
<td>{l s='Browser cache duration for static files' mod='pagecache'}</td>
<td><input id="pcstatic2" name="pagecache_static_expires" style="padding: 0 10px;" type="text" data-slider-ticks="[0, 15, 30, 45, 60]" data-slider-value="{$pagecache_static_expires|escape:'html':'UTF-8'}" data-slider-tooltip="hide" data-slider-ticks-snap-bounds="3" data-slider-handle="square"/>&nbsp;<span id="pcstatic2SliderVal" style="font-weight:bold"></span></td>
</tr>
</table>
<h4 style="margin-top: 2rem">{l s='By Pages' mod='pagecache'}</h4>
{*ULTIMATE£*}
<table>
{foreach $managed_controllers as $controller_name => $controller}
<tr class="first">
<td class="label">{$controller['title']|escape:'html':'UTF-8'}</td>
<td>{l s='Server cache maximum duration' mod='pagecache'}:</td>
<td class="slider"><input id="pc{$controller_name|escape:'html':'UTF-8'}" name="pagecache_{$controller_name|escape:'html':'UTF-8'}_timeout" style="padding: 0 10px;" type="text" data-slider-ticks="[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" data-slider-value="{$controller['timeout']|escape:'html':'UTF-8'}" data-slider-tooltip="hide" data-slider-handle="square"/>&nbsp;<span id="pc{$controller_name|escape:'html':'UTF-8'}SliderVal" style="font-weight:bold"></span></td>
</tr>
{*ULTIMATE*}
<tr>
<td></td>
<td>{l s='Browser cache duration' mod='pagecache'}:</td>
<td class="slider"><input id="pc{$controller_name|escape:'html':'UTF-8'}2" name="pagecache_{$controller_name|escape:'html':'UTF-8'}_expires" style="padding: 0 10px;" type="text" data-slider-ticks="[0, 15, 30, 45, 60]" data-slider-value="{$controller['expires']|escape:'html':'UTF-8'}" data-slider-tooltip="hide" data-slider-ticks-snap-bounds="3" data-slider-handle="square"/>&nbsp;<span id="pc{$controller_name|escape:'html':'UTF-8'}2SliderVal" style="font-weight:bold"></span></td>
</tr>
{*ULTIMATE£*}
{/foreach}
</table>
</div>
<div class="bootstrap">
<button type="submit" value="1" id="submitModuleTimeouts" name="submitModuleTimeouts" class="btn btn-default pull-right">
<i class="process-icon-save"></i> {l s='Save' mod='pagecache'}
</button>
</div>
</fieldset>
</form>
</div>

View File

@@ -0,0 +1,144 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<script type="application/javascript">
$(function () {
$("input[name=pagecache_typecache]").click(function(){
$('.pagecache_typecache_conf').hide();
$('#pagecache_typecache_conf_'+$(this).val()).show();
$('#pagecache_typecache_conf_'+$(this).val()+' input').first().focus();
checkMemcacheConf();
checkMemcachedConf();
});
});
function checkMemcacheConf() {
$('#memcache_test').prop('disabled', !$('#memcache_host').val() || !$('#memcache_port').val());
$('#testMemcacheResult').html('').hide();
}
function testMemcache() {
$('#memcache_test').prop('disabled', true);
$('#testMemcacheResult').html('{l s='Checking connection...' mod='pagecache'}').show();
$.ajax({ url: '{$pagecache_typecache_memcache_testurl|escape:'javascript':'UTF-8'}', cache: true, data: { host:$('#memcache_host').val(), port:$('#memcache_port').val() },
success: function(response) {
let result = JSON.parse(response);
if (result.status === 1) {
$('#testMemcacheResult').html('<div class="alert alert-success" role="alert"><strong>'+result.host+':'+result.port+'</strong> '+result.comments+'</div>');
}
else {
$('#testMemcacheResult').html('<div class="alert alert-danger" role="alert"><strong>'+result.host+':'+result.port+'</strong> '+result.comments+'</div>');
}
},
error: function(result, status, error) {
$('#testMemcacheResult').html(result + ' - ' + status + ' - ' + error);
}});
$('#memcache_test').prop('disabled', false);
}
function checkMemcachedConf() {
$('#memcached_test').prop('disabled', !$('#memcached_host').val() || !$('#memcached_port').val());
$('#testMemcachedResult').html('').hide();
}
function testMemcached() {
$('#memcached_test').prop('disabled', true);
$('#testMemcachedResult').html('{l s='Checking connection...' mod='pagecache'}').show();
$.ajax({ url: '{$pagecache_typecache_memcached_testurl|escape:'javascript':'UTF-8'}', cache: true, data: { host:$('#memcached_host').val(), port:$('#memcached_port').val() },
success: function(response) {
let result = JSON.parse(response);
if (result.status === 1) {
$('#testMemcachedResult').html('<div class="alert alert-success" role="alert"><strong>'+result.host+':'+result.port+'</strong> '+result.comments+'</div>');
}
else {
$('#testMemcachedResult').html('<div class="alert alert-danger" role="alert"><strong>'+result.host+':'+result.port+'</strong> '+result.comments+'</div>');
}
},
error: function(result, status, error) {
$('#testMemcachedResult').html(result + ' - ' + status + ' - ' + error);
}});
$('#memcached_test').prop('disabled', false);
}
</script>
<div class="panel">
<h3>{if $avec_bootstrap}<i class="icon-gear"></i>{else}<img width="16" height="16" src="../img/admin/AdminPreferences.gif" alt=""/>{/if}&nbsp;{l s='Caching system' mod='pagecache'}</h3>
{if count($pagecache_shopsinfos) > 1}
<div class="alert alert-info">
{l s='Be aware that the caching system is the same for all shops' mod='pagecache'}
</div>
{/if}
<form id="pagecache_form_typecache" action="{$request_uri|escape:'html':'UTF-8'}" method="post">
<input type="hidden" name="submitModule" value="true"/>
<input type="hidden" name="pctab" value="typecache"/>
<fieldset>
<div style="clear: both;">
<div class="margin-form">
<h4>{l s='Recommended ones' mod='pagecache'}</h4>
<div class="radio">
<label>
<input type="radio" {if !$pagecache_typecache_static}disabled="true"{/if} name="pagecache_typecache" value="static" {if $pagecache_typecache === 'static'}checked{/if}>{l s='Prestashop Static!' mod='pagecache'}
</label>
<p class="help-block">{l s='Fastest cache, consummes a lot of files on the disk but they are compressed' mod='pagecache'}</p>
</div>
<div class="radio">
<label>
<input type="radio" name="pagecache_typecache" value="std" {if $pagecache_typecache === 'std'}checked{/if}>{l s='Standard file system' mod='pagecache'}
</label>
<p class="help-block">{l s='Fast but is consumming a lot of files on the disk' mod='pagecache'}</p>
</div>
<div class="radio">
<label>
<input type="radio" {if !$pagecache_typecache_stdzip}disabled="true"{/if} name="pagecache_typecache" value="stdzip" {if $pagecache_typecache === 'stdzip'}checked{/if}>{l s='Zipped Standard file system' mod='pagecache'}
</label>
<p class="help-block">{l s='Same as "Standard file system" but files are compressed with ZIP to consumme less disk space, but of course it is a bit slower.' mod='pagecache'}</p>
</div>
<h4>{l s='Not recommended ones' mod='pagecache'}</h4>
<p>{l s='When using a Memcache server, make sure it is correctly configured and sized or the hit rate could be limited' mod='pagecache'}</p>
<div class="radio">
<label>
<input type="radio" id="pagecache_typecache_memcache" {if !$pagecache_typecache_memcache}disabled="true" {/if}name="pagecache_typecache" value="memcache" {if $pagecache_typecache === 'memcache'}checked{/if}>{l s='PHP Memcache' mod='pagecache'}
</label>
<p class="help-block">{if !$pagecache_typecache_memcache}{if $avec_bootstrap}<i class="icon-exclamation-circle"></i>{else}<img width="16" height="16" src="../img/admin/warning.gif" alt=""/>{/if}&nbsp;{l s='You must install PHP memcache extension in order to use this cache; ask to your hosting provider for more informations.' mod='pagecache'}{else}{l s='Please, provide the hostname and port of the memcache server to use. If you don\'t know what it is then choose an other caching system. Be aware that if your memcache server is down this will slow down your shop.' mod='pagecache'}{/if}</p>
<div id="pagecache_typecache_conf_memcache" class="form-inline pagecache_typecache_conf" {if $pagecache_typecache !== 'memcache'}style="display:none"{/if}>
<div class="form-group">
<label for="memcache_host">{l s='Server IP/Hostname' mod='pagecache'}</label>
<input type="text" onchange="checkMemcacheConf()" onkeyup="checkMemcacheConf()" class="form-control" id="memcache_host" name="pagecache_typecache_memcache_host" value="{$pagecache_typecache_memcache_host|escape:'html':'UTF-8'}">
</div>
<div class="form-group">
<label for="memcache_port">{l s='Server port' mod='pagecache'}</label>
<input type="number" onchange="checkMemcacheConf()" onkeyup="checkMemcacheConf()" class="form-control" id="memcache_port" name="pagecache_typecache_memcache_port" value="{$pagecache_typecache_memcache_port|escape:'html':'UTF-8'}">
</div>
<button type="button" onclick="testMemcache(); return false;" id="memcache_test" class="btn btn-default">Test</button>
<div id="testMemcacheResult" style="padding: 20px; display:none;"></div>
</div>
</div>
<div class="radio">
<label>
<input type="radio" id="pagecache_typecache_memcached" {if !$pagecache_typecache_memcached}disabled="true" {/if}name="pagecache_typecache" value="memcached" {if $pagecache_typecache === 'memcached'}checked{/if}>{l s='PHP Memcached' mod='pagecache'}
</label>
<p class="help-block">{if !$pagecache_typecache_memcached}{if $avec_bootstrap}<i class="icon-exclamation-circle"></i>{else}<img width="16" height="16" src="../img/admin/warning.gif" alt=""/>{/if}&nbsp;{l s='You must install PHP memcached extension in order to use this cache; ask to your hosting provider for more informations.' mod='pagecache'}{else}{l s='Please, provide the hostname and port of the memcache server to use. If you don\'t know what it is then choose an other caching system. Be aware that if your memcache server is down this will slow down your shop.' mod='pagecache'}{/if}</p>
<div id="pagecache_typecache_conf_memcached" class="form-inline pagecache_typecache_conf" {if $pagecache_typecache !== 'memcached'}style="display:none"{/if}>
<div class="form-group">
<label for="memcached_host">{l s='Server IP/Hostname' mod='pagecache'}</label>
<input type="text" onchange="checkMemcachedConf()" onkeyup="checkMemcachedConf()" class="form-control" id="memcached_host" name="pagecache_typecache_memcached_host" value="{$pagecache_typecache_memcached_host|escape:'html':'UTF-8'}">
</div>
<div class="form-group">
<label for="memcached_port">{l s='Server port' mod='pagecache'}</label>
<input type="number" onchange="checkMemcachedConf()" onkeyup="checkMemcachedConf()" class="form-control" id="memcached_port" name="pagecache_typecache_memcached_port" value="{$pagecache_typecache_memcached_port|escape:'html':'UTF-8'}">
</div>
<button type="button" onclick="testMemcached(); return false;" id="memcached_test" class="btn btn-default">Test</button>
<div id="testMemcachedResult" style="padding: 20px; display:none;"></div>
</div>
</div>
</div>
</div>
<div class="bootstrap">
<button type="submit" value="1" id="submitModuleTypeCache" name="submitModuleTypeCache" class="btn btn-default pull-right">
<i class="process-icon-save"></i> {l s='Save' mod='pagecache'}
</button>
</div>
</fieldset>
</form>
</div>

View File

@@ -0,0 +1,414 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<style>
#pagecachecfg .dynhooks label{ line-height:18px;}
#pagecachecfg .tag{ background-color:#eee;border:1px solid #CCCED7;border-radius:4px;display:inline-block;margin:2px;padding:3px;}
#linkadvanced{ font-weight:700;display:block;margin:15px 5px;}
#pagecachecfg input[disabled]{ opacity:0.5;filter:alpha(opacity=50);}
#pagecachecfg .bootstrap .nav-tabs{ margin-left:0;}
#pagecachecfg .bootstrap .label{ color:black;}
#pagecachecfg .bootstrap .nav-tabs li a{ font-size:1.2em;white-space: nowrap;}
#pagecachecfg .bootstrap .nav-tabs li.active a, #pagecachecfg .bootstrap .nav-tabs li.active a:visited,.bootstrap .nav-tabs li.active a:hover, #pagecachecfg .bootstrap .nav-tabs li.active a:focus{ background-color:#ebedf4;}
#pagecachecfg .nobootstrap fieldset{ border:1px solid #ddd;margin:0;}
#pagecachecfg .installstep{ font-size:0.9rem;margin:5px 0 20px;}
#pagecachecfg a.browsebtn{ display:inline-block;color:#FFF;background-color:#F0AD4E;border:1px solid #EEA236;border-radius:3px;text-decoration:none;padding:2px;}
#pagecachecfg a.browsebtn:hover{ background-color:#F5C177}
#pagecachecfg .okbtn{ display:inline-block;color:#FFF;background-color:#59C763;border:1px solid #4EA948;border-radius:3px;text-decoration:none;margin:3px;padding:2px;}
#pagecachecfg .okbtn:hover{ background-color:#7DD385}
#pagecachecfg a.kobtn{ display:inline-block;color:#DA0000;border-radius:3px;margin:3px;padding:2px;}
#pagecachecfg a.kobtn:hover{ color:#ED8080}
#pagecachecfg div.step{ margin:5px 0 5px 20px;}
#pagecachecfg .step span{ border-radius:.8em;color:#FFF;display:inline-block;font-weight:700;line-height:1.6em;margin-right:15px;text-align:center;width:1.6em;}
#pagecachecfg .step img{ margin-right:15px;}
#pagecachecfg .steptodo span{ background:#CCC;}
#pagecachecfg .stepok span{ background:#5EA226;color:#FFF;}
#pagecachecfg .stepok{ color:#5EA226;}
#pagecachecfg .stepdesc{ border-left:2px solid #CCCED7;margin-left:44px;padding:10px 0 10px 24px;}
#pagecachecfg .stepdesc img{ margin:2px;}
#pagecachecfg .stepdesc ol,.stephelp ol{ margin:0;padding:0 0 0 24px;}
#pagecachecfg .stephelp { display:none;border: 1px solid rgb(229, 229, 29);background-color: lightyellow;border-radius: 8px;padding: 10px;margin: 10px 0;}
#pagecachecfg .morehook { display: none}
#pagecachecfg .actions { margin: 15px 0 0 15px;}
#pagecachecfg .btn { margin-right: 5px}
#pagecachecfg.ps15 .row { background: initial;}
#pagecachecfg.ps15 ul.nav-tabs li{ display: inline-block; padding: 5px; margin: 0 5px 0 0; border-radius: 5px 5px 0 0; background-color: #EBEDF4; border: 1px solid #CCCED7; border-bottom: none;}
#pagecachecfg.ps15 ul.nav-tabs li.active{ background-color: #49B2FF; color:white}
#pagecachecfg.ps15 ul.nav-tabs li a, #pagecachecfg.ps15 a.okbtn, #pagecachecfg.ps15 a.browsebtn { text-decoration: none;}
#pagecachecfg.ps15 .bootstrap .nav-tabs li.active a { background-color: #49B2FF; color:white;text-decoration: none;}
#pagecachecfg.ps15 a { text-decoration: underline;}
#pagecachecfg.ps15 ol { list-style-type: decimal;}
#pagecachecfg.ps15 .col-sm-2 { width: 15%; float: left;}
#pagecachecfg.ps15 .col-sm-10 { width: 85%; float: right;}
#pagecachecfg.ps15 li { margin: 10px;}
#pagecachecfg.ps15 .hint { display: block; margin-bottom: 5px;}
#pagecachecfg.ps15 .jprestamenu { display: inline-block; vertical-align: top; width: 20%; padding: 0 16px 5px 5px; margin-right: 10px; border: 1px solid #ccc;}
#pagecachecfg.ps15 .jprestacontent { display: inline-block; vertical-align: top; width: 70%;}
#pagecachecfg.ps15 .panel {
border: 1px solid lightgrey;
border-radius: 3px;
padding: 3px;
margin: 0 0 12px 0;
}
#pagecachecfg.ps15 .jprestamenu .panel { border: none;}
#pagecachecfg.ps15 .panel h3 {
border-bottom: 1px solid lightgrey;
margin-top: 1px;
}
#pagecachecfg.ps15 fieldset {
background-color: transparent;
border: none;
}
#pagecachecfg #timeouts .slider-horizontal { margin: 5px 10px;}
#pagecachecfg #timeouts table td { padding: 3px;text-align:right}
#pagecachecfg #timeouts table td.slider { text-align:left}
#pagecachecfg #timeouts table td.label { padding-right: 5px; font-weight: bold;}
#pagecachecfg #timeouts table .first td { padding-top: 20px;}
#profilingTable td:nth-child(4) { text-align: right}
#profilingTable td:nth-child(3) { text-align: center}
#pagecachecfg .dataTables_length { display:none}
#pagecachecfg.ps15 ul { display: block;list-style-type: disc;padding-left: 2rem;}
#pagecachecfg.ps15 pre {
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 3px;
color: #333;
display: block;
font-size: 11px;
line-height: 1.42857;
padding: 8px;
word-break: break-all;
word-wrap: break-word;
}
#toolbar-nav i.process-icon-delete:before {
color: white;
}
.bootstrap .nav-pills>li.error>a, .bootstrap .nav-pills>li.error>a:hover, .bootstrap .nav-pills>li.error>a:focus {
color: #fff;
background-color: #f44336;
}
#pagecachecfg ul.nav ul.nav {
margin-left: 30px;
padding-left: 5px;
border-left: 1px solid #25b9d7;
}
#pagecachecfg .option-off {
font-style: italic;
}
#pagecachecfg .pc_specifics {
position: absolute;
border: 1px solid gray;
background-color: white;
padding: 3px;
z-index: 99;
text-align: left;
display: none;
unicode-bidi: embed;
font-family: monospace;
white-space: pre;
border-radius: 3px;
margin-left: 100px;
}
#pagecachecfg .specifics:hover .pc_specifics {
display: block;
}
#lioptions a, #licachekey a {
color: orange
}
#pagecachecfg .bootstrap h4 {
font-weight: bold;
}
#pagecachecfg label.form-check-label {
margin-right: 1rem;
}
#pagecachecfg .table th, #pagecachecfg #datasTable th {
font-weight: bold !important;
font-size: 0.8rem;
border-bottom: 2px solid #a0d0eb !important;
vertical-align: baseline;
}
#pagecachecfg #datasTable th {
vertical-align: middle;
}
#pagecachecfg .btn-xs i.material-icons {
font-size: 1.3rem;
}
#pagecachecfg .btn.btn-xs {
line-height: 0;
}
#pagecachecfg .cachewarmer_count {
font-size: 1rem;
font-weight: bold;
text-align: right;
}
#pagecachecfg #total_pages_count.cachewarmer_count {
color: green;
}
#pagecachecfg #total_pages_count.cachewarmer_count_warn {
color: orange;
}
#pagecachecfg #total_pages_count.cachewarmer_count_danger {
color: red;
}
.help a {
color: #59c763;
font-weight: bold;
}
#pagecachecfg .bootstrap input[type=number] {
background: #f5f8f9 none;
border: 1px solid #c7d6db;
line-height: 27px;
text-align: right;
border-radius: 3px;
}
#pagecachecfg .bootstrap input:focus[type=number] {
background-color: #fefbe2;
border: 1px solid #66afe9 !important;
box-shadow: none;
outline: 0;
}
#pagecachecfg .chart {
border: 1px solid #bbcdd2;
margin: 0.5rem 0;
border-radius: 4px;
}
</style>
<script type="text/javascript">
let currentTab = null;
let is_cachewarmer_valid = false;
$( document ).ready(function() {
switch (window.location.hash) {
case "#tabinstall": displayTab("install"); break;
case "#tablicense": displayTab("license"); break;
case "#tabdynhooks": displayTab("dynhooks"); break;
case "#tabdynhooksjs": displayTab("dynhooks"); break;
case "#taboptions": displayTab("options"); break;
case "#tabcachekey": displayTab("cachekey"); break;
case "#tabdatas": displayTab("datas"); break;
case "#tabcachewarmer": displayTab("cachewarmer"); break;
case "#tabcachewarmer-settings": displayTab("cachewarmer-settings"); break;
case "#tabcachewarmer-status": displayTab("cachewarmer-status"); break;
case "#tabcachewarmer-report": displayTab("cachewarmer-report"); break;
case "#tabtypecache": displayTab("typecache"); break;
case "#tabdiagnostic": displayTab("diagnostic"); break;
case "#tabtimeouts": displayTab("timeouts"); break;
case "#tabcron": displayTab("cron"); break;
case "#tabshopsinfos": displayTab("shopsinfos"); break;
case "#tabcachemanagement": displayTab("cachemanagement"); break;
}
$('#desc-module-clearcache-li').prependTo('.btn-toolbar ul.nav');
$('#btn-pagecache-faq-li').prependTo('.btn-toolbar ul.nav');
// Bug in PS1.7.8.5
$('.btn-toolbar ul.nav #dingedi-mdtr-app').remove();
// JPresta-Cache-Warmer tabs
window.addEventListener(
"message",
(event) => {
if ((event.origin === "http://localhost" || event.origin === "https://cachewarmer.jpresta.com")
&& typeof event.data === 'object'
&& typeof event.data.name === 'string'
&& event.data.name === 'jpresta-cache-warmer-subscription'
) {
console.log('JPresta-Cache-Warmer subscription informations received.');
let subscriptionInfos = event.data;
if (subscriptionInfos.is_valid) {
is_cachewarmer_valid = true;
if (subscriptionInfos.page_status === 'show') {
$('#licachewarmer-status').show().removeClass('option-off');
}
else if (subscriptionInfos.page_status === 'show_disabled') {
$('#licachewarmer-status').show().addClass('option-off');
}
else {
$('#licachewarmer-status').hide();
}
if (subscriptionInfos.page_report === 'show') {
$('#licachewarmer-report').show().removeClass('option-off');
}
else if (subscriptionInfos.page_report === 'show_disabled') {
$('#licachewarmer-report').show().addClass('option-off');
}
else {
$('#licachewarmer-report').hide();
}
$('#cw-submenu').show();
if (currentTab === 'cachewarmer') {
// This will update the active menu
displayTab('cachewarmer');
}
}
}
},
false
);
// If the cache-warmer frame is ready before us we retreive the information again.
try {
document.getElementById("jprestaCacheWamer").contentWindow.postMessage('jpresta-admin-ready', '*');
}
catch (e) {
console.log('Cannot send message "jpresta-admin-ready" to iframe #jprestaCacheWamer', e);
}
});
function displayTab(tab) {
$(".pctab").hide();
$("#"+tab).show();
$(".nav-pills .active").removeClass("active");
if (!is_cachewarmer_valid || tab !== 'cachewarmer') {
$("#li" + tab).addClass("active");
}
else {
$("#licachewarmer-dashboard").addClass("active");
}
currentTab = tab;
if (tab === 'install' && typeof nv !== 'undefined' && typeof nv.graphs[0] !== 'undefined') {
nv.graphs[0].update();
}
}
</script>
<div id="pagecachecfg" {if !$avec_bootstrap}class="ps15"{/if}>
{foreach $msg_success as $msg}
<div class="bootstrap">
<div class="module_confirmation conf confirm alert alert-success">{if $avec_bootstrap}<button type="button" class="close" data-dismiss="alert">&times;</button>{/if}{$msg|escape:'html':'UTF-8'}</div>
</div>
{/foreach}
{foreach $msg_infos as $msg}
<div class="bootstrap">
<div class="alert alert-info">{if $avec_bootstrap}<button type="button" class="close" data-dismiss="alert">&times;</button>{/if}{$msg|escape:'html':'UTF-8'}</div>
</div>
{/foreach}
{foreach $msg_warnings as $msg}
<div class="bootstrap">
<div class="module_warning alert alert-warning">{if $avec_bootstrap}<button type="button" class="close" data-dismiss="alert">&times;</button>{/if}{$msg|escape:'html':'UTF-8'}</div>
</div>
{/foreach}
{foreach $msg_errors as $msg}
<div class="bootstrap">
<div class="module_error alert alert-danger">{if $avec_bootstrap}<button type="button" class="close" data-dismiss="alert">&times;</button>{/if}{$msg|escape:'html':'UTF-8'}</div>
</div>
{/foreach}
{if !$module_enabled}
<div class="alert alert-warning" style="display: block;">
&nbsp;{l s='The module is currently disabled' mod='pagecache'}
</div>
{/if}
<div class="bootstrap">
<div class="row">
<div class="col-md-4 col-lg-3 col-xl-2 jprestamenu">
<div class="panel">
<h3 title="Prestashop {$prestashop_version|escape:'html':'UTF-8'}"><img src="../modules/{$module_name|escape:'html':'UTF-8'}/logo.png" width="20" height="20"/> {$module_displayName|escape:'html':'UTF-8'} v{$module_version|escape:'html':'UTF-8'}</h3>
<ul class="nav nav-pills nav-stacked">
<li id="liinstall" role="presentation" {if $pctab eq 'install'}class="active"{/if}><a href="#tabinstall" onclick="displayTab('install');return true;">{if $avec_bootstrap}<i class="icon-dashboard"></i>{else}<img width="16" height="16" src="../img/admin/prefs.gif" alt=""/>{/if}&nbsp;{l s='Dashboard' mod='pagecache'}</a></li>
<li id="lilicense" role="presentation" class="{if $pctab eq 'license'}active{/if}{if $pagecache_clone_detected} error{/if}"><a href="#tablicense" onclick="displayTab('license');return true;">{if $avec_bootstrap}<i class="icon-key"></i>{else}<img width="16" height="16" src="../img/admin/htaccess.gif" alt=""/>{/if}&nbsp;{l s='License' mod='pagecache'}</a></li>
<li id="licachewarmer" role="presentation" {if $pctab eq 'cachewarmer'}class="active"{/if}><a href="#tabcachewarmer" onclick="displayTab('cachewarmer');return true;">{if $avec_bootstrap}<i class="icon-fire"></i>{else}<img width="16" height="16" src="../img/admin/quick.gif" alt=""/>{/if}&nbsp;{l s='JPresta Cache Warmer' mod='pagecache'}</a>
<ul id="cw-submenu" style="display: none" class="nav nav-pills nav-stacked">
<li id="licachewarmer-dashboard" {if $pctab eq 'cachewarmer'}class="active"{/if}><a href="#tabcachewarmer" onclick="displayTab('cachewarmer');return true;">{l s='Dashboard and options' mod='pagecache'}</a></li>
<li id="licachewarmer-settings" {if $pctab eq 'cachewarmer-settings'}class="active"{/if}><a href="#tabcachewarmer-settings" onclick="displayTab('cachewarmer-settings');return true;">{l s='Pages to warmup' mod='pagecache'}</a></li>
<li id="licachewarmer-status" {if $pctab eq 'cachewarmer-status'}class="active"{/if}><a href="#tabcachewarmer-status" onclick="displayTab('cachewarmer-status');return true;">{l s='Status of your shop' mod='pagecache'}</a></li>
<li id="licachewarmer-report" {if $pctab eq 'cachewarmer-report'}class="active"{/if}><a href="#tabcachewarmer-report" onclick="displayTab('cachewarmer-report');return true;">{l s='Monthly reports' mod='pagecache'}</a></li>
</ul>
</li>
<li id="lidynhooks" role="presentation" {if $pctab eq 'dynhooks'}class="active"{/if}><a href="#tabdynhooks" onclick="displayTab('dynhooks');return true;">{if $avec_bootstrap}<i class="icon-puzzle-piece"></i>{else}<img width="16" height="16" src="../img/admin/tab-plugins.gif" alt=""/>{/if}&nbsp;{l s='Dynamic modules and widgets' mod='pagecache'}</a></li>
{*ULTIMATE*}
<li id="litypecache" role="presentation" {if $pctab eq 'typecache'}class="active"{/if}><a href="#tabtypecache" onclick="displayTab('typecache');return true;">{if $avec_bootstrap}<i class="icon-gear"></i>{else}<img width="16" height="16" src="../img/admin/AdminPreferences.gif" alt=""/>{/if}&nbsp;{l s='Caching system' mod='pagecache'}</a></li>
{*ULTIMATE£*}
<li id="litimeouts" role="presentation" {if $pctab eq 'timeouts'}class="active"{/if}><a href="#tabtimeouts" onclick="displayTab('timeouts');return true;">{if $avec_bootstrap}<i class="icon-time"></i>{else}<img width="16" height="16" src="../img/admin/time.gif" alt=""/>{/if}&nbsp;{l s='Pages & timeouts' mod='pagecache'}</a></li>
<li id="lidatas" role="presentation" {if $pctab eq 'datas'}class="active"{/if}><a href="#tabdatas" onclick="displayTab('datas');return true;">{if $avec_bootstrap}<i class="icon-line-chart"></i>{else}<img width="16" height="16" src="../img/admin/AdminStats.gif" alt=""/>{/if}&nbsp;{l s='Statistics' mod='pagecache'}</a></li>
{*ULTIMATE*}
<li id="lidiagnostic" role="presentation" {if $pctab eq 'diagnostic'}class="active"{/if}><a href="#tabdiagnostic" onclick="displayTab('diagnostic');return true;">{if $avec_bootstrap}<i class="icon-user-md"></i>{else}<img width="16" height="16" src="../img/admin/binoculars.png" alt=""/>{/if}&nbsp;{l s='Diagnostic & performances' mod='pagecache'} <span class="badge">{$diagnostic_count|escape:'html':'UTF-8'}</span></a></li>
<li id="licron" role="presentation" {if $pctab eq 'cron'}class="active"{/if}><a href="#tabcron" onclick="displayTab('cron');return true;">{if $avec_bootstrap}<i class="icon-link"></i>{else}<img width="16" height="16" src="../img/admin/subdomain.gif" alt=""/>{/if}&nbsp;{l s='API (URLs to clear the cache)' mod='pagecache'}</a></li>
{*ULTIMATE£*}
{if $advanced_mode}
<li id="lioptions" role="presentation" {if $pctab eq 'options'}class="active"{/if}><a href="#taboptions" onclick="displayTab('options');return true;">{if $avec_bootstrap}<i class="icon-gear"></i>{else}<img width="16" height="16" src="../img/admin/AdminPreferences.gif" alt=""/>{/if}&nbsp;{l s='Options' mod='pagecache'}</a></li>
<li id="licachekey" role="presentation" {if $pctab eq 'cachekey'}class="active"{/if}><a href="#tabcachekey" onclick="displayTab('cachekey');return true;">{if $avec_bootstrap}<i class="icon-gear"></i>{else}<img width="16" height="16" src="../img/admin/AdminPreferences.gif" alt=""/>{/if}&nbsp;{l s='Cache key' mod='pagecache'}</a></li>
{/if}
{if count($pagecache_shopsinfos) > 1}
<li id="lishopsinfos" role="presentation" {if $pctab eq 'shopsinfos'}class="active"{/if}><a href="#tabshopsinfos" onclick="displayTab('shopsinfos');return true;">{if $avec_bootstrap}<i class="icon-sitemap"></i>{else}<img width="16" height="16" src="../img/admin/multishop_config.png" alt=""/>{/if}&nbsp;{l s='Multistore' mod='pagecache'}</a></li>
{/if}
<li id="lifaq" class="help"><a href="https://jpresta.com/{$jpresta_language_isocode|default:'en'|escape:'javascript':'UTF-8'}/faq?from=jprestaspeedpack" target="_blank">{if $avec_bootstrap}<i class="icon-question-sign"></i>{else}<img width="16" height="16" src="../img/admin/help.png" alt=""/>{/if}&nbsp;{l s='FAQ' mod='pagecache'}</a></li>
</ul>
<ul style="display:none">
<li id="btn-pagecache-faq-li">
<a id="pagecache-faq" class="toolbar_btn" href="https://jpresta.com/{$jpresta_language_isocode|default:'en'|escape:'javascript':'UTF-8'}/faq?from=jprestaspeedpack" target="_blank" style="color:white; background-color: #33bd25">
<i class="process-icon-help" style="color:white;"></i>
<div>{l s='FAQ' mod='pagecache'}</div>
</a>
</li>
</ul>
</div>
{if !$advanced_mode}
<div style="text-align: center"><a href="{$advanced_mode_url|escape:'html':'UTF-8'}">{l s='Advanced mode' mod='pagecache'}</a></div>
{/if}
</div>
<div class="col-md-8 col-lg-9 col-xl-10 jprestacontent">
<div id="install" class="pctab" {if $pctab neq 'install'}style="display:none"{/if}>
{include file='./get-content-tab-install.tpl'}
</div>
<div id="dynhooks" class="pctab" {if $pctab neq 'dynhooks'}style="display:none"{/if}>
{include file='./get-content-tab-dynhooks.tpl'}
</div>
<div id="timeouts" class="pctab" {if $pctab neq 'timeouts'}style="display:none"{/if}>
{include file='./get-content-tab-timeouts.tpl'}
</div>
<div id="datas" class="pctab" {if $pctab neq 'datas'}style="display:none"{/if}>
{include file='./get-content-tab-datas.tpl'}
</div>
<div id="cron" class="pctab" {if $pctab neq 'cron'}style="display:none"{/if}>
{include file='./get-content-tab-cron.tpl'}
</div>
{if $advanced_mode}
<div id="options" class="pctab" {if $pctab neq 'options'}style="display:none"{/if}>
{include file='./get-content-tab-options.tpl'}
</div>
<div id="cachekey" class="pctab" {if $pctab neq 'cachekey'}style="display:none"{/if}>
{include file='./get-content-tab-cachekey.tpl'}
</div>
{/if}
{*ULTIMATE*}
<div id="typecache" class="pctab" {if $pctab neq 'typecache'}style="display:none"{/if}>
{include file='./get-content-tab-typecache.tpl'}
</div>
<div id="diagnostic" class="pctab" {if $pctab neq 'diagnostic'}style="display:none"{/if}>
{include file='./get-content-tab-diagnostic.tpl'}
</div>
{*ULTIMATE£*}
<div id="license" class="pctab" {if $pctab neq 'license'}style="display:none"{/if}>
{include file='./get-content-tab-license.tpl'}
</div>
<div id="cachewarmer" class="pctab" {if $pctab neq 'cachewarmer'}style="display:none"{/if}>
{include file='./get-content-tab-jpresta.tpl'}
</div>
<div id="cachewarmer-settings" class="pctab" {if $pctab neq 'cachewarmer-settings'}style="display:none"{/if}>
{include file='./get-content-tab-jpresta-settings.tpl'}
</div>
<div id="cachewarmer-status" class="pctab" {if $pctab neq 'cachewarmer-status'}style="display:none"{/if}>
{include file='./get-content-tab-jpresta-status.tpl'}
</div>
<div id="cachewarmer-report" class="pctab" {if $pctab neq 'cachewarmer-report'}style="display:none"{/if}>
{include file='./get-content-tab-jpresta-report.tpl'}
</div>
{if count($pagecache_shopsinfos) > 1}
<div id="shopsinfos" class="pctab" {if $pctab neq 'shopsinfos'}style="display:none"{/if}>
{include file='./get-content-tab-shopsinfos.tpl'}
</div>
{/if}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,19 @@
<?php
/**
* This file protect the directory
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*/
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,10 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="alert alert-warning">
<div class="alert-text">{l s='Clone detected, please check the configuration of Page Cache Ultimate (or JPresta Speed Pack) to avoid any license conflict' mod='pagecache'}</div>
</div>

View File

@@ -0,0 +1,10 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="alert alert-warning">
<div class="alert-text">{l s='You must finish the upgrade of "%module_name%" (%module_current_version% => %module_new_version%), go in modules list and click on button "Upgrade" next to "%module_name%". This is important to do it now!' sprintf=['%module_name%' => $jpresta_module_name, '%module_new_version%' => $jpresta_module_new_version, '%module_current_version%' => $jpresta_module_current_version] d='pagecache'}</div>
</div>

View File

@@ -0,0 +1,10 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div class="alert alert-warning">
{l s='Please, select a shop to configure (you cannot configure a group of shops).' mod='pagecache'}
</div>

View File

@@ -0,0 +1,154 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<div id="queryAnalysis{$id_query|intval}">
{if isset($tables) && (count($tables) > 0)}
<div style="width: fit-content; float: right; margin: 0 1rem;">
<div class="sqlprofsubtitle" style="margin-top: 0">{l s='Tables used in this query' mod=$module_name}</div>
<table>
<thead>
<tr>
<th>{l s='Table' mod=$module_name}</th>
<th class="tdright">{l s='Row count' mod=$module_name}</th>
</tr>
</thead>
<tbody>
{foreach $tables as $tableName => $rowCount}
<tr>
<td>{$tableName|escape:'html':'UTF-8'}</td>
<td class="tdright">{$rowCount|intval}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{/if}
<div>
<div class="sqlprofsubtitle">{l s='Example of query with real parameters' mod=$module_name}</div>
{if !empty($sql)}
<div class="sql">{$sql nofilter}</div>
{else}
<div class="sql"><pre>{$query->getExampleQuery()|trim|escape:'html':'UTF-8'}</pre></div>
{/if}
</div>
{if isset($explain) && (count($explain) > 0)}
<div>
<div class="sqlprofsubtitle">{l s='"EXPLAIN" of the query' mod=$module_name}</div>
<table>
<thead>
<tr>
{foreach $explain[0] as $colName => $colValue}
<th>{$colName|escape:'html':'UTF-8'}</th>
{/foreach}
</tr>
</thead>
<tbody>
{foreach $explain as $row}
<tr>
{foreach $row as $col}
<td>{$col|escape:'html':'UTF-8'}</td>
{/foreach}
</tr>
{/foreach}
</tbody>
</table>
</div>
{/if}
{if isset($indexes) && count($indexes) > 0}
<div>
<div class="sqlprofsubtitle">{l s='Indexes created from here' mod=$module_name}</div>
<div class="alert alert-info">{l s='Suggested indexes do not always improve SQL queries. If you do not see any improvements, then you can delete them.' mod=$module_name}</div>
<table>
<thead>
<tr>
<th>{l s='Index name' mod=$module_name}</th>
<th>{l s='Table' mod=$module_name}</th>
<th>{l s='Columns' mod=$module_name}</th>
<th style="text-align: center">{l s='Actions' mod=$module_name}</th>
</tr>
</thead>
<tbody>
{foreach $indexes as $index}
<tr>
<td>{$index['index']|escape:'html':'UTF-8'}</td>
<td>{$index['table']|escape:'html':'UTF-8'}</td>
<td>{$index['columns']|escape:'html':'UTF-8'}</td>
<td><a class="btn btn-sm btn-danger" onclick="deleteIndex({$id_query|intval}, '{$index['table']|escape:'html':'UTF-8'}', '{$index['index']|escape:'html':'UTF-8'}'); return false;"><i class="material-icons" style="font-size: 1rem; vertical-align: bottom;">delete</i> {l s='Delete this index' mod=$module_name}</a></td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{/if}
{if isset($suggestions)}
<div>
<div class="sqlprofsubtitle">{l s='Suggestions or tips' mod=$module_name}</div>
{if count($suggestions) === 0}
<div>:-( {l s='Sorry, no suggestion found for this query' mod=$module_name}</div>
{else}
{foreach $suggestions as $suggestion}
<div class="suggestions suggestions-{$suggestion.type|escape:'html':'UTF-8'}">
{$suggestion.msg|escape:'html':'UTF-8'}
{if isset($suggestion.action) && isset($suggestion.action_label) }
<a class="btn btn-sm btn-primary" style="margin-left: 2rem" onclick="{$suggestion.action|escape:'html':'UTF-8'};return false;"><span class="material-icons">arrow_right_alt</span> {$suggestion.action_label|escape:'javascript':'UTF-8'}</a>
{/if}
</div>
{/foreach}
{/if}
</div>
{/if}
{if count($callstacks) > 0}
<div>
<div class="sqlprofsubtitle">{l s='Callstacks' mod=$module_name}</div>
<table>
<thead>
<tr>
<th>{l s='Executions count' mod=$module_name}</th>
<th>{l s='Callstacks' mod=$module_name}</th>
</tr>
</thead>
<tbody>
{foreach $callstacks as $callstack}
<tr>
<td style="text-align: center; vertical-align: top">{$callstack->getExecutedCount()|intval}</td>
<td class="callstack">
<a href="#" onclick="$('#cs{$callstack->getIdStack()|intval}').toggle();return false;">{$callstack->getCaller()|escape:'html':'UTF-8'}</a>
<div id="cs{$callstack->getIdStack()|intval}" style="display: none; margin-top: 5px">
{foreach $callstack->getCallstack() as $call}
{if isset($call.file)}
<div class="cs-call">
<span class="cs-file">{$call.file|escape:'html':'UTF-8'}</span>:<span class="cs-line">{$call.line|intval}</span> - <span class="cs-function">{$call.class|escape:'html':'UTF-8'|default:''}::{$call.function|escape:'html':'UTF-8'}()</span>
</div>
{/if}
{/foreach}
</div>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{/if}
<div>
<div class="sqlprofsubtitle">{l s='Actions' mod=$module_name}</div>
{if isset($duration_ms)}
<div class="suggestions {if $duration_percent > 5 && $duration_diff < -2}suggestions-success{elseif $duration_percent < -5 && $duration_diff > 2}suggestions-error{/if}" style="margin-bottom: 1rem;">
<p><i class="material-icons" style="vertical-align: bottom;font-size: 1.1rem;color: #25b9d7;">warning</i> {l s='Please note, this duration may vary depending on the current server load. We recommend running the query multiple times with and without optimizations to be able to compare.' mod=$module_name}</p>
{l s='Current duration of the query' mod=$module_name}: <b>{$duration_ms|escape:'html':'UTF-8'}ms</b> ({$query->getDurationMaxMs()|round}ms)<br/>
{if $duration_percent > 5 && $duration_diff < -2}
{l s='The query is faster than during the profiling' mod=$module_name}: <b style="color: green">{$duration_percent|escape:'html':'UTF-8'}%</b> ({$duration_diff|intval}ms)<br/>
{elseif $duration_percent < -5 && $duration_diff > 2}
{l s='The query is slower than during the profiling' mod=$module_name}: <b style="color: red">{$duration_percent|escape:'html':'UTF-8'}%</b> ({$duration_diff|intval}ms)<br/>
{else}
{l s='The query is almost as fast as during the profiling' mod=$module_name}: <b>{$duration_percent|escape:'html':'UTF-8'}%</b> ({$duration_diff|intval}ms)<br/>
{/if}
</div>
{/if}
<button onclick="displayQueryAnalysis({$id_query|intval}, 1);$(this).prop('disabled', true);return false;" class="btn btn-primary"><i class="material-icons">refresh</i>&nbsp;{l s='Refresh analysis' mod=$module_name}</button>
</div>
</div>

View File

@@ -0,0 +1,676 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<script type="text/javascript">
$(document).ready(function () {
$('#btn-sqlprofiler-faq-li').prependTo('.btn-toolbar ul.nav');
});
</script>
<ul style="display:none">
<li id="btn-sqlprofiler-faq-li">
<a id="sqlprofiler-faq" class="toolbar_btn" href="{$faq_url|escape:'html':'UTF-8'}" target="_blank" style="color:white; background-color: #33bd25">
<i class="process-icon-help"></i>
<div>{l s='FAQ SQL Profiler' mod=$module_name}</div>
</a>
</li>
</ul>
{if $sql_profiler_enabled}
<style>
#datasRunsTable, #datasRunsTable_wrapper, #datasRunsTable_wrapper {
margin-top: 2rem;
}
tr.shown + tr > td {
padding: 1rem !important;
background-color: #eff1f2;
}
#datasQueriesTable tr.shown + tr > td {
padding: 0 1rem 1rem 1rem !important;
background-color: #d4e1e7;
}
#datasRunsTable th {
font-weight: bold !important;
font-size: 0.8rem;
border-bottom: 2px solid #a0d0eb !important;
vertical-align: middle;
padding-right: 20px;
}
#datasRunsTable > tbody > tr.even > td, #datasRunsTable > tbody > tr.odd > td {
cursor: pointer;
}
#datasQueriesTable > tbody > tr.even > td, #datasQueriesTable > tbody > tr.odd > td {
cursor: pointer;
}
.dataTables_processing {
border: 2px solid orange;
border-radius: 5px;
padding: 0 !important;
line-height: 3rem;
height: auto !important;
z-index: 99;
font-weight: bold;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
border: 2px solid #25b9d7;
}
.dataTables_length {
margin-bottom: 0.5rem;
}
.dataTables_length label {
display: inline !important;
}
.dataTables_length select {
display: inline-block !important;
width: initial !important;
height: 1.8rem;
padding: 0 5px;
}
th.sorting_desc, th.sorting_asc {
background-color: #a0d0eb;
color: white;
border: 1px solid #a0d0eb;
}
td.sorting_1 {
border-right: 1px solid #a0d0eb !important;
border-left: 1px solid #a0d0eb !important;
}
.percent-bg-10 td { background-color: #E1F5FE !important }
.percent-bg-20 td { background-color: #B3E0F2 !important }
.percent-bg-30 td { background-color: #81D4FA !important }
.percent-bg-40 td { background-color: #4FC3F7 !important }
.percent-bg-50 td { background-color: #29B6F6 !important }
.percent-bg-60 td { background-color: #03A9F4 !important }
.percent-bg-70 td { background-color: #039BE5 !important; color: white; }
.percent-bg-80 td { background-color: #0288D1 !important; color: white; }
.percent-bg-90 td { background-color: #0277BD !important; color: white; }
.percent-bg-100 td { background-color: #01579B !important; color: white; }
.form-check {
margin: 0.5rem 2rem;
}
.mypanel-footer {
padding: 10px 15px;
background-color: #fcfdfe;
border-top: 1px solid #eee;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
margin: 15px -20px -20px;
text-align: right;
}
.truncateIfLong {
max-width: 400px;
overflow: hidden;
text-overflow: ellipsis;
}
.tdid{
max-width: 50px !important;
}
.tddate {
white-space: nowrap !important;
text-align: center !important;
max-width: 140px !important;
}
.tdright {
text-align: right !important;
}
.sqlprofsubtitle {
border-bottom: 1px solid #f1f1f1;
font-size: 1rem;
margin: 1rem 0 0.5rem 0;
}
.inprogress .jsDisplayStopped, .jsDisplayInProgress {
display : none !important;
}
.jsDisplayStopped, .inprogress .jsDisplayInProgress {
display : initial !important;
}
.recording {
font-size: 0.85rem;
}
.suggestions {
font-size: 0.85rem;
border: 1px solid #555555;
background-color: #ccc;
padding: 0.5rem;
border-radius: 5px;
margin-top: 3px;
}
.suggestions.suggestions-suggest {
border: 1px solid orange;
background-color: #ffecc8;
}
.suggestions.suggestions-success {
border: 1px solid green;
background-color: #ddfddd;
}
.suggestions.suggestions-error {
border: 1px solid #d20000;
background-color: #ffd0d0;
}
.suggestions.suggestions-tip {
border: 1px solid #3ed2f0;
background-color: #c7f6ff;
}
.callstack {
font-family: monospace, monospace;
}
.callstack .cs-function {
font-weight: bold;
}
.queryLoading {
margin: 1rem;
}
.help {
border: 1px solid #72c279;
padding: 0 0.5rem;
border-radius: 5px;
}
.help h4 {
color: #72c279;
}
.sql pre {
white-space: break-spaces;
}
</style>
<script type="text/javascript">
function initializeRunsTable() {
return $('#datasRunsTable').on('error.dt', handleDataTableError).DataTable({
processing: true,
serverSide: true,
searching: false,
ajax: '{$datas_run_url|escape:'javascript':'UTF-8'}',
columns: [
{ width: '2rem', className: 'tdid' },
{ width: '7rem', className: 'tddate' },
{
className: 'truncateIfLong',
orderable : false,
render: function (data, type, row) {
let html = '<span class="badge badge';
switch (parseInt(row[5])) {
case 1:
html += '-success">GET';
break;
case 2:
html += '-warning">POST';
break;
case 3:
html += '-warning">PUT';
break;
case 4:
html += '-danger">DELETE';
break;
default:
html += '">?';
break;
}
html += '</span> ';
if (parseInt(row[6])) {
// Ajax
html += '<span class="badge">ajax<\/span> ';
}
return html + data;
}
},
{ width: '7rem', className: 'tdright' },
{ width: '7rem', className: 'tdright',
render: function (data, type, row) {
let html = '';
if (parseInt(row[7])) {
html += '<i class="material-icons" title="'+parseInt(row[7])+' {l s='suspicious queries' mod=$module_name}" style="vertical-align: bottom;font-size: 1.1rem;color: #f1b746;">warning</i> ';
}
return html + data;
}
}
],
order: [[1, 'desc']],
language: getLocalizationSettings(),
dom: 'Blfrtip',
lengthMenu: getLengthMenuOptions(),
buttons: [],
});
}
function initializeQueriesTable(id_run) {
return $('#datasQueriesTable').on('error.dt', handleDataTableError).DataTable({
processing: true,
serverSide: true,
searching: false,
ajax: '{$datas_run_url|escape:'javascript':'UTF-8'}&id_run=' + id_run,
columns: [
{ width: '2rem', className: 'tdid'},
{
className: 'truncateIfLong',
orderable : false,
render: function (data, type, row) {
let html = '';
if (parseInt(row[8])) {
html += '<i class="material-icons" title="{l s='This query should probably be optimized' mod=$module_name}" style="vertical-align: bottom;font-size: 1.1rem;color: #f1b746;">warning</i> ';
}
return html + data;
}
},
{ width: '7rem', className: 'tdright'},
{ width: '7rem', className: 'tdright'},
{ width: '7rem', className: 'tdright'},
{ width: '7rem', className: 'tdright'},
{
width: '7rem',
className: 'tdright',
render: function (data, type, row) {
return data + ' (' + row[7] + '%)';
}
},
],
order: [[6, 'desc']],
language: getLocalizationSettings(),
dom: 'Blfrtip',
lengthMenu: getLengthMenuOptions(),
buttons: [],
createdRow: (row, data, index) => {
if (data[7] > 1) {
let cssClass = getCssClassByPercentage(parseFloat(data[7]));
if (cssClass) {
row.classList.add(cssClass);
}
}
}
});
}
function handleDataTableError(e, settings, techNote, message) {
console.error('SQL Profiler - Cannot display profiling datas: ', message);
}
function getLocalizationSettings() {
return {
processing: "<i class=\"icon-refresh icon-spin icon-fw\"></i> {l s='Loading datas...' mod=$module_name}",
search: "{l s='Search' mod=$module_name}:",
lengthMenu: "{l s='Showing _MENU_ rows' mod=$module_name}",
info: "{l s='Showing _START_ to _END_ of _TOTAL_ rows' mod=$module_name}",
infoEmpty: "{l s='Showing 0 to 0 of 0 row' mod=$module_name}",
infoFiltered: "{l s='Filtered of _MAX_ rows' mod=$module_name}",
infoPostFix: "",
loadingRecords: "{l s='Loading datas...' mod=$module_name}",
zeroRecords: "{l s='No data to display' mod=$module_name}",
emptyTable: "{l s='No data to display' mod=$module_name}",
paginate: {
first: "{l s='First' mod=$module_name}",
previous: "{l s='Previous' mod=$module_name}",
next: "{l s='Next' mod=$module_name}",
last: "{l s='Last' mod=$module_name}"
}
}
}
function getLengthMenuOptions() {
return [
[10, 25, 50, 100],
['10', '25', '50', '100'],
];
}
function deleteAllData(datasTable, keepRelevant = 0) {
if (keepRelevant || confirm("{l s='Really delete all profiling datas?' mod=$module_name}")) {
let parameters = datasTable.ajax.params();
parameters.deleteAll = true;
parameters.keepRelevant = keepRelevant;
$.ajax({
url: datasTable.ajax.url(),
method: 'post',
data: parameters,
success: function (response) {
datasTable.ajax.reload();
},
error: function (result, status, error) {
console.log(result + ' - ' + status + ' - ' + error);
},
});
}
}
function jprestaPcSetCookie(cname, cvalue, ttl_minutes, path) {
let d = new Date();
d.setTime(d.getTime() + (ttl_minutes*60*1000));
let expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=" + path;
}
function jprestaPcGetCookie(cname, defaultValue) {
if (defaultValue === undefined) {
defaultValue = null;
}
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return defaultValue;
}
let profilingCookieName = 'jpresta_profiler_run';
let datasRunsTable = null;
let datasQueriesTable = null;
function startProfiling() {
jprestaPcSetCookie(profilingCookieName, $('input[name=profilingType]:checked').val(), 60, '/');
jprestaRefreshProfilingStatus();
}
function stopProfiling() {
document.cookie = profilingCookieName + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
reloadDatas();
jprestaRefreshProfilingStatus();
}
function reloadDatas() {
if (datasRunsTable) {
datasRunsTable.ajax.reload();
}
}
function startLoading(id_query) {
$('#queryAnalysis .btn').attr('disabled', true);
document.body.style.cursor='wait';
}
function stopLoading(id_query) {
document.body.style.cursor='default';
$('#queryAnalysis .btn').removeAttr('disabled');
}
function displayQueryAnalysis(id_query, run_it = 0) {
try {
startLoading(id_query);
$.get('{$url_query_ctrl|escape:'javascript':'UTF-8'}', { id_query: id_query, run_it: run_it }, function (data) {
if (data.includes('queryAnalysis' + id_query)) {
$('#queryAnalysis').html(data);
} else {
handleErrorResponse();
}
}).fail(function () {
handleErrorResponse();
}).always(function() {
stopLoading(id_query);
});
} catch (error) {
handleErrorResponse();
}
function handleErrorResponse() {
$('#queryAnalysis').html("<div class=\"alert alert-danger\">{l s='Sorry, looks like an error occurred during the analysis of this query' mod=$module_name}</div>");
}
}
function createIndex(id_query, tableName, cols) {
try {
startLoading(id_query);
$.get('{$url_query_ctrl|escape:'javascript':'UTF-8'}', { id_query: id_query, add_idx_tbl: tableName, add_idx_cols: cols }, function (data) {
if (data.includes('queryAnalysis' + id_query)) {
$('#queryAnalysis').html(data);
} else {
handleErrorResponse();
}
}).fail(function () {
handleErrorResponse();
}).always(function() {
stopLoading(id_query);
});
} catch (error) {
handleErrorResponse();
}
function handleErrorResponse() {
$('#queryAnalysis').html("<div class=\"alert alert-danger\">{l s='Sorry, looks like an error occurred during the analysis of this query' mod=$module_name}</div>");
}
}
function deleteIndex(id_query, tableName, indexName) {
try {
startLoading(id_query);
$.get('{$url_query_ctrl|escape:'javascript':'UTF-8'}', { id_query: id_query, del_idx_tbl: tableName, del_idx_name: indexName }, function (data) {
if (data.includes('queryAnalysis' + id_query)) {
$('#queryAnalysis').html(data);
} else {
handleErrorResponse();
}
}).fail(function () {
handleErrorResponse();
}).always(function() {
stopLoading(id_query);
});
} catch (error) {
handleErrorResponse();
}
function handleErrorResponse() {
$('#queryAnalysis').html("<div class=\"alert alert-danger\">{l s='Sorry, looks like an error occurred during the analysis of this query' mod=$module_name}</div>");
}
}
function jprestaRefreshProfilingStatus() {
let profilingCookieValue = jprestaPcGetCookie(profilingCookieName, 0);
if (profilingCookieValue !== 0) {
$('#sqlprofiler').addClass('inprogress');
if (profilingCookieValue === 'admin') {
$('#profilingTypeAdmin').prop('checked', true);
}
else {
$('#profilingTypeFront').prop('checked', true);
}
$('#sqlprofiler .jsDisabledInProgress input').prop('readonly', true).prop('disabled', true);
}
else {
$('#sqlprofiler').removeClass('inprogress');
$('#sqlprofiler .jsDisabledInProgress input').prop('readonly', false).prop('disabled', false);
}
}
function getTemplate(tplId) {
const template = document.querySelector('#' + tplId);
return template.content.cloneNode(true);
}
function getCssClassByPercentage(percentage) {
if (percentage < 5) {
return null;
}
percentage = Math.min(100, Math.max(0, percentage));
const index = Math.floor(percentage / 10);
return `percent-bg-${ (index + 1) * 10 }`;
}
$(document).ready(function () {
$.fn.dataTable.ext.errMode = 'none';
datasRunsTable = initializeRunsTable();
jprestaRefreshProfilingStatus();
$('#startProfiling').on('click', function () {
startProfiling();
});
$('#stopProfiling').on('click', function () {
stopProfiling();
});
$('#deleteAll').on('click', function () {
deleteAllData(datasRunsTable);
});
$('#deleteIrrelevant').on('click', function () {
deleteAllData(datasRunsTable, 1);
});
$('#reloadAll').on('click', function(event) {
reloadDatas();
});
// Add event listener for opening and closing run details
$('#datasRunsTable > tbody').on('click', '> tr.even > td, > tr.odd > td', function () {
let tr = $(this).closest('tr');
let row = datasRunsTable.row( tr );
let open = row.child.isShown();
datasRunsTable.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
if (this.child.isShown()) {
this.child.hide();
if (datasQueriesTable) {
datasQueriesTable.destroy(true);
}
$(this.node()).removeClass('shown');
}
});
// Now open this row
if (!open) {
let datas = row.data();
if (typeof datas !== 'undefined') {
row.child(getTemplate('datasQueriesTableTpl')).show();
datasQueriesTable = initializeQueriesTable(datas[0]);
// Add event listener for opening and closing query details
$('#datasQueriesTable > tbody').on('click', '> tr.even > td, > tr.odd > td', function () {
let tr = $(this).closest('tr');
let row = datasQueriesTable.row( tr );
let open = row.child.isShown();
datasQueriesTable.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
if (this.child.isShown()) {
this.child.hide();
$(this.node()).removeClass('shown');
}
});
// Now open this row
if (!open) {
let datas = row.data();
if (typeof datas !== 'undefined') {
row.child(getTemplate('detailsQueryTpl')).show();
displayQueryAnalysis(datas[0]);
tr.addClass('shown');
}
}
});
tr.addClass('shown');
}
}
});
});
</script>
<div id="sqlprofiler" class="row">
<div class="col-lg-12">
<div class="panel">
<div class="panel-heading">{l s="SQL Profiler" mod=$module_name}</div>
<div class="help">
<h4>{l s="How does it work?" mod=$module_name}</h4>
<p>{l s="This SQL profiler is a tool that helps you identify slow SQL queries, which are often the cause of your shop's sluggish performance on certain pages or actions." mod=$module_name}</p>
<p>{l s="It can analyze all SQL queries in the back office (admin) and in the front office (the shop)." mod=$module_name}</p>
<p>{l s="You can use it on a production server because it has a very low impact on real visitors; it is only enabled in the user's browser (yours) through a cookie." mod=$module_name}</p>
<p>{l s="To use it, simply start the profiling, then navigate to the pages and/or perform the actions you want to analyze. Return here, stop the profiling, and click on queries to understand the slowness." mod=$module_name}</p>
</div>
<div style="margin: 1rem 0;">
<table>
<tr>
<td class="jsDisabledInProgress" style="vertical-align: middle">
{l s='What do you want to analyze?' mod=$module_name}
<div class="form-check">
<input class="form-check-input" type="radio" name="profilingType"
id="profilingTypeFront" value="front" checked>
<label class="form-check-label" for="profilingTypeFront">
{l s='Front office (the shop)' mod=$module_name}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="profilingType"
id="profilingTypeAdmin" value="admin">
<label class="form-check-label" for="profilingTypeAdmin">
{l s='Back office (the admin)' mod=$module_name}
</label>
</div>
</td>
<td style="vertical-align: middle">
<button id="startProfiling" class="btn btn-success jsDisplayStopped"><i
class="material-icons" style="vertical-align: middle">play_arrow</i> {l s='Start profiling' mod=$module_name}
</button>
<button id="stopProfiling" class="btn btn-danger jsDisplayInProgress"><i
class="material-icons stop" style="vertical-align: middle">stop</i> {l s='Stop profiling' mod=$module_name}
</button>
</td>
<td style="vertical-align: middle">
<div class="recording jsDisplayInProgress">
<img src="../modules/{$module_name|escape:'html':'UTF-8'}/views/img/eating.gif" style="float:left;vertical-align: ;margin: 0 0 0 1rem;" width="104" height="68">
<b>{l s='Profiling is in progress for YOU only!' mod=$module_name}</b>
<br/>{l s="Now you should display pages and/or perform actions that you want to analyse" mod=$module_name}
</div>
</td>
</tr>
</table>
</div>
<table id="datasRunsTable" class="display cell-border compact stripe" style="width:100%">
<thead>
<tr class="column-headers">
<th class="tdid">{l s='ID Run' mod=$module_name}</th>
<th class="tddate">{l s='Date' mod=$module_name}</th>
<th>{l s='URL' mod=$module_name}</th>
<th class="tdright">{l s='Query count' mod=$module_name}</th>
<th class="tdright">{l s='Query duration (ms)' mod=$module_name}</th>
</tr>
</thead>
<tbody></tbody>
</table>
<div class="mypanel-footer">
<button type="button" id="reloadAll" class="btn btn-default">
<i class="process-icon-refresh"></i> {l s='Refresh' mod=$module_name}
</button>
<button type="button" id="deleteIrrelevant" class="btn btn-warning">
<i class="process-icon-delete"></i> {l s='Delete irrelevant data' mod=$module_name}
</button>
<button type="button" id="deleteAll" class="btn btn-danger">
<i class="process-icon-delete"></i> {l s='Delete all data' mod=$module_name}
</button>
</div>
</div>
</div>
</div>
<template id="datasQueriesTableTpl">
<div style="margin-bottom: 0.5rem;">
<span style="padding: 1px 8px; background-color: #00ABEC; border: 1px solid #ccc; margin-right: 5px;"></span>
{l s='The blue lines mean that they represent a significant percentage of the time spent querying the database for this request.' mod=$module_name}
</div>
<table id="datasQueriesTable" class="display cell-border compact stripe" style="width:100%;">
<thead>
<tr class="column-headers">
<th class="tdid">{l s='ID Query' mod=$module_name}</th>
<th class="tdcenter">{l s='SQL' mod=$module_name}</th>
<th class="tdright">{l s='Count' mod=$module_name}</th>
<th class="tdright">{l s='Max (ms)' mod=$module_name}</th>
<th class="tdright">{l s='Median (ms)' mod=$module_name}</th>
<th class="tdright">{l s='Average (ms)' mod=$module_name}</th>
<th class="tdright">{l s='Total (ms)' mod=$module_name}</th>
</tr>
</thead>
<tbody></tbody>
</table>
</template>
<template id="detailsQueryTpl">
<div id="queryAnalysis">
<div class="queryLoading"><i class="icon-refresh icon-spin icon-fw"></i> {l s='Query analysis in progress...' mod=$module_name}</div>
</div>
</template>
{/if}

View File

@@ -0,0 +1,24 @@
{*
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*}
<script type="text/javascript">
$( document ).ready(function() {
$('#btn-webp-faq-li').prependTo('.btn-toolbar ul.nav');
});
</script>
<div style="font-size: 1rem; border: 1px solid #3ed2f0; padding: 0.5rem; background-color: #f4f9fb;">
<i class="material-icons mi-help" style="vertical-align: text-top;">help</i>
{l s='If some images are not compressed in WEBP, consult our FAQ which lists the known problems with their solutions' mod='pagecache'}: <a href="{$faq_url|escape:'html':'UTF-8'}" target="_blank" class="btn btn-sm btn-success">{l s='FAQ Webp' mod='pagecache'}</a>
</div>
<ul style="display:none">
<li id="btn-webp-faq-li">
<a id="webp-faq" class="toolbar_btn" href="{$faq_url|escape:'html':'UTF-8'}" target="_blank" style="color:white; background-color: #33bd25">
<i class="process-icon-help" style="color:white;"></i>
<div>{l s='FAQ Webp' mod='pagecache'}</div>
</a>
</li>
</ul>