mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-11-22 18:09:06 +01:00
Compare commits
2 commits
000222ae89
...
6cfde7f084
Author | SHA1 | Date | |
---|---|---|---|
|
6cfde7f084 | ||
|
ee69cc302c |
7 changed files with 72 additions and 189 deletions
|
@ -6,8 +6,6 @@ Cette section décrit le tableau de configuration de la journalisation de l'appl
|
||||||
$GLOBALS['LSlog'] = array(
|
$GLOBALS['LSlog'] = array(
|
||||||
'enable' => [booléen],
|
'enable' => [booléen],
|
||||||
'level' => '[niveau]',
|
'level' => '[niveau]',
|
||||||
'log_errors_context' => [booléen],
|
|
||||||
'log_errors_context_with_args' => [booléen],
|
|
||||||
'handlers' => array(
|
'handlers' => array(
|
||||||
'[handler 1]',
|
'[handler 1]',
|
||||||
array (
|
array (
|
||||||
|
@ -55,17 +53,6 @@ $GLOBALS['LSlog'] = array(
|
||||||
- `ERROR`
|
- `ERROR`
|
||||||
- `FATAL`
|
- `FATAL`
|
||||||
|
|
||||||
- `log_errors_context`
|
|
||||||
|
|
||||||
Booléen permatant de définir si le contexte _(=backtrace)_ doit être inclus lors de la
|
|
||||||
journalisation d'une erreurs.
|
|
||||||
|
|
||||||
- `log_errors_context_with_args`
|
|
||||||
|
|
||||||
Booléen permatant de définir si les arguments des méthodes/fonctions appelées doivent être
|
|
||||||
inclus lors de la journalisation du contexte des erreurs.
|
|
||||||
__Note :__ ce paramètre n'as aucun effet si le paramètre `log_errors_context` n'est pas activé.
|
|
||||||
|
|
||||||
- `handlers`
|
- `handlers`
|
||||||
|
|
||||||
Tableau permettant de configurer les *handlers* de la journalisation. Chaque *handler* gère les
|
Tableau permettant de configurer les *handlers* de la journalisation. Chaque *handler* gère les
|
||||||
|
|
|
@ -204,77 +204,60 @@ define('LS_CSS_DIR', 'css');
|
||||||
define('LSdebug',false);
|
define('LSdebug',false);
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
$GLOBALS['LSlog'] = array (
|
$GLOBALS['LSlog']['handlers'] = array (
|
||||||
// Enable/disable logs
|
array (
|
||||||
'enable' => true,
|
'handler' => 'file',
|
||||||
|
'path' => 'tmp/LS.log',
|
||||||
// Global logs level (TRACE, DEBUG, INFO, WARNING, ERROR, FATAL)
|
//'level' => 'DEBUG',
|
||||||
'level' => 'INFO',
|
//'enabled' => false, // Uncomment to disable this handler
|
||||||
|
// Filter on specific loggers
|
||||||
// Log errors's context (=backtrace)
|
//'loggers' => array('LSurl', 'LSlang'),
|
||||||
'log_errors_context' => true,
|
'excluded_loggers' => array('generate_lang_file', 'generate_ldapsaisie_pot'),
|
||||||
|
// Default formats
|
||||||
// Log errors's context with arguments of called method/functions
|
//'format' => '%{requesturi} - %{remoteaddr} - %{ldapservername} - %{authuser} - %{level} - %{message}',
|
||||||
'log_errors_context_with_args' => false,
|
//'cli_format' => '%{clibinpath} - %{level} - %{message}',
|
||||||
|
//'datetime_prefix' => true, // Prefix message with datetime ?
|
||||||
/**
|
//'datetime_format' => 'Y/m/d H:i:s', // Datetime prefix format (see php date() function)
|
||||||
* Logs handlers are components that logged message emitted by the application.
|
|
||||||
* Each handlers handle emitted message as its own way (storing it in file/database, send it via
|
|
||||||
* email or to an external backend, ...).
|
|
||||||
*/
|
|
||||||
'handlers' => array (
|
|
||||||
array(
|
|
||||||
'handler' => 'file',
|
|
||||||
'path' => 'tmp/LS.log',
|
|
||||||
//'level' => 'DEBUG',
|
|
||||||
//'enabled' => false, // Uncomment to disable this handler
|
|
||||||
// Filter on specific loggers
|
|
||||||
//'loggers' => array('LSurl', 'LSlang'),
|
|
||||||
'excluded_loggers' => array('generate_lang_file', 'generate_ldapsaisie_pot'),
|
|
||||||
// Default formats
|
|
||||||
//'format' => '%{requesturi} - %{remoteaddr} - %{ldapservername} - %{authuser} - %{level} - %{message}',
|
|
||||||
//'cli_format' => '%{clibinpath} - %{level} - %{message}',
|
|
||||||
//'datetime_prefix' => true, // Prefix message with datetime ?
|
|
||||||
//'datetime_format' => 'Y/m/d H:i:s', // Datetime prefix format (see php date() function)
|
|
||||||
),
|
|
||||||
array (
|
|
||||||
'handler' => 'email', // Email handler (each logged message generated an email)
|
|
||||||
'level' => 'FATAL',
|
|
||||||
'recipient' => 'root@localhost', // Email recipient
|
|
||||||
),
|
|
||||||
/*
|
|
||||||
array (
|
|
||||||
'handler' => 'syslog', // Syslog handler
|
|
||||||
//'priority' => 'WARNING', // Force priority : EMERG, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG
|
|
||||||
),
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
array (
|
|
||||||
'handler' => 'system', // System logging (using PHP error_log)
|
|
||||||
'level' => 'ERROR',
|
|
||||||
),
|
|
||||||
*/
|
|
||||||
),
|
),
|
||||||
|
array (
|
||||||
|
'handler' => 'email', // Email handler (each logged message generated an email)
|
||||||
|
'level' => 'FATAL',
|
||||||
|
'recipient' => 'root@localhost', // Email recipient
|
||||||
|
),
|
||||||
|
/*
|
||||||
|
array (
|
||||||
|
'handler' => 'syslog', // Syslog handler
|
||||||
|
//'priority' => 'WARNING', // Force priority : EMERG, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
array (
|
||||||
|
'handler' => 'system', // System logging (using PHP error_log)
|
||||||
|
'level' => 'ERROR',
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
);
|
||||||
|
$GLOBALS['LSlog']['loggers'] = array (
|
||||||
/**
|
/**
|
||||||
* Loggers permit to define different log parameters for specific components
|
* Loggers permit to define different log parameters for specific components
|
||||||
* of LdapSaisie (a class, an addon, ...). You could :
|
* of LdapSaisie (a class, an addon, ...). You could :
|
||||||
* - Enabled/disabled logs for this component with 'enabled' parameter
|
* - Enabled/disabled logs for this component with 'enabled' parameter
|
||||||
* - Set a specific log level for this component with 'enabled' parameter
|
* - Set a specific log level for this component with 'enabled' parameter
|
||||||
**/
|
**/
|
||||||
"loggers" => array(
|
/*
|
||||||
/*
|
'LSurl' => array (
|
||||||
'LSurl' => array (
|
'level' => 'DEBUG',
|
||||||
'level' => 'DEBUG',
|
|
||||||
),
|
|
||||||
'LSldap' => array (
|
|
||||||
'level' => 'DEBUG',
|
|
||||||
),
|
|
||||||
'LSlang' => array (
|
|
||||||
'enabled' => false,
|
|
||||||
),
|
|
||||||
*/
|
|
||||||
),
|
),
|
||||||
|
'LSldap' => array (
|
||||||
|
'level' => 'DEBUG',
|
||||||
|
),
|
||||||
|
'LSlang' => array (
|
||||||
|
'enabled' => false,
|
||||||
|
),
|
||||||
|
*/
|
||||||
);
|
);
|
||||||
|
$GLOBALS['LSlog']['level'] = 'INFO'; // TRACE, DEBUG, INFO, WARNING, ERROR, FATAL
|
||||||
|
$GLOBALS['LSlog']['enable'] = true;
|
||||||
|
|
||||||
define('NB_LSOBJECT_LIST',30);
|
define('NB_LSOBJECT_LIST',30);
|
||||||
define('NB_LSOBJECT_LIST_SELECT',20);
|
define('NB_LSOBJECT_LIST_SELECT',20);
|
||||||
|
|
|
@ -234,12 +234,6 @@ class LSattr_html_select_object extends LSattr_html{
|
||||||
|
|
||||||
// Compute search params based on value attribute type (DN or attribute valued) and $fromDNs
|
// Compute search params based on value attribute type (DN or attribute valued) and $fromDNs
|
||||||
if($fromDNs || in_array($conf['value_attribute'], ['dn', '%{dn}'])) {
|
if($fromDNs || in_array($conf['value_attribute'], ['dn', '%{dn}'])) {
|
||||||
if (!checkDn($value)) {
|
|
||||||
self :: log_warning(
|
|
||||||
"getFormValues(): value '$value' is not a valid DN, pass"
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($conf['onlyAccessible'] && !LSsession :: canAccess($conf['object_type'], $value)) {
|
if ($conf['onlyAccessible'] && !LSsession :: canAccess($conf['object_type'], $value)) {
|
||||||
self :: log_debug(
|
self :: log_debug(
|
||||||
"getFormValues(): object {$conf['object_type']} '$value' is not accessible, pass"
|
"getFormValues(): object {$conf['object_type']} '$value' is not accessible, pass"
|
||||||
|
@ -326,12 +320,12 @@ class LSattr_html_select_object extends LSattr_html{
|
||||||
if ($retrieveAttrValues) {
|
if ($retrieveAttrValues) {
|
||||||
// Retrieve attribute value case: $selected_objects[dn] = attribute value
|
// Retrieve attribute value case: $selected_objects[dn] = attribute value
|
||||||
if(($conf['value_attribute']=='dn') || ($conf['value_attribute']=='%{dn}')) {
|
if(($conf['value_attribute']=='dn') || ($conf['value_attribute']=='%{dn}')) {
|
||||||
$selected_objects[$entry->dn] = $entry->dn;
|
$selected_objects[$value] = $entry->dn;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$val = ensureIsArray($entry -> get($conf['value_attribute']));
|
$val = ensureIsArray($entry -> get($conf['value_attribute']));
|
||||||
if (!empty($val)) {
|
if (!empty($val)) {
|
||||||
$selected_objects[$entry->dn] = $val[0];
|
$selected_objects[$value] = $val[0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LSerror :: addErrorCode(
|
LSerror :: addErrorCode(
|
||||||
|
@ -346,13 +340,13 @@ class LSattr_html_select_object extends LSattr_html{
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// General case: $selected_objects[dn] = array(name + object_type)
|
// General case: $selected_objects[dn] = array(name + object_type)
|
||||||
$selected_objects[$entry->dn] = array(
|
$selected_objects[$value] = array(
|
||||||
'name' => $entry -> displayName,
|
'name' => $entry -> displayName,
|
||||||
'object_type' => $conf['object_type'],
|
'object_type' => $conf['object_type'],
|
||||||
);
|
);
|
||||||
self :: log_debug(
|
self :: log_debug(
|
||||||
"getFormValues(): object {$conf['object_type']} info for value '$value': ".
|
"getFormValues(): object {$conf['object_type']} info for value '$value': ".
|
||||||
varDump($selected_objects[$entry->dn])
|
varDump($selected_objects[$value])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,7 +357,7 @@ class LSattr_html_select_object extends LSattr_html{
|
||||||
return array_values($selected_objects);
|
return array_values($selected_objects);
|
||||||
|
|
||||||
// General case
|
// General case
|
||||||
$this -> unrecognizedValues = array_diff($values, array_keys($found_values));
|
$this -> unrecognizedValues = array_diff($values, array_keys($selected_objects));
|
||||||
self :: log_debug("getFormValues(): unrecognizedValues=".varDump($this -> unrecognizedValues));
|
self :: log_debug("getFormValues(): unrecognizedValues=".varDump($this -> unrecognizedValues));
|
||||||
self :: log_debug("getFormValues(): final values=".varDump($selected_objects));
|
self :: log_debug("getFormValues(): final values=".varDump($selected_objects));
|
||||||
return $selected_objects;
|
return $selected_objects;
|
||||||
|
|
|
@ -33,18 +33,6 @@ class LSlog {
|
||||||
*/
|
*/
|
||||||
private static $enabled = false;
|
private static $enabled = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Log errors context
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private static $log_errors_context = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log errors context with arguments
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private static $log_errors_context_with_args = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configured handlers
|
* Configured handlers
|
||||||
* @see self::start()
|
* @see self::start()
|
||||||
|
@ -103,8 +91,6 @@ class LSlog {
|
||||||
public static function start() {
|
public static function start() {
|
||||||
// Load configuration
|
// Load configuration
|
||||||
self :: $enabled = self :: getConfig('enable', false, 'bool');
|
self :: $enabled = self :: getConfig('enable', false, 'bool');
|
||||||
self :: $log_errors_context = self :: getConfig('log_errors_context', false, 'bool');
|
|
||||||
self :: $log_errors_context_with_args = self :: getConfig('log_errors_context_with_args', false, 'bool');
|
|
||||||
self :: setLevel();
|
self :: setLevel();
|
||||||
|
|
||||||
// Load default handlers class
|
// Load default handlers class
|
||||||
|
@ -266,13 +252,6 @@ class LSlog {
|
||||||
$message = varDump($message);
|
$message = varDump($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append context to message (if enabled)
|
|
||||||
if (self :: $log_errors_context && self :: checkLevel($level, "ERROR"))
|
|
||||||
$message .= "\n".self :: get_debug_backtrace_context(
|
|
||||||
self :: $log_errors_context_with_args,
|
|
||||||
2
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach (self :: $handlers as $handler) {
|
foreach (self :: $handlers as $handler) {
|
||||||
// Check handler level
|
// Check handler level
|
||||||
if (!$handler -> checkLevel($level))
|
if (!$handler -> checkLevel($level))
|
||||||
|
@ -331,34 +310,25 @@ class LSlog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate current context backtrace
|
* Generate current context backtrace
|
||||||
* @param bool $with_args Add args (optional, default: false)
|
*
|
||||||
* @param int|null $ignore_last_frames Ignore last frames (optional, default: 1)
|
|
||||||
* @return string Current context backtrace
|
* @return string Current context backtrace
|
||||||
**/
|
**/
|
||||||
public static function get_debug_backtrace_context($with_args=false, $ignore_last_frames=null) {
|
public static function get_debug_backtrace_context() {
|
||||||
$traces = debug_backtrace();
|
$traces = debug_backtrace();
|
||||||
if (!is_array($traces) || count($traces) < 2)
|
if (!is_array($traces) || count($traces) < 2)
|
||||||
return "unknown context";
|
return "unknown context";
|
||||||
|
|
||||||
$msg = array();
|
$msg = array();
|
||||||
$j=0;
|
$j=0;
|
||||||
for ($i=count($traces)-1; $i >= (is_int($ignore_last_frames)?$ignore_last_frames:1); $i--) {
|
for ($i=count($traces)-1; $i >= 1; $i--) {
|
||||||
$j += 1;
|
$j += 1;
|
||||||
$trace = array("#$j");
|
$trace = array("#$j");
|
||||||
if (isset($traces[$i]['file']))
|
if (isset($traces[$i]['file']))
|
||||||
$trace[] = $traces[$i]['file'].(isset($traces[$i]['line'])?":".$traces[$i]['line']:"");
|
$trace[] = $traces[$i]['file'].(isset($traces[$i]['line'])?":".$traces[$i]['line']:"");
|
||||||
$args = (
|
|
||||||
$with_args && isset($traces[$i]["args"])?
|
|
||||||
format_callable_args($traces[$i]["args"]):
|
|
||||||
""
|
|
||||||
);
|
|
||||||
if (isset($traces[$i]['class']) && isset($traces[$i]['function']))
|
if (isset($traces[$i]['class']) && isset($traces[$i]['function']))
|
||||||
$trace[] = sprintf(
|
$trace[] = $traces[$i]['class'] . " " . $traces[$i]['type'] . " " . $traces[$i]['function']. "()";
|
||||||
"%s %s %s(%s)",
|
|
||||||
$traces[$i]['class'], $traces[$i]['type'], $traces[$i]['function'], $args
|
|
||||||
);
|
|
||||||
elseif (isset($traces[$i]['function']))
|
elseif (isset($traces[$i]['function']))
|
||||||
$trace[] = sprintf("%s(%s)", $traces[$i]['function'], $args);
|
$trace[] = $traces[$i]['function']. "()";
|
||||||
$msg[] = implode(" - ", $trace);
|
$msg[] = implode(" - ", $trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,24 +192,13 @@ class LSurl extends LSlog_staticLoggerClass {
|
||||||
$public_root_url = LSconfig :: get('public_root_url', '/', 'string');
|
$public_root_url = LSconfig :: get('public_root_url', '/', 'string');
|
||||||
|
|
||||||
if ($absolute && $public_root_url[0] == '/') {
|
if ($absolute && $public_root_url[0] == '/') {
|
||||||
self :: log_debug(
|
self :: log_debug("LSurl :: public_root_url(absolute=true): configured public root URL is relative ($public_root_url) => try to detect it from current request infos.");
|
||||||
"LSurl :: public_root_url(absolute=true): configured public root URL is relative ".
|
$public_root_url = 'http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'?'s':'').'://'.$_SERVER['HTTP_HOST'].$public_root_url;
|
||||||
"($public_root_url) => try to detect it from current request infos."
|
self :: log_debug("LSurl :: public_root_url(absolute=true): detected public absolute root URL: $public_root_url");
|
||||||
);
|
|
||||||
$public_root_url = sprintf(
|
|
||||||
"http%s://%s%s",
|
|
||||||
isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'?'s':'',
|
|
||||||
$_SERVER['HTTP_HOST'],
|
|
||||||
$public_root_url
|
|
||||||
);
|
|
||||||
self :: log_debug(
|
|
||||||
"LSurl :: public_root_url(absolute=true): detected public absolute root URL: ".
|
|
||||||
$public_root_url
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($relative_url) {
|
if ($relative_url) {
|
||||||
if ($public_root_url[-1] != '/') $public_root_url .= "/";
|
if ($public_root_url[0] == '/') $public_root_url .= "/";
|
||||||
return $public_root_url.$relative_url;
|
return $public_root_url.$relative_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,15 +329,6 @@ function LSdebugDefined() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check specified value is a valid DN
|
|
||||||
* @param mixed $dn
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
function checkDn($dn) {
|
|
||||||
return is_string($dn) && boolval(@ldap_explode_dn($dn, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie la compatibilite des DN
|
* Vérifie la compatibilite des DN
|
||||||
*
|
*
|
||||||
|
@ -746,45 +737,20 @@ function dumpFile($file_path, $mime_type=null, $max_age=3600, $force_download=fa
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a callable object for logging
|
* Format a callable object for logging
|
||||||
* @param string|array|\ReflectionMethod|\ReflectionFunction $callable The callable object
|
* @param callable $callable The callable object
|
||||||
* @param null|array<int,mixed> $args Optional argument(s)
|
|
||||||
* @return string The callable object string representation
|
* @return string The callable object string representation
|
||||||
*/
|
*/
|
||||||
function format_callable($callable, $args=null) {
|
function format_callable($callable) {
|
||||||
$formatted_args = format_callable_args($args);
|
|
||||||
if (is_string($callable))
|
if (is_string($callable))
|
||||||
return $callable."($formatted_args)";
|
return $callable."()";
|
||||||
if (is_array($callable))
|
if (is_array($callable) && count($callable)==2)
|
||||||
if (is_string($callable[0]))
|
if (is_string($callable[0]))
|
||||||
return $callable[0]."::".$callable[1]."($formatted_args)";
|
return $callable[0]."::".$callable[1]."()";
|
||||||
elseif (is_object($callable[0]))
|
elseif (is_object($callable[0]))
|
||||||
return get_class($callable[0])."->".$callable[1]."($formatted_args)";
|
return get_class($callable[0])."->".$callable[1]."()";
|
||||||
else
|
else
|
||||||
return "Unknown->".$callable[1]."($formatted_args)";
|
return "Unkown->".$callable[1]."()";
|
||||||
if ($callable instanceof \ReflectionFunction)
|
return varDump($callable);
|
||||||
return sprintf("%s(%s)", $callable->name, $formatted_args);
|
|
||||||
if ($callable instanceof \ReflectionMethod)
|
|
||||||
return sprintf(
|
|
||||||
"%s::%s(%s)",
|
|
||||||
$callable->class,
|
|
||||||
$callable->name,
|
|
||||||
$formatted_args
|
|
||||||
);
|
|
||||||
return sprintf("%s(%s)", varDump($callable), $formatted_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format callable arguments for logging
|
|
||||||
* @param array<mixed> $args Arguments
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function format_callable_args($args) {
|
|
||||||
if (!is_array($args) || empty($args))
|
|
||||||
return "";
|
|
||||||
$formatted_args = [];
|
|
||||||
foreach($args as $arg)
|
|
||||||
$formatted_args[] = str_replace("\n", '\n', var_export($arg, true));
|
|
||||||
return implode(", ", $formatted_args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_empty($val) {
|
function is_empty($val) {
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
{if $dn}
|
{if $dn}
|
||||||
<a class='LSformElement_select_object'
|
<a href='object/{$info.object_type|escape:"url"}/{$dn|escape:'url'}' class='LSformElement_select_object'>{$info.name|escape:"htmlall"}</a>
|
||||||
href='object/{$info.object_type|escape:"url"}/{$dn|escape:'url'}'>
|
{if !$freeze}<input type='hidden' class='LSformElement_select_object' name='{$attr_name|escape:"htmlall"}[]' value='{$dn|escape:"htmlall"}' data-object-type='{$info.object_type|escape:'quotes'}'/>{/if}
|
||||||
{$info.name|escape:"htmlall"}
|
|
||||||
</a>
|
|
||||||
{if !$freeze}
|
|
||||||
<input class='LSformElement_select_object' name='{$attr_name|escape:"htmlall"}[]' type='hidden'
|
|
||||||
value='{$dn|escape:"htmlall"}' data-object-type='{$info.object_type|escape:'quotes'}'/>
|
|
||||||
{/if}
|
|
||||||
{else}
|
{else}
|
||||||
{$noValueTxt|escape:"htmlall"}
|
{$noValueTxt|escape:"htmlall"}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Reference in a new issue