Example #1
0
 private static function _getVotesOverTime($vars, $users = false)
 {
     $time = time();
     $startDate = Lib\Url::GetInt('startDate', $time - 3600 * 24, $vars);
     // Default to the last 24 hours
     $endDate = Lib\Url::GetInt('endDate', $time, $vars);
     $bracketId = Lib\Url::GetInt('bracketId', null, $vars);
     $granularity = Lib\Url::GetInt('granularity', 2, $vars);
     $cacheKey = '_getVotesOverTime_' . implode('_', [$startDate, $endDate, $bracketId, $granularity, $users]);
     $retVal = Lib\Cache::Get($cacheKey);
     if (false === $retVal && $bracketId) {
         $selectCount = $users ? 'DISTINCT user_id' : '1';
         $result = Lib\Db::Query('SELECT COUNT(' . $selectCount . ') AS total, DATE(FROM_UNIXTIME(vote_date)) AS date, HOUR(FROM_UNIXTIME(vote_date)) AS hour, (MINUTE(FROM_UNIXTIME(vote_date)) % :granularity) AS hour_fraction FROM votes WHERE bracket_id = :bracketId AND vote_date BETWEEN :start AND :end GROUP BY date, hour, hour_fraction ORDER BY date, hour, hour_fraction', [':granularity' => $granularity, ':bracketId' => $bracketId, ':start' => $startDate, ':end' => $endDate]);
         if ($result && $result->count) {
             $retVal = [];
             while ($row = Lib\Db::Fetch($result)) {
                 $obj = new stdClass();
                 $obj->date = (int) $row->date;
                 $obj->hour = (int) $row->hour;
                 $obj->minutes = $row->hour_fraction == 0 ? 0 : 60 * ((int) $row->hour_fraction / $granularity);
                 $obj->count = (int) $row->total;
                 $retVal[] = $obj;
             }
             Lib\Cache::Set($cacheKey, $retVal, STATS_CACHE_DURATION);
         }
     }
     return $retVal;
 }
Example #2
0
 public static function set($key, $value)
 {
     if (!self::$_sess instanceof stdClass) {
         self::$_sess = new stdClass();
     }
     self::$_sess->{$key} = $value;
     Cache::Set(SESSION_NAME . '_' . self::$_id, self::$_sess, SESSION_EXPIRE);
 }
Example #3
0
 /**
  * Gets all characters for a bracket
  */
 public static function getByBracketId($bracketId)
 {
     $retVal = null;
     if (is_numeric($bracketId)) {
         $cacheKey = 'Character_getByBracketId_' . $bracketId;
         $retVal = Lib\Cache::Get($cacheKey);
         if (false === $retVal) {
             $retVal = null;
             // TODO - make order by column configurable
             $retVal = Character::queryReturnAll(['bracketId' => $bracketId], ['source' => 'ASC', 'name' => 'ASC']);
             Lib\Cache::Set($cacheKey, $retVal);
         }
     }
     return $retVal;
 }
Example #4
0
 /**
  * Returns an array of parent items for this object
  */
 public function getParents()
 {
     $cacheKey = 'MalItem::getItemParents_' . $this->id;
     $retVal = Lib\Cache::Get($cacheKey);
     if (false === $retVal && $this->id) {
         $retVal = null;
         $result = Lib\Db::Query('SELECT i.* FROM mal_xref x INNER JOIN mal_items i ON i.item_id = x.mal_parent WHERE x.mal_child = :id ORDER BY x.mal_parent ASC', [':id' => $this->id]);
         if ($result && $result->count) {
             $retVal = [];
             while ($row = Lib\Db::Fetch($result)) {
                 $retVal[] = new MalItem($row);
             }
         }
         Lib\Cache::Set($retVal, 3600);
     }
     return $retVal;
 }
Example #5
0
 public static function generate(array $params)
 {
     $message = null;
     $bracket = self::_getBracket(array_shift($params));
     if ($bracket) {
         $cacheKey = 'Controller::Admin::Advance_bracketAdvanceTime_' . $bracket->id;
         $lastBracketAdvance = Lib\Cache::Get($cacheKey);
         if (!$lastBracketAdvance || $lastBracketAdvance + self::BRACKET_ADVANCE_DELAY < time()) {
             Lib\Cache::Set($cacheKey, time());
             $bracket->advance();
             $message = new stdClass();
             $message->type = 'success';
             $message->message = $bracket->name . ' has advanced to the next round';
             self::_refreshCaches($bracket);
         } else {
             $message = new stdClass();
             $message->type = 'error';
             $delta = $lastBracketAdvance + self::BRACKET_ADVANCE_DELAY - time();
             $time = Lib\Util::relativeTime(time() - $delta);
             $message->message = $bracket->name . ' was recently advanced. Please wait ' . $time . ' before advancing again.';
         }
     }
     return self::_main($message, true);
 }
Example #6
0
 /**
  * Gets the unvoted rounds for a bracket and tier
  */
 public static function getBracketRounds($bracketId, $tier, $group = false, $ignoreCache = false)
 {
     // If no user, check as guest
     $user = User::getCurrentUser();
     if (!$user) {
         $user = new User();
         $user->id = 0;
     }
     $cacheKey = 'GetBracketRounds_' . $bracketId . '_' . $tier . '_' . ($group !== false ? $group : 'all') . '_' . $user->id;
     $retVal = Lib\Cache::Get($cacheKey);
     if (false === $retVal || $ignoreCache) {
         $params = [':bracketId' => $bracketId, ':tier' => $tier, ':userId' => $user->id];
         if (false !== $group) {
             $params[':group'] = $group;
             // Check to see how many rounds there are in the group total. If there's only one, come back and get them all
             $row = Lib\Db::Fetch(Lib\Db::Query('SELECT COUNT(1) AS total FROM round WHERE bracket_id = :bracketId AND round_tier = :tier AND round_group = :group', [':bracketId' => $bracketId, ':tier' => $tier, ':group' => $group]));
             if (is_object($row) && (int) $row->total == 1) {
                 $retVal = self::getBracketRounds($bracketId, $tier, false, $ignoreCache);
                 $result = null;
             } else {
                 $result = Lib\Db::Query('SELECT *, (SELECT character_id FROM votes WHERE user_id = :userId AND round_id = r.round_id) AS user_vote FROM round r WHERE r.bracket_id = :bracketId AND r.round_tier = :tier AND r.round_group = :group ORDER BY r.round_order', $params);
             }
         } else {
             $result = Lib\Db::Query('SELECT *, (SELECT character_id FROM votes WHERE user_id = :userId AND round_id = r.round_id) AS user_vote FROM round r WHERE r.bracket_id = :bracketId AND r.round_tier = :tier ORDER BY r.round_order', $params);
         }
         if ($result && $result->count > 0) {
             $retVal = [];
             // Hashmap of characters to retrieve in the next step
             $characters = [];
             while ($row = Lib\Db::Fetch($result)) {
                 $round = new Round($row);
                 // If the tier is not 0, character2 is "nobody", and the number of items is not a power of two
                 // this is a wildcard round and the user has already voted
                 if ($row->round_tier != 0 && $row->round_character2_id == 1 && ($result->count + 1 & $result->count) != 0) {
                     return null;
                 }
                 // Save off the character IDs for retrieval later
                 $characters[$row->round_character1_id] = true;
                 $characters[$row->round_character2_id] = true;
                 $retVal[] = $round;
             }
             // Retrieve the characters
             $result = Character::query(['id' => ['in' => array_keys($characters)]]);
             if ($result && $result->count) {
                 while ($row = Lib\Db::Fetch($result)) {
                     $character = new Character($row);
                     $characters[$character->id] = $character;
                 }
                 // Replace all the instances for the rounds
                 foreach ($retVal as $round) {
                     $round->character1 = $characters[$round->character1Id];
                     $round->character2 = $characters[$round->character2Id];
                     // Flag the character the user voted for if the voted
                     if ($round->votedCharacterId) {
                         if ($round->votedCharacterId == $round->character1->id) {
                             $round->character1->voted = true;
                         } else {
                             $round->character2->voted = true;
                         }
                     }
                 }
             }
         }
         Lib\Cache::Set($cacheKey, $retVal);
     }
     return $retVal;
 }
Example #7
0
 private static function _vote($user)
 {
     $out = new stdClass();
     $out->success = false;
     $bracketId = Lib\Url::Post('bracketId', true);
     $bracket = Api\Bracket::getById($bracketId);
     if ($bracket) {
         $state = $bracket ? (int) $bracket->state : null;
         if ($bracket->isLocked()) {
             $out->message = 'Voting is closed for this round. Please refresh to see the latest round.';
         } else {
             if ($state === BS_ELIMINATIONS || $state === BS_VOTING) {
                 if (self::_verifyAccountAge($user, $bracket)) {
                     // Break the votes down into an array of round/character objects
                     $votes = [];
                     foreach ($_POST as $key => $val) {
                         if (strpos($key, 'round:') === 0) {
                             $key = str_replace('round:', '', $key);
                             $obj = new stdClass();
                             $obj->roundId = (int) $key;
                             $obj->characterId = (int) $val;
                             $votes[] = $obj;
                         }
                     }
                     $count = count($votes);
                     if ($count > 0) {
                         $query = 'INSERT INTO `votes` (`user_id`, `vote_date`, `round_id`, `character_id`, `bracket_id`) VALUES ';
                         $params = [':userId' => $user->id, ':date' => time(), ':bracketId' => $bracketId];
                         $insertCount = 0;
                         // Only run an insert for rounds that haven't been voted on
                         $rounds = Api\Votes::getOpenRounds($user, $votes);
                         for ($i = 0; $i < $count; $i++) {
                             if (!isset($rounds[$votes[$i]->roundId])) {
                                 $query .= '(:userId, :date, :round' . $i . ', :character' . $i . ', :bracketId),';
                                 $params[':round' . $i] = $votes[$i]->roundId;
                                 $params[':character' . $i] = $votes[$i]->characterId;
                                 $insertCount++;
                                 $rounds[$votes[$i]->roundId] = true;
                             }
                         }
                         if ($insertCount > 0) {
                             $query = substr($query, 0, strlen($query) - 1);
                             if (Lib\Db::Query($query, $params)) {
                                 $out->success = true;
                                 // I am vehemently against putting markup in the controller, but there's much refactor needed to make this right
                                 // So, that's a note that it will be changed in the future
                                 $out->message = 'Your votes were successfully submitted! <a href="/results/' . $bracket->perma . '">View Results</a>';
                                 // Oops, I did it again...
                                 if ($bracket->externalId) {
                                     $out->message .= ' or <a href="http://redd.it/' . $bracket->externalId . '" target="_blank">discuss on reddit</a>.';
                                 }
                                 // Clear any user related caches
                                 $round = Api\Round::getById($votes[0]->roundId);
                                 Lib\Cache::Set('GetBracketRounds_' . $bracketId . '_' . $round->tier . '_' . $round->group . '_' . $user->id, false);
                                 Lib\Cache::Set('GetBracketRounds_' . $bracketId . '_' . $round->tier . '_all_' . $user->id, false);
                                 Lib\Cache::Set('CurrentRound_' . $bracketId . '_' . $user->id, false);
                                 $bracket->getVotesForUser($user, true);
                             } else {
                                 $out->message = 'There was an unexpected error. Please try again in a few moments.';
                             }
                         } else {
                             $out->message = 'Voting for this round has closed';
                             $out->code = 'closed';
                         }
                     } else {
                         $out->message = 'No votes were submitted';
                     }
                 } else {
                     $out->message = 'Your reddit account is not old enough to vote in this bracket';
                 }
             } else {
                 $out->message = 'Voting is closed on this bracket';
                 $out->code = 'closed';
             }
         }
     } else {
         $out->message = 'Invalid parameters';
     }
     return $out;
 }
Example #8
0
 /**
  * Makes an internal API call
  */
 private static function _internal($module, $method, $params, $cache)
 {
     global $_apiHits;
     $cacheKey = md5($module . '-' . $method . '-' . serialize($params));
     $retVal = Lib\Cache::Get($cacheKey);
     if ($retVal === false || $cache == 0) {
         $_apiHits++;
         $retVal = Api\DxApi::handleRequest($module, $method, $params);
         Lib\Cache::Set($cacheKey, $retVal);
     }
     return $retVal;
 }
Example #9
0
 /**
  * Makes an API call to another instance of DxApi via REST
  */
 private static function _external($module, $method, $params, $cache, $apiUri)
 {
     global $_apiHits;
     $qs = '/index.php?type=json&method=' . $module . '.' . $method;
     // Build the query string
     if (count($params) > 0) {
         foreach ($params as $key => $val) {
             $qs .= "&{$key}=" . urlencode($val);
         }
     }
     // Check to see if there is a cached version of this
     $cacheKey = md5($apiUri . $qs);
     $retVal = Cache::Get($cacheKey);
     if ($retVal === false || $cache == 0) {
         $_apiHits++;
         $file = file_get_contents($apiUri . $qs);
         $retVal = json_decode($file);
         // Only cache on success
         if ($retVal->status->ret_code == 0) {
             Cache::Set($cacheKey, $retVal, $cache);
         }
     }
     // Return the request
     return $retVal;
 }
Example #10
0
 /**
  * Retrieves a stashed message from caches and then clears it
  */
 protected static function _getStashedMessage()
 {
     $retVal = null;
     if (self::$_user) {
         $cacheKey = self::_stashCacheKey();
         $retVal = Lib\Cache::Get($cacheKey);
         Lib\Cache::Set($cacheKey, false);
     }
     return $retVal;
 }
Example #11
0
 /**
  * Advances a standard bracket tier
  */
 private function _advanceBracket()
 {
     $rounds = Round::getCurrentRounds($this->id, true);
     if (count($rounds) > 1) {
         for ($i = 0, $count = count($rounds); $i < $count; $i += 2) {
             // Get the round winners
             $winner1 = $rounds[$i]->getWinnerId();
             $winner2 = $rounds[$i + 1]->getWinnerId();
             // Create the round for the next tier
             $newRound = new Round();
             $newRound->bracketId = $this->id;
             $newRound->tier = $rounds[$i]->tier + 1;
             $newRound->group = $rounds[$i]->group;
             $newRound->order = $i / 2;
             $newRound->character1Id = $winner1;
             $newRound->character2Id = $winner2;
             $newRound->sync();
             // Finalize the current tier
             $rounds[$i]->getVoteCount();
             $rounds[$i]->final = true;
             $rounds[$i]->sync();
             $rounds[$i + 1]->getVoteCount();
             $rounds[$i + 1]->final = true;
             $rounds[$i + 1]->sync();
         }
     } else {
         if (count($rounds) === 1) {
             $round = $rounds[0];
             $round->getVoteCount();
             $round->final = true;
             $round->sync();
             $this->winner = $round->getWinner();
             $this->winnerCharacterId = $this->winner->id;
             $this->state = BS_FINAL;
             $this->sync();
         }
     }
     // Clear the results cache
     Lib\Cache::Set('Api:Bracket:getResults_' . $this->id, false, 1);
 }
Example #12
0
 /**
  * Gets a record from the database by the primary key
  */
 private function _getById($id)
 {
     $retVal = null;
     if (self::_verifyProperties($this)) {
         if (is_numeric($id)) {
             $cacheKey = 'Lib:Dal:' . $this->_dbTable . '_getById_' . $id;
             $retVal = Cache::Get($cacheKey);
             if (!$retVal) {
                 $query = 'SELECT `' . implode('`, `', $this->_dbMap) . '` FROM `' . $this->_dbTable . '` ';
                 $query .= 'WHERE `' . $this->_dbMap[$this->_dbPrimaryKey] . '` = :id LIMIT 1';
                 $result = Db::Query($query, [':id' => $id]);
                 if (null !== $result && $result->count === 1) {
                     $retVal = Db::Fetch($result);
                     Cache::Set($cacheKey, $retVal);
                 }
             }
             if ($retVal) {
                 $this->copyFromDbRow($retVal);
             }
         } else {
             throw new Exception('ID must be a number');
         }
     } else {
         throw new Exception('Class must have "_dbTable", "_dbMap", and "_dbPrimaryKey" properties to use method "getById"');
     }
 }