public static function generate(array $params) { $action = Lib\Url::Get('action', null); $out = new stdClass(); $out->success = false; $user = Api\User::getCurrentUser(); if ($user) { if (self::_isFlooding($user)) { $out->message = 'You\'re doing that too fast!'; } else { switch ($action) { case 'nominate': $out = self::_nominate($user); break; case 'vote': $out = self::_vote($user); break; default: $out->message = 'No action specified'; break; } if ($out->success) { self::_setFloodMarker($user); } } } else { $out->message = 'You must be logged in'; } Lib\Display::renderJson($out); }
public static function generate(array $params) { $active = array_shift($params) !== 'past'; $brackets = Lib\Cache::fetch(function () use($active) { $allBrackets = Api\Bracket::getAll(); // Filter out active/completed brackets $brackets = []; foreach ($allBrackets as $bracket) { if ($active && ($bracket->state == BS_ELIMINATIONS || $bracket->state == BS_VOTING || $bracket->state == BS_NOMINATIONS)) { $bracket->title = Api\Round::getBracketTitleForActiveRound($bracket); $brackets[] = $bracket; } if (!$active && $bracket->state == BS_FINAL) { $brackets[] = $bracket; } } // Check for card images foreach ($brackets as $bracket) { if (is_readable('./images/bracket_' . $bracket->id . '_card.jpg')) { $bracket->cardImage = '/images/bracket_' . $bracket->id . '_card.jpg'; } else { $bracket->entrants = Api\Character::getRandomCharacters($bracket, 9); } } return $brackets; }, 'Controller::Brackets_displayBrackets_' . ($active ? 'active' : 'completed')); Lib\Display::addKey('page', 'brackets'); $title = $active ? 'Current Brackets' : 'Past Brackets'; Lib\Display::renderAndAddKey('content', 'bracketsView', ['brackets' => $brackets, 'title' => $title]); }
private static function _cropImage() { $out = new stdClass(); $out->success = false; $out->message = 'Unable to crop image'; $imageFile = Lib\Url::Post('imageFile'); $x = Lib\Url::Post('x', true); $y = Lib\Url::Post('y', true); $width = Lib\Url::Post('width', true); $height = Lib\Url::Post('height', true); if ($imageFile && null !== $x && null !== $y && null !== $width && null !== $height) { $imageFile = $imageFile[0] === '/' ? '.' . $imageFile : $imageFile; $image = Lib\ImageLoader::loadImage($imageFile); if ($image) { $image = self::_sizeUp($image->image); $croppedImage = imagecreatetruecolor(BRACKET_IMAGE_SIZE, BRACKET_IMAGE_SIZE); imagecopyresampled($croppedImage, $image, 0, 0, $x, $y, BRACKET_IMAGE_SIZE, BRACKET_IMAGE_SIZE, $width, $height); $fileName = '/cache/' . md5($imageFile) . '.jpg'; imagejpeg($croppedImage, '.' . $fileName); imagedestroy($image); imagedestroy($croppedImage); $out->success = true; $out->fileName = $fileName; } } else { $out->message = 'Parameters missing'; } Lib\Display::renderJson($out); }
public static function generate(array $params) { $code = Lib\Url::Get('code', null); $action = array_shift($params); if ($action === 'logout') { $user = Api\User::getCurrentUser(); if ($user) { $user->logout(); header('Location: /brackets/'); } } if ($code) { $success = Api\User::authenticateUser($code); if ($success) { $redirect = Lib\Url::Get('state', '/'); header('Location: ' . $redirect); exit; } else { Lib\Display::addKey('content', 'We were unable to verify your account at this time or your account age does not meet the requirements.'); } } else { $obj = new stdClass(); $obj->loginUrl = Api\User::getLoginUrl(Lib\Url::Get('redirect')); // Do a mobile check if (preg_match('/iphone|android|windows phone/i', $_SERVER['HTTP_USER_AGENT'])) { $obj->loginUrl = str_replace('authorize', 'authorize.compact', $obj->loginUrl); } $obj->originalUrl = Lib\Url::Get('redirect'); Lib\Display::addKey('page', 'login'); Lib\Display::addKey('title', 'Login' . DEFAULT_TITLE_SUFFIX); Lib\Display::renderAndAddKey('content', 'login', $obj); } }
/** * Loads the test buckets and sets the bucket seed */ public static function initialize($seed = null) { if (!self::$_initialized) { self::$_tests = Cache::fetch(function () { return json_decode(@file_get_contents('buckets.json')); }, TEST_BUCKET_CACHE_KEY); self::$_initialized = true; // Add template helpers Display::addHelper('inTestBucket', function ($template, $context, $args, $source) { if (preg_match_all('/([\\w]+)=\\"([^\\"]+)\\"/i', $args, $matches)) { $args = new stdClass(); for ($i = 0, $count = count($matches[0]); $i < $count; $i++) { $key = $matches[1][$i]; $args->{$key} = str_replace('"', '', $matches[2][$i]); } if (isset($args->key) && isset($args->value)) { if (self::get($args->key) == $args->value) { return $template->render($context); } } else { throw new Exception('inTestBucket requires "key" and "test" parameters'); } } }); } if ($seed || !self::$_seed) { self::$_seed = $seed ?: (int) str_replace('.', '', $_SERVER['REMOTE_ADDR']); } }
public static function generate(array $params) { $bracket = self::_getBracket(array_shift($params)); if ($bracket) { // Create the bracket on POST if ($_POST) { $id = Lib\Url::Post('bracketId', true); $name = Lib\Url::Post('bracketName'); $rules = Lib\Url::Post('rules'); if ($name && $rules) { $bracket->name = trim($name); $bracket->rules = $rules; $bracket->nameLabel = Lib\Url::Post('nameLabel'); $sourceOn = Lib\Url::Post('hideSource') !== 'on'; $bracket->sourceLabel = $sourceOn ? Lib\Url::Post('sourceLabel') : 'NO_SOURCE'; $advanceHour = Lib\Url::Post('advanceHour', true); $advanceHour = null !== $advanceHour ? $advanceHour : -1; $bracket->advanceHour = $advanceHour; if ($bracket->sync()) { // Clear the generic bracket related caches self::_refreshCaches($bracket); header('Location: /me/?edited'); exit; } } } $bracket->sourceHidden = $bracket->sourceLabel === 'NO_SOURCE'; $bracket->times = self::_generateAdvanceTimes($bracket->advanceHour); Lib\Display::renderAndAddKey('content', 'admin/bracket', $bracket); } }
public static function generate(array $params) { $bracket = Api\Bracket::getBracketByPerma(array_shift($params)); if ($bracket) { Lib\Display::addKey('page', 'characters'); $content = Lib\Display::renderAndAddKey('content', 'characters', (object) ['bracket' => $bracket, 'characters' => Api\Character::getByBracketId($bracket->id)]); } }
public static function generate(array $params) { $bracket = Api\Bracket::getBracketByPerma(array_shift($params)); if ($bracket) { Lib\Display::addKey('page', 'characters'); Lib\Display::addKey('title', $bracket->name . ' Entrants' . DEFAULT_TITLE_SUFFIX); $hasSource = $bracket->hasSourceLabel(); $hasSeed = $bracket->state == BS_VOTING || $bracket->state == BS_FINAL; $content = Lib\Display::renderAndAddKey('content', 'characters', (object) ['bracket' => $bracket, 'characters' => Api\Character::getByBracketId($bracket->id), 'hasSource' => $hasSource, 'hasSeed' => $hasSeed, 'hasSorter' => $hasSource || $hasSeed]); } }
public static function generate(array $params) { $perma = array_shift($params); $bracket = Api\Bracket::getBracketByPerma($perma); if ($bracket) { // TODO - get full voting stats $entrantStats = Api\Stats::getEntrantPerformanceStats($bracket); Lib\Display::addKey('page', 'stats'); Lib\Display::addKey('title', 'Stats for ' . $bracket->name . DEFAULT_TITLE_SUFFIX); Lib\Display::renderAndAddKey('content', 'stats', ['entrants' => $entrantStats, 'bracket' => $bracket]); } }
public static function render() { $query = Lib\Url::Get('q'); $bracketId = Lib\Url::GetInt('bracketId'); $out = Api\MalItem::getNameTypeahead($query, 'character'); if ($bracketId) { $out = array_merge($out, self::_getSimilarCharacters($bracketId, $query)); } // Standardize the output $out = self::_standardizeData($out); Lib\Display::renderJson($out); }
public static function generate(array $params) { $bracket = self::_getBracket(array_shift($params)); if ($bracket) { $stats = Api\Round::getVotingStats($bracket->id); if ($stats) { $out = new stdClass(); $out->bracket = $bracket; $out->stats = $stats; Lib\Display::renderAndAddKey('content', 'admin/stats', $out); } } }
public static function generate(array $params) { $page = array_shift($params); $page = $page ?: 'about'; $path = VIEW_PATH . '/' . $page . '.md'; $out = 'Uh oh... that doesn\'t seem to exist...'; if (is_readable($path)) { $file = file_get_contents($path); $out = Lib\Michelf\Markdown::defaultTransform($file); } Lib\Display::addKey('page', 'static'); Lib\Display::renderAndAddKey('content', 'static', $out); }
public static function generate(array $params) { $perma = array_shift($params); $bracket = Api\Bracket::getBracketByPerma($perma); if ($bracket) { $bracket->results = $bracket->getResults(); $user = Api\User::getCurrentUser(); if ($user) { $bracket->userVotes = $bracket->getVotesForUser($user); } Lib\Display::addKey('page', 'results'); Lib\Display::renderAndAddKey('content', 'results', $bracket); } }
public static function generate(array $params) { self::_checkLogin(); $bracket = Api\Bracket::getBracketByPerma(array_shift($params)); self::_enableAd(); if ($bracket) { $bracket->nameLabel = $bracket->nameLabel ?: 'Character name'; $bracket->sourceLabel = $bracket->sourceLabel ?: 'Source'; $bracket->sourceLabel = $bracket->sourceLabel === 'NO_SOURCE' ? false : $bracket->sourceLabel; $out = (object) ['rules' => Lib\Michelf\Markdown::defaultTransform($bracket->rules), 'bracket' => $bracket]; Lib\Display::addKey('page', 'nominate'); Lib\Display::renderAndAddKey('content', 'nominate', $out); } }
public static function generate(array $params) { // Create the bracket on POST if ($_POST) { $name = Lib\Url::Post('name'); $rules = Lib\Url::Post('rules'); if ($name && $rules) { $bracket = new Api\Bracket(); $bracket->name = trim($name); $bracket->rules = $rules; $bracket->state = 0; $bracket->start = time(); $bracket->generatePerma(); $bracket->nameLabel = Lib\Url::Post('nameLabel'); $bracket->minAge = Lib\Url::Post('minAge', true); $hideSource = Lib\Url::Post('hideSource') === 'on'; $bracket->sourceLabel = $hideSource ? 'NO_SOURCE' : Lib\Url::Post('sourceLabel'); $advanceHour = Lib\Url::Post('advanceHour', true); if ($advanceHour !== null) { $utcOffset = Lib\Url::Post('utcOffset', true); $advanceHour += $utcOffset !== null ? $utcOffset : 0; } else { $advanceHour = -1; } $bracket->advanceHour = $advanceHour; if ($bracket->sync()) { $bracket->addUser(self::$_user); self::_refreshCaches(); // Clear the generic bracket related caches header('Location: /me/?created'); exit; } } } // Or display the form $_POST['times'] = self::_generateAdvanceTimes(); $_POST['ages'] = self::_generateAges(REDDIT_MINAGE); Lib\Display::renderAndAddKey('content', 'admin/bracket', $_POST); }
public static function generate(array $params) { $user = self::_checkLogin(); self::_enableAd(); $perma = array_shift($params); $bracket = Api\Bracket::getBracketByPerma($perma); if ($bracket->start <= time() && ($bracket->state == BS_ELIMINATIONS || $bracket->state == BS_VOTING || $bracket->state == BS_WILDCARD)) { $cacheKey = 'CurrentRound_' . $bracket->id . '_' . $user->id; $out = Lib\Cache::fetch(function () use($user, $bracket) { $out = new stdClass(); $out->userId = $user->id; $out->round = Api\Round::getCurrentRounds($bracket->id); $out->title = Api\Round::getBracketTitleForActiveRound($bracket); return $out; }, $cacheKey, CACHE_MEDIUM); if ($out) { $out->bracket = $bracket; $template = $out->bracket->state == BS_ELIMINATIONS ? 'eliminations' : 'voting'; if ($bracket->state != BS_ELIMINATIONS) { $entrantSwap = Lib\TestBucket::get('entrantSwap'); if ($entrantSwap !== 'control') { foreach ($out->round as $round) { // Interesting side effect that I had not considered before: // When TestBucket initializes, it's setting the random seed for the entire RNG (duh). // That means the following random line will produce a static set of results, so the // user experience won't be wonky. if ($entrantSwap === 'flip' || $entrantSwap === 'random' && rand() % 2 === 0) { $round = self::_flipEntrants($round); } } } } Lib\Display::addKey('page', 'vote'); Lib\Display::addKey('title', $bracket->name . ' - Voting' . DEFAULT_TITLE_SUFFIX); Lib\Display::renderAndAddKey('content', $template, $out); } } }
public static function _generateBracket(Api\Bracket $bracket) { $retVal = null; if ($bracket) { $availableEntrants = Api\Round::getRoundCountForTier($bracket, 0); // Can't have much of a bracket with only two entrants... if ($availableEntrants < 2) { $message = self::_createMessage('error', 'There are not enough entrants to generate a bracket :('); self::_main($message); } else { if (count($_POST) > 0) { $entrants = Lib\Url::Post('entrants', true); $groups = Lib\Url::Post('groups', true); if ($entrants && $groups) { // Verify that the entrants/groups combo doesn't exceed to number of available entrants if ($entrants * $groups > $availableEntrants) { $message = self::_createMessage('error', 'Cannot generate a bracket of that size'); self::_main($message); } else { $bracket->advance(); if ($bracket->createBracketFromEliminations($entrants * $groups, $groups)) { $message = self::_createMessage('success', 'Voting for bracket "' . $bracket->name . '" has successfully started!'); self::_refreshCaches($bracket); self::_main($message); } else { $message = self::_createMessage('error', 'There are not enough entrants to create a bracket of that size'); self::_main($message); } } } else { $message = self::_createMessage('error', 'There was an error starting the bracket'); self::_main($message); } } else { $out = (object) ['bracket' => $bracket, 'count' => $availableEntrants]; Lib\Display::renderAndAddKey('content', 'admin/start_bracket', $out); } } } }
protected static function _enableAd() { Lib\Display::addKey('showAd', true); Lib\Display::addKey('isMobile', preg_match('/(iphone|android)/i', $_SERVER['HTTP_USER_AGENT'])); }
protected static function _main($message = null, $force = false) { $out = new stdClass(); $out->brackets = Api\Bracket::getUserOwnedBrackets(self::$_user, $force); if ($out->brackets) { // Check for card images foreach ($out->brackets as $bracket) { if (is_readable('./images/bracket_' . $bracket->id . '_card.jpg')) { $bracket->cardImage = '/images/bracket_' . $bracket->id . '_card.jpg'; } else { $bracket->entrants = Api\Character::getRandomCharacters($bracket, 9); } } // Sort the brackets by reverse date usort($out->brackets, function ($a, $b) { return $a->state == BS_FINAL || $a->state > $b->state ? 1 : -1; }); // Decorate each bracket with some information about what phase it can // safely move to. Mostly this is for eliminations foreach ($out->brackets as $bracket) { $bracket->title = Api\Round::getBracketTitleForActiveRound($bracket); $bracket->nextIsFinal = $bracket->title === 'Title Match'; // Get the title of the next round $nextRounds = Api\Round::getNextRounds($bracket); $bracket->nextTitle = null; if ($nextRounds) { $bracket->nextTitle = str_replace(['Voting - ', 'Eliminations - '], '', Api\Round::getBracketTitleForRound($bracket, $nextRounds[0])); } // This is a dumb catch all while I work out issues in the stored procedure $bracket->nextTitle = $bracket->nextTitle ?: 'Next Round'; if ($bracket->state == BS_ELIMINATIONS) { // Should query all the brackets at once, but I'm feeling lazy tonight... $result = Lib\Db::Query('SELECT MIN(round_group) AS current_group, MAX(round_group) AS last_group FROM `round` WHERE bracket_id = :bracketId AND round_final = 0', [':bracketId' => $bracket->id]); if ($result && $result->count) { $row = Lib\Db::Fetch($result); // If the eliminations are on the last group, don't show the // advance button if ($row->current_group == $row->last_group) { $bracket->showStart = true; } else { $bracket->showAdvance = true; } } } } } if ($message) { $out->message = $message; } Lib\Display::renderAndAddKey('content', 'admin/brackets', $out); }
public static function generate(array $params) { Lib\Display::setLayout('landing'); Lib\Display::addKey('rounds', Api\Round::getRandomCompletedRounds(30)); Lib\Display::addKey('phrase', static::$_phrases[rand() % count(static::$_phrases)]); }
private static function _updateCharacter(Api\Bracket $bracket) { $out = new stdClass(); $out->success = false; $id = Lib\Url::Post('characterId', true); $name = Lib\Url::Post('name'); $source = Lib\Url::Post('source'); $action = Lib\Url::Post('action'); if ($id && $name && $action) { $out->action = $action; $character = Api\Character::getById($id); if ($character && $character->bracketId == $bracket->id) { if ($action == 'update') { $character->name = $name; $character->source = $source; if ($character->sync()) { $out->success = true; } else { $out->message = 'Error updating database'; } } else { if ($action == 'delete') { if ($bracket->state == BS_NOMINATIONS || $bracket->state == BS_ELIMINATIONS) { if ($character->delete()) { $out->success = true; } else { $out->message = 'Delete failed'; } } else { $out->message = 'Cannot delete characters after voting has started'; } } else { $out->message = 'Unknown action'; } } } else { $out->message = 'Character does not belong to this bracket'; } } else { $out->message = 'Missing fields'; } Lib\Display::renderJson($out); }
{ self::$_tplData[KEY_CLIENT_DATA]->{$key} = $obj; } /** * Adds a helper to the Handlebars engine */ public static function addHelper($name, $function) { self::$_hbEngine->addHelper($name, $function); } /** * Adds a set of standard utility helpers to the render engine */ private static function _addStandardHelpers() { self::addHelper('relativeTime', function ($template, $context, $args, $source) { return Util::relativeTime($context->get($args)); }); // Idea lifted right out of dust.js self::addHelper('sep', function ($template, $context, $args, $source) { if (!$context->get('@last')) { return $source; } }); self::addHelper('jsonBlob', function ($template, $context, $args, $source) { return json_encode($context->get($args)); }); } } Display::init();