Example #1
0
 public static function filter($text, $replacementText = null)
 {
     if (self::$words === null) {
         self::$words = file(dirname(__FILE__) . self::BAD_WORDS_FILE, FILE_IGNORE_NEW_LINES);
     }
     if (extension_loaded('mbstring')) {
         mb_internal_encoding("UTF-8");
         foreach (self::$words as $word) {
             $notFuzzyMatching = true;
             $word = trim($word);
             // detect empty lines and comments:
             if (self::isCommentOrEmpty($word)) {
                 continue;
             }
             // fuzzy matching:
             if (self::isFuzzyMatchingMb($word)) {
                 $notFuzzyMatching = false;
                 $word = trim($word, '[]');
             }
             // masked word:
             $masked = self::getMaskedWordMb($word, $replacementText);
             // compose regexp for the word:
             $regexp = mb_substr($word, 0, 1);
             for ($i = 1; $i < mb_strlen($word); $i++) {
                 $regexp .= "[^\\p{L}]*";
                 $regexp .= preg_quote(mb_substr($word, $i, 1));
             }
             // if not fuzzy matching:
             if ($notFuzzyMatching) {
                 $regexp = "(^|[^\\p{L}])" . $regexp . "([^\\p{L}]|\$)";
                 $masked = '$1' . $masked . '$2';
             }
             $text = preg_replace("/{$regexp}/ui", $masked, $text);
         }
     } else {
         foreach (self::$words as $word) {
             $notFuzzyMatching = true;
             $word = trim($word);
             // detect empty lines and comments:
             if (self::isCommentOrEmpty($word)) {
                 continue;
             }
             // fuzzy matching:
             if (self::isFuzzyMatching($word)) {
                 $notFuzzyMatching = false;
                 $word = trim($word, '[]');
             }
             // masked word:
             $masked = $replacementText !== null ? $replacementText : self::getMaskedWord($word);
             // compose regexp for the word:
             $regexp = substr($word, 0, 1);
             for ($i = 1; $i < strlen($word); $i++) {
                 $regexp .= "[^\\p{L}]*";
                 $regexp .= preg_quote(substr($word, $i, 1));
             }
             // if not fuzzy matching:
             if ($notFuzzyMatching) {
                 $regexp = "(^|[^\\p{L}])" . $regexp . "([^\\p{L}]|\$)";
                 $masked = '$1' . $masked . '$2';
             }
             $text = preg_replace("/{$regexp}/i", $masked, $text);
         }
     }
     return $text;
 }
 /**
  * Validates given username.
  *
  * @param string $userName
  *
  * @return string Validated username (trimmed and filtered)
  * @throws Exception If username is not valid
  */
 public function validateUserName($userName)
 {
     $userName = trim($userName);
     // check for valid characters:
     if (strlen($userName) == 0 || !preg_match('/^[a-zA-Z0-9\\-_ ]+$/', $userName)) {
         throw new Exception($this->options->getOption('message_error_1', 'Only letters, number, spaces, hyphens and underscores are allowed'));
     }
     // filter the new username:
     if ($this->options->isOptionEnabled('filter_bad_words')) {
         WiseChatContainer::load('rendering/filters/pre/WiseChatFilter');
         $userName = WiseChatFilter::filter($userName);
     }
     // check if the new username is already occupied:
     $occupiedException = new Exception($this->options->getOption('message_error_2', 'This name is already occupied'));
     $prefix = $this->options->getOption('user_name_prefix', 'Anonymous');
     if ($this->getUserNameOrEmptyString() == $userName || $this->usersDAO->getWpUserByDisplayName($userName) !== null || $this->usersDAO->getWpUserByLogin($userName) !== null || $this->channelUsersDAO->isUserNameOccupied($userName, $this->userSessionDAO->getSessionId()) || preg_match("/^{$prefix}/", $userName) || $userName == $this->getSystemUser()->getName()) {
         throw $occupiedException;
     }
     return $userName;
 }
Example #3
0
 /**
  * @dataProvider dataFuzzyNegativeUnicode
  */
 public function testFuzzyNegativeUnicode($input, $output)
 {
     WiseChatFilter::$words = array('[balls]', '[kość]');
     if (extension_loaded(self::$mbExtension)) {
         $this->assertEquals($output, WiseChatFilter::filter($input));
     }
 }
 /**
  * Publishes a message in the given channel of the chat and returns it.
  *
  * @param WiseChatUser $user Author of the message
  * @param WiseChatChannel $channel A channel to publish in
  * @param string $text Content of the message
  * @param boolean $isAdmin Indicates whether to mark the message as admin-owned
  *
  * @return WiseChatMessage|null
  * @throws Exception On validation error
  */
 public function addMessage($user, $channel, $text, $isAdmin = false)
 {
     $text = trim($text);
     $filteredMessage = $text;
     // basic validation:
     if ($user === null) {
         throw new Exception('User cannot be null');
     }
     if ($channel === null) {
         throw new Exception('Channel cannot be null');
     }
     if ($this->bansService->isIpAddressBanned($user->getIp())) {
         throw new Exception($this->options->getOption('message_error_3', 'You were banned from posting messages'));
     }
     // use bad words filtering:
     if ($this->options->isOptionEnabled('filter_bad_words')) {
         WiseChatContainer::load('rendering/filters/pre/WiseChatFilter');
         $badWordsFilterReplacement = $this->options->getOption('bad_words_replacement_text');
         $filteredMessage = WiseChatFilter::filter($filteredMessage, strlen($badWordsFilterReplacement) > 0 ? $badWordsFilterReplacement : null);
     }
     // auto-ban feature:
     if ($this->options->isOptionEnabled('enable_autoban') && $filteredMessage != $text) {
         $counter = $this->abuses->incrementAndGetAbusesCounter();
         $threshold = $this->options->getIntegerOption('autoban_threshold', 3);
         if ($counter >= $threshold && $threshold > 0) {
             $duration = $this->options->getIntegerOption('autoban_duration', 1440);
             $this->bansService->banIpAddress($user->getIp(), $this->bansService->getDurationFromString($duration . 'm'));
             $this->abuses->clearAbusesCounter();
         }
     }
     // flood prevention feature:
     if ($this->options->isOptionEnabled('enable_flood_control')) {
         $floodControlThreshold = $this->options->getIntegerOption('flood_control_threshold', 200);
         $floodControlTimeFrame = $this->options->getIntegerOption('flood_control_time_frame', 1);
         if ($floodControlThreshold > 0 && $floodControlTimeFrame > 0) {
             $messagesAmount = $this->messagesDAO->getNumberByCriteria(WiseChatMessagesCriteria::build()->setIp($user->getIp())->setMinimumTime(time() - $floodControlTimeFrame * 60));
             if ($messagesAmount > $floodControlThreshold) {
                 $duration = $this->options->getIntegerOption('flood_control_ban_duration', 1440);
                 $this->bansService->banIpAddress($user->getIp(), $this->bansService->getDurationFromString($duration . 'm'));
             }
         }
     }
     // go through the custom filters:
     $filterChain = WiseChatContainer::get('services/WiseChatFilterChain');
     $filteredMessage = $filterChain->filter($filteredMessage);
     // cut the message:
     $messageMaxLength = $this->options->getIntegerOption('message_max_length', 100);
     if ($messageMaxLength > 0) {
         $filteredMessage = substr($filteredMessage, 0, $messageMaxLength);
     }
     // convert images and links into proper shortcodes and download images (if enabled):
     /** @var WiseChatLinksPreFilter $linksPreFilter */
     $linksPreFilter = WiseChatContainer::get('rendering/filters/pre/WiseChatLinksPreFilter');
     $filteredMessage = $linksPreFilter->filter($filteredMessage, $this->options->isOptionEnabled('allow_post_images'), $this->options->isOptionEnabled('enable_youtube'));
     $message = new WiseChatMessage();
     $message->setTime(time());
     $message->setAdmin($isAdmin);
     $message->setUserName($user->getName());
     $message->setUserId($user->getId());
     $message->setText($filteredMessage);
     $message->setChannelName($channel->getName());
     $message->setIp($user->getIp());
     if ($user->getWordPressId() !== null) {
         $message->setWordPressUserId($user->getWordPressId());
     }
     $message = $this->messagesDAO->save($message);
     // mark attachments created by the links pre-filter:
     $createdAttachments = $linksPreFilter->getCreatedAttachments();
     if (count($createdAttachments) > 0) {
         $this->attachmentsService->markAttachmentsWithDetails($createdAttachments, $channel->getName(), $message->getId());
     }
     return $message;
 }