diff --git a/anti-spam-links/SMF-2.1/Sources/AntiSpamLinks.php b/anti-spam-links/SMF-2.1/Sources/AntiSpamLinks.php new file mode 100644 index 0000000..99ea50a --- /dev/null +++ b/anti-spam-links/SMF-2.1/Sources/AntiSpamLinks.php @@ -0,0 +1,532 @@ + Posts and Topics > Posts. + * + * @param array $config_vars + * @return void + */ +function AntiSpamLinks_ModifyPostSettings(&$config_vars) +{ + global $txt; + + antiSpamLinks_load_text(); + + $config_vars[] = ''; + $config_vars[] = $txt['anti_spam_links']; + $config_vars[] = array('int', 'anti_spam_links_nolinks', 'subtext' => $txt['anti_spam_links_zero_disable']); + $config_vars[] = array('int', 'anti_spam_links_newbielinks', 'subtext' => $txt['anti_spam_links_zero_disable']); + $config_vars[] = array('int', 'anti_spam_links_nofollowlinks', 'subtext' => $txt['anti_spam_links_zero_disable']); + $config_vars[] = array('select', 'anti_spam_links_guests', array( + $txt['anti_spam_links_guests_opt0'], + $txt['anti_spam_links_guests_opt1'], + $txt['anti_spam_links_guests_opt2'], + $txt['anti_spam_links_guests_opt3'], + )); +} + +/** + * Normalize settings before SMF saves them. + * + * @return void + */ +function AntiSpamLinks_SavePostSettings() +{ + if (!isset($_POST['anti_spam_links_newbielinks'], $_POST['anti_spam_links_nofollowlinks'])) + return; + + $_POST['anti_spam_links_newbielinks'] = max(0, (int) $_POST['anti_spam_links_newbielinks']); + $_POST['anti_spam_links_nofollowlinks'] = max(0, (int) $_POST['anti_spam_links_nofollowlinks']); + $_POST['anti_spam_links_nolinks'] = isset($_POST['anti_spam_links_nolinks']) ? max(0, (int) $_POST['anti_spam_links_nolinks']) : 0; + $_POST['anti_spam_links_guests'] = isset($_POST['anti_spam_links_guests']) ? min(3, max(0, (int) $_POST['anti_spam_links_guests'])) : 0; + + if (!empty($_POST['anti_spam_links_newbielinks']) && !empty($_POST['anti_spam_links_nofollowlinks']) && $_POST['anti_spam_links_nofollowlinks'] <= $_POST['anti_spam_links_newbielinks']) + $_POST['anti_spam_links_nofollowlinks'] = $_POST['anti_spam_links_newbielinks'] + 1; +} + +/** + * Validate post submission against link rules. + * + * @param array $post_errors + * @param array $minor_errors + * @param string $form_message + * @param string $form_subject + * @return void + */ +function AntiSpamLinks_PostErrors(&$post_errors, &$minor_errors, $form_message, $form_subject) +{ + $poster = antiSpamLinks_get_target_poster_context(); + + if (!antiSpamLinks_should_block_links($poster['id_member'], $poster['posts'])) + return; + + if (!antiSpamLinks_message_has_external_link($form_message)) + return; + + antiSpamLinks_load_text(); + + $error_key = antiSpamLinks_get_block_error_key($poster['id_member']); + + if (!in_array($error_key, $post_errors, true)) + $post_errors[] = $error_key; +} + +/** + * Adjust preview output for nonactive/nofollow rendering. + * + * @param string $form_message + * @param string $form_subject + * @return void + */ +function AntiSpamLinks_PreviewPost(&$form_message, &$form_subject) +{ + global $context; + + if (empty($context['preview_message'])) + return; + + $poster = antiSpamLinks_get_target_poster_context(); + $context['preview_message'] = antiSpamLinks_apply_to_html($context['preview_message'], $poster['id_member'], $poster['posts']); +} + +/** + * Validate quick-edit submissions. + * + * @param array $post_errors + * @param array $row + * @return void + */ +function AntiSpamLinks_JavaScriptModify(&$post_errors, $row) +{ + global $context; + + $poster_id = empty($row['id_member']) ? 0 : (int) $row['id_member']; + $posts = $poster_id === 0 ? 0 : antiSpamLinks_get_member_posts($poster_id); + + $context['anti_spam_links_jsmodify'] = array( + 'poster_id' => $poster_id, + 'posts' => $posts, + ); + + if (!isset($_POST['message'])) + return; + + if (!antiSpamLinks_should_block_links($poster_id, $posts)) + return; + + if (!antiSpamLinks_message_has_external_link($_POST['message'])) + return; + + antiSpamLinks_load_text(); + + $error_key = antiSpamLinks_get_block_error_key($poster_id); + $context['anti_spam_links_jsmodify_errors'] = array($error_key); + + if (!in_array($error_key, $post_errors, true)) + $post_errors[] = $error_key; +} + +/** + * Mark quick-edit body errors and post-process returned HTML. + * + * @return void + */ +function AntiSpamLinks_JavaScriptModifyXml() +{ + global $context; + + if (!empty($context['message']['body']) && !empty($context['anti_spam_links_jsmodify'])) + { + $context['message']['body'] = antiSpamLinks_apply_to_html( + $context['message']['body'], + $context['anti_spam_links_jsmodify']['poster_id'], + $context['anti_spam_links_jsmodify']['posts'] + ); + } + + if (!empty($context['message']) && !empty($context['anti_spam_links_jsmodify_errors'])) + $context['message']['error_in_body'] = true; +} + +/** + * Post-process displayed message HTML. + * + * @param array $output + * @param array $message + * @param int $counter + * @return void + */ +function AntiSpamLinks_PrepareDisplayContext(&$output, &$message, $counter) +{ + $poster_id = !empty($message['id_member']) ? (int) $message['id_member'] : 0; + $posts = !empty($output['member']['real_posts']) ? (int) $output['member']['real_posts'] : 0; + + $output['body'] = antiSpamLinks_apply_to_html($output['body'], $poster_id, $posts); +} + +/** + * Post-process previous topic summary posts on the editor screen. + * + * @param array $row + * @return void + */ +function AntiSpamLinks_PreviousPost(&$row) +{ + $poster_id = empty($row['id_member']) ? 0 : (int) $row['id_member']; + $posts = $poster_id === 0 ? 0 : antiSpamLinks_get_member_posts($poster_id); + + $row['body'] = antiSpamLinks_apply_to_html($row['body'], $poster_id, $posts); +} + +/** + * Post-process member signatures after SMF has parsed them. + * + * @param array $member + * @param int $user + * @param bool $display_custom_fields + * @return void + */ +function AntiSpamLinks_MemberContext(&$member, $user, $display_custom_fields) +{ + if (empty($member['signature'])) + return; + + $member['signature'] = antiSpamLinks_apply_to_html( + $member['signature'], + empty($member['id']) ? 0 : (int) $member['id'], + isset($member['real_posts']) ? (int) $member['real_posts'] : 0 + ); +} + +/** + * Load language strings once. + * + * @return void + */ +function antiSpamLinks_load_text() +{ + static $loaded = false; + + if ($loaded) + return; + + loadLanguage('AntiSpamLinks'); + $loaded = true; +} + +/** + * Resolve the poster context that should be used for validation/preview. + * + * @return array + */ +function antiSpamLinks_get_target_poster_context() +{ + global $user_info; + + if (!empty($_REQUEST['msg'])) + return antiSpamLinks_get_message_poster_context((int) $_REQUEST['msg']); + + return array( + 'id_member' => empty($user_info['is_guest']) ? (int) $user_info['id'] : 0, + 'posts' => empty($user_info['is_guest']) ? (int) $user_info['posts'] : 0, + ); +} + +/** + * Load the original poster context for a message. + * + * @param int $message_id + * @return array + */ +function antiSpamLinks_get_message_poster_context($message_id) +{ + global $smcFunc; + static $cache = array(); + + $message_id = (int) $message_id; + if (isset($cache[$message_id])) + return $cache[$message_id]; + + $cache[$message_id] = array( + 'id_member' => 0, + 'posts' => 0, + ); + + if (empty($message_id)) + return $cache[$message_id]; + + $request = $smcFunc['db_query']('', ' + SELECT IFNULL(m.id_member, 0) AS id_member, IFNULL(mem.posts, 0) AS posts + FROM {db_prefix}messages AS m + LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) + WHERE m.id_msg = {int:id_msg} + LIMIT 1', + array( + 'id_msg' => $message_id, + ) + ); + + if ($smcFunc['db_num_rows']($request) !== 0) + { + $row = $smcFunc['db_fetch_assoc']($request); + $cache[$message_id] = array( + 'id_member' => empty($row['id_member']) ? 0 : (int) $row['id_member'], + 'posts' => empty($row['posts']) ? 0 : (int) $row['posts'], + ); + } + + $smcFunc['db_free_result']($request); + + return $cache[$message_id]; +} + +/** + * Load a member's post count with a small request cache. + * + * @param int $member_id + * @return int + */ +function antiSpamLinks_get_member_posts($member_id) +{ + global $smcFunc; + static $cache = array(0 => 0); + + $member_id = (int) $member_id; + if (isset($cache[$member_id])) + return $cache[$member_id]; + + $cache[$member_id] = 0; + + if (empty($member_id)) + return 0; + + $request = $smcFunc['db_query']('', ' + SELECT posts + FROM {db_prefix}members + WHERE id_member = {int:id_member} + LIMIT 1', + array( + 'id_member' => $member_id, + ) + ); + + if ($smcFunc['db_num_rows']($request) !== 0) + { + list ($cache[$member_id]) = $smcFunc['db_fetch_row']($request); + $cache[$member_id] = (int) $cache[$member_id]; + } + + $smcFunc['db_free_result']($request); + + return $cache[$member_id]; +} + +/** + * Determine whether posting external links should be blocked. + * + * @param int $poster_id + * @param int $posts + * @return bool + */ +function antiSpamLinks_should_block_links($poster_id, $posts) +{ + global $modSettings; + + $poster_id = (int) $poster_id; + $posts = (int) $posts; + + if ($poster_id === 0) + return !empty($modSettings['anti_spam_links_guests']) && (int) $modSettings['anti_spam_links_guests'] === 1; + + return !empty($modSettings['anti_spam_links_nolinks']) && $posts < (int) $modSettings['anti_spam_links_nolinks']; +} + +/** + * Get the appropriate error key for posting restrictions. + * + * @param int $poster_id + * @return string + */ +function antiSpamLinks_get_block_error_key($poster_id) +{ + return (int) $poster_id === 0 ? 'anti_spam_links_nolinks_guest' : 'anti_spam_links_nolinks_member'; +} + +/** + * Check whether a raw message contains at least one external link after BBC parsing. + * + * @param string $message + * @return bool + */ +function antiSpamLinks_message_has_external_link($message) +{ + $parsed = parse_bbc($message, false); + + if ($parsed === '' || stripos($parsed, ']*\bhref="([^"]+)"[^>]*>~i', $parsed, $matches)) + return false; + + foreach ($matches[1] as $url) + if (!antiSpamLinks_is_internal_url($url)) + return true; + + return false; +} + +/** + * Apply nonactive/nofollow behavior to parsed HTML. + * + * @param string $html + * @param int $poster_id + * @param int $posts + * @return string + */ +function antiSpamLinks_apply_to_html($html, $poster_id, $posts) +{ + global $txt; + + $policy = antiSpamLinks_get_render_policy($poster_id, $posts); + + if ($policy['mode'] === 'none' || $html === '' || stripos($html, ']*\bhref="([^"]+)"[^>]*>.*?~i', + function ($matches) use ($policy, $txt) { + $url = $matches[1]; + if (antiSpamLinks_is_internal_url($url)) + return $matches[0]; + + return $txt['anti_spam_links_newbielink'] . $url . ' ' . $txt['anti_spam_links_nonactive'] . ''; + }, + $html + ); + } + + return preg_replace_callback( + '~]*\bhref="([^"]+)"[^>]*>.*?~i', + function ($matches) use ($policy, $txt) { + $url = $matches[1]; + $link = $matches[0]; + + if (antiSpamLinks_is_internal_url($url)) + return $link; + + if (preg_match('~\brel="([^"]*)"~i', $link, $rel_match)) + { + $rels = preg_split('~\s+~', trim($rel_match[1])); + if (!in_array('nofollow', $rels, true)) + $rels[] = 'nofollow'; + + $link = preg_replace('~\brel="[^"]*"~i', 'rel="' . implode(' ', array_filter($rels)) . '"', $link, 1); + } + else + $link = preg_replace('~' . $txt['anti_spam_links_nofollow'] . ''; + }, + $html + ); +} + +/** + * Decide which rendering policy applies to a poster. + * + * @param int $poster_id + * @param int $posts + * @return array + */ +function antiSpamLinks_get_render_policy($poster_id, $posts) +{ + global $modSettings, $txt; + + antiSpamLinks_load_text(); + + $poster_id = (int) $poster_id; + $posts = (int) $posts; + + if ($poster_id === 0) + { + $guest_mode = empty($modSettings['anti_spam_links_guests']) ? 0 : (int) $modSettings['anti_spam_links_guests']; + + if ($guest_mode === 2) + return array('mode' => 'nonactive', 'title' => $txt['anti_spam_links_guests_nonactive_info']); + if ($guest_mode === 3) + return array('mode' => 'nofollow', 'title' => $txt['anti_spam_links_guests_nofollow_info']); + + return array('mode' => 'none', 'title' => ''); + } + + if (!empty($modSettings['anti_spam_links_newbielinks']) && $posts < (int) $modSettings['anti_spam_links_newbielinks']) + return array( + 'mode' => 'nonactive', + 'title' => sprintf($txt['anti_spam_links_newbielinks_info'], (int) $modSettings['anti_spam_links_newbielinks']), + ); + + if (!empty($modSettings['anti_spam_links_nofollowlinks']) && $posts < (int) $modSettings['anti_spam_links_nofollowlinks']) + return array( + 'mode' => 'nofollow', + 'title' => sprintf($txt['anti_spam_links_nofollowlinks_info'], (int) $modSettings['anti_spam_links_nofollowlinks']), + ); + + return array('mode' => 'none', 'title' => ''); +} + +/** + * Check whether a URL should be treated as internal to the forum. + * + * @param string $url + * @return bool + */ +function antiSpamLinks_is_internal_url($url) +{ + global $boardurl; + + $url = trim(htmlspecialchars_decode((string) $url, ENT_QUOTES)); + + if ($url === '') + return true; + + if ($url[0] === '#' || $url[0] === '/') + return true; + + if (strpos($url, './') === 0 || strpos($url, '../') === 0) + return true; + + $normalized_boardurl = rtrim((string) $boardurl, '/'); + if ($normalized_boardurl !== '' && stripos($url, $normalized_boardurl) === 0) + return true; + + $board_parts = @parse_url($boardurl); + $url_parts = @parse_url($url); + + if (!empty($board_parts['host']) && !empty($url_parts['host']) && strtolower($board_parts['host']) === strtolower($url_parts['host'])) + return true; + + return false; +} + diff --git a/anti-spam-links/SMF-2.1/Themes/default/languages/AntiSpamLinks.english.php b/anti-spam-links/SMF-2.1/Themes/default/languages/AntiSpamLinks.english.php new file mode 100644 index 0000000..eb363e6 --- /dev/null +++ b/anti-spam-links/SMF-2.1/Themes/default/languages/AntiSpamLinks.english.php @@ -0,0 +1,24 @@ +(Use 0 to disable)'; +$txt['anti_spam_links_guests'] = 'Guests...'; +$txt['anti_spam_links_guests_opt0'] = '(disable mod for guests)'; +$txt['anti_spam_links_guests_opt1'] = 'cannot post links'; +$txt['anti_spam_links_guests_opt2'] = 'links are shown [nonactive]'; +$txt['anti_spam_links_guests_opt3'] = 'links are set [nofollow]'; + diff --git a/anti-spam-links/SMF-2.1/Themes/default/languages/AntiSpamLinks.vietnamese.php b/anti-spam-links/SMF-2.1/Themes/default/languages/AntiSpamLinks.vietnamese.php new file mode 100644 index 0000000..fd0cf95 --- /dev/null +++ b/anti-spam-links/SMF-2.1/Themes/default/languages/AntiSpamLinks.vietnamese.php @@ -0,0 +1,24 @@ +(Nhap 0 de tat)'; +$txt['anti_spam_links_guests'] = 'Khach...'; +$txt['anti_spam_links_guests_opt0'] = '(tat mod cho khach)'; +$txt['anti_spam_links_guests_opt1'] = 'khong duoc dang lien ket'; +$txt['anti_spam_links_guests_opt2'] = 'lien ket hien [nonactive]'; +$txt['anti_spam_links_guests_opt3'] = 'lien ket duoc gan [nofollow]'; + diff --git a/anti-spam-links/install.php b/anti-spam-links/install.php new file mode 100644 index 0000000..bce4df3 --- /dev/null +++ b/anti-spam-links/install.php @@ -0,0 +1,89 @@ + dirname(__FILE__) . '/SMF-2.1/Sources/AntiSpamLinks.php', + 'destination' => $sourcedir . '/AntiSpamLinks.php', + ), + array( + 'source' => dirname(__FILE__) . '/SMF-2.1/Themes/default/languages/AntiSpamLinks.english.php', + 'destination' => $boarddir . '/Themes/default/languages/AntiSpamLinks.english.php', + ), + array( + 'source' => dirname(__FILE__) . '/SMF-2.1/Themes/default/languages/AntiSpamLinks.vietnamese.php', + 'destination' => $boarddir . '/Themes/default/languages/AntiSpamLinks.vietnamese.php', + ), +); + +if ($manual) +{ + foreach ($package_files as $file) + { + if (!file_exists($file['source'])) + continue; + + @copy($file['source'], $file['destination']); + @chmod($file['destination'], 0644); + } + + $hooks = array( + array('integrate_load_theme', 'AntiSpamLinks_LoadTheme'), + array('integrate_modify_post_settings', 'AntiSpamLinks_ModifyPostSettings'), + array('integrate_save_post_settings', 'AntiSpamLinks_SavePostSettings'), + array('integrate_post_errors', 'AntiSpamLinks_PostErrors'), + array('integrate_preview_post', 'AntiSpamLinks_PreviewPost'), + array('integrate_post_JavascriptModify', 'AntiSpamLinks_JavaScriptModify'), + array('integrate_jsmodify_xml', 'AntiSpamLinks_JavaScriptModifyXml'), + array('integrate_prepare_display_context', 'AntiSpamLinks_PrepareDisplayContext'), + array('integrate_getTopic_previous_post', 'AntiSpamLinks_PreviousPost'), + array('integrate_member_context', 'AntiSpamLinks_MemberContext'), + ); + + foreach ($hooks as $hook) + add_integration_function($hook[0], $hook[1], true, '$sourcedir/AntiSpamLinks.php'); +} + +$defaults = array( + 'anti_spam_links_nolinks' => 0, + 'anti_spam_links_newbielinks' => 0, + 'anti_spam_links_nofollowlinks' => 0, + 'anti_spam_links_guests' => 0, +); + +$to_update = array(); +foreach ($defaults as $setting => $value) +{ + if (!isset($modSettings[$setting])) + $to_update[$setting] = $value; +} + +if (!empty($to_update)) + updateSettings($to_update); + +if (isset($cacheAPI) && is_object($cacheAPI) && is_callable(array($cacheAPI, 'cleanCache'))) + $cacheAPI->cleanCache(); + +if ($manual) +{ + header('Content-Type: text/plain; charset=UTF-8'); + echo "Anti-Spam Links for SMF 2.1.x installed.\n"; +} + diff --git a/anti-spam-links/license.txt b/anti-spam-links/license.txt index db80f4c..00e4e8b 100644 --- a/anti-spam-links/license.txt +++ b/anti-spam-links/license.txt @@ -1,24 +1,20 @@ -Copyright (c) 2018, Simple Machines -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +BSD 3-Clause License + +Acknowledgements + +This package is based on the original Anti-Spam Links modification for SMF: +https://custom.simplemachines.org/mods/index.php?mod=2404 + +SMF 2.1.x port and rewrite by: +Thanh Nguyen (hoidulich.com) + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of Thanh Nguyen nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED. + diff --git a/anti-spam-links/modification.xml b/anti-spam-links/modification.xml deleted file mode 100644 index 4eeae2a..0000000 --- a/anti-spam-links/modification.xml +++ /dev/null @@ -1,374 +0,0 @@ - - - - CustomizeTeam:AntiSpamLinks - 1.0 - - - - - - - - - - - - - - - - - - - $txt['anti_spam_links_zero_disable']), - array('int', 'anti_spam_links_newbielinks', 'subtext' => $txt['anti_spam_links_zero_disable']), - array('int', 'anti_spam_links_nofollowlinks', 'subtext' => $txt['anti_spam_links_zero_disable']), - array('select', 'anti_spam_links_guests', array(&$txt['anti_spam_links_guests_opt0'], &$txt['anti_spam_links_guests_opt1'], &$txt['anti_spam_links_guests_opt2'], &$txt['anti_spam_links_guests_opt3'])), - '', -]]> - - - - - = (int) $save_vars['anti_spam_links_nofollowlinks']) - (int) $save_vars['anti_spam_links_nofollowlinks'] = (int) $save_vars['anti_spam_links_newbielinks'] + 1; - - // End of Anti-Spam-Links mod - -]]> - - - - - - - $_REQUEST['msg'], - ) - ); - // Error, so treat them as a guest. - if ($smcFunc['db_num_rows']($request) == 0) - $poster_id = $posts = 0; - - list($poster_id, $posts) = $smcFunc['db_fetch_row']($request); - $smcFunc['db_free_result']($request); - } - else - { - $poster_id = $user_info['is_guest'] ? 0 : $user_info['id']; - $posts = $user_info['is_guest'] ? 0 : $user_info['posts']; - } - // Are we editing our own post - $own_post = $poster_id != $user_info['id']; - - global $boardurl; - // Ugly but necessary. - // Takes into account moderation when deciding whether to show the post error. - if((($own_post && $user_info['is_guest']) || (!$own_post && empty($poster_id)) && $modSettings['anti_spam_links_guests'] == 1) || ((($own_post && !$user_info['is_guest']) || !$own_post && !empty($poster_id)) && !empty($modSettings['anti_spam_links_nolinks']) && $posts < $modSettings['anti_spam_links_nolinks'])) - // Your not allowed to use links, so give them an error. - if (preg_match('~ - - - - - - - - - - - $poster_id, - ) - ); - // Error, so treat them as a guest. - if ($smcFunc['db_num_rows']($request) == 0) - $poster_id = $posts = 0; - - list($posts) = $smcFunc['db_fetch_row']($request); - $smcFunc['db_free_result']($request); - } - else - $posts = 0; - } - else - // Editing own post - $posts = $user_info['is_guest'] ? 0 : $user_info['posts']; - - global $boardurl; - // Ugly but necessary. - // Takes into account moderation when deciding whether to show the post error. - if((($own_post && $user_info['is_guest']) || (!$own_post && empty($poster_id)) && $modSettings['anti_spam_links_guests'] == 1) || ((($own_post && !$user_info['is_guest']) || !$own_post && !empty($poster_id)) && !empty($modSettings['anti_spam_links_nolinks']) && $posts < $modSettings['anti_spam_links_nolinks'])) - // Your not allowed to use links, so give them an error. - if (preg_match('~ - - - - - - - - - - - $poster_id, - ) - ); - // Error, so treat them as a guest. - if ($smcFunc['db_num_rows']($request) == 0) - $poster_id = $posts = 0; - - list($posts) = $smcFunc['db_fetch_row']($request); - $smcFunc['db_free_result']($request); - } - else - $posts = 0; - } - else - // Editing own post - $posts = $user_info['is_guest'] ? 0 : $user_info['posts']; - - global $boardurl; - // Ugly but necessary. - // Takes into account moderation when deciding whether to show the post error. - if((($own_post && $user_info['is_guest']) || (!$own_post && empty($poster_id)) && $modSettings['anti_spam_links_guests'] == 1) || ((($own_post && !$user_info['is_guest']) || !$own_post && !empty($poster_id)) && !empty($modSettings['anti_spam_links_nolinks']) && $posts < $modSettings['anti_spam_links_nolinks'])) - // Your not allowed to use links, so give them an error. - if (preg_match('~ - - - - - in_array('no_message', $post_errors) || in_array('long_message', $post_errors), -]]> - in_array('no_message', $post_errors) || in_array('long_message', $post_errors) || in_array('anti_spam_links_nolinks_member', $post_errors) || in_array('anti_spam_links_nolinks_guest', $post_errors), -]]> - - - - - - - - - - - '  ', "\r" => '', "\n" => '
', '
' => '
 ', ' ' => "\n")); -]]>
- ]*?)>(?:.*?)
~i', $txt['anti_spam_links_newbielink'] . '$1 ' . $txt['anti_spam_links_nonactive'] . '', $message); - - // Links get rel="nofollow" so no page rank for you. - elseif ((($poster_id === 0 && $modSettings['anti_spam_links_guests'] == 3) || (!empty($poster_id) && !empty($modSettings['anti_spam_links_nofollowlinks']) && $posts != '' && $posts < $modSettings['anti_spam_links_nofollowlinks'])) && strpos($message, ']*?)\>(?:.*?))~i', '$1 rel="nofollow"$2 ' . $txt['anti_spam_links_nofollow'] . '', $message); - - // End of Anti-Spam-Links mod -]]> - - - - - - - (Use 0 to disable)'; -$txt['anti_spam_links_guests'] = 'Guests... '; -$txt['anti_spam_links_guests_opt0'] = '(disable mod for guests)'; -$txt['anti_spam_links_guests_opt1'] = 'can not post links'; -$txt['anti_spam_links_guests_opt2'] = 'links are shown [nonactive]'; -$txt['anti_spam_links_guests_opt3'] = 'links are set [nofollow]'; -]]> - - - - - - (Use 0 to disable)'; -$txt['anti_spam_links_guests'] = 'Guests... '; -$txt['anti_spam_links_guests_opt0'] = '(disable mod for guests)'; -$txt['anti_spam_links_guests_opt1'] = 'can not post links'; -$txt['anti_spam_links_guests_opt2'] = 'links are shown [nonactive]'; -$txt['anti_spam_links_guests_opt3'] = 'links are set [nofollow]'; -]]> - - -
\ No newline at end of file diff --git a/anti-spam-links/modificationrc4.xml b/anti-spam-links/modificationrc4.xml deleted file mode 100644 index 2ca925e..0000000 --- a/anti-spam-links/modificationrc4.xml +++ /dev/null @@ -1,374 +0,0 @@ - - - - CustomizeTeam:AntiSpamLinks - 1.0 - - - - - - - - - - - - - - - - - - - $txt['anti_spam_links_zero_disable']), - array('int', 'anti_spam_links_newbielinks', 'subtext' => $txt['anti_spam_links_zero_disable']), - array('int', 'anti_spam_links_nofollowlinks', 'subtext' => $txt['anti_spam_links_zero_disable']), - array('select', 'anti_spam_links_guests', array(&$txt['anti_spam_links_guests_opt0'], &$txt['anti_spam_links_guests_opt1'], &$txt['anti_spam_links_guests_opt2'], &$txt['anti_spam_links_guests_opt3'])), - '', -]]> - - - - - = (int) $save_vars['anti_spam_links_nofollowlinks']) - (int) $save_vars['anti_spam_links_nofollowlinks'] = (int) $save_vars['anti_spam_links_newbielinks'] + 1; - - // End of Anti-Spam-Links mod - -]]> - - - - - - - $_REQUEST['msg'], - ) - ); - // Error, so treat them as a guest. - if ($smcFunc['db_num_rows']($request) == 0) - $poster_id = $posts = 0; - - list($poster_id, $posts) = $smcFunc['db_fetch_row']($request); - $smcFunc['db_free_result']($request); - } - else - { - $poster_id = $user_info['is_guest'] ? 0 : $user_info['id']; - $posts = $user_info['is_guest'] ? 0 : $user_info['posts']; - } - // Are we editing our own post - $own_post = $poster_id != $user_info['id']; - - global $boardurl; - // Ugly but necessary. - // Takes into account moderation when deciding whether to show the post error. - if((($own_post && $user_info['is_guest']) || (!$own_post && empty($poster_id)) && $modSettings['anti_spam_links_guests'] == 1) || ((($own_post && !$user_info['is_guest']) || !$own_post && !empty($poster_id)) && !empty($modSettings['anti_spam_links_nolinks']) && $posts < $modSettings['anti_spam_links_nolinks'])) - // Your not allowed to use links, so give them an error. - if (preg_match('~ - - - - - - - - - - - $poster_id, - ) - ); - // Error, so treat them as a guest. - if ($smcFunc['db_num_rows']($request) == 0) - $poster_id = $posts = 0; - - list($posts) = $smcFunc['db_fetch_row']($request); - $smcFunc['db_free_result']($request); - } - else - $posts = 0; - } - else - // Editing own post - $posts = $user_info['is_guest'] ? 0 : $user_info['posts']; - - global $boardurl; - // Ugly but necessary. - // Takes into account moderation when deciding whether to show the post error. - if((($own_post && $user_info['is_guest']) || (!$own_post && empty($poster_id)) && $modSettings['anti_spam_links_guests'] == 1) || ((($own_post && !$user_info['is_guest']) || !$own_post && !empty($poster_id)) && !empty($modSettings['anti_spam_links_nolinks']) && $posts < $modSettings['anti_spam_links_nolinks'])) - // Your not allowed to use links, so give them an error. - if (preg_match('~ - - - - - - - - - - - $poster_id, - ) - ); - // Error, so treat them as a guest. - if ($smcFunc['db_num_rows']($request) == 0) - $poster_id = $posts = 0; - - list($posts) = $smcFunc['db_fetch_row']($request); - $smcFunc['db_free_result']($request); - } - else - $posts = 0; - } - else - // Editing own post - $posts = $user_info['is_guest'] ? 0 : $user_info['posts']; - - global $boardurl; - // Ugly but necessary. - // Takes into account moderation when deciding whether to show the post error. - if((($own_post && $user_info['is_guest']) || (!$own_post && empty($poster_id)) && $modSettings['anti_spam_links_guests'] == 1) || ((($own_post && !$user_info['is_guest']) || !$own_post && !empty($poster_id)) && !empty($modSettings['anti_spam_links_nolinks']) && $posts < $modSettings['anti_spam_links_nolinks'])) - // Your not allowed to use links, so give them an error. - if (preg_match('~ - - - - - in_array('no_message', $post_errors) || in_array('long_message', $post_errors), -]]> - in_array('no_message', $post_errors) || in_array('long_message', $post_errors) || in_array('anti_spam_links_nolinks_member', $post_errors) || in_array('anti_spam_links_nolinks_guest', $post_errors), -]]> - - - - - - - - - - - '  ', "\r" => '', "\n" => '
', '
' => '
 ', ' ' => "\n")); -]]>
- ]*?)>(?:.*?)
~i', $txt['anti_spam_links_newbielink'] . '$1 ' . $txt['anti_spam_links_nonactive'] . '', $message); - - // Links get rel="nofollow" so no page rank for you. - elseif ((($poster_id === 0 && $modSettings['anti_spam_links_guests'] == 3) || (!empty($poster_id) && !empty($modSettings['anti_spam_links_nofollowlinks']) && $posts != '' && $posts < $modSettings['anti_spam_links_nofollowlinks'])) && strpos($message, ']*?)\>(?:.*?))~i', '$1 rel="nofollow"$2 ' . $txt['anti_spam_links_nofollow'] . '', $message); - - // End of Anti-Spam-Links mod -]]> - - - - - - - (Use 0 to disable)'; -$txt['anti_spam_links_guests'] = 'Guests... '; -$txt['anti_spam_links_guests_opt0'] = '(disable mod for guests)'; -$txt['anti_spam_links_guests_opt1'] = 'can not post links'; -$txt['anti_spam_links_guests_opt2'] = 'links are shown [nonactive]'; -$txt['anti_spam_links_guests_opt3'] = 'links are set [nofollow]'; -]]> - - - - - - (Use 0 to disable)'; -$txt['anti_spam_links_guests'] = 'Guests... '; -$txt['anti_spam_links_guests_opt0'] = '(disable mod for guests)'; -$txt['anti_spam_links_guests_opt1'] = 'can not post links'; -$txt['anti_spam_links_guests_opt2'] = 'links are shown [nonactive]'; -$txt['anti_spam_links_guests_opt3'] = 'links are set [nofollow]'; -]]> - - -
\ No newline at end of file diff --git a/anti-spam-links/package-info.xml b/anti-spam-links/package-info.xml index 29cc22e..769e9e7 100644 --- a/anti-spam-links/package-info.xml +++ b/anti-spam-links/package-info.xml @@ -1,30 +1,48 @@ - - - - Anti-Spam Links - CustomizeTeam:AntiSpamLinks - modification - 1.0.2 - - modification - - - readme.txt - modification.xml - updateDatabase.php - - - - modification.xml - - - - readme.txt - modificationrc4.xml - updateDatabase.php - - - - modificationrc4.xml - - \ No newline at end of file + + + + + CustomizeTeam:AntiSpamLinks + Anti-Spam Links for SMF 2.1.x + 2.1.0 + modification + + + readme.txt + install.php + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + uninstall.php + + + + + + diff --git a/anti-spam-links/readme.txt b/anti-spam-links/readme.txt index acf998d..c7235ca 100644 --- a/anti-spam-links/readme.txt +++ b/anti-spam-links/readme.txt @@ -1,49 +1,36 @@ -[center][size=1.7em][color=purple][b]Anti-Spam Links[/b][/color][/size][/center] - -[hr] -[b]Original Author:[/b] JBlaze | [b]Current Author:[/b] [url=https://www.simplemachines.org/community/index.php?action=profile;u=1][b]SMF Customization Team[/b][/url] -[b]Supported Languages:[/b] English -[url=https://custom.simplemachines.org/mods/index.php?mod=2404][b]Link to Mod[/b][/url] | [url=https://www.simplemachines.org/community/index.php?topic=364169.0][b]Mod Discussion[/b][/url] | [url=https://custom.simplemachines.org/mods/index.php?action=profile;u=1][b]Other SMF Customization Team Mods[/b][/url] -[hr] - -[color=purple][b]Compatibility[/b][/color] -For SMF 2.0.x - -[color=purple][b]Introduction[/b][/color] -Adds some new settings based on post counts to help curb link spammers. - -[color=purple][b]Features[/b][/color] -Adds some new settings based on post counts to help curb link spammers. -- No links -- Links set [nonactive] and with newbielink: -- Links set [nofollow] so no pagerank -- Guest setting -EXCLUDES yoursite.com links, so only use on any part of *.yoursite.com ;) - -Translations for other languages are welcome. Please post the translated language strings in the Support Topic. - -[color=purple][b]Installation[/b][/color] -Any previous versions of this mod MUST be uninstalled BEFORE installing this version. - -Simply install the package to install on the SMF Default Core Theme ONLY. - -Manual edits will be required for ALL themes (other than SMF Default Core Theme) which have a custom MessageIndex.template.php and/or Display.template.php - -If your theme has its own versions of the language files Modifications.english.php and/or Modifications.english-utf8.php, OR if you're using a language other than those supported (listed above) by the mod then you will need to copy the language strings into each custom version of those files. - -[b]Useful Links[/b] -[url=https://docs.simplemachines.org/index.php?topic=402]Manual Installation Of Mods[/url] -[url=https://www.simplemachines.org/community/index.php?topic=24110.0]How Do I Modify Files?[/url] - -[color=purple][b]Support[/b][/color] -Please use the modification thread for support with this modification. - -[color=purple][b]Changelog[/b][/color] -[tt] -[b]Version 1.1 - 6/12/09[/b] - Initial Release -[/tt] - - -Copyright (c) 2020, Simple Machines, under BSD 3-Clause License. -All rights reserved. \ No newline at end of file +Anti-Spam Links for SMF 2.1.x +================================ + +This package ports the classic Anti-Spam Links mod from SMF 2.0.x to SMF 2.1.x. + +What it does +------------ +- Blocks external links for low-post members if configured. +- Rewrites external links as non-clickable text for low-post members if configured. +- Adds rel="nofollow" to external links for low-post members if configured. +- Supports guest-specific handling. +- Applies to post preview, quick edit XML responses, displayed posts, topic summaries, and member signatures. + +How this port differs from the old 2.0.x package +------------------------------------------------ +- Uses SMF 2.1 integration hooks instead of editing SMF core files directly. +- Adds a Vietnamese language file in addition to English. +- Keeps settings under: + Admin > Posts and Topics > Posts + +Settings +-------- +- Post count under which members cannot post external links +- Post count under which members external links are shown [nonactive] +- Post count under which members external links are set [nofollow] +- Guest behavior: + - disable mod for guests + - cannot post links + - links are shown [nonactive] + - links are set [nofollow] + +Notes +----- +- Internal links to your forum are excluded. +- If both "nonactive" and "nofollow" thresholds are enabled, the package ensures the nofollow threshold stays above the nonactive threshold. + diff --git a/anti-spam-links/screenshots/admin-setting.png b/anti-spam-links/screenshots/admin-setting.png new file mode 100644 index 0000000..6e8c6b8 Binary files /dev/null and b/anti-spam-links/screenshots/admin-setting.png differ diff --git a/anti-spam-links/screenshots/link-converted.png b/anti-spam-links/screenshots/link-converted.png new file mode 100644 index 0000000..1bd04cf Binary files /dev/null and b/anti-spam-links/screenshots/link-converted.png differ diff --git a/anti-spam-links/screenshots/post-blocked-link.png b/anti-spam-links/screenshots/post-blocked-link.png new file mode 100644 index 0000000..a745238 Binary files /dev/null and b/anti-spam-links/screenshots/post-blocked-link.png differ diff --git a/anti-spam-links/uninstall.php b/anti-spam-links/uninstall.php new file mode 100644 index 0000000..a6e2393 --- /dev/null +++ b/anti-spam-links/uninstall.php @@ -0,0 +1,68 @@ + null, + 'anti_spam_links_newbielinks' => null, + 'anti_spam_links_nofollowlinks' => null, + 'anti_spam_links_guests' => null, +)); + +$package_files = array( + $sourcedir . '/AntiSpamLinks.php', + $boarddir . '/Themes/default/languages/AntiSpamLinks.english.php', + $boarddir . '/Themes/default/languages/AntiSpamLinks.vietnamese.php', +); + +if ($manual) +{ + foreach ($package_files as $file) + if (file_exists($file)) + @unlink($file); +} + +if (isset($cacheAPI) && is_object($cacheAPI) && is_callable(array($cacheAPI, 'cleanCache'))) + $cacheAPI->cleanCache(); + +if ($manual) +{ + header('Content-Type: text/plain; charset=UTF-8'); + echo "Anti-Spam Links for SMF 2.1.x uninstalled.\n"; +} + diff --git a/anti-spam-links/updateDatabase.php b/anti-spam-links/updateDatabase.php deleted file mode 100644 index c750ab2..0000000 --- a/anti-spam-links/updateDatabase.php +++ /dev/null @@ -1,20 +0,0 @@ - 0, - 'anti_spam_links_newbielinks' => 0, - 'anti_spam_links_nofollowlinks' => 0, - 'anti_spam_links_guests' => 0, -)); - -?> \ No newline at end of file