diff --git a/core/action.class.inc.php b/core/action.class.inc.php index 2ff7ee69c..b2d070bb5 100644 --- a/core/action.class.inc.php +++ b/core/action.class.inc.php @@ -566,7 +566,7 @@ class ActionEmail extends ActionNotification // Prefix $sPrefix = sprintf('%s_%s_%d', $sAppName, $sObjClass, $sObjId); if ($sHeaderName === static::ENUM_HEADER_NAME_MESSAGE_ID) { - $sPrefix .= sprintf('_%f', microtime(true /* get as float*/)); + $sPrefix .= sprintf('_%F', microtime(true /* get as float*/)); } // Suffix $sSuffix = sprintf('@%s.openitop.org', MetaModel::GetEnvironmentId()); diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 658774d31..e346f3b6a 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -7503,14 +7503,11 @@ abstract class MetaModel $aSearches = array(); $aReplacements = array(); - foreach ($aParams as $sSearch => $replace) - { + foreach ($aParams as $sSearch => $replace) { // Some environment parameters are objects, we just need scalars - if (is_object($replace)) - { + if (is_object($replace)) { $iPos = strpos($sSearch, '->object()'); - if ($iPos !== false) - { + if ($iPos !== false) { // Expand the parameters for the object $sName = substr($sSearch, 0, $iPos); // Note: Capturing @@ -7518,63 +7515,67 @@ abstract class MetaModel // 2 - The arrow // 3 - The attribute code $aRegExps = array( - '/(\\$)'.$sName.'-(>|>)([^\\$]+)\\$/', // Support both syntaxes: $this->xxx$ or $this->xxx$ for HTML compatibility - '/(%24)'.$sName.'-(>|>)([^%24]+)%24/', // Support for urlencoded in HTML attributes (%20this->xxx%20) - ); - foreach($aRegExps as $sRegExp) - { - if(preg_match_all($sRegExp, $sInput, $aMatches)) - { - foreach($aMatches[3] as $idx => $sPlaceholderAttCode) - { - try - { - $sReplacement = $replace->GetForTemplate($sPlaceholderAttCode); - if($sReplacement !== null) - { - $aReplacements[] = $sReplacement; - $aSearches[] = $aMatches[1][$idx] . $sName . '-' . $aMatches[2][$idx] . $sPlaceholderAttCode . $aMatches[1][$idx]; - } - } - catch(Exception $e) - { - // No replacement will occur - } - } - } - } - } - else - { + '/(\\$)'.$sName.'-(>|>)([^\\$]+)\\$/', // Support both syntaxes: $this->xxx$ or $this->xxx$ for HTML compatibility + '/(%24)'.$sName.'-(>|>)([^%24]+)%24/', // Support for urlencoded in HTML attributes (%20this->xxx%20) + ); + foreach ($aRegExps as $sRegExp) { + if (preg_match_all($sRegExp, $sInput, $aMatches)) { + foreach ($aMatches[3] as $idx => $sPlaceholderAttCode) { + try { + $sReplacement = $replace->GetForTemplate($sPlaceholderAttCode); + if ($sReplacement !== null) { + $aReplacements[] = $sReplacement; + $aSearches[] = $aMatches[1][$idx].$sName.'-'.$aMatches[2][$idx].$sPlaceholderAttCode.$aMatches[1][$idx]; + } + } + catch (Exception $e) { + $aContext = [ + 'placeholder' => $sPlaceholderAttCode, + 'replace class' => get_class($replace), + ]; + if ($replace instanceof DBObject) { + $aContext['replace id'] = $replace->GetKey(); + } + IssueLog::Debug( + 'Invalid placeholder in notification, no replacement will occur!', + LogChannels::NOTIFICATION, + $aContext + ); + } + } + } + } + } else { continue; // Ignore this non-scalar value } - } - else - { + } else { $aRegExps = array( '/(\$)'.$sSearch.'\$/', // Support for regular placeholders (eg. $APP_URL$) '/(%24)'.$sSearch.'%24/', // Support for urlencoded in HTML attributes (eg. %24APP_URL%24) ); - foreach($aRegExps as $sRegExp) - { - if(preg_match_all($sRegExp, $sInput, $aMatches)) - { - foreach($aMatches[1] as $idx => $sDelimiter) - { - try - { - $aReplacements[] = (string) $replace; - $aSearches[] = $aMatches[1][$idx] . $sSearch . $aMatches[1][$idx]; + foreach ($aRegExps as $sRegExp) { + if (preg_match_all($sRegExp, $sInput, $aMatches)) { + foreach ($aMatches[1] as $idx => $sDelimiter) { + try { + $aReplacements[] = (string)$replace; + $aSearches[] = $aMatches[1][$idx].$sSearch.$aMatches[1][$idx]; } - catch(Exception $e) - { - // No replacement will occur + catch (Exception $e) { + IssueLog::Debug( + 'Invalid placeholder in notification, no replacement will occur !', + LogChannels::NOTIFICATION, + [ + 'placeholder' => $sPlaceholderAttCode, + 'replace' => $replace, + ] + ); } } } } } } + return str_replace($aSearches, $aReplacements, $sInput); }