Example #1
0
function execute($request)
{
    $path_parts = $request['path_parts'];
    $category_key = $path_parts[1];
    $thread_id = intval($path_parts[2]);
    $page_id = 0;
    // returns null for admin-only threads if not an admin
    $thread_info = api_forum_get_thread_info($request['user_id'], $request['is_admin'], $thread_id, true);
    if ($thread_info == null || $thread_info['category_info']['key'] != $category_key) {
        return build_response_not_found("Thread not found.");
    }
    $total_posts = $thread_info['post_count'];
    if (count($path_parts) > 3 && substr($path_parts[3], 0, strlen('page')) == 'page') {
        $page_id = intval(substr($path_parts[3], strlen('page'))) - 1;
        if ($page_id < 0) {
            $page_id = 0;
        }
    } else {
        if ($path_parts[3] == 'new') {
            // TODO: per-user new post tracking
        }
    }
    $current_page = $page_id + 1;
    $total_pages = intval(($total_posts - 1) / 25) + 1;
    // List of integers including 1-indexed page numbers or -1 for ellipses.
    // Links to first 3 pages and last 3 pages should always be available, along with pages within 2 of the current page.
    $paginator_links = array();
    $first_range = 3;
    $end_range = $total_pages - 2;
    $mid_begin_range = $current_page - 2;
    $mid_end_range = $current_page + 2;
    $last_item_is_ellipsis = false;
    for ($i = 1; $i <= $total_pages; ++$i) {
        if ($i <= $first_range || $i >= $end_range || $i >= $mid_begin_range && $i <= $mid_end_range) {
            array_push($paginator_links, $i);
            $last_item_is_ellipses = false;
        } else {
            if (!$last_item_is_ellipses) {
                array_push($paginator_links, -1);
                $last_item_is_ellipses = true;
            }
        }
    }
    $starting_post_index = $page_id * 25;
    if ($starting_post_index >= $total_posts) {
    }
    $forum_posts = api_forum_fetch_posts_for_thread($request['user_id'], $category_key, $thread_id, $page_id);
    $post_ids = $forum_posts['ordered_post_ids'];
    $thread_info = $forum_posts['thread_' . $thread_id];
    $category_info = $forum_posts['category_' . $thread_info['category_id']];
    if ($category_info == null) {
        return build_response_not_found("Thread not found.");
    }
    $output = array();
    array_push($output, '<h1 style="font-size:16px;">', '<a href="/forum">Forum</a> &gt; ', '<a href="/forum/' . $category_key . '">' . htmlspecialchars($category_info['name']) . '</a> &gt; ', htmlspecialchars($thread_info['title']), '</h1>');
    $paginator_html = array();
    if ($total_pages > 1) {
        array_push($paginator_html, '<div style="text-align:right;">');
        if ($current_page > 1) {
            array_push($paginator_html, '<a href="/forum/' . $category_key . '/' . $thread_id . '/page' . ($current_page - 1) . '">Prev</a> ');
        }
        foreach ($paginator_links as $page) {
            if ($page === -1) {
                array_push($paginator_html, ' ... ');
            } else {
                if ($page == $current_page) {
                    array_push($paginator_html, '[' . $current_page . ']');
                } else {
                    array_push($paginator_html, '<a href="/forum/' . $category_key . '/' . $thread_id . '/page' . $page . '">' . $page . '</a>');
                }
            }
        }
        if ($current_page < $total_pages) {
            array_push($paginator_html, '<a href="/forum/' . $category_key . '/' . $thread_id . '/page' . ($current_page + 1) . '">Next</a> ');
        }
        array_push($paginator_html, '</div>');
    }
    $paginator_html = implode("\n", $paginator_html);
    array_push($output, $paginator_html);
    if (count($post_ids) == 0) {
        return build_response_not_found("No posts found.");
    }
    array_push($output, '</div>');
    //array_push($output, '<div style="margin-bottom:20px;">');
    foreach ($post_ids as $post_id) {
        $post = $forum_posts['post_' . $post_id];
        $user = $forum_posts['user_' . $post['user_id']];
        array_push($output, '<div style="clear:both; padding-top:20px;">', '<div class="block" style="float:left; width:120px; margin-right:20px;">', '<div style="text-align:center;">', strlen($user['image_id']) > 0 ? '<img src="/uploads/avatars/' . $user['image_id'] . '" />' : ":'(", '</div>', '</div>', '<div style="float:left; width:780px; background-color:#fff;">', '<div style="background-color:#ddd;font-weight:bold; padding:8px; font-size:12px;">', '<div title="' . date("M j, Y g:i:s A", $post['time']) . '" style="float:right;width:300px;text-align:right;font-weight:normal;color:#555;">', unix_to_scaling_time($post['time']), '</div>', '<a href="/profiles/' . $user['login_id'] . '">' . htmlspecialchars($user['name']) . '</a>', '</div>', '<div style="clear:right;padding:20px;">', nl2br(htmlspecialchars($post['content_raw'])), '</div>', '</div>', '</div>');
    }
    //array_push($output, '</div>');
    array_push($output, '<div class="fullblock" style="clear:both;margin-top:20px;">');
    array_push($output, $paginator_html);
    array_push($output, '<div><a href="/forum/' . $category_key . '/' . $thread_id . '/reply">Reply</a></div>');
    return build_response_ok("Forum thread", implode("\n", $output));
}
Example #2
0
function execute($request)
{
    $output = array('<h1>Code Golf</h1>', "<p><a href=\"https://en.wikipedia.org/wiki/Code_golf\">Code Golf</a> is a competition to see who can solve a programming problem using the fewest [key] \"strokes\".</p>", '</div>');
    $now = time();
    // TODO: migrate to api layer
    $current_challenge = api_autograder_canonicalize_problem(sql_query_item("SELECT * FROM `code_problems` WHERE `type` = 'golf' AND `golf_start_time` <= {$now} AND `golf_end_time` > {$now} LIMIT 1"));
    array_push($output, '<div style="padding-top:20px; margin-bottom:20px;">', '<div class="block" style="float:left; width:460px;">', '<p>' . "A new problem is posted every <s>2 weeks</s> once in a while. " . "During that time you can submit solutions. " . "Once time is up, the highest ranking (shortest) solutions will be awarded points. " . "You may still submit solutions after time is up for practice, but they won't be recorded for scores." . '</p>', '<p>Points are granted as follows on a per-language basis:</p>', '<ul>', '<li>First place: 3 points</li>', '<li>Second place: 2 points</li>', '<li>Third through fifth: 1 point</li>', '</ul>', '<p>Preference is given to earlier solutions in the event of ties. The maximum points you can receive is 3 &times; {number of languages}.</p>', '<p>More about <a href="/about#points">NP points</a>.</p>', '<p>Want a reminder every 2 weeks? New Golf questions will be announced via <a href="https://twitter.com/nerdparadise">twitter</a>.</p>', '</div>', '<div class="block" style="float:left; margin-left:20px; width:400px;">');
    if ($current_challenge == null) {
        array_push($output, '<h2>Current Challenge: None</h2>', '<div>Check back soon or poke <a href="/profiles/blake">Blake</a></div>');
    } else {
        array_push($output, '<h2>Current Challenge: <a href="/golf/' . $current_challenge['problem_id'] . '">' . htmlspecialchars($current_challenge['title']) . '</a></h2>', '<div><span style="color:#048; font-weight:bold;">' . seconds_to_duration($current_challenge['golf_end_time'] - time()) . '</span> Remain.</div>', '');
        // TODO: migrate to api
        $ranked_entries = sql_query("\r\n\t\t\t\tSELECT\r\n\t\t\t\t\tr.`user_id`,\r\n\t\t\t\t\tr.`integer_rank`,\r\n\t\t\t\t\tr.`code_size`,\r\n\t\t\t\t\tr.`language_id`,\r\n\t\t\t\t\tlang.`name` AS 'lang_name',\r\n\t\t\t\t\tlang.`key` AS 'lang_key'\r\n\t\t\t\tFROM `code_solutions` r\r\n\t\t\t\tINNER JOIN `languages` lang ON (lang.`language_id` = r.`language_id`)\r\n\t\t\t\tWHERE\r\n\t\t\t\t\tr.`problem_id` = " . $current_challenge['problem_id'] . " AND\r\n\t\t\t\t\tr.`integer_rank` <= 3\r\n\t\t\t\tORDER BY r.`integer_rank`");
        if ($ranked_entries->num_rows == 0) {
            array_push($output, '<p>Currently there are no submissions.</p>', '<p><a href="/golf/' . $current_challenge['problem_id'] . '">Be the first!</a></p>');
        } else {
            array_push($output, '<h2 style="padding-top:20px; padding-bottom:10px;">Rankings</h2>');
            $user_ids = array();
            $languages = array();
            $language_keys = array();
            $language_names = array();
            for ($i = 0; $i < $ranked_entries->num_rows; ++$i) {
                $entry = $ranked_entries->fetch_assoc();
                array_push($user_ids, $entry['user_id']);
                $language_key = $entry['lang_key'];
                if (!isset($languages[$language_key])) {
                    $languages[$language_key] = array();
                    array_push($language_keys, $language_key);
                    $language_names[$language_key] = $entry['lang_name'];
                }
                array_push($languages[$language_key], $entry);
            }
            sort($language_keys);
            $user_infos = api_account_fetch_mini_profiles($user_ids);
            foreach ($language_keys as $language_key) {
                array_push($output, '<h3>', '<img src="/images/languages/' . $language_key . '_small.png" valign="middle" />', htmlspecialchars($language_names[$language_key]), '</h3>', '<table style="width:100%">');
                $rank = 1;
                foreach ($languages[$language_key] as $entry) {
                    $user_info = $user_infos['user_' . $entry['user_id']];
                    array_push($output, '<tr>', '<td>#' . $rank . '</td>', '<td><a href="/profiles/' . $user_info['login_id'] . '">' . htmlspecialchars($user_info['name']) . '</a></td>', '<td>' . $entry['code_size'] . ' byte' . ($entry['code_size'] == 1 ? '' : 's') . '</td>', '</tr>');
                    ++$rank;
                }
                array_push($output, '</table>');
            }
        }
    }
    array_push($output, '</div>', '</div>');
    array_push($output, '<div style="clear:left; padding-top:20px;">', '<div class="fullblock">', '<h2>All Challenges</h2>');
    $languages = api_autograder_get_language_infos(true);
    $problems_and_scores = api_autograder_menu_get_problems($request['user_id'], $request['is_admin'], 'golf', 0, true);
    $ordered_problem_ids = $problems_and_scores['ordered_problem_ids'];
    array_push($output, '<table cellspacing="0" cellpadding="4"><tr style="font-size:14px; font-weight:bold;"><td></td><td></td>');
    foreach ($languages as $language) {
        array_push($output, '<td style="padding-right:30px;">');
        array_push($output, '<img src="/images/languages/' . htmlspecialchars($language['key']) . '_small.png" valign="middle" />');
        array_push($output, htmlspecialchars($language['name']));
        array_push($output, '</td>');
    }
    array_push($output, '</tr>');
    $now = time();
    $alt = true;
    foreach ($ordered_problem_ids as $problem_id) {
        $problem_info = $problems_and_scores['problem_' . $problem_id];
        $is_active = $now < $problem_info['golf_end_time'];
        $alt = !$alt;
        $bg_color = $is_active ? 'cde' : ($alt ? 'fff' : 'eee');
        array_push($output, '<tr style="' . ($is_active ? 'font-weight:bold;' : '') . 'text-align:center;background-color:#' . $bg_color . ';">', '<td style="text-align:left;"><a href="/golf/' . $problem_id . '">', htmlspecialchars($problem_info['title']), '</a></td>', '<td>');
        if ($is_active) {
            array_push($output, "Ends: " . unix_to_scaling_time($problem_info['golf_end_time']));
        } else {
            array_push($output, "Ended: " . unix_to_scaling_time($problem_info['golf_start_time']));
        }
        array_push($output, '</td>');
        foreach ($languages as $language) {
            $score = $problems_and_scores['score_' . $problem_id . '_' . $language['language_id']];
            if (intval($score['code_size']) > 0) {
                array_push($output, '<td>');
                array_push($output, $score['code_size']);
                array_push($output, ' (#' . $score['integer_rank'] . ')');
                // TODO: little trophy images.
            } else {
                array_push($output, '<td style="color:#888;">');
                array_push($output, 'N/A');
            }
            array_push($output, '</td>');
        }
        array_push($output, '</tr>');
    }
    array_push($output, '</table>');
    array_push($output, '</div>');
    return build_response_ok("Code Golf", implode("\n", $output));
}