| 1 |
<?php |
| 2 |
|
| 3 |
use AcyMailing\Classes\UserClass; |
| 4 |
|
| 5 |
trait ManagetextInsertion |
| 6 |
{ |
| 7 |
private array $noIfStatementTags = []; |
| 8 |
|
| 9 |
public function replaceContent(object &$email): void |
| 10 |
{ |
| 11 |
$this->replaceRandom($email); |
| 12 |
$this->handleAnchors($email); |
| 13 |
$this->fixPicturesOutlook($email); |
| 14 |
} |
| 15 |
|
| 16 |
public function replaceUserInformation(object &$email, ?object &$user, bool $send = true): void |
| 17 |
{ |
| 18 |
$this->pluginHelper->cleanHtml($email->body); |
| 19 |
$this->pluginHelper->replaceVideos($email->body); |
| 20 |
|
| 21 |
$this->removeText($email); |
| 22 |
$this->ifStatement($email, $user); |
| 23 |
$this->replaceConstant($email, $user); |
| 24 |
} |
| 25 |
|
| 26 |
private function replaceConstant(&$email, $user) |
| 27 |
{ |
| 28 |
$tags = $this->pluginHelper->extractTags($email, '(?:const|trans|config)'); |
| 29 |
if (empty($tags)) { |
| 30 |
return; |
| 31 |
} |
| 32 |
|
| 33 |
$tagsReplaced = []; |
| 34 |
foreach ($tags as $i => $oneTag) { |
| 35 |
$val = ''; |
| 36 |
$arrayVal = []; |
| 37 |
foreach ($oneTag as $valname => $oneValue) { |
| 38 |
if ($valname == 'id') { |
| 39 |
$val = trim(strip_tags($oneValue)); |
| 40 |
} elseif ($valname != 'default') { |
| 41 |
$arrayVal[] = '{'.$valname.'}'; |
| 42 |
} |
| 43 |
} |
| 44 |
|
| 45 |
if (empty($val)) { |
| 46 |
continue; |
| 47 |
} |
| 48 |
$tagValues = explode(':', $i); |
| 49 |
$type = ltrim($tagValues[0], '{'); |
| 50 |
if ($type === 'const') { |
| 51 |
$tagsReplaced[$i] = defined($val) ? constant($val) : 'Constant not defined : '.$val; |
| 52 |
} elseif ($type === 'config') { |
| 53 |
if ($val === 'sitename') { |
| 54 |
$tagsReplaced[$i] = acym_getCMSConfig($val); |
| 55 |
} |
| 56 |
} else { |
| 57 |
if (!empty($user->language)) { |
| 58 |
$language = $user->language; |
| 59 |
} elseif (!empty($email->language)) { |
| 60 |
$language = $email->language; |
| 61 |
} else { |
| 62 |
$language = acym_getLanguageTag(); |
| 63 |
} |
| 64 |
|
| 65 |
$previousLanguage = acym_setLanguage($language); |
| 66 |
acym_loadLanguage($language); |
| 67 |
|
| 68 |
static $done = false; |
| 69 |
if (!$done && strpos($val, 'COM_USERS') !== false) { |
| 70 |
$done = true; |
| 71 |
|
| 72 |
acym_loadLanguageFile('com_users'); |
| 73 |
} |
| 74 |
if (!empty($arrayVal)) { |
| 75 |
$translation = acym_translation($val); |
| 76 |
$paramsIncluded = vsprintf($translation, $arrayVal); |
| 77 |
if ($translation === $paramsIncluded) { |
| 78 |
$translation = preg_replace( |
| 79 |
'/\{[A-Z_]+\}/', |
| 80 |
'%s', |
| 81 |
$translation |
| 82 |
); |
| 83 |
$paramsIncluded = vsprintf($translation, $arrayVal); |
| 84 |
} |
| 85 |
$tagsReplaced[$i] = nl2br($paramsIncluded); |
| 86 |
} else { |
| 87 |
$tagsReplaced[$i] = acym_translation($val); |
| 88 |
} |
| 89 |
|
| 90 |
if (empty($previousLanguage)) $previousLanguage = acym_getLanguageTag(); |
| 91 |
acym_setLanguage($previousLanguage); |
| 92 |
acym_loadLanguage($previousLanguage); |
| 93 |
} |
| 94 |
} |
| 95 |
|
| 96 |
$this->pluginHelper->replaceTags($email, $tagsReplaced, true); |
| 97 |
} |
| 98 |
|
| 99 |
private function replaceRandom(&$email) |
| 100 |
{ |
| 101 |
$randTag = $this->pluginHelper->extractTags($email, 'rand'); |
| 102 |
if (empty($randTag)) { |
| 103 |
return; |
| 104 |
} |
| 105 |
foreach ($randTag as $oneRandTag) { |
| 106 |
$results[$oneRandTag->id] = explode(';', $oneRandTag->id); |
| 107 |
$randNumber = rand(0, count($results[$oneRandTag->id]) - 1); |
| 108 |
$results[$oneRandTag->id][count($results[$oneRandTag->id])] = $results[$oneRandTag->id][$randNumber]; |
| 109 |
} |
| 110 |
|
| 111 |
$tags = []; |
| 112 |
foreach (array_keys($results) as $oneResult) { |
| 113 |
$tags['{rand:'.$oneResult.'}'] = end($results[$oneResult]); |
| 114 |
} |
| 115 |
|
| 116 |
if (empty($tags)) { |
| 117 |
return; |
| 118 |
} |
| 119 |
$this->pluginHelper->replaceTags($email, $tags, true); |
| 120 |
} |
| 121 |
|
| 122 |
private function ifStatement(&$email, $user, $loop = 1) |
| 123 |
{ |
| 124 |
if (empty($email->id) || isset($this->noIfStatementTags[$email->id])) { |
| 125 |
return; |
| 126 |
} |
| 127 |
|
| 128 |
$isAdmin = acym_isAdmin(); |
| 129 |
|
| 130 |
if ($loop > 3) { |
| 131 |
if ($isAdmin) { |
| 132 |
acym_display('You cannot have more than 3 nested {if} tags.', 'warning'); |
| 133 |
} |
| 134 |
|
| 135 |
return; |
| 136 |
} |
| 137 |
|
| 138 |
$match = '#{if:(((?!{if).)*)}(((?!{if).)*){/if}#Uis'; |
| 139 |
$variables = ['subject', 'body', 'altbody', 'From', 'FromName', 'ReplyTo']; |
| 140 |
$found = false; |
| 141 |
$results = []; |
| 142 |
foreach ($variables as $var) { |
| 143 |
if (empty($email->$var)) continue; |
| 144 |
|
| 145 |
if (is_array($email->$var)) { |
| 146 |
foreach ($email->$var as $i => &$arrayField) { |
| 147 |
if (empty($arrayField) || !is_array($arrayField)) continue; |
| 148 |
|
| 149 |
foreach ($arrayField as $key => &$oneval) { |
| 150 |
$found = preg_match_all($match, $oneval, $results[$var.$i.'-'.$key]) || $found; |
| 151 |
if (empty($results[$var.$i.'-'.$key][0])) unset($results[$var.$i.'-'.$key]); |
| 152 |
} |
| 153 |
} |
| 154 |
} else { |
| 155 |
$found = preg_match_all($match, $email->$var, $results[$var]) || $found; |
| 156 |
if (empty($results[$var][0])) unset($results[$var]); |
| 157 |
} |
| 158 |
} |
| 159 |
|
| 160 |
if (!$found) { |
| 161 |
if ($loop == 1) { |
| 162 |
$this->noIfStatementTags[$email->id] = true; |
| 163 |
} |
| 164 |
|
| 165 |
return; |
| 166 |
} |
| 167 |
|
| 168 |
static $alreadyHandled = false; |
| 169 |
|
| 170 |
$userClass = new UserClass(); |
| 171 |
if (!empty($user->id)) { |
| 172 |
$acymUser = $userClass->getOneByIdWithCustomFields($user->id); |
| 173 |
} |
| 174 |
$tags = []; |
| 175 |
foreach ($results as $allresults) { |
| 176 |
foreach ($allresults[0] as $i => $oneTag) { |
| 177 |
if (empty($user->id)) { |
| 178 |
$tags[$oneTag] = ''; |
| 179 |
continue; |
| 180 |
} |
| 181 |
|
| 182 |
if (isset($tags[$oneTag])) { |
| 183 |
continue; |
| 184 |
} |
| 185 |
$allresults[1][$i] = html_entity_decode($allresults[1][$i]); |
| 186 |
if ( |
| 187 |
!preg_match('#^(.+)(!=|<|>|>|<|!~)([^=!<>~]+)$#is', $allresults[1][$i], $operators) |
| 188 |
&& !preg_match('#^(.+)(=|~)([^=!<>~]+)$#is', $allresults[1][$i], $operators) |
| 189 |
) { |
| 190 |
if ($isAdmin) { |
| 191 |
acym_enqueueMessage(acym_translationSprintf('ACYM_OPERATION_NOT_FOUND', $allresults[1][$i]), 'error'); |
| 192 |
} |
| 193 |
$tags[$oneTag] = $allresults[3][$i]; |
| 194 |
continue; |
| 195 |
} |
| 196 |
$field = trim($operators[1]); |
| 197 |
$prop = ''; |
| 198 |
|
| 199 |
$operatorsParts = explode('.', $operators[1]); |
| 200 |
$type = 'acym'; |
| 201 |
if (count($operatorsParts) > 1 && in_array($operatorsParts[0], ['acym', 'joomla', 'var'])) { |
| 202 |
$type = $operatorsParts[0]; |
| 203 |
unset($operatorsParts[0]); |
| 204 |
$field = implode('.', $operatorsParts); |
| 205 |
} |
| 206 |
|
| 207 |
if ($type === 'joomla') { |
| 208 |
if (!empty($user->userid)) { |
| 209 |
if ($field === 'gid') { |
| 210 |
$prop = implode(';', acym_loadResultArray('SELECT group_id FROM #__user_usergroup_map WHERE user_id = '.intval($user->userid))); |
| 211 |
} else { |
| 212 |
$juser = acym_loadObject('SELECT * FROM #__users WHERE id = '.intval($user->userid)); |
| 213 |
if (isset($juser->{$field})) { |
| 214 |
$prop = strtolower($juser->{$field}); |
| 215 |
} else { |
| 216 |
if ($isAdmin && !$alreadyHandled) { |
| 217 |
acym_enqueueMessage('User variable not set: '.$field.' in '.$allresults[1][$i], 'error'); |
| 218 |
} |
| 219 |
$alreadyHandled = true; |
| 220 |
} |
| 221 |
} |
| 222 |
} |
| 223 |
} elseif ($type === 'var') { |
| 224 |
$prop = strtolower($field); |
| 225 |
} else { |
| 226 |
if (!isset($acymUser[$field])) { |
| 227 |
if ($isAdmin && !$alreadyHandled) { |
| 228 |
acym_enqueueMessage('User variable not set: '.$field.' in '.$allresults[1][$i], 'error'); |
| 229 |
} |
| 230 |
$alreadyHandled = true; |
| 231 |
} else { |
| 232 |
$prop = strtolower($acymUser[$field]); |
| 233 |
} |
| 234 |
} |
| 235 |
|
| 236 |
$tags[$oneTag] = ''; |
| 237 |
$val = strtolower(trim($operators[3])); |
| 238 |
$prop = strip_tags($prop); |
| 239 |
if ($operators[2] === '=' && ($prop == $val || in_array($prop, explode(';', $val)) || in_array($val, explode(';', $prop)))) { |
| 240 |
$tags[$oneTag] = $allresults[3][$i]; |
| 241 |
} elseif ($operators[2] === '!=' && $prop != $val) { |
| 242 |
$tags[$oneTag] = $allresults[3][$i]; |
| 243 |
} elseif (($operators[2] === '>' || $operators[2] === '>') && $prop > $val) { |
| 244 |
$tags[$oneTag] = $allresults[3][$i]; |
| 245 |
} elseif (($operators[2] === '<' || $operators[2] === '<') && $prop < $val) { |
| 246 |
$tags[$oneTag] = $allresults[3][$i]; |
| 247 |
} elseif ($operators[2] === '~' && strpos($prop, $val) !== false) { |
| 248 |
$tags[$oneTag] = $allresults[3][$i]; |
| 249 |
} elseif ($operators[2] === '!~' && strpos($prop, $val) === false) { |
| 250 |
$tags[$oneTag] = $allresults[3][$i]; |
| 251 |
} |
| 252 |
} |
| 253 |
} |
| 254 |
|
| 255 |
$this->pluginHelper->replaceTags($email, $tags, true); |
| 256 |
|
| 257 |
$this->ifStatement($email, $user, $loop + 1); |
| 258 |
} |
| 259 |
|
| 260 |
private function removeText(&$email) |
| 261 |
{ |
| 262 |
$removeText = '{reg},{/reg},{pub},{/pub}'; |
| 263 |
if (!empty($removeText)) { |
| 264 |
$removeArray = explode(',', trim($removeText, ' ,')); |
| 265 |
if (!empty($email->body)) { |
| 266 |
$email->body = str_replace($removeArray, '', $email->body); |
| 267 |
} |
| 268 |
} |
| 269 |
|
| 270 |
|
| 271 |
$removetags = 'youtube'; |
| 272 |
if (!empty($removetags)) { |
| 273 |
$regex = []; |
| 274 |
$removeArray = explode(',', trim($removetags, ' ,')); |
| 275 |
foreach ($removeArray as $oneTag) { |
| 276 |
if (empty($oneTag)) { |
| 277 |
continue; |
| 278 |
} |
| 279 |
$regex[] = '#(?:{|%7B)'.preg_quote($oneTag, '#').'(?:}|%7D).*(?:{|%7B)/'.preg_quote($oneTag, '#').'(?:}|%7D)#Uis'; |
| 280 |
$regex[] = '#(?:{|%7B)'.preg_quote($oneTag, '#').'[^}]*(?:}|%7D)#Uis'; |
| 281 |
} |
| 282 |
|
| 283 |
if (!empty($email->body)) { |
| 284 |
$email->body = preg_replace($regex, '', $email->body); |
| 285 |
} |
| 286 |
} |
| 287 |
} |
| 288 |
|
| 289 |
private function handleAnchors(&$email) |
| 290 |
{ |
| 291 |
if (empty($email->body)) return; |
| 292 |
|
| 293 |
$newBody = preg_replace('/(<a +href="#[^"]*"[^>]*) target="_blank"([^>]*>)/Uis', '$1 $2', $email->body); |
| 294 |
|
| 295 |
if (!empty($newBody)) $email->body = $newBody; |
| 296 |
} |
| 297 |
|
| 298 |
public function fixPicturesOutlook(&$email) |
| 299 |
{ |
| 300 |
$this->addPictureDimensions($email->body); |
| 301 |
$this->addPictureAlign($email->body); |
| 302 |
} |
| 303 |
|
| 304 |
public function addPictureDimensions(&$html) |
| 305 |
{ |
| 306 |
if (!preg_match_all('#(<img)([^>]*>)#i', $html, $results)) { |
| 307 |
return; |
| 308 |
} |
| 309 |
|
| 310 |
$replace = []; |
| 311 |
$widthheight = ['width', 'height']; |
| 312 |
foreach ($results[0] as $num => $oneResult) { |
| 313 |
$add = []; |
| 314 |
foreach ($widthheight as $whword) { |
| 315 |
if (preg_match('#'.$whword.' *=#i', $oneResult) || !preg_match('#[^a-z_\-]'.$whword.' *:([0-9 ]{1,8})px#i', $oneResult, $resultWH)) continue; |
| 316 |
|
| 317 |
if (empty($resultWH[1])) continue; |
| 318 |
$add[] = $whword.'="'.trim($resultWH[1]).'" '; |
| 319 |
} |
| 320 |
|
| 321 |
if (!empty($add)) { |
| 322 |
$replace[$oneResult] = '<img '.implode(' ', $add).$results[2][$num]; |
| 323 |
} |
| 324 |
} |
| 325 |
|
| 326 |
if (!empty($replace)) { |
| 327 |
$html = str_replace(array_keys($replace), $replace, $html); |
| 328 |
preg_match_all('#(<img)([^>]*>)#i', $html, $results); |
| 329 |
} |
| 330 |
|
| 331 |
static $replace = []; |
| 332 |
foreach ($results[0] as $num => $oneResult) { |
| 333 |
if (isset($replace[$oneResult])) continue; |
| 334 |
if (strpos($oneResult, 'width=') || strpos($oneResult, 'height=')) continue; |
| 335 |
if (preg_match('#[^a-z_\-]width *:([0-9 ]{1,8})#i', $oneResult, $res)) continue; |
| 336 |
if (preg_match('#[^a-z_\-]height *:([0-9 ]{1,8})#i', $oneResult, $res)) continue; |
| 337 |
if (!preg_match('#src="([^"]*)"#i', $oneResult, $url)) continue; |
| 338 |
|
| 339 |
$imageUrl = $url[1]; |
| 340 |
|
| 341 |
$replace[$oneResult] = $oneResult; |
| 342 |
|
| 343 |
$base = str_replace(['http://www.', 'https://www.', 'http://', 'https://'], '', ACYM_LIVE); |
| 344 |
$replacements = ['https://www.'.$base, 'http://www.'.$base, 'https://'.$base, 'http://'.$base]; |
| 345 |
$localpict = false; |
| 346 |
foreach ($replacements as $oneReplacement) { |
| 347 |
if (strpos($imageUrl, $oneReplacement) === false) continue; |
| 348 |
|
| 349 |
$imageUrl = str_replace( |
| 350 |
[$oneReplacement, '/'], |
| 351 |
[ACYM_ROOT, DS], |
| 352 |
urldecode($imageUrl) |
| 353 |
); |
| 354 |
$localpict = true; |
| 355 |
break; |
| 356 |
} |
| 357 |
|
| 358 |
if (!$localpict) continue; |
| 359 |
|
| 360 |
$dim = @getimagesize($imageUrl); |
| 361 |
if (!$dim) continue; |
| 362 |
if (empty($dim[0]) || empty($dim[1])) continue; |
| 363 |
|
| 364 |
$replace[$oneResult] = str_replace('<img', '<img width="'.$dim[0].'" height="'.$dim[1].'"', $oneResult); |
| 365 |
} |
| 366 |
|
| 367 |
if (!empty($replace)) { |
| 368 |
$html = str_replace(array_keys($replace), $replace, $html); |
| 369 |
} |
| 370 |
} |
| 371 |
|
| 372 |
public function addPictureAlign(&$html) |
| 373 |
{ |
| 374 |
preg_match_all('#< *img([^>]*)>#Ui', $html, $allPictures); |
| 375 |
|
| 376 |
foreach ($allPictures[0] as $i => $onePict) { |
| 377 |
if (strpos($onePict, 'align=') !== false) continue; |
| 378 |
if (!preg_match('#(style="[^"]*)(float *: *)(right|left|top|bottom|middle)#Ui', $onePict, $pictParams)) continue; |
| 379 |
|
| 380 |
$newPict = str_replace('<img', '<img align="'.$pictParams[3].'" ', $onePict); |
| 381 |
$html = str_replace($onePict, $newPict, $html); |
| 382 |
|
| 383 |
|
| 384 |
if (strpos($onePict, 'hspace=') !== false) continue; |
| 385 |
|
| 386 |
$hspace = 5; |
| 387 |
if (preg_match('#margin(-right|-left)? *:([^";]*)#i', $onePict, $margins)) { |
| 388 |
$currentMargins = explode(' ', trim($margins[2])); |
| 389 |
$myMargin = (count($currentMargins) > 1) ? $currentMargins[1] : $currentMargins[0]; |
| 390 |
if (strpos($myMargin, 'px') !== false) $hspace = preg_replace('#[^0-9]#i', '', $myMargin); |
| 391 |
} |
| 392 |
|
| 393 |
$lastPict = str_replace('<img', '<img hspace="'.$hspace.'" ', $newPict); |
| 394 |
|
| 395 |
$html = str_replace($newPict, $lastPict, $html); |
| 396 |
} |
| 397 |
} |
| 398 |
} |
| 399 |
|