12 const TABLE_NAME =
"LeaderBoard";
21 const VALUE_FLOAT = 1;
35 const SCORE_UNIQUE_NONE = 0;
39 const SCORE_UNIQUE_INCREASE = 1;
43 const SCORE_UNIQUE_REPLACE_HIGHER = 2;
47 const SCORE_UNIQUE_REPLACE_ANY = 3;
52 const HIGHSCORE_TOTAL = 0;
56 const HIGHSCORE_MONTH = 1;
60 const HIGHSCORE_WEEK = 2;
64 const HIGHSCORE_TODAY = 3;
66 const USERSCOPE_GLOBAL = 0;
67 const USERSCOPE_FRIENDS = 1;
73 public $Description =
"";
74 public $UniqueRecords = self::SCORE_UNIQUE_INCREASE;
75 public $ValueType = self::VALUE_INT;
76 public $OrderType = self::ORDER_DESC;
77 public $AllowAnonymous = 0;
82 public function __construct($src = null, $stripSlashes =
false) {
89 $this->_loadByRow($src, $stripSlashes);
90 }
else if (is_numeric($src)) {
92 if (intval($src) > 0) {
93 $this->_loadFilter(self::GetTableName(__CLASS__),
"Id = " . intval($src));
97 $this->_loadFilter(self::GetTableName(__CLASS__), sprintf(
"Code = '%s'", $Database->Escape($src)));
108 $sql =
"SELECT Id FROM " . self::GetTableName(__CLASS__) .
" WHERE Code = '" . $Database->Escape($this->Code) .
"'";
110 $sql .=
" AND Id <> " . $this->Id;
112 $res = $Database->Query($sql);
114 $row = $Database->FetchAssoc($res);
129 self::SCORE_UNIQUE_NONE =>
"Create new score per match",
130 self::SCORE_UNIQUE_INCREASE =>
"Increase the same score per user",
131 self::SCORE_UNIQUE_REPLACE_HIGHER =>
"Replace the best score per user",
132 self::SCORE_UNIQUE_REPLACE_ANY =>
"Replace the same score per user" 146 public static function Load ($idApp = 0, $limit = null, $offset = null, &$count = null, $returnArray =
false) {
149 $where = sprintf(
"(IdApp = 0 OR IdApp = %d)", $idApp);
151 return self::_load(self::GetTableName(__CLASS__), ($returnArray ?
"" : __CLASS__), $where,
"IdApp, Id", $limit, $offset, $count);
162 $query = sprintf(
"UPDATE %s SET Code = '%s', Title = '%s', Description = '%s', ValueType = %d, OrderType = %d, AllowAnonymous = %d WHERE Id = %d",
163 self::GetTableName(__CLASS__),
164 $Database->Escape($this->Code),
165 $Database->Escape($this->Title),
166 $Database->Escape($this->Description),
169 $this->AllowAnonymous,
172 $query = sprintf(
"INSERT INTO %s (IdApp, Code, Title, Description, UniqueRecords, ValueType, OrderType, AllowAnonymous) VALUES (%d, '%s', '%s', '%s', %d, %d, %d, %d)",
173 self::GetTableName(__CLASS__),
175 $Database->Escape($this->Code),
176 $Database->Escape($this->Title),
177 $Database->Escape($this->Description),
178 $this->UniqueRecords,
181 $this->AllowAnonymous);
183 if ($Database->Query($query)) {
184 if ($this->Id <= 0) {
185 $this->Id = $Database->InsertedId();
199 if ($this->_Delete(self::GetTableName(__CLASS__),
"Id = " . $this->Id)) {
201 $this->_Delete(self::GetTableName(LeaderBoard_User::class),
"IdLeaderboard = " . $this->Id);
212 self::TruncateClass(__CLASS__);
213 LeaderBoard_User::Prune();
228 public function LoadHighscore ($timeInterval, $userScope, $groupPlayer = FALSE, $sumPlayer = FALSE, $limit = NULL, $offset = NULL, &$count = NULL) {
229 global $LoggedAccount;
231 $where = sprintf(
"(IdLeaderboard = %d)", $this->Id);
233 switch ($timeInterval) {
234 case self::HIGHSCORE_TODAY:
235 $where .= sprintf(
" AND (LastUpdated BETWEEN '%s 00:00:00' AND '%s 23:59:59')",
239 case self::HIGHSCORE_WEEK:
240 $where .= sprintf(
" AND (LastUpdated BETWEEN '%s 00:00:00' AND '%s 23:59:59')",
241 date(
"Y-m-d", mktime(0, 0, 0, date(
"m"), date(
"d") - 7, date(
"Y"))),
244 case self::HIGHSCORE_MONTH:
245 $where .= sprintf(
" AND (LastUpdated BETWEEN '%s 00:00:00' AND '%s 23:59:59')",
246 date(
"Y-m-d", mktime(0, 0, 0, date(
"m"), 1, date(
"Y"))),
247 date(
"Y-m-t", mktime(0, 0, 0, date(
"m"), 1, date(
"Y"))));
249 case self::HIGHSCORE_TOTAL:
254 switch ($userScope) {
255 case self::USERSCOPE_FRIENDS:
256 $filterId = array($LoggedAccount->Id);
257 $friends = Friend::Load($LoggedAccount->Id, FRIEND_STATE_ACCEPTED);
258 foreach ($friends as $friend) {
259 $filterId[] = $friend->IdFriend;
261 $where = sprintf(
"(IdAccount IN (%s))", implode(
",", $filterId));
267 $this->GetOrderBy($order, $field);
269 if ($this->UniqueRecords == self::SCORE_UNIQUE_NONE && ($groupPlayer || $sumPlayer)) {
271 $where .=
" GROUP BY IdAccount";
273 $select =
"*, SUM(ValueInt) AS ValueInt, SUM(ValueFloat) AS ValueFloat";
275 $select =
"*, MAX(ValueInt) AS ValueInt, MAX(ValueFloat) AS ValueFloat";
277 $records = self::_loadEx($select, self::GetTableName(LeaderBoard_User::class), LeaderBoard_User::class, $where, $order, $limit, $offset);
278 $recordCount = self::_loadQuery(
"SELECT COUNT(Id) AS CountScores FROM (SELECT Id FROM " . self::GetTableName(LeaderBoard_User::class) .
" WHERE " . $where .
") T");
279 if (count($recordCount) > 0) {
280 $count = $recordCount[0][
"CountScores"];
284 $records = self::_load(self::GetTableName(LeaderBoard_User::class), LeaderBoard_User::class, $where, $order, $limit, $offset, $count);
287 $highscore = array();
289 foreach ($records as $record) {
290 if ($record->IdAccount > 0) {
291 $user =
new Account($record->IdAccount);
294 $user->Username = $record->Username;
296 $highscore[] = array(
298 "IdLeaderboard" => $this->Id,
300 "User" => $user->ToJson(),
301 "Score" => $record->$field
309 switch ($this->ValueType) {
310 case self::VALUE_FLOAT:
311 $order = $field =
"ValueFloat";
313 case self::VALUE_INT:
315 $order = $field =
"ValueInt";
319 if ($this->OrderType == self::ORDER_ASC) {
320 $order .=
" ASC, IdAccount ASC";
322 $order .=
" DESC, IdAccount ASC";
329 switch ($timeInterval) {
330 case self::HIGHSCORE_TODAY:
331 $where_time .= sprintf(
" AND (LastUpdated BETWEEN '%s 00:00:00' AND '%s 23:59:59')",
335 case self::HIGHSCORE_WEEK:
336 $where_time .= sprintf(
" AND (LastUpdated BETWEEN '%s 00:00:00' AND '%s 23:59:59')",
337 date(
"Y-m-d", mktime(0, 0, 0, date(
"m"), date(
"d") - 7, date(
"Y"))),
340 case self::HIGHSCORE_MONTH:
341 $where_time .= sprintf(
" AND (LastUpdated BETWEEN '%s 00:00:00' AND '%s 23:59:59')",
342 date(
"Y-m-d", mktime(0, 0, 0, date(
"m"), 1, date(
"Y"))),
343 date(
"Y-m-t", mktime(0, 0, 0, date(
"m"), 1, date(
"Y"))));
345 case self::HIGHSCORE_TOTAL:
351 $where = sprintf(
"(IdLeaderboard = %d AND IdAccount = %d)", $this->Id, $idAccount) . $where_time;
354 $this->GetOrderBy($order, $field);
355 $records = self::_load(self::GetTableName(LeaderBoard_User::class), LeaderBoard_User::class, $where);
357 if (count($records) > 0) {
358 if ($this->UniqueRecords == self::SCORE_UNIQUE_NONE && ($groupPlayer || $sumPlayer)) {
359 foreach ($records as $record) {
361 $userScore += $record->$field;
362 }
else if ($record->$field > $userScore) {
363 $userScore = $record->$field;
367 $userScore = $records[0]->$field;
371 $where = sprintf(
"(IdLeaderboard = %d AND $field " . ($this->OrderType == self::ORDER_ASC ?
"<" :
">") .
" %f)", $this->Id, $userScore) . $where_time;
372 if ($this->UniqueRecords == self::SCORE_UNIQUE_NONE && ($groupPlayer || $sumPlayer)) {
373 $where .=
" GROUP BY IdAccount";
375 $select =
"*, SUM(ValueInt) AS ValueInt, SUM(ValueFloat) AS ValueFloat";
377 $select =
"*, MAX(ValueInt) AS ValueInt, MAX(ValueFloat) AS ValueFloat";
379 $recordCount = self::_loadQuery(
"SELECT COUNT(Id) AS CountScores FROM (SELECT Id FROM " . self::GetTableName(LeaderBoard_User::class) .
" WHERE " . $where .
") T");
380 if (count($recordCount) > 0) {
381 $rank = $recordCount[0][
"CountScores"];
384 $rank = self::_count(self::GetTableName(LeaderBoard_User::class), $where);
388 $where = sprintf(
"(IdLeaderboard = %d AND $field = %f AND IdAccount < %d)", $this->Id, $userScore, $idAccount);
389 $rank += count(self::_load(self::GetTableName(LeaderBoard_User::class), LeaderBoard_User::class, $where));
390 return array(
"IdLeaderboard" => $this->Id,
"CodeLeaderboard" => $this->Code,
"Score" => $userScore,
"Rank" => $rank );
403 switch ($this->ValueType) {
404 case self::VALUE_FLOAT:
405 $field =
"ValueFloat";
406 $scoreValue = floatval($scoreValue);
408 case self::VALUE_INT:
411 $scoreValue = intval($scoreValue);
416 if ($account->Id > 0) {
417 $records = LeaderBoard_User::LoadAccount($account->Id, $this->Id);
419 if (count($records) == 0) {
422 $newRecord->IdLeaderboard = $this->Id;
423 $newRecord->IdAccount = $account->Id;
424 $newRecord->Username = $account->Username;
425 $newRecord->$field = $scoreValue;
426 return $newRecord->Save();
430 if ($this->UniqueRecords != self::SCORE_UNIQUE_NONE) {
432 $records[0]->Username = $account->Username;
433 switch ($this->UniqueRecords) {
434 case self::SCORE_UNIQUE_INCREASE:
436 $records[0]->$field += $scoreValue;
438 case self::SCORE_UNIQUE_REPLACE_HIGHER:
440 if (($this->OrderType == self::ORDER_DESC && $records[0]->$field >= $scoreValue) || ($this->OrderType == self::ORDER_ASC && $records[0]->$field <= $scoreValue)) {
443 $records[0]->$field = $scoreValue;
445 case self::SCORE_UNIQUE_REPLACE_ANY:
446 $records[0]->$field = $scoreValue;
449 return $records[0]->Save();
453 $newRecord->IdLeaderboard = $this->Id;
454 $newRecord->IdAccount = $account->Id;
455 $newRecord->Username = $account->Username;
456 $newRecord->$field = $scoreValue;
457 return $newRecord->Save();
GetOrderBy(&$order, &$field)
LoadHighscoreForAccount($timeInterval, $groupPlayer, $sumPlayer, $idAccount)
LoadHighscore($timeInterval, $userScope, $groupPlayer=FALSE, $sumPlayer=FALSE, $limit=NULL, $offset=NULL, &$count=NULL)
__construct($src=null, $stripSlashes=false)
PostScore($account, $scoreValue)
static Load($idApp=0, $limit=null, $offset=null, &$count=null, $returnArray=false)