/** * @param type $message the message: this must run before bb codes are parsed, * because user tags are translated to bb codes. * @return type int - an array of member ids that were tagged in the message. * the array contains unique ids only. */ function handleUserTags(&$message) { global $user_info, $modSettings, $context; $users_found = array(); if (!isset($context['can_tag_users']) || !$context['can_tag_users'] || isset($_REQUEST['allowtags']) && $_REQUEST['allowtags'] || empty($modSettings['enableUserTagging']) || 0 == $modSettings['maxTagsPerPost']) { return $users_found; } $pat = '~@@([\\s\\w,;-_\\[\\]\\{\\}\\\\/\\+\\.\\~\\$\\!]+):~u'; $matches = array(); $querynames = array(); $searchnames = array(); $displaynames = array(); /* * maximum number of unique tagged users a single message can have. defaults to 10, but never more than * 20 which should be waaaaaay enough anyway and we don't want to abuse this feature. */ $max_unique_tags = empty($modSettings['maxTagsPerPost']) ? 10 : min(array(20, $modSettings['maxTagsPerPost'])); /* * collect all @mentions and build an array of unique, lowercased * names to use in the db query. */ if (preg_match_all($pat, $message, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { $names = explode(',', trim($match[1])); foreach ($names as $name) { $querynames[] = CommonAPI::strtolower(trim($name)); } } } else { return $users_found; } // nothing to see here, sir... $querynames = array_slice(array_unique($querynames), 0, $max_unique_tags); $result = smf_db_query('SELECT id_member, real_name FROM {db_prefix}members WHERE LOWER(real_name) IN({array_string:names})', array('names' => array_unique($querynames))); while ($row = mysql_fetch_assoc($result)) { $searchnames[$row['id_member']] = CommonAPI::strtolower($row['real_name']); // this is for the lookup $displaynames[$row['id_member']] = $row['real_name']; // ... and this for pretty-formatting the output } mysql_free_result($result); reset($matches); /* * look at our matches again and build the formatted result(s). Filter out any names * that couldn't be found in the db query (mis-spelled, non-existing or whatever... simply ignore them). */ foreach ($matches as $match) { $bbc_results = array(); $names = explode(',', trim($match[1])); foreach ($names as $name) { $id = array_search(CommonAPI::strtolower(trim($name)), $searchnames); if ((int) $id > 0 && $id != $user_info['id']) { // trying to be funny and mention yourself? troll alert... :) $bbc_results[] = '[user id=' . $id . ']' . $displaynames[$id] . '[/user]'; $users_found[] = $id; } } $bbc_result = count($bbc_results) ? '@' . implode(', ', $bbc_results) . ':' : ''; $message = str_replace($match[0], $bbc_result, $message); } return array_unique($users_found); }
/** * Cleans a string of everything but alphanumeric characters * * @param string $string A string to clean * @return string A cleaned up string */ function _cleanString($string) { // Decode the entities first $string = html_entity_decode($string, ENT_QUOTES, 'UTF-8'); // Lowercase string $string = CommonAPI::strtolower($string); // Fix numbers so they search easier (phone numbers, SSN, dates, etc) $string = preg_replace('~([[:digit:]]+)\\pP+(?=[[:digit:]])~u', '', $string); // Last but not least, strip everything out that's not alphanumeric $string = preg_replace('~[^\\pL\\pN]+~u', ' ', $string); return $string; }