2011-12-05 15:53:12 +00:00
|
|
|
<?php
|
2011-12-05 17:00:03 +00:00
|
|
|
namespace wcf\util;
|
2011-12-23 14:26:54 +00:00
|
|
|
use \wcf\system\user\storage\UserStorageHandler;
|
|
|
|
use \wcf\system\package\PackageDependencyHandler;
|
|
|
|
use \wcf\system\WCF;
|
2011-12-05 15:53:12 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Chat utilities
|
|
|
|
*
|
|
|
|
* @author Tim Düsterhus
|
2012-01-28 16:50:33 +00:00
|
|
|
* @copyright 2010-2012 Tim Düsterhus
|
2011-12-05 15:53:12 +00:00
|
|
|
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
2012-03-12 16:18:15 +00:00
|
|
|
* @package be.bastelstu.wcf.chat
|
2011-12-05 15:53:12 +00:00
|
|
|
* @subpackage util
|
|
|
|
*/
|
2012-03-12 21:51:29 +00:00
|
|
|
final class ChatUtil {
|
2011-12-10 13:43:18 +00:00
|
|
|
/**
|
|
|
|
* Matches a time-interval with modifiers.
|
|
|
|
* Each part may be optionally separated by a comma
|
|
|
|
*
|
|
|
|
* @see \wcf\util\ChatUtil::timeModifier()
|
|
|
|
*/
|
2011-12-14 16:25:16 +00:00
|
|
|
const TIME_MODIFIER_REGEX = '((?:[0-9]+[s|h|d|w|m|y|S|H|D|W|M|Y]?,?)+)';
|
2011-12-10 13:43:18 +00:00
|
|
|
|
2012-03-08 21:07:46 +00:00
|
|
|
/**
|
|
|
|
* Package identifier of Tims Chat.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
2012-03-12 16:18:15 +00:00
|
|
|
const PACKAGE_IDENTIFIER = 'be.bastelstu.wcf.chat';
|
2012-03-08 21:07:46 +00:00
|
|
|
|
2011-12-23 14:26:54 +00:00
|
|
|
public static $serialize = array('color' => true);
|
|
|
|
|
2012-03-08 21:07:46 +00:00
|
|
|
/**
|
|
|
|
* Cached packageID of Tims Chat.
|
|
|
|
*
|
|
|
|
* @var integer
|
|
|
|
*/
|
|
|
|
private static $packageID = null;
|
|
|
|
|
2012-04-15 19:37:20 +00:00
|
|
|
/**
|
|
|
|
* Fetches the userIDs of died users.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public static function getDiedUsers() {
|
|
|
|
$packageID = \wcf\util\ChatUtil::getPackageID();
|
2012-04-27 17:53:52 +00:00
|
|
|
if (CHAT_SOCKET_IO_PATH && file_exists(WCF_DIR.'acp/be.bastelstu.wcf.chat.serverPush/data.sock')) {
|
|
|
|
$sql = "SELECT
|
|
|
|
time
|
|
|
|
FROM
|
|
|
|
wcf".WCF_N."_chat_message
|
|
|
|
ORDER BY
|
|
|
|
messageID DESC";
|
|
|
|
$stmt = WCF::getDB()->prepareStatement($sql, 1);
|
|
|
|
$stmt->execute();
|
|
|
|
$time = $stmt->fetchColumn();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$time = TIME_NOW;
|
|
|
|
}
|
|
|
|
|
2012-04-15 19:37:20 +00:00
|
|
|
$sql = "SELECT
|
|
|
|
r.userID, r.fieldValue AS roomID
|
|
|
|
FROM
|
|
|
|
wcf".WCF_N."_user_storage r
|
|
|
|
LEFT JOIN
|
|
|
|
wcf".WCF_N."_user_storage a
|
|
|
|
ON a.userID = r.userID
|
|
|
|
AND a.field = ?
|
|
|
|
AND a.packageID = ?
|
|
|
|
WHERE
|
|
|
|
r.field = ?
|
|
|
|
AND r.packageID = ?
|
2012-04-18 19:36:07 +00:00
|
|
|
AND r.fieldValue IS NOT NULL
|
2012-04-15 19:37:20 +00:00
|
|
|
AND (
|
|
|
|
a.fieldValue < ?
|
|
|
|
OR a.fieldValue IS NULL
|
|
|
|
)";
|
|
|
|
$stmt = WCF::getDB()->prepareStatement($sql);
|
2012-04-27 17:53:52 +00:00
|
|
|
$stmt->execute(array('lastActivity', $packageID, 'roomID', $packageID, $time - 30));
|
2012-04-15 19:37:20 +00:00
|
|
|
$users = array();
|
|
|
|
while ($users[] = $stmt->fetchArray());
|
|
|
|
|
|
|
|
return $users;
|
|
|
|
}
|
2012-03-08 21:07:46 +00:00
|
|
|
/**
|
|
|
|
* Returns the packageID of Tims Chat.
|
|
|
|
*/
|
|
|
|
public static function getPackageID() {
|
|
|
|
if (self::$packageID === null) {
|
|
|
|
self::$packageID = PackageDependencyHandler::getInstance()->getPackageID(self::PACKAGE_IDENTIFIER);
|
|
|
|
}
|
|
|
|
|
|
|
|
return self::$packageID;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a random number.
|
|
|
|
*
|
|
|
|
* @return integer
|
|
|
|
*/
|
|
|
|
public static function /* int */ getRandomNumber() {
|
|
|
|
return 4; // chosen by a fair dice roll
|
|
|
|
// guaranteed to be random
|
|
|
|
}
|
|
|
|
|
2011-12-05 15:53:12 +00:00
|
|
|
/**
|
|
|
|
* Creates a gradient out of two colors represented by an integer.
|
|
|
|
* The first byte is red, the second byte is green, the third one is blue.
|
|
|
|
* The numbers can be easily expressed in hexadecimal notation: 0xFF0000 being red.
|
|
|
|
*
|
|
|
|
* @param string $string
|
|
|
|
* @param integer $start
|
|
|
|
* @param integer $end
|
2011-12-23 14:26:54 +00:00
|
|
|
* @return string
|
2011-12-05 15:53:12 +00:00
|
|
|
*/
|
|
|
|
public static function gradient($string, $start, $end) {
|
2011-12-13 17:15:30 +00:00
|
|
|
$string = self::str_split($string);
|
2011-12-14 16:24:41 +00:00
|
|
|
if (count($string) === 0) return '';
|
|
|
|
|
2011-12-10 13:45:14 +00:00
|
|
|
$r = (int) ((($start >> 16 & 255) - ($end >> 16 & 255)) / (count($string) - 1));
|
|
|
|
$g = (int) ((($start >> 8 & 255) - ($end >> 8 & 255)) / (count($string) - 1));
|
|
|
|
$b = (int) ((($start & 255) - ($end & 255)) / (count($string) - 1));
|
2011-12-05 15:53:12 +00:00
|
|
|
|
|
|
|
$result = '';
|
|
|
|
for ($i = 0, $max = count($string); $i < $max; $i++) {
|
2011-12-17 17:40:20 +00:00
|
|
|
$result .= '<span style="color:rgb('.(($start >> 16 & 255) - $i * $r).','.(($start >> 8 & 255) - $i * $g).','.(($start & 255) - $i * $b).')">'.StringUtil::encodeHTML($string[$i]).'</span>';
|
2011-12-05 15:53:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
2011-12-10 13:25:36 +00:00
|
|
|
|
2011-12-23 14:26:54 +00:00
|
|
|
/**
|
|
|
|
* Reads user data.
|
|
|
|
*
|
2012-03-23 22:27:15 +00:00
|
|
|
* @param string $field
|
|
|
|
* @param \wcf\data\user\User $user
|
2011-12-23 14:26:54 +00:00
|
|
|
* @return mixed
|
|
|
|
*/
|
2012-03-23 22:27:15 +00:00
|
|
|
public static function readUserData($field, \wcf\data\user\User $user = null) {
|
|
|
|
if ($user === null) $user = WCF::getUser();
|
2011-12-23 14:26:54 +00:00
|
|
|
$ush = UserStorageHandler::getInstance();
|
2012-03-08 21:07:46 +00:00
|
|
|
$packageID = self::getPackageID();
|
2011-12-23 14:26:54 +00:00
|
|
|
|
|
|
|
// load storage
|
2012-03-23 22:27:15 +00:00
|
|
|
$ush->loadStorage(array($user->userID), $packageID);
|
|
|
|
$data = $ush->getStorage(array($user->userID), $field, $packageID);
|
2011-12-23 14:26:54 +00:00
|
|
|
|
2012-03-23 22:27:15 +00:00
|
|
|
if ($data[$user->userID] === null) {
|
2011-12-23 14:26:54 +00:00
|
|
|
switch ($field) {
|
|
|
|
case 'color':
|
2012-03-23 22:27:15 +00:00
|
|
|
$data[$user->userID] = array(1 => self::getRandomNumber(), 2 => self::getRandomNumber() * 0xFFFF);
|
2011-12-23 14:26:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-03-23 22:27:15 +00:00
|
|
|
static::writeUserData(array($field => $data[$user->userID]));
|
2011-12-24 15:59:29 +00:00
|
|
|
|
2012-03-23 22:27:15 +00:00
|
|
|
return $data[$user->userID];
|
2011-12-23 14:26:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-23 22:27:15 +00:00
|
|
|
if (isset(static::$serialize[$field])) return unserialize($data[$user->userID]);
|
|
|
|
else return $data[$user->userID];
|
2011-12-23 14:26:54 +00:00
|
|
|
}
|
|
|
|
|
2011-12-13 17:15:30 +00:00
|
|
|
/**
|
|
|
|
* Splits a string into smaller chunks.
|
|
|
|
* UTF-8 safe version of str_split().
|
|
|
|
*
|
|
|
|
* @param string $string
|
|
|
|
* @param integer $length
|
|
|
|
* @return array<string>
|
|
|
|
*/
|
|
|
|
public static function str_split($string, $length = 1) {
|
|
|
|
$result = array();
|
|
|
|
for ($i = 0, $max = StringUtil::length($string); $i < $max; $i += $length) {
|
|
|
|
$result[] = StringUtil::substring($string, $i, $length);
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2011-12-10 13:43:18 +00:00
|
|
|
/**
|
|
|
|
* Creates an interval out of a string with modifiers.
|
|
|
|
* Modifiers may be mixed. Valid modifiers are: _s_econd, _h_our, _d_ay, _w_week, _m_onth, _y_ear
|
|
|
|
* '2' -> 2 minutes
|
|
|
|
* '2h' -> 2 hours
|
|
|
|
* '1y12m2w3d12h' -> 1 year, 12 months, 2 weeks, 3 days, 12 hours
|
|
|
|
*
|
|
|
|
* @param string $time
|
|
|
|
* @return integer
|
|
|
|
*/
|
|
|
|
public static function timeModifier($time) {
|
2011-12-23 19:28:09 +00:00
|
|
|
$regex = new \wcf\system\Regex('([0-9]+[s|h|d|w|m|y]?)', \wcf\system\Regex::CASE_INSENSITIVE);
|
|
|
|
if (!$regex->match($time, true)) return 0;
|
|
|
|
$matches = $regex->getMatches();
|
|
|
|
|
2011-12-10 13:43:18 +00:00
|
|
|
$result = 0;
|
|
|
|
foreach ($matches[1] as $time) {
|
|
|
|
// 60 seconds a minute
|
|
|
|
$multiplier = 60;
|
|
|
|
$modifier = substr($time, -1);
|
|
|
|
|
|
|
|
switch ($modifier) {
|
|
|
|
case 'y':
|
|
|
|
case 'Y':
|
|
|
|
// twelve months a year
|
|
|
|
$multiplier *= 12;
|
|
|
|
case 'm':
|
|
|
|
case 'M':
|
|
|
|
// about 4.3 weeks per month
|
|
|
|
$multiplier *= 4.34812141;
|
|
|
|
case 'w':
|
|
|
|
case 'W':
|
|
|
|
// seven days a weeks
|
|
|
|
$multiplier *= 7;
|
|
|
|
case 'd':
|
|
|
|
case 'D':
|
|
|
|
// 24 hours a day
|
|
|
|
$multiplier *= 24;
|
|
|
|
case 'h':
|
|
|
|
case 'H':
|
|
|
|
// 60 minutes an hour
|
|
|
|
$multiplier *= 60;
|
|
|
|
$time = substr($time, 0, -1);
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
case 'S':
|
|
|
|
// 60 seconds per minute
|
|
|
|
$multiplier /= 60;
|
|
|
|
$time = substr($time, 0, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
$result += $time * $multiplier;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (int) round($result, 0);
|
|
|
|
}
|
2012-03-08 21:07:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Writes user data
|
|
|
|
*
|
2012-04-18 20:45:11 +00:00
|
|
|
* @param \wcf\data\user\User $user
|
2012-03-08 21:07:46 +00:00
|
|
|
* @param array $data
|
|
|
|
*/
|
2012-04-18 20:45:11 +00:00
|
|
|
public static function writeUserData(array $data, \wcf\data\user\User $user = null) {
|
|
|
|
if ($user === null) $user = WCF::getUser();
|
2012-03-08 21:07:46 +00:00
|
|
|
$ush = UserStorageHandler::getInstance();
|
|
|
|
$packageID = self::getPackageID();
|
|
|
|
|
|
|
|
foreach($data as $key => $value) {
|
2012-04-18 20:45:11 +00:00
|
|
|
$ush->update($user->userID, $key, (isset(static::$serialize[$key])) ? serialize($value) : $value, $packageID);
|
2012-03-08 21:07:46 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-12 21:51:29 +00:00
|
|
|
|
|
|
|
private function __construct() { }
|
2011-12-05 15:53:12 +00:00
|
|
|
}
|