5 * Page callbacks for the Achievements module.
9 * Menu callback and block; show the site-wide leaderboard.
12 * Whether this is a block display (defaults to FALSE).
14 function achievements_leaderboard_totals($block = FALSE
) {
15 $achievers = achievements_totals($block ?
5 : 50);
16 $header = array(t('#'), t('Who'), t('Points'), t('Unlocks'), t('When'));
17 $header = $block ?
array_slice($header, 0, 3) : $header; // UNIQUEZORS.
18 !$block ?
drupal_set_title(t('Achievement leaderboard')) : ''; // UNIQUEZORS+.
19 drupal_add_css(drupal_get_path('module', 'achievements') .
'/achievements.css');
22 foreach ($achievers as
$achiever) {
23 $row = array( // dueling styles for wipe.
25 'data' => $achiever->rank
,
26 'class' => array('achievement-leaderboard-rank')
29 'data' => theme('username', array('account' => $achiever)),
30 'class' => array('achievement-leaderboard-username')
33 'data' => l($achiever->points
, 'user/' .
$achiever->uid .
'/achievements'),
34 'class' => array('achievement-leaderboard-points')
40 'data' => l($achiever->unlocks
, 'user/' .
$achiever->uid .
'/achievements'),
41 'class' => array('achievement-leaderboard-unlocks')
44 'data' => format_date($achiever->timestamp
, 'small'),
45 'class' => array('achievement-leaderboard-when')
52 $build['achievements']['leaderboard'] = array(
53 '#attributes' => array('class' => array('achievement-leaderboard')),
54 '#header' => $header, // 3 or 5 columns based on $block.
55 '#empty' => t('No one has been ranked yet.'),
60 if ($block) { // link off to more. MOOOReEeE!
61 $build['achievements']['see-more'] = array(
62 '#prefix' => '<div class="achievement-see-more">',
63 '#markup' => l(t('View the top 50 leaders ยป'), 'achievements/leaderboard'),
64 '#suffix' => '</div>',
72 * Menu callback; display a single achievement page with leaderboards.
74 function achievements_leaderboard_for($achievement) {
75 drupal_add_css(drupal_get_path('module', 'achievements') .
'/achievements.css');
76 drupal_set_title(t('Achievement: @title', array('@title' => $achievement['title'])));
78 $build['achievements']['achievement'] = array(
79 '#theme' => 'achievement',
80 '#achievement' => $achievement,
81 '#unlock' => achievements_unlocked_already($achievement['id']),
84 // get stats for first and most recent unlocks.
85 $query = db_select('achievement_unlocks', 'au');
86 $query->join('achievement_totals', 'at', 'at.uid = au.uid');
87 $query->join('users', 'u', 'u.uid = au.uid'); // same basic start for both queries.
88 $query->condition('achievement_id', $achievement['id']); // ... with a slight tweak.
89 $query->fields('au', array('uid', 'rank', 'timestamp'))->fields('at', array('points', 'unlocks'))->fields('u', array('name'));
90 $query2 = clone
$query; // allows us to save a few lines of duplicate query building. never used clone before. awesome.
91 $stats['first'] = $query->orderBy('rank')->range(0, 10)->execute()->fetchAllAssoc('rank'); // FI... sigh.
92 $stats['recent'] = $query2->orderBy('timestamp', 'DESC')->range(0, 10)->execute()->fetchAllAssoc('rank');
94 // both stat tables are displayed similarly.
95 foreach (array('first', 'recent') as
$type) {
96 $rows = array(); // clear previous run.
97 foreach ($stats[$type] as
$stat) {
100 'data' => $stat->rank
,
101 'class' => array('achievement-leaderboard-rank')
104 'data' => theme('username', array('account' => $stat)),
105 'class' => array('achievement-leaderboard-username')
108 'data' => l($stat->points
, 'user/' .
$stat->uid .
'/achievements'),
109 'class' => array('achievement-leaderboard-points')
112 'data' => format_date($stat->timestamp
, 'short'),
113 'class' => array('achievement-leaderboard-when')
118 $build['achievements']['stats'][$type] = array(
119 '#attributes' => array('class' => array('achievement-stats-' .
$type)),
120 '#caption' => t('@type achievement unlocks', array('@type' => drupal_ucfirst($type))),
121 '#header' => array(t('#'), t('Who'), t('Points'), t('When')),
122 '#empty' => t('No one has unlocked this yet. Keep trying!'),
132 * Menu callback; display all achievements for the passed user.
135 * The user object this request applies against.
137 function achievements_user_page($account) {
138 drupal_add_css(drupal_get_path('module', 'achievements') .
'/achievements.css');
139 drupal_set_title(t('Achievements for @name', array('@name' => $account->name
)));
141 $achievements = achievements_load(NULL
, TRUE
);
142 $unlocks = db_select('achievement_unlocks', 'au')->fields('au', array('achievement_id', 'rank', 'timestamp'))
143 ->condition('uid', $account->uid
)->orderBy('timestamp', 'DESC')->execute()->fetchAllAssoc('achievement_id');
145 $build['achievements']['stats'] = array(
146 '#prefix' => '<div class="achievement-stats">',
147 '#markup' => t('@name is ranked #@rank with @points points. @unlocks_count of @total_count achievements have been unlocked.', array(
148 '@name' => $account->name
,
149 '@rank' => achievements_totals_user('rank', $account->uid
),
150 '@points' => achievements_totals_user('points', $account->uid
),
151 '@unlocks_count' => count($unlocks),
152 '@total_count' => count($achievements))),
153 '#suffix' => '</div>',
156 foreach ($achievements as
$group_id => $group) {
157 foreach ($group['achievements'] as
$achievement_id => $achievement) {
158 $build['achievements'][$group_id][$achievement_id]['#theme'] = 'achievement';
159 $build['achievements'][$group_id][$achievement_id]['#achievement'] = $achievement;
161 if (isset($unlocks[$achievement_id])) {
162 $build['achievements'][$group_id][$achievement_id]['#unlock'] = (array) $unlocks[$achievement_id];
163 $build['achievements'][$group_id][$achievement_id]['#weight'] = -$unlocks[$achievement_id]->timestamp
;
164 // by setting the weight to the timestamp, the latest unlocks are always shown at the top.
173 * Menu callback; Retrieve autocomplete suggestions for achievement names.
175 function achievements_autocomplete($string = '') {
176 $achievements = achievements_load(); // MmmMMmMm, gooOoaaAaalLLlsss.
177 array_walk($achievements, 'achievements_autocomplete_search', $string);
178 drupal_json_output(array_slice(array_filter($achievements), 0, 10));
182 * array_walk helper function for achievements_autocomplete().
184 function achievements_autocomplete_search(&$value, $key, $string) {
185 $value = (stripos($value['title'], $string) === FALSE
) ? FALSE
: $value['title'];