Commit cb253da5 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge branch 'F4434DisableSpecialColumnNamesStartingWithoutUnderscore' into 'master'

fixes #4434 Disable special column names starting without underscore

See merge request !174
parents 9146f8ca d034355a
Pipeline #2294 passed with stages
in 2 minutes and 30 seconds
...@@ -1547,6 +1547,13 @@ const COLUMN_EXCEL_NUMERIC = 'XLSn'; ...@@ -1547,6 +1547,13 @@ const COLUMN_EXCEL_NUMERIC = 'XLSn';
const COLUMN_EXCEL_STRING = 'XLSs'; const COLUMN_EXCEL_STRING = 'XLSs';
const COLUMN_EXCEL_BASE64 = 'XLSb'; const COLUMN_EXCEL_BASE64 = 'XLSb';
const COLUMN_BULLET = "bullet";
const COLUMN_CHECK = "check";
const COLUMN_IMG = "img";
const COLUMN_MAILTO = "mailto";
const COLUMN_SENDMAIL = "sendmail";
const COLUMN_VERTICAL = "vertical";
const COLUMN_WRAP_TOKEN = '+'; const COLUMN_WRAP_TOKEN = '+';
const COLUMN_STORE_USER = '='; const COLUMN_STORE_USER = '=';
...@@ -1893,6 +1900,11 @@ const QFQ_VERSION_KEY_FUNCTION_VERSION = 'functionVersion'; ...@@ -1893,6 +1900,11 @@ const QFQ_VERSION_KEY_FUNCTION_VERSION = 'functionVersion';
const QFQ_VERSION_KEY = 'Version'; const QFQ_VERSION_KEY = 'Version';
const QFQ_FUNCTION_SQL = 'function.sql'; const QFQ_FUNCTION_SQL = 'function.sql';
// update special column names (add '_' in front)
const ACTION_SPECIAL_COLUMN_UPDATE = '_scupdate'; // get parameter to set the update behaviour
const ACTION_SPECIAL_COLUMN_DO_REPLACE = 'replace'; // special columns are automatically replaced
const ACTION_SPECIAL_COLUMN_DO_SKIP_REPLACE = 'skip_replace'; // special columns are automatically replaced
// tablesorter // tablesorter
const TABLESORTER_VIEW_SAVER = 'tablesorter-view-saver'; const TABLESORTER_VIEW_SAVER = 'tablesorter-view-saver';
const DATA_TABLESORTER_VIEW = 'data-tablesorter-view'; const DATA_TABLESORTER_VIEW = 'data-tablesorter-view';
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace IMATHUZH\Qfq\Core\Database; namespace IMATHUZH\Qfq\Core\Database;
use IMATHUZH\Qfq\Core\Helper\Logger; use IMATHUZH\Qfq\Core\Helper\Logger;
use IMATHUZH\Qfq\Core\Store\Store;
/* /*
...@@ -32,14 +33,18 @@ class DatabaseUpdate { ...@@ -32,14 +33,18 @@ class DatabaseUpdate {
/** /**
* @var Database instantiated class * @var Database instantiated class
* @var Store instantiated class
*/ */
protected $db = null; protected $db = null;
protected $store = null;
/** /**
* @param Database $db * @param Database $db
* @param Store $store
*/ */
public function __construct(Database $db) { public function __construct(Database $db, Store $store) {
$this->db = $db; $this->db = $db;
$this->store = $store;
} }
/** /**
...@@ -129,6 +134,10 @@ class DatabaseUpdate { ...@@ -129,6 +134,10 @@ class DatabaseUpdate {
$versionInfo = $this->getDatabaseVersion(); $versionInfo = $this->getDatabaseVersion();
$old = $versionInfo[QFQ_VERSION_KEY] ?? false; $old = $versionInfo[QFQ_VERSION_KEY] ?? false;
if (version_compare($old, '19.9.9') === -1) { #TODO: change version number before new release! (replace 19.9.9 with the version of the new release)
$this->updateSpecialColumns();
}
if ($dbUpdate === SYSTEM_DB_UPDATE_ALWAYS || ($dbUpdate === SYSTEM_DB_UPDATE_AUTO && $new != $old)) { if ($dbUpdate === SYSTEM_DB_UPDATE_ALWAYS || ($dbUpdate === SYSTEM_DB_UPDATE_AUTO && $new != $old)) {
$newFunctionHash = $this->updateSqlFunctions($versionInfo[QFQ_VERSION_KEY_FUNCTION_HASH] ?? ''); $newFunctionHash = $this->updateSqlFunctions($versionInfo[QFQ_VERSION_KEY_FUNCTION_HASH] ?? '');
...@@ -154,12 +163,120 @@ class DatabaseUpdate { ...@@ -154,12 +163,120 @@ class DatabaseUpdate {
} }
} }
/**
* Check if there are special columns without prepended underscore in the QFQ application. If yes, then throw an error.
* A link is provided to automatically prepend all found special columns. And another link to skip the auto-replacement.
*
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
*/
private function updateSpecialColumns() {
// Prepare regex patterns to find "AS <special column name>"
$special_columns = ['link', 'exec', 'Page', 'Pagec', 'Paged', 'Pagee', 'Pageh', 'Pagei', 'Pagen', 'Pages'
, 'page', 'pagec', 'paged', 'pagee', 'pageh', 'pagei', 'pagen', 'pages', 'yank', 'Pdf', 'File', 'Zip'
, 'pdf', 'file', 'zip', 'excel', 'savePdf', 'thumbnail', 'monitor', 'mimeType', 'fileSize', 'nl2br'
, 'htmlentities', 'striptags', 'XLS', 'XLSs', 'XLSb', 'XLSn', 'bullet', 'check', 'img', 'mailto'
, 'sendmail', 'vertical'];
$make_pattern = function ($column) {
return '/([aA][sS]\s+)(' . $column . ')/s';
};
$patterns = array_map($make_pattern, $special_columns);
// Prepare search and replace
$placeholder = '%%%UNDERLINE%%%'; // used temporarily to mark where '_' should go
$actionSpecialColumn = $_GET[ACTION_SPECIAL_COLUMN_UPDATE] ?? ''; // get parameter to decide whether to execute the replacement
$dbT3 = $this->store->getVar(SYSTEM_DB_NAME_T3, STORE_SYSTEM);
$message = ''; // error message in case an old special column is found
// TT_CONTENT tt_content.bodytext
$message_fe = '';
if (defined('PHPUNIT_QFQ')) {
$res = array();
} else {
$res = $this->db->sql("SELECT uid, header, bodytext FROM " . $dbT3 . ".tt_content WHERE CType='qfq_qfq' AND deleted=0;");
}
foreach ($res as $i => $tt_content) {
$replaced_placeholder = preg_replace($patterns, '${1}' . $placeholder . '${2}', $tt_content['bodytext']);
if (strpos($replaced_placeholder, $placeholder) !== false) {
if ($actionSpecialColumn === ACTION_SPECIAL_COLUMN_DO_REPLACE) {
$replace = str_replace($placeholder, '_', $replaced_placeholder);
$query = "UPDATE " . $dbT3 . ".tt_content SET bodytext='" . addslashes($replace) . "' WHERE uid='" . $tt_content['uid'] . "'";
$this->db->sql($query);
}
$message_fe .= '<hr><b>' . $tt_content['header'] . ' [uid:' . $tt_content['uid'] . ']</b><br><br>';
$message_fe .= str_replace($placeholder,
'<span style="font-weight: bold; color: red;">>>>_</span>',
htmlentities($replaced_placeholder));
}
}
if ($message_fe != '') {
$message .= '<hr><h3>Typo3 Table: tt_content (column: bodytext)</h3>' . $message_fe;
}
// FORM ELEMENTS FormElement.value, FormElement.note
$message_ttc = '';
if (defined('PHPUNIT_QFQ')) {
$res = array();
} else {
$res = $this->db->sql("SELECT fe.id, fe.name, fe.value, fe.note FROM FormElement as fe WHERE fe.type='note' AND fe.value LIKE '#!report%' OR fe.note LIKE '%#!report%';");
}
foreach ($res as $i => $tt_content) {
foreach (['value', 'note'] as $j => $columnName) {
$replaced_placeholder = preg_replace($patterns, '${1}' . $placeholder . '${2}', $tt_content[$columnName]);
if (strpos($replaced_placeholder, $placeholder) !== false) {
if ($actionSpecialColumn === ACTION_SPECIAL_COLUMN_DO_REPLACE) {
$replace = str_replace($placeholder, '_', $replaced_placeholder);
$query = "UPDATE FormElement SET " . $columnName . "='" . addslashes($replace) . "' WHERE id='" . $tt_content['id'] . "'";
$this->db->sql($query);
}
$message_ttc .= '<hr><b>' . $tt_content['name'] . ' [id:' . $tt_content['id'] . '] (FormElement.' . $columnName . ')</b><br><br>';
$message_ttc .= str_replace($placeholder,
'<span style="font-weight: bold; color: red;">>>>_</span>',
htmlentities($replaced_placeholder));
}
}
}
if ($message_ttc != '') {
$message .= '<hr><h3>QFQ Table: FormElement (columns: value and note)</h3>' . $message_ttc;
}
// show error message or save log
if ($message != '') {
if ($actionSpecialColumn === ACTION_SPECIAL_COLUMN_DO_REPLACE) {
// save log file
$message = '<h1>Special column names replaced</h1>The following special column names were replaced.<hr>' . $message;
Logger::logMessage($message, SYSTEM_FILEADMIN_PROTECTED_LOG . '/' . date("YmdHi") . '_special_columns_auto_update.html');
} elseif ($actionSpecialColumn === ACTION_SPECIAL_COLUMN_DO_SKIP_REPLACE) {
// do nothing
} else {
// show error
$message = $actionSpecialColumn
. '<h2>Special Column names without prepended underscore found.</h2>'
. ' Those are not supported any longer.'
. '<h2>SOLUTION</h2>'
. 'Click <a href="?' . http_build_query(array_merge($_GET, array(ACTION_SPECIAL_COLUMN_UPDATE => ACTION_SPECIAL_COLUMN_DO_REPLACE))) . '">Auto-Replace</a>'
. ' to automatically prepend the found column names with an underscore.'
. ' In the report below the missing underscores are marked by "<span style="font-weight: bold; color: red;">>>>_</span>".'
. ' This report will be saved in ' . SYSTEM_FILEADMIN_PROTECTED_LOG . ' after the automatic replacement.'
. ' <br><br>To update qfq without changing the special columns (your app will probably be broken): '
. '<a href="?' . http_build_query(array_merge($_GET, array(ACTION_SPECIAL_COLUMN_UPDATE => ACTION_SPECIAL_COLUMN_DO_SKIP_REPLACE))) . '">Skip Auto-Replace</a>'
. '<h2>Report</h2>'
. $message;
$errorMsg[ERROR_MESSAGE_TO_USER] = 'Error while updating qfq. ';
$errorMsg[ERROR_MESSAGE_TO_DEVELOPER] = $message;
$errorMsg[ERROR_MESSAGE_TO_DEVELOPER_SANITIZE] = false;
throw new \DbException(json_encode($errorMsg), ERROR_PLAY_SQL_FILE);
}
}
}
/** /**
* @param $oldFunctionsHash * @param $oldFunctionsHash
* *
* @return string * @return string
* *
* @throws \CodeException
* @throws \DbException * @throws \DbException
* @throws \UserFormException * @throws \UserFormException
*/ */
......
...@@ -173,7 +173,7 @@ class QuickFormQuery { ...@@ -173,7 +173,7 @@ class QuickFormQuery {
$this->evaluate = new Evaluate($this->store, $this->dbArray[$this->dbIndexData]); $this->evaluate = new Evaluate($this->store, $this->dbArray[$this->dbIndexData]);
$dbUpdate = $this->store->getVar(SYSTEM_DB_UPDATE, STORE_SYSTEM); $dbUpdate = $this->store->getVar(SYSTEM_DB_UPDATE, STORE_SYSTEM);
$updateDb = new DatabaseUpdate($this->dbArray[$this->dbIndexQfq]); $updateDb = new DatabaseUpdate($this->dbArray[$this->dbIndexQfq], $this->store);
$updateDb->checkNupdate($dbUpdate); $updateDb->checkNupdate($dbUpdate);
$this->store->FillStoreSystemBySql(); // Do this after the DB-update $this->store->FillStoreSystemBySql(); // Do this after the DB-update
......
...@@ -859,241 +859,241 @@ class Report { ...@@ -859,241 +859,241 @@ class Report {
$flagOutput = false; $flagOutput = false;
$columnName = substr($columnName, 1); $columnName = substr($columnName, 1);
} }
}
//TODO: reserved names,not starting with '_' will be still accepted - stop this!
switch ($columnName) {
case COLUMN_LINK:
$content .= $this->link->renderLink($columnValue);
break;
case COLUMN_EXEC: //TODO: reserved names,not starting with '_' will be still accepted - stop this!
$rc = ''; switch ($columnName) {
$content .= Support::qfqExec($columnValue, $rc); case COLUMN_LINK:
break; $content .= $this->link->renderLink($columnValue);
break;
// Uppercase 'P' case COLUMN_EXEC:
case COLUMN_PPAGE: $rc = '';
case COLUMN_PPAGEC: $content .= Support::qfqExec($columnValue, $rc);
case COLUMN_PPAGED: break;
case COLUMN_PPAGEE:
case COLUMN_PPAGEH:
case COLUMN_PPAGEI:
case COLUMN_PPAGEN:
case COLUMN_PPAGES:
$lowerColumnName = strtolower($columnName);
$tokenizedValue = $this->doFixColPosPage($columnName, $columnValue);
$linkValue = $this->doPage($lowerColumnName, $tokenizedValue);
$content .= $this->link->renderLink($linkValue);
break;
// Lowercase 'P' // Uppercase 'P'
case COLUMN_PAGE: case COLUMN_PPAGE:
case COLUMN_PAGEC: case COLUMN_PPAGEC:
case COLUMN_PAGED: case COLUMN_PPAGED:
case COLUMN_PAGEE: case COLUMN_PPAGEE:
case COLUMN_PAGEH: case COLUMN_PPAGEH:
case COLUMN_PAGEI: case COLUMN_PPAGEI:
case COLUMN_PAGEN: case COLUMN_PPAGEN:
case COLUMN_PAGES: case COLUMN_PPAGES:
$linkValue = $this->doPage($columnName, $columnValue); $lowerColumnName = strtolower($columnName);
$content .= $this->link->renderLink($linkValue); $tokenizedValue = $this->doFixColPosPage($columnName, $columnValue);
break; $linkValue = $this->doPage($lowerColumnName, $tokenizedValue);
$content .= $this->link->renderLink($linkValue);
break;
case COLUMN_YANK: // Lowercase 'P'
$linkValue = $this->doYank($columnName, $columnValue); case COLUMN_PAGE:
$content .= $this->link->renderLink($linkValue); case COLUMN_PAGEC:
break; case COLUMN_PAGED:
case COLUMN_PAGEE:
case COLUMN_PAGEH:
case COLUMN_PAGEI:
case COLUMN_PAGEN:
case COLUMN_PAGES:
$linkValue = $this->doPage($columnName, $columnValue);
$content .= $this->link->renderLink($linkValue);
break;
case COLUMN_PPDF: case COLUMN_YANK:
case COLUMN_FFILE: $linkValue = $this->doYank($columnName, $columnValue);
case COLUMN_ZZIP: $content .= $this->link->renderLink($linkValue);
$lowerColumnName = strtolower($columnName); break;
$tokenizedValue = $this->doFixColPosDownload($columnValue);
$linkValue = $this->doDownload($lowerColumnName, $tokenizedValue);
$content .= $this->link->renderLink($linkValue);
break;
case COLUMN_PDF: case COLUMN_PPDF:
case COLUMN_FILE: case COLUMN_FFILE:
case COLUMN_ZIP: case COLUMN_ZZIP:
case COLUMN_EXCEL: $lowerColumnName = strtolower($columnName);
$linkValue = $this->doDownload($columnName, $columnValue); $tokenizedValue = $this->doFixColPosDownload($columnValue);
$content .= $this->link->renderLink($linkValue); $linkValue = $this->doDownload($lowerColumnName, $tokenizedValue);
break; $content .= $this->link->renderLink($linkValue);
break;
case COLUMN_SAVE_PDF: case COLUMN_PDF:
$tokenGiven = []; case COLUMN_FILE:
$vars = $this->link->fillParameter($columnValue, $tokenGiven); case COLUMN_ZIP:
$vars[DOWNLOAD_MODE] = DOWNLOAD_MODE_PDF; case COLUMN_EXCEL:
$vars[SIP_DOWNLOAD_PARAMETER] = implode(PARAM_DELIMITER, $vars[NAME_COLLECT_ELEMENTS]); $linkValue = $this->doDownload($columnName, $columnValue);
$content .= $this->link->renderLink($linkValue);
// Save file with specified export filename break;
$pathFileName = $vars[DOWNLOAD_EXPORT_FILENAME];
$sanitizedFileName = Sanitize::safeFilename($pathFileName, false, true);
if ($pathFileName == '' ||
substr($pathFileName, 0, strlen("fileadmin/")) !== "fileadmin/" ||
substr($pathFileName, -4) !== '.pdf') {
throw new \UserReportException("savePdf filenames need to be in the fileadmin/ directory and end in .pdf for security reasons.", ERROR_INVALID_SAVE_PDF_FILENAME);
} elseif ($pathFileName !== $sanitizedFileName) {
throw new \UserReportException("The provided filename '$pathFileName' does not meet sanitize criteria. Use '$sanitizedFileName' instead.", ERROR_INVALID_SAVE_PDF_FILENAME);
} else {
$vars[DOWNLOAD_EXPORT_FILENAME] = $sanitizedFileName;
$download = new Download();
$download->process($vars, OUTPUT_MODE_COPY_TO_FILE);
}
break;
case COLUMN_THUMBNAIL: case COLUMN_SAVE_PDF:
if ($this->thumbnail == null) { $tokenGiven = [];
$this->thumbnail = new Thumbnail(); $vars = $this->link->fillParameter($columnValue, $tokenGiven);
} $vars[DOWNLOAD_MODE] = DOWNLOAD_MODE_PDF;
$content .= $this->thumbnail->process($columnValue); $vars[SIP_DOWNLOAD_PARAMETER] = implode(PARAM_DELIMITER, $vars[NAME_COLLECT_ELEMENTS]);
break;
// Save file with specified export filename
$pathFileName = $vars[DOWNLOAD_EXPORT_FILENAME];
$sanitizedFileName = Sanitize::safeFilename($pathFileName, false, true);
if ($pathFileName == '' ||
substr($pathFileName, 0, strlen("fileadmin/")) !== "fileadmin/" ||
substr($pathFileName, -4) !== '.pdf') {
throw new \UserReportException("savePdf filenames need to be in the fileadmin/ directory and end in .pdf for security reasons.", ERROR_INVALID_SAVE_PDF_FILENAME);
} elseif ($pathFileName !== $sanitizedFileName) {
throw new \UserReportException("The provided filename '$pathFileName' does not meet sanitize criteria. Use '$sanitizedFileName' instead.", ERROR_INVALID_SAVE_PDF_FILENAME);
} else {
$vars[DOWNLOAD_EXPORT_FILENAME] = $sanitizedFileName;
$download = new Download();
$download->process($vars, OUTPUT_MODE_COPY_TO_FILE);
}
break;
case COLUMN_MONITOR: case COLUMN_THUMBNAIL:
$content .= $this->link->renderLink(TOKEN_MONITOR . '|' . $columnValue); if ($this->thumbnail == null) {
break; $this->thumbnail = new Thumbnail();
}
$content .= $this->thumbnail->process($columnValue);
break;
case COLUMN_MIME_TYPE: case COLUMN_MONITOR:
$content .= HelperFile::getMimeType($columnValue, true); $content .= $this->link->renderLink(TOKEN_MONITOR . '|' . $columnValue);
break; break;
case COLUMN_FILE_SIZE: case COLUMN_MIME_TYPE:
$arr = HelperFile::getFileStat($columnValue); $content .= HelperFile::getMimeType($columnValue, true);
$content .= $arr[VAR_FILE_SIZE] ?? '-'; break;
break;
case COLUMN_NL2BR: case COLUMN_FILE_SIZE:
$content .= nl2br($columnValue); $arr = HelperFile::getFileStat($columnValue);
break; $content .= $arr[VAR_FILE_SIZE] ?? '-';
break;
case COLUMN_HTMLENTITIES: case COLUMN_NL2BR:
$content .= htmlentities($columnValue); $content .= nl2br($columnValue);
break; break;
case COLUMN_STRIPTAGS: case COLUMN_HTMLENTITIES:
$content .= strip_tags($columnValue); $content .= htmlentities($columnValue);
break; break;
case COLUMN_EXCEL_PLAIN: case COLUMN_STRIPTAGS:
$content .= $columnValue . PHP_EOL; $content .= strip_tags($columnValue);
break; break;
case COLUMN_EXCEL_STRING:
$content .= EXCEL_STRING . '=' . $columnValue . PHP_EOL;
break;
case COLUMN_EXCEL_BASE64:
$content .= EXCEL_BASE64 . '=' . base64_encode($columnValue) . PHP_EOL;
break;
case COLUMN_EXCEL_NUMERIC:
$content .= EXCEL_NUMERIC . '=' . $columnValue . PHP_EOL;
break;
case "bullet": case COLUMN_EXCEL_PLAIN:
if ($columnValue === '') { $content .= $columnValue . PHP_EOL;
break;
case COLUMN_EXCEL_STRING:
$content .= EXCEL_STRING . '=' . $columnValue . PHP_EOL;
break;
case COLUMN_EXCEL_BASE64:
$content .= EXCEL_BASE64 . '=' . base64_encode($columnValue) . PHP_EOL;
break;
case COLUMN_EXCEL_NUMERIC:
$content .= EXCEL_NUMERIC . '=' . $columnValue . PHP_EOL;
break; break;
}
// r:3|B: case COLUMN_BULLET:
$linkValue = TOKEN_RENDER . ":3|" . TOKEN_BULLET . ":" . $columnValue; if ($columnValue === '') {
$content .= $this->link->renderLink($linkValue); break;
break; }
case "check": // r:3|B:
if ($columnValue === '') { $linkValue = TOKEN_RENDER . ":3|" . TOKEN_BULLET . ":" . $columnValue;
$content .= $this->link->renderLink($linkValue);
break; break;
}
// "r:3|C: case COLUMN_CHECK:
$linkValue = TOKEN_RENDER . ":3|" . TOKEN_CHECK . ":" . $columnValue; if ($columnValue === '') {
$content .= $this->link->renderLink($linkValue); break;
break; }
case "img": // "r:3|C:
// "<path to image>|[alttext]|[text behind]" renders to: <img src="<path to image>" alt="[alttext]">[text behind] $linkValue = TOKEN_RENDER . ":3|" . TOKEN_CHECK . ":" . $columnValue;
if (empty($columnValue)) { $content .= $this->link->renderLink($linkValue);
break; break;
}
$mailConfig = explode("|", $columnValue, 3); case COLUMN_IMG:
// "<path to image>|[alttext]|[text behind]" renders to: <img src="<path to image>" alt="[alttext]">[text behind]
if (empty($columnValue)) {
break;
}
// Fake values for tmp[1], tmp[2] to suppress access errors. $mailConfig = explode("|", $columnValue, 3);
$mailConfig[] = '';
$mailConfig[] = '';
if (empty($mailConfig[0])) { // Fake values for tmp[1], tmp[2] to suppress access errors.
break; $mailConfig[] = '';
} $mailConfig[] = '';
$attribute = Support::doAttribute('src', $mailConfig[0]);
$attribute .= Support::doAttribute('alt', $mailConfig[1]);
$content .= '<img ' . $attribute . '>' . $mailConfig[2]; if (empty($mailConfig[0])) {
break; break;
}
$attribute = Support::doAttribute('src', $mailConfig[0]);
$attribute .= Support::doAttribute('alt', $mailConfig[1]);
case "mailto": $content .= '<img ' . $attribute . '>' . $mailConfig[2];
// "<email address>|[Real Name]" renders to (encrypted via JS): <a href="mailto://<email address>"><email address></a> OR <a href="mailto://<email address>">[Real Name]</a>
$mailConfig = explode("|", $columnValue, 2);
if (empty($mailConfig[0])) {
break; break;
}
$t1 = explode("@", $mailConfig[0], 2); case COLUMN_MAILTO:
$content .= "<script language=javascript><!--" . chr(10); // "<email address>|[Real Name]" renders to (encrypted via JS): <a href="mailto://<email address>"><email address></a> OR <a href="mailto://<email address>">[Real Name]</a>
if (empty($mailConfig[1])) { $mailConfig = explode("|", $columnValue, 2);
$mailConfig[1] = $mailConfig[0]; if (empty($mailConfig[0])) {
} break;
}
$t1 = explode("@", $mailConfig[0], 2);
$content .= "<script language=javascript><!--" . chr(10);
if (empty($mailConfig[1])) {
$mailConfig[1] = $mailConfig[0];
}