313 lines
9.6 KiB
PHP
313 lines
9.6 KiB
PHP
<?php
|
|
/**
|
|
* LiteSpeed Cache for Prestashop.
|
|
*
|
|
* NOTICE OF LICENSE
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see https://opensource.org/licenses/GPL-3.0 .
|
|
*
|
|
* @author LiteSpeed Technologies
|
|
* @copyright Copyright (c) 2017-2018 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
|
|
* @license https://opensource.org/licenses/GPL-3.0
|
|
*/
|
|
|
|
use LiteSpeedCacheLog as LSLog;
|
|
use LiteSpeedCacheEsiItem as EsiItem;
|
|
|
|
class LiteSpeedCacheEsiModConf implements JsonSerializable
|
|
{
|
|
// avail types
|
|
const TYPE_BUILTIN = 0;
|
|
|
|
const TYPE_INTEGRATED = 1;
|
|
|
|
const TYPE_CUSTOMIZED = 2;
|
|
|
|
// avail fields
|
|
const FLD_PRIV = 'priv';
|
|
|
|
const FLD_TAG = 'tag';
|
|
|
|
const FLD_TTL = 'ttl';
|
|
|
|
// comma separated purge events
|
|
const FLD_PURGE_EVENTS = 'events';
|
|
|
|
// comma separate controller classes, with :P for POST only
|
|
const FLD_PURGE_CONTROLLERS = 'ctrl';
|
|
|
|
// comma separated list of method, if proceed with "!", meaning not included
|
|
const FLD_HOOK_METHODS = 'methods';
|
|
|
|
// *: all, list of allowed hooks, or not-allowed hooks
|
|
const FLD_RENDER_WIDGETS = 'render';
|
|
|
|
const FLD_ASVAR = 'asvar';
|
|
|
|
const FLD_IGNORE_EMPTY = 'ie';
|
|
|
|
const FLD_ONLY_CACHE_EMPTY = 'ce';
|
|
|
|
const FLD_TIPURL = 'tipurl';
|
|
|
|
private $moduleName;
|
|
|
|
private $type;
|
|
|
|
private $data;
|
|
|
|
private $parsed = array();
|
|
|
|
public function __construct($moduleName, $type, $data)
|
|
{
|
|
$this->moduleName = $moduleName;
|
|
$this->type = $type;
|
|
$this->data = array();
|
|
//sanatize data
|
|
$this->data[self::FLD_PRIV] = $data[self::FLD_PRIV] ? 1 : 0;
|
|
if (isset($data[self::FLD_TAG])) {
|
|
$this->data[self::FLD_TAG] = $data[self::FLD_TAG];
|
|
}
|
|
if (isset($data[self::FLD_TTL])) {
|
|
$this->data[self::FLD_TTL] = $data[self::FLD_TTL];
|
|
}
|
|
if (isset($data[self::FLD_PURGE_EVENTS])) {
|
|
$this->data[self::FLD_PURGE_EVENTS] = $data[self::FLD_PURGE_EVENTS];
|
|
}
|
|
if (isset($data[self::FLD_PURGE_CONTROLLERS])) {
|
|
$this->data[self::FLD_PURGE_CONTROLLERS] = $data[self::FLD_PURGE_CONTROLLERS];
|
|
}
|
|
if (isset($data[self::FLD_HOOK_METHODS])) {
|
|
$this->data[self::FLD_HOOK_METHODS] = $data[self::FLD_HOOK_METHODS];
|
|
}
|
|
if (isset($data[self::FLD_RENDER_WIDGETS])) {
|
|
$this->data[self::FLD_RENDER_WIDGETS] = $data[self::FLD_RENDER_WIDGETS];
|
|
}
|
|
if (isset($data[self::FLD_ASVAR])) {
|
|
$this->data[self::FLD_ASVAR] = $data[self::FLD_ASVAR];
|
|
}
|
|
if (isset($data[self::FLD_IGNORE_EMPTY])) {
|
|
$this->data[self::FLD_IGNORE_EMPTY] = $data[self::FLD_IGNORE_EMPTY];
|
|
}
|
|
if (isset($data[self::FLD_ONLY_CACHE_EMPTY])) {
|
|
$this->data[self::FLD_ONLY_CACHE_EMPTY] = $data[self::FLD_ONLY_CACHE_EMPTY];
|
|
}
|
|
if (isset($data[self::FLD_TIPURL])) {
|
|
$this->data[self::FLD_TIPURL] = $data[self::FLD_TIPURL];
|
|
}
|
|
$this->parseList(self::FLD_RENDER_WIDGETS);
|
|
$this->parseList(self::FLD_HOOK_METHODS);
|
|
}
|
|
|
|
public function getModuleName()
|
|
{
|
|
return $this->moduleName;
|
|
}
|
|
|
|
public function getCustConfArray()
|
|
{
|
|
$cdata = array(
|
|
'id' => $this->moduleName,
|
|
'name' => $this->moduleName,
|
|
'priv' => $this->isPrivate(),
|
|
'ttl' => $this->getTTL(),
|
|
'tag' => $this->getTag(),
|
|
'type' => $this->type,
|
|
'events' => $this->getFieldValue(self::FLD_PURGE_EVENTS, false, true),
|
|
'ctrl' => $this->getFieldValue(self::FLD_PURGE_CONTROLLERS, false, true),
|
|
'methods' => $this->getFieldValue(self::FLD_HOOK_METHODS, false, true),
|
|
'render' => $this->getFieldValue(self::FLD_RENDER_WIDGETS, false, true),
|
|
'asvar' => $this->getFieldValue(self::FLD_ASVAR, true),
|
|
'ie' => $this->getFieldValue(self::FLD_IGNORE_EMPTY, true),
|
|
'ce' => $this->getFieldValue(self::FLD_ONLY_CACHE_EMPTY, true),
|
|
'tipurl' => $this->getFieldValue(self::FLD_TIPURL),
|
|
);
|
|
if ($tmp_instance = Module::getInstanceByName($this->moduleName)) {
|
|
$cdata['name'] = $tmp_instance->displayName;
|
|
}
|
|
|
|
return $cdata;
|
|
}
|
|
|
|
public function jsonSerialize()
|
|
{
|
|
$sdata = $this->data;
|
|
$sdata['id'] = $this->moduleName;
|
|
|
|
return $sdata;
|
|
}
|
|
|
|
public function isPrivate()
|
|
{
|
|
return ($this->data[self::FLD_PRIV] != null);
|
|
}
|
|
|
|
private function getFieldValue($field, $isbool = false, $splitClean = false)
|
|
{
|
|
$value = (isset($this->data[$field])) ? $this->data[$field] : '';
|
|
if ($isbool) {
|
|
$value = ($value) ? true : false;
|
|
}
|
|
if ($splitClean && $value) {
|
|
$dv = preg_split("/[\s,]+/", $value, null, PREG_SPLIT_NO_EMPTY);
|
|
$value = implode(', ', $dv);
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
public function getTTL()
|
|
{
|
|
return isset($this->data[self::FLD_TTL]) ?
|
|
$this->data[self::FLD_TTL] : '';
|
|
}
|
|
|
|
public function getTag()
|
|
{
|
|
if (!empty($this->data[self::FLD_TAG])) {
|
|
return $this->data[self::FLD_TAG];
|
|
} else {
|
|
return $this->moduleName;
|
|
}
|
|
}
|
|
|
|
public function asVar()
|
|
{
|
|
return (isset($this->data[self::FLD_ASVAR]) && $this->data[self::FLD_ASVAR]);
|
|
}
|
|
|
|
public function onlyCacheEmtpy()
|
|
{
|
|
return (isset($this->data[self::FLD_ONLY_CACHE_EMPTY]) && $this->data[self::FLD_ONLY_CACHE_EMPTY]);
|
|
}
|
|
|
|
public function ignoreEmptyContent()
|
|
{
|
|
return (isset($this->data[self::FLD_IGNORE_EMPTY]) && $this->data[self::FLD_IGNORE_EMPTY]);
|
|
}
|
|
|
|
// return array( lowercased classname => 0, 1 )
|
|
public function getPurgeControllers()
|
|
{
|
|
if (empty($this->data[self::FLD_PURGE_CONTROLLERS])) {
|
|
return null;
|
|
}
|
|
$controllers = array();
|
|
$list = preg_split("/[\s,]+/", $this->data[self::FLD_PURGE_CONTROLLERS], null, PREG_SPLIT_NO_EMPTY);
|
|
foreach ($list as $item) {
|
|
// allow ClassName?param1¶m2
|
|
$ct = explode('?', $item);
|
|
if (count($ct) == 1) {
|
|
$controllers[$item] = 0;
|
|
} else {
|
|
$controllers[$ct[0]] = $ct[1];
|
|
}
|
|
}
|
|
|
|
return $controllers;
|
|
}
|
|
|
|
public function getPurgeEvents()
|
|
{
|
|
if (isset($this->data[self::FLD_PURGE_EVENTS])) {
|
|
return preg_split("/[\s,]+/", $this->data[self::FLD_PURGE_EVENTS], null, PREG_SPLIT_NO_EMPTY);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function canInject($params)
|
|
{
|
|
if (empty($params['pt'])) {
|
|
if (_LITESPEED_DEBUG_ >= LSLog::LEVEL_UNEXPECTED) {
|
|
LSLog::log(__FUNCTION__ . ' missing pt', LSLog::LEVEL_UNEXPECTED);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
switch ($params['pt']) {
|
|
case EsiItem::ESI_RENDERWIDGET:
|
|
return $this->checkInjection(self::FLD_RENDER_WIDGETS, $params['h']);
|
|
|
|
case EsiItem::ESI_CALLHOOK:
|
|
return $this->checkInjection(self::FLD_HOOK_METHODS, $params['mt']);
|
|
|
|
case EsiItem::ESI_SMARTYFIELD:
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public function isCustomized()
|
|
{
|
|
return ($this->type == self::TYPE_CUSTOMIZED);
|
|
}
|
|
|
|
private function checkInjection($field, $value)
|
|
{
|
|
$res = $this->parsed[$field];
|
|
$type = $res[0];
|
|
if ($type == 9) { // allow all
|
|
return true;
|
|
}
|
|
$value = Tools::strtolower($value);
|
|
if ($type == 1) {
|
|
return in_array($value, $res[1]); // include
|
|
} elseif ($type == 2) {
|
|
return !in_array($value, $res[2]); // exclude
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// stringData is comma separated list, * for all, ! is not include
|
|
private function parseList($field)
|
|
{
|
|
// $res[0] = -1: none; 9: all; 1: included, 2: excluded
|
|
$res = array();
|
|
if (!isset($this->data[$field])) {
|
|
$res[0] = -1; // none
|
|
} elseif ($this->data[$field] == '*') {
|
|
$res[0] = 9; // all
|
|
} else {
|
|
$list = preg_split("/[\s,]+/", $this->data[$field], null, PREG_SPLIT_NO_EMPTY);
|
|
$isInclude = 0; // included is 1, excluded is 2
|
|
foreach ($list as $d) {
|
|
$d = Tools::strtolower($d);
|
|
if ($d{0} == '!') {
|
|
$isInclude |= 2;
|
|
if (!isset($res[2])) {
|
|
$res[2] = array();
|
|
}
|
|
$res[2][] = ltrim($d, '!');
|
|
} else {
|
|
$isInclude |= 1;
|
|
if (!isset($res[1])) {
|
|
$res[1] = array();
|
|
}
|
|
$res[1][] = $d;
|
|
}
|
|
}
|
|
if (($isInclude & 1) == 1) {
|
|
$res[0] = 1; // if contains included, will only check included
|
|
} elseif (($isInclude & 2) == 2) {
|
|
$res[0] = 2;
|
|
} else {
|
|
$res[0] = -1;
|
|
}
|
|
}
|
|
$this->parsed[$field] = $res;
|
|
}
|
|
}
|