From 5ab0d021f3e96722af5d96d2b9036430200c06cb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Mon, 21 Jan 2013 19:25:51 +0000 Subject: [PATCH] Introduced new extension ext-blacklist: - Extracted new extension ext-blacklist from aldready existing functions, as this should become a more generic black-/white listing feature - TODOs.txt updated --- .gitattributes | 6 + DOCS/TODOs.txt | 4 +- inc/extensions/ext-blacklist.php | 117 ++++++++++++ inc/extensions/ext-order.php | 24 +-- inc/language/blacklist_de.php | 54 ++++++ inc/language/order_de.php | 1 - inc/libs/blacklist_functions.php | 172 ++++++++++++++++++ inc/modules/admin/what-config_blacklist.php | 55 ++++++ inc/modules/admin/what-unlock_emails.php | 15 +- inc/modules/member/what-order.php | 2 +- inc/mysql-manager.php | 34 ---- inc/template-functions.php | 2 +- inc/wrapper-functions.php | 12 -- install/tables.sql | 1 - .../de/html/admin/admin_config_blacklist.tpl | 36 ++++ .../de/html/admin/admin_config_order.tpl | 7 - templates/de/html/ext/ext_blacklist.tpl | 4 + 17 files changed, 461 insertions(+), 85 deletions(-) create mode 100644 inc/extensions/ext-blacklist.php create mode 100644 inc/language/blacklist_de.php create mode 100644 inc/libs/blacklist_functions.php create mode 100644 inc/modules/admin/what-config_blacklist.php create mode 100644 templates/de/html/admin/admin_config_blacklist.tpl create mode 100644 templates/de/html/ext/ext_blacklist.tpl diff --git a/.gitattributes b/.gitattributes index 3666209573..34919c11b9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -176,6 +176,7 @@ inc/extensions/ext-bank.php svneol=native#text/plain inc/extensions/ext-beg.php svneol=native#text/plain inc/extensions/ext-birthday.php svneol=native#text/plain inc/extensions/ext-bitcoins.php svneol=native#text/plain +inc/extensions/ext-blacklist.php svneol=native#text/plain inc/extensions/ext-bonus.php svneol=native#text/plain inc/extensions/ext-booking.php svneol=native#text/plain inc/extensions/ext-cache.php svneol=native#text/plain @@ -343,6 +344,7 @@ inc/language/autopurge_de.php svneol=native#text/plain inc/language/bank_de.php svneol=native#text/plain inc/language/beg_de.php svneol=native#text/plain inc/language/birthday_de.php svneol=native#text/plain +inc/language/blacklist_de.php svneol=native#text/plain inc/language/bonus_de.php svneol=native#text/plain inc/language/booking_de.php svneol=native#text/plain inc/language/cache_de.php svneol=native#text/plain @@ -404,6 +406,7 @@ inc/libs/admins_functions.php svneol=native#text/plain inc/libs/autopurge_functions.php svneol=native#text/plain inc/libs/beg_functions.php svneol=native#text/plain inc/libs/birthday_functions.php svneol=native#text/plain +inc/libs/blacklist_functions.php svneol=native#text/plain inc/libs/bonus_functions.php svneol=native#text/plain inc/libs/booking_functions.php svneol=native#text/plain inc/libs/cache_functions.php svneol=native#text/plain @@ -537,6 +540,7 @@ inc/modules/admin/what-config_admin.php svneol=native#text/plain inc/modules/admin/what-config_autopurge.php svneol=native#text/plain inc/modules/admin/what-config_beg.php svneol=native#text/plain inc/modules/admin/what-config_birthday.php svneol=native#text/plain +inc/modules/admin/what-config_blacklist.php svneol=native#text/plain inc/modules/admin/what-config_bonus.php svneol=native#text/plain inc/modules/admin/what-config_cache.php svneol=native#text/plain inc/modules/admin/what-config_cats.php svneol=native#text/plain @@ -1250,6 +1254,7 @@ templates/de/html/admin/admin_config_autopurge_pro.tpl svneol=native#text/plain templates/de/html/admin/admin_config_beg.tpl svneol=native#text/plain templates/de/html/admin/admin_config_beg_pro.tpl svneol=native#text/plain templates/de/html/admin/admin_config_birthday.tpl svneol=native#text/plain +templates/de/html/admin/admin_config_blacklist.tpl svneol=native#text/plain templates/de/html/admin/admin_config_bonus.tpl svneol=native#text/plain templates/de/html/admin/admin_config_bonus_pro.tpl svneol=native#text/plain templates/de/html/admin/admin_config_cache.tpl svneol=native#text/plain @@ -1762,6 +1767,7 @@ templates/de/html/ext/ext_bank.tpl svneol=native#text/plain templates/de/html/ext/ext_beg.tpl svneol=native#text/plain templates/de/html/ext/ext_birthday.tpl svneol=native#text/plain templates/de/html/ext/ext_bitcoins.tpl svneol=native#text/plain +templates/de/html/ext/ext_blacklist.tpl svneol=native#text/plain templates/de/html/ext/ext_bonus.tpl svneol=native#text/plain templates/de/html/ext/ext_booking.tpl svneol=native#text/plain templates/de/html/ext/ext_cache.tpl svneol=native#text/plain diff --git a/DOCS/TODOs.txt b/DOCS/TODOs.txt index e9e86ea6ef..56d24cb2dc 100644 --- a/DOCS/TODOs.txt +++ b/DOCS/TODOs.txt @@ -84,7 +84,7 @@ ./inc/language-functions.php:254: // @TODO These are all valid languages, again hard-coded ./inc/language/install_de.php:142: // @TODO Move this to e.g. ext-smtp ./inc/language/newsletter_de.php:13: * @TODO This language file is completely out-dated, please do no * -./inc/language/order_de.php:70: // @TODO Find better text +./inc/language/order_de.php:69: // @TODO Find better text ./inc/language/rallye_de.php:13: * @TODO Naming convention not applied for language strings * ./inc/language/refback_de.php:51: // @TODO Rewrite these constants to one ./inc/libs/admins_functions.php:537: // @TODO This can be, somehow, rewritten @@ -216,7 +216,7 @@ ./inc/template-functions.php:209: * @TODO On some pages this is buggy ./inc/template-functions.php:298: // @TODO Remove these sanity checks if all is fine ./inc/template-functions.php:747: // @TODO $userid is deprecated and should be removed from loadEmailTemplate() and replaced with $content[userid] in all templates -./inc/wrapper-functions.php:3209: // @TODO Find a way to not use direct module comparison +./inc/wrapper-functions.php:3197: // @TODO Find a way to not use direct module comparison ./inc/wrapper-functions.php:524:// @TODO Do some more sanity check here ./inc/xml-functions.php:240: // @TODO Handle characters ./mailid.php:123: // @TODO Rewrite this to a filter/function diff --git a/inc/extensions/ext-blacklist.php b/inc/extensions/ext-blacklist.php new file mode 100644 index 0000000000..50fd459df6 --- /dev/null +++ b/inc/extensions/ext-blacklist.php @@ -0,0 +1,117 @@ + diff --git a/inc/extensions/ext-order.php b/inc/extensions/ext-order.php index 8d970104d6..f6ad5bd84e 100644 --- a/inc/extensions/ext-order.php +++ b/inc/extensions/ext-order.php @@ -41,10 +41,10 @@ if (!defined('__SECURITY')) { } // END - if // Version number -setThisExtensionVersion('0.5.6'); +setThisExtensionVersion('0.5.7'); // Version history array (add more with , '0.0.1' and so on) -setExtensionVersionHistory(array('0.0.0', '0.1.0', '0.1.1', '0.1.2', '0.1.3', '0.1.4', '0.1.5', '0.1.6', '0.1.7', '0.1.8', '0.1.9', '0.2.0', '0.2.1', '0.2.2', '0.2.3', '0.2.4', '0.2.5', '0.2.6', '0.2.7', '0.2.8', '0.2.9', '0.3.0', '0.3.1', '0.3.2', '0.3.3', '0.3.4', '0.3.5', '0.3.6', '0.3.7', '0.3.8', '0.3.9', '0.4.0', '0.4.1', '0.4.2', '0.4.3', '0.4.4', '0.4.5', '0.4.6', '0.4.7', '0.4.8', '0.4.9', '0.5.0', '0.5.1', '0.5.2', '0.5.3', '0.5.4', '0.5.5', '0.5.6')); +setExtensionVersionHistory(array('0.0.0', '0.1.0', '0.1.1', '0.1.2', '0.1.3', '0.1.4', '0.1.5', '0.1.6', '0.1.7', '0.1.8', '0.1.9', '0.2.0', '0.2.1', '0.2.2', '0.2.3', '0.2.4', '0.2.5', '0.2.6', '0.2.7', '0.2.8', '0.2.9', '0.3.0', '0.3.1', '0.3.2', '0.3.3', '0.3.4', '0.3.5', '0.3.6', '0.3.7', '0.3.8', '0.3.9', '0.4.0', '0.4.1', '0.4.2', '0.4.3', '0.4.4', '0.4.5', '0.4.6', '0.4.7', '0.4.8', '0.4.9', '0.5.0', '0.5.1', '0.5.2', '0.5.3', '0.5.4', '0.5.5', '0.5.6', '0.5.7')); switch (getExtensionMode()) { case 'setup': // Do stuff when installation is running @@ -54,7 +54,6 @@ switch (getExtensionMode()) { case 'remove': // Do stuff when removing extension // SQL commands to run - addDropTableSql('url_blacklist'); addExtensionSql("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_admin_menu` WHERE `what`='config_order' LIMIT 1"); addExtensionSql("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_member_menu` WHERE `action`='order'"); @@ -305,18 +304,8 @@ nicht die vom Mitglied eingegebene. Resultat: Das Script beschwerte sich, der Us break; case '0.5.0': // SQL queries for v0.5.0 - addDropTableSql('url_blacklist'); - addCreateTableSql('url_blacklist', " -`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, -`url` VARCHAR(255) NOT NULL DEFAULT '', -`pool_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, -`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -PRIMARY KEY (`id`), -INDEX (`pool_id`)", - 'URL blacklist'); - // Update notes (these will be set as task text!) - setExtensionUpdateNotes("Tabelle für URL-Sperrliste angelegt."); + setExtensionUpdateNotes("Nicht mehr gültiges Update."); break; case '0.5.1': // SQL queries for v0.5.1 @@ -375,6 +364,13 @@ INDEX (`pool_id`)", // Update notes (these will be set as task text!) setExtensionUpdateNotes("Filter für Spaltenname des gesperrten Werbeguthabens hinzugefügt."); break; + + case '0.5.7': // SQL queries for v0.5.7 + addDropTableSql('url_blacklist'); + + // Update notes (these will be set as task text!) + setExtensionUpdateNotes("Tabelle für URL-Sperrliste gelöscht (nach ext-blacklist verschoben)."); + break; } // END - switch break; diff --git a/inc/language/blacklist_de.php b/inc/language/blacklist_de.php new file mode 100644 index 0000000000..1884f02bb6 --- /dev/null +++ b/inc/language/blacklist_de.php @@ -0,0 +1,54 @@ + "Konfiguration von Sperrlisten", + 'ADMIN_CONFIG_BLACKLIST_LEGEND' => "Sperrlisten aktvieren:", + 'ADMIN_CONFIG_EMAIL_BLACKLIST_ENABLED' => "Sperrliste für Email-Adressen aktivieren?", + 'ADMIN_CONFIG_URL_BLACKLIST_ENABLED' => "Sperrliste für gebuchte URLs aktivieren?", + 'ADMIN_CONFIG_BLACKLIST_NOTICE' => "Hinweise: Die Sperrliste für Email-Adressen gilt sowohl für die Mitgliedsanmeldung als auch wenn das Mitglied seine Daten ändert. Ist die vom Mitglied eingegebene Email-Adresse gesperrt, wird diese nicht angenommen. Die URL-Sperrliste gilt für alle Erweiterungen (Besuchertausch, Mailbuchung, Forced-Buchungen usw.).", +)); + +// [EOF] +?> diff --git a/inc/language/order_de.php b/inc/language/order_de.php index ec2c935672..04eabde296 100644 --- a/inc/language/order_de.php +++ b/inc/language/order_de.php @@ -54,7 +54,6 @@ addMessages(array( 'ADMIN_CONFIG_MAX_UNCONFIRMED_MAILS' => "Maximale erlaubter Anzahl unbest. Mails um eine Mailbuchung durchzuführen", 'ADMIN_CONFIG_CHECK_EMAIL_TEXT' => "Sind URLs im Werbetext erlaubt?", 'ADMIN_CONFIG_CHECK_EMAIL_SUBJECT' => "Sind URLs in der Betreffzeile erlaubt?", - 'ADMIN_CONFIG_URL_BLACKLIST' => "Black-Liste für gebuchte URLs aktivieren?", 'ADMIN_CONFIG_ORDER_NOTICE' => "Das Auswahlverfahren von Mailempfängern wirkt sich nur auf kleinere Buchungen - mit weniger Empfänger als maximal möglich - aus.", // Admin config - repay options diff --git a/inc/libs/blacklist_functions.php b/inc/libs/blacklist_functions.php new file mode 100644 index 0000000000..92e0b2b4d1 --- /dev/null +++ b/inc/libs/blacklist_functions.php @@ -0,0 +1,172 @@ + black-listed + $listed = TRUE; + } + + // Return result + return $listed; +} + +// Inserts a given URL in blacklist if not found +function insertUrlInBlacklist ($url, $id) { + // Is this feature turned on and is the URL not there? + if (!isUrlBlacklistEnabled()) { + // Not enabled, then please don't call this function + reportBug(__FUNCTION__, __LINE__, 'URL blacklisting is disabled, url=' . $url . ',id=' . $id); + } elseif (!isUrlBlacklisted($url)) { + // Did not find a record so we can add it... :) + SQL_QUERY_ESC("INSERT INTO `{?_MYSQL_PREFIX?}_blacklist` (`data`, `pool_id`, `type`) VALUES ('%s', %s, 'URL')", + array( + $url, + $id + ), __FUNCTION__, __LINE__); + } // END - if +} + +// Checks whether given URL is blacklisted +function isUrlBlacklisted ($url) { + // Mark it as not listed by default + $listed = FALSE; + + // Is black-listing enbaled? + if (!isUrlBlacklistEnabled()) { + // No, then all URLs are not in this list + return FALSE; + } elseif (!isset($GLOBALS['blacklist_data']['url'][$url])) { + // Check black-list for given URL + $result = SQL_QUERY_ESC("SELECT UNIX_TIMESTAMP(`added`) AS `added`, `pool_id` FROM `{?_MYSQL_PREFIX?}_blacklist` WHERE `data`='%s' AND `type`='URL' LIMIT 1", + array($url), __FUNCTION__, __LINE__); + + // Is there an entry? + if (SQL_NUMROWS($result) == 1) { + // Jupp, we got one listed + $GLOBALS['blacklist_data']['url'][$url] = SQL_FETCHARRAY($result); + + // Mark it as listed + $listed = TRUE; + } // END - if + + // Free result + SQL_FREERESULT($result); + } else { + // Is found in cache -> black-listed + $listed = TRUE; + } + + // Return result + return $listed; +} + +// ---------------------------------------------------------------------------- +// Configuration wrapper functions +// ---------------------------------------------------------------------------- + +// Wrapper to check if url_blacklist is enabled +function isUrlBlacklistEnabled () { + // Is there cache? + if (!isset($GLOBALS[__FUNCTION__])) { + // Determine it + $GLOBALS[__FUNCTION__] = (getConfig('url_blacklist') == 'Y'); + } // END - if + + // Return cache + return $GLOBALS[__FUNCTION__]; +} + +// Wrapper to check if email_blacklist is enabled +function isEmailBlacklistEnabled () { + // Is there cache? + if (!isset($GLOBALS[__FUNCTION__])) { + // Determine it + $GLOBALS[__FUNCTION__] = (getConfig('email_blacklist') == 'Y'); + } // END - if + + // Return cache + return $GLOBALS[__FUNCTION__]; +} + +// [EOF] +?> diff --git a/inc/modules/admin/what-config_blacklist.php b/inc/modules/admin/what-config_blacklist.php new file mode 100644 index 0000000000..11f5b17bee --- /dev/null +++ b/inc/modules/admin/what-config_blacklist.php @@ -0,0 +1,55 @@ + diff --git a/inc/modules/admin/what-unlock_emails.php b/inc/modules/admin/what-unlock_emails.php index a9145f11b7..f23946d3ba 100644 --- a/inc/modules/admin/what-unlock_emails.php +++ b/inc/modules/admin/what-unlock_emails.php @@ -179,23 +179,14 @@ LIMIT 1', // Nothing selected displayMessage('{--ADMIN_MAILS_NOTHING_CHECKED--}'); } - } elseif ((isFormSent('lock')) && (ifPostContainsSelections()) && (isUrlBlacklistEnabled())) { + } elseif ((isFormSent('lock')) && (ifPostContainsSelections()) && (isExtensionActive('blacklist')) && (isUrlBlacklistEnabled())) { // Lock URLs foreach (postRequestElement('sel') as $id => $url) { // Secure id number $id = bigintval($id); // Lookup in blacklist - $result = SQL_QUERY_ESC("SELECT `id` FROM `{?_MYSQL_PREFIX?}_url_blacklist` WHERE `url`='%s' LIMIT 1", - array($url), __FILE__, __LINE__); - if (SQL_HASZERONUMS($result)) { - // Did not find a record so we can add it... :) - SQL_QUERY_ESC("INSERT INTO `{?_MYSQL_PREFIX?}_url_blacklist` (`url`, `pool_id`) VALUES ('%s',%s)", - array($url, $id), __FILE__, __LINE__); - } // END - if - - // Free memory - SQL_FREERESULT($result); + insertUrlInBlacklist($url); } // END - foreach // Output message @@ -219,7 +210,7 @@ LIMIT 1', // Load main template loadTemplate('admin_unlock_emails', FALSE, $content); - } elseif ((isFormSent('lock')) && (!isUrlBlacklistEnabled())) { + } elseif ((isFormSent('lock')) && ((!isExtensionActive('blacklist')) || (!isUrlBlacklistEnabled()))) { // URL blacklist not activated displayMessage('{--ADMIN_URL_BLACKLIST_DISABLED--}'); } else { diff --git a/inc/modules/member/what-order.php b/inc/modules/member/what-order.php index 60a07e03cf..a1f7a2a08f 100644 --- a/inc/modules/member/what-order.php +++ b/inc/modules/member/what-order.php @@ -124,7 +124,7 @@ LIMIT 1", } // END - if // And shall I check that his URL is not in the black list? - if (isUrlBlacklisted(postRequestElement('url'))) { + if ((isExtensionActive('blacklist')) && (isUrlBlacklisted(postRequestElement('url')))) { // Create redirect-URL $data['url'] = 'modules.php?module=login&what=order&code=' . getCode('BLIST_URL') . '&blist=' . $GLOBALS['blacklist_data'][postRequestElement('url')]['timestamp']; } // END - if diff --git a/inc/mysql-manager.php b/inc/mysql-manager.php index 6824a16c43..fd5fa60bc9 100644 --- a/inc/mysql-manager.php +++ b/inc/mysql-manager.php @@ -2451,40 +2451,6 @@ function doGenericListBuilder ($prefix, $listType, $tableName, $columns, $filter ); } -// Checks whether given URL is blacklisted -function isUrlBlacklisted ($url) { - // Mark it as not listed by default - $listed = FALSE; - - // Is black-listing enbaled? - if (!isUrlBlacklistEnabled()) { - // No, then all URLs are not in this list - return FALSE; - } elseif (!isset($GLOBALS['blacklist_data'][$url])) { - // Check black-list for given URL - $result = SQL_QUERY_ESC("SELECT UNIX_TIMESTAMP(`timestamp`) AS `blist_timestamp` FROM `{?_MYSQL_PREFIX?}_url_blacklist` WHERE `url`='%s' LIMIT 1", - array($url), __FILE__, __LINE__); - - // Is there an entry? - if (SQL_NUMROWS($result) == 1) { - // Jupp, we got one listed - $GLOBALS['blacklist_data'][$url] = SQL_FETCHARRAY($result); - - // Mark it as listed - $listed = TRUE; - } // END - if - - // Free result - SQL_FREERESULT($result); - } else { - // Is found in cache -> black-listed - $listed = TRUE; - } - - // Return result - return $listed; -} - // Adds key/value pair to a working SQL string together function addKeyValueSql ($key, $value) { // Init SQL diff --git a/inc/template-functions.php b/inc/template-functions.php index 8c749ab3a0..474a86baf0 100644 --- a/inc/template-functions.php +++ b/inc/template-functions.php @@ -2286,7 +2286,7 @@ function anonymizeSensitiveData ($data) { if (isAdmin()) { // Is admin, has always priority $data = '[{--ADMIN_TEST_URL--}]'; - } elseif (isUrlBlacklisted($data)) { + } elseif ((isExtensionActive('blacklist')) && (isUrlBlacklisted($data))) { // Yes, so replace it with text $data = '{--URL_IS_BLACKLISTED--}'; } else { diff --git a/inc/wrapper-functions.php b/inc/wrapper-functions.php index 35af66dc44..ad43853728 100644 --- a/inc/wrapper-functions.php +++ b/inc/wrapper-functions.php @@ -2816,18 +2816,6 @@ function getUserUsedPoints ($userid) { return $GLOBALS[__FUNCTION__][$userid]; } -// Wrapper to check if url_blacklist is enabled -function isUrlBlacklistEnabled () { - // Is there cache? - if (!isset($GLOBALS[__FUNCTION__])) { - // Determine it - $GLOBALS[__FUNCTION__] = (getConfig('url_blacklist') == 'Y'); - } // END - if - - // Return cache - return $GLOBALS[__FUNCTION__]; -} - // Checks whether direct payment is allowed in configuration function isDirectPaymentEnabled () { // Is there cache? diff --git a/install/tables.sql b/install/tables.sql index 0cc24a4e58..377eb78972 100644 --- a/install/tables.sql +++ b/install/tables.sql @@ -41,7 +41,6 @@ CREATE TABLE `{?_MYSQL_PREFIX?}_config` ( `max_tlength` BIGINT(20) UNSIGNED NOT NULL DEFAULT 1000, `autosend_active` ENUM('Y','N') NOT NULL DEFAULT 'N', `max_send` TINYINT(3) UNSIGNED NOT NULL DEFAULT 100, - `url_blacklist` ENUM('Y','N') NOT NULL DEFAULT 'Y', `auto_purge` TINYINT(3) UNSIGNED NOT NULL DEFAULT 14, `auto_purge_active` ENUM('Y','N') NOT NULL DEFAULT 'Y', `last_update` VARCHAR(10) NOT NULL DEFAULT '0', diff --git a/templates/de/html/admin/admin_config_blacklist.tpl b/templates/de/html/admin/admin_config_blacklist.tpl new file mode 100644 index 0000000000..5c21df5697 --- /dev/null +++ b/templates/de/html/admin/admin_config_blacklist.tpl @@ -0,0 +1,36 @@ +
+{%form,formMethodPost=modules.php?module=admin&what=config_blacklist%} +
+
+ {--ADMIN_CONFIG_BLACKLIST_TITLE--} +
+ +
+ {--ADMIN_CONFIG_BLACKLIST_LEGEND--} + +
+ +
+ {%template,ConfigurationYesNoSelectionBox=email_blacklist%} +
+
+ +
+ +
+ {%template,ConfigurationYesNoSelectionBox=url_blacklist%} +
+
+
+ + +
+{%form_close%} +
+ +
+ {--ADMIN_CONFIG_BLACKLIST_NOTICE--} +
diff --git a/templates/de/html/admin/admin_config_order.tpl b/templates/de/html/admin/admin_config_order.tpl index 8aac624d26..3157100795 100644 --- a/templates/de/html/admin/admin_config_order.tpl +++ b/templates/de/html/admin/admin_config_order.tpl @@ -54,13 +54,6 @@ -
- -
- {%template,ConfigurationYesNoSelectionBox=url_blacklist%} -
-
-
diff --git a/templates/de/html/ext/ext_blacklist.tpl b/templates/de/html/ext/ext_blacklist.tpl new file mode 100644 index 0000000000..b9a43270be --- /dev/null +++ b/templates/de/html/ext/ext_blacklist.tpl @@ -0,0 +1,4 @@ +
+ Sperren Sie Email-Adressen oder URLs mit dieser Erweiterung. Diese + Erweiterung sollte in keinem {?mt_word?} fehlen. +
-- 2.39.5