예제 #1
0
 function output_widget($region, $place, $themeobject, $template, $request, $qa_content)
 {
     if (!qa_opt('event_logger_to_database')) {
         return;
     }
     $badges = qa_db_read_all_assoc(qa_db_query_sub('SELECT event,handle,params, UNIX_TIMESTAMP(datetime) AS datetime FROM ^eventlog WHERE event=$' . (qa_opt('badge_widget_date_max') ? ' AND DATE_SUB(CURDATE(),INTERVAL ' . (int) qa_opt('badge_widget_date_max') . ' DAY) <= datetime' : '') . ' ORDER BY datetime DESC' . (qa_opt('badge_widget_list_max') ? ' LIMIT ' . (int) qa_opt('badge_widget_list_max') : ''), 'badge_awarded'));
     if (empty($badges)) {
         return;
     }
     $themeobject->output('<h2>' . qa_lang('badges/badge_widget_title') . '</h2>');
     foreach ($badges as $badge) {
         $params = array();
         $paramsa = explode("\t", $badge['params']);
         foreach ($paramsa as $param) {
             $parama = explode('=', $param);
             $params[$parama[0]] = $parama[1];
         }
         $slug = $params['badge_slug'];
         $typea = qa_get_badge_type_by_slug($slug);
         $types = $typea['slug'];
         $typed = $typea['name'];
         $badge_name = qa_lang('badges/' . $slug);
         if (!qa_opt('badge_' . $slug . '_name')) {
             qa_opt('badge_' . $slug . '_name', $badge_name);
         }
         $var = qa_opt('badge_' . $slug . '_var');
         $name = qa_opt('badge_' . $slug . '_name');
         $desc = qa_badge_desc_replace($slug, $var, $name);
         $string = '<span class="badge-' . $types . '" title="' . $desc . ' (' . $typed . ')">' . qa_html($name) . '<br/>- ' . $badge['handle'] . ' -</span>';
         $themeobject->output('<div class="badge-widget-entry" style="padding-top:8px;">', $string, '</div>');
     }
 }
 function admin_form(&$qa_content)
 {
     //	Process form input
     $ok = null;
     $badges = qa_get_badge_list();
     if (qa_clicked('badge_award_button')) {
         if ((bool) qa_post_text('badge_award_delete')) {
             qa_db_query_sub('DROP TABLE IF EXISTS ^userbadges');
             qa_db_query_sub('CREATE TABLE ^userbadges (' . 'awarded_at DATETIME NOT NULL,' . 'user_id INT(11) NOT NULL,' . 'notify TINYINT DEFAULT 0 NOT NULL,' . 'object_id INT(10),' . 'badge_slug VARCHAR (64) CHARACTER SET ascii DEFAULT \'\',' . 'id INT(11) NOT NULL AUTO_INCREMENT,' . 'PRIMARY KEY (id)' . ') ENGINE=MyISAM DEFAULT CHARSET=utf8');
         }
         $ok = $this->qa_check_all_users_badges();
     } else {
         if (qa_clicked('badge_reset_names')) {
             foreach ($badges as $slug => $info) {
                 qa_opt('badge_' . $slug . '_name', qa_badge_name($slug));
             }
             $ok = qa_lang('badges/badge_names_reset');
         } else {
             if (qa_clicked('badge_reset_values')) {
                 foreach ($badges as $slug => $info) {
                     if (isset($info['var'])) {
                         qa_opt('badge_' . $slug . '_var', $info['var']);
                     }
                 }
                 $ok = qa_lang('badges/badge_values_reset');
             } else {
                 if (qa_clicked('badge_trigger_notify')) {
                     $qa_content['test-notify'] = 1;
                 } else {
                     if (qa_clicked('badge_reset_css')) {
                         qa_opt('badges_css', $this->option_default('badges_css'));
                         $ok = 'CSS Reset';
                     } else {
                         if (qa_clicked('badge_save_settings')) {
                             qa_opt('badge_active', (bool) qa_post_text('badge_active_check'));
                             if (qa_opt('badge_active')) {
                                 qa_db_query_sub('CREATE TABLE IF NOT EXISTS ^userbadges (' . 'awarded_at DATETIME NOT NULL,' . 'user_id INT(11) NOT NULL,' . 'notify TINYINT DEFAULT 0 NOT NULL,' . 'object_id INT(10),' . 'badge_slug VARCHAR (64) CHARACTER SET ascii DEFAULT \'\',' . 'id INT(11) NOT NULL AUTO_INCREMENT,' . 'PRIMARY KEY (id)' . ') ENGINE=MyISAM DEFAULT CHARSET=utf8');
                                 qa_db_query_sub('CREATE TABLE IF NOT EXISTS ^achievements (' . 'user_id INT(11) UNIQUE NOT NULL,' . 'first_visit DATETIME,' . 'oldest_consec_visit DATETIME,' . 'longest_consec_visit INT(10),' . 'last_visit DATETIME,' . 'total_days_visited INT(10),' . 'questions_read INT(10),' . 'posts_edited INT(10)' . ') ENGINE=MyISAM DEFAULT CHARSET=utf8');
                                 // set badge names, vars and states
                                 foreach ($badges as $slug => $info) {
                                     // update var
                                     if (isset($info['var']) && qa_post_text('badge_' . $slug . '_var')) {
                                         qa_opt('badge_' . $slug . '_var', qa_post_text('badge_' . $slug . '_var'));
                                     }
                                     // toggle activation
                                     if ((bool) qa_post_text('badge_' . $slug . '_enabled') === false) {
                                         qa_opt('badge_' . $slug . '_enabled', '0');
                                     } else {
                                         qa_opt('badge_' . $slug . '_enabled', '1');
                                     }
                                     // set custom names
                                     if (qa_post_text('badge_' . $slug . '_edit') != qa_opt('badge_' . $slug . '_name')) {
                                         qa_opt('badge_' . $slug . '_name', qa_post_text('badge_' . $slug . '_edit'));
                                         $qa_lang_default['badges'][$slug] = qa_opt('badge_' . $slug . '_name');
                                     }
                                 }
                                 // options
                                 qa_opt('badge_notify_time', (int) qa_post_text('badge_notify_time'));
                                 qa_opt('badge_show_users_badges', (bool) qa_post_text('badge_show_users_badges'));
                                 qa_opt('badge_show_source_posts', (bool) qa_post_text('badge_show_source_posts'));
                                 qa_opt('badge_show_source_users', (bool) qa_post_text('badge_show_source_users'));
                                 qa_opt('badge_admin_user_widget', (bool) qa_post_text('badge_admin_user_widget'));
                                 qa_opt('badge_admin_user_widget_q_item', (bool) qa_post_text('badge_admin_user_widget_q_item'));
                                 qa_opt('badge_admin_user_field', (bool) qa_post_text('badge_admin_user_field'));
                                 qa_opt('badge_admin_user_field_no_tab', (bool) qa_post_text('badge_admin_user_field_no_tab'));
                                 qa_opt('badge_widget_date_max', (int) qa_post_text('badge_widget_date_max'));
                                 qa_opt('badge_widget_list_max', (int) qa_post_text('badge_widget_list_max'));
                                 qa_opt('badge_email_notify', (bool) qa_post_text('badge_email_notify'));
                                 qa_opt('badge_email_notify_on', (bool) qa_post_text('badge_email_notify_on'));
                                 qa_opt('badge_email_subject', qa_post_text('badge_email_subject'));
                                 qa_opt('badge_email_body', qa_post_text('badge_email_body'));
                                 qa_opt('badges_css', qa_post_text('badges_css'));
                             }
                             $ok = qa_lang('badges/badge_admin_saved');
                         }
                     }
                 }
             }
         }
     }
     //	Create the form for display
     $fields = array();
     $fields[] = array('label' => qa_lang('badges/badge_admin_activate'), 'tags' => 'NAME="badge_active_check"', 'value' => qa_opt('badge_active'), 'type' => 'checkbox');
     if (qa_opt('badge_active')) {
         $fields[] = array('label' => qa_lang('badges/active_badges') . ':', 'type' => 'static');
         $fields[] = array('label' => qa_lang('badges/badge_admin_select_all'), 'tags' => 'onclick="var isx = this.checked; jQuery(\'.badge-listing :checkbox\').prop(\'checked\',isx);"', 'value' => false, 'type' => 'checkbox');
         foreach ($badges as $slug => $info) {
             $badge_name = qa_badge_name($slug);
             if (!qa_opt('badge_' . $slug . '_name')) {
                 qa_opt('badge_' . $slug . '_name', $badge_name);
             }
             $name = qa_opt('badge_' . $slug . '_name');
             $badge_desc = qa_badge_desc_replace($slug, qa_opt('badge_' . $slug . '_var'), true);
             $type = qa_get_badge_type($info['type']);
             $types = $type['slug'];
             $fields[] = array('type' => 'static', 'note' => '<table class="badge-listing"><tr><td><input type="checkbox" name="badge_' . $slug . '_enabled"' . (qa_opt('badge_' . $slug . '_enabled') !== '0' ? ' checked' : '') . '></td><td><input type="text" name="badge_' . $slug . '_edit" id="badge_' . $slug . '_edit" style="display:none" size="16" onblur="badgeEdit(\'' . $slug . '\',true)" value="' . $name . '"><span id="badge_' . $slug . '_badge" class="badge-' . $types . '" onclick="badgeEdit(\'' . $slug . '\')" title="' . qa_lang('badges/badge_admin_click_edit') . '">' . $name . '</span></td><td>' . $badge_desc . '</td></tr></table>');
         }
         $fields[] = array('type' => 'blank');
         $fields[] = array('label' => qa_lang('badges/notify_time') . ':', 'type' => 'number', 'value' => qa_opt('badge_notify_time'), 'tags' => 'NAME="badge_notify_time"', 'note' => '<em>' . qa_lang('badges/notify_time_desc') . '</em>');
         $fields[] = array('type' => 'blank');
         $fields[] = array('label' => qa_lang('badges/badge_admin_user_field'), 'tags' => 'NAME="badge_admin_user_field"', 'value' => (bool) qa_opt('badge_admin_user_field'), 'type' => 'checkbox');
         $fields[] = array('label' => qa_lang('badges/badge_admin_user_field_no_tab'), 'tags' => 'NAME="badge_admin_user_field_no_tab"', 'value' => (bool) qa_opt('badge_admin_user_field_no_tab'), 'type' => 'checkbox');
         $fields[] = array('type' => 'blank');
         $fields[] = array('label' => qa_lang('badges/badge_show_source_posts'), 'tags' => 'NAME="badge_show_source_posts"', 'value' => (bool) qa_opt('badge_show_source_posts'), 'type' => 'checkbox');
         $fields[] = array('label' => qa_lang('badges/badge_show_source_users'), 'tags' => 'NAME="badge_show_source_users"', 'value' => (bool) qa_opt('badge_show_source_users'), 'type' => 'checkbox');
         $fields[] = array('label' => qa_lang('badges/badge_admin_user_widget'), 'tags' => 'NAME="badge_admin_user_widget"', 'value' => (bool) qa_opt('badge_admin_user_widget'), 'type' => 'checkbox');
         $fields[] = array('label' => qa_lang('badges/badge_admin_user_widget_q_item'), 'tags' => 'NAME="badge_admin_user_widget_q_item"', 'value' => (bool) qa_opt('badge_admin_user_widget_q_item'), 'type' => 'checkbox');
         $fields[] = array('label' => qa_lang('badges/badge_show_users_badges'), 'tags' => 'NAME="badge_show_users_badges"', 'value' => (bool) qa_opt('badge_show_users_badges'), 'type' => 'checkbox');
         if (qa_clicked('badge_trigger_notify')) {
             $fields['test-notify'] = 1;
         }
         $fields[] = array('label' => 'Badge css stylesheet', 'tags' => 'NAME="badges_css"', 'value' => qa_opt('badges_css'), 'rows' => 20, 'type' => 'textarea');
         $fields[] = array('type' => 'blank');
         $fields[] = array('label' => qa_lang('badges/widget_list_max') . ':', 'type' => 'number', 'value' => qa_opt('badge_widget_list_max'), 'tags' => 'NAME="badge_widget_list_max"');
         $fields[] = array('label' => qa_lang('badges/widget_date_max') . ':', 'type' => 'number', 'value' => qa_opt('badge_widget_date_max'), 'tags' => 'NAME="badge_widget_date_max"');
         $fields[] = array('type' => 'blank');
         $fields[] = array('label' => qa_lang('badges/badge_email_notify'), 'tags' => 'NAME="badge_email_notify" onclick="if(this.checked) jQuery(\'#badge_email_container\').fadeIn(); else jQuery(\'#badge_email_container\').fadeOut();"', 'value' => (bool) qa_opt('badge_email_notify'), 'type' => 'checkbox', 'note' => '<table id="badge_email_container" style="display:' . (qa_opt('badge_email_notify') ? 'block' : 'none') . '"><tr><td>');
         $fields[] = array('label' => qa_lang('badges/badge_email_notify_on'), 'tags' => 'NAME="badge_email_notify_on" id="badge_email_notify_on"', 'value' => (bool) qa_opt('badge_email_notify_on'), 'type' => 'checkbox');
         $fields[] = array('label' => qa_lang('badges/badge_email_subject'), 'tags' => 'NAME="badge_email_subject" id="badge_email_subject"', 'value' => qa_opt('badge_email_subject'), 'type' => 'text');
         $fields[] = array('label' => qa_lang('badges/badge_email_body'), 'tags' => 'name="badge_email_body" id="badge_email_body"', 'value' => qa_opt('badge_email_body'), 'type' => 'textarea', 'rows' => 20, 'note' => 'Available replacement text:<br/><br/><i>^site_title<br/>^handle<br/>^email<br/>^open<br/>^close<br/>^badge_name<br/>^post_title<br/>^post_url<br/>^profile_url<br/>^site_url<br/>^if_post_text="text"</i></td></tr></table>');
         $fields[] = array('type' => 'blank');
     }
     return array('ok' => $ok && !isset($error) ? $ok : null, 'fields' => $fields, 'buttons' => array(array('label' => qa_lang('badges/badge_trigger_notify'), 'tags' => 'name="badge_trigger_notify"' . (qa_opt('badge_active') ? '' : ' disabled="true"'), 'note' => '<br/><em>' . qa_lang('badges/badge_trigger_notify_desc') . '</em><br/>'), array('label' => qa_lang('badges/badge_reset_names'), 'tags' => 'NAME="badge_reset_names"', 'note' => '<br/><em>' . qa_lang('badges/badge_reset_names_desc') . '</em><br/>'), array('label' => qa_lang('badges/badge_reset_css'), 'tags' => 'NAME="badge_reset_css"'), array('label' => qa_lang('badges/badge_reset_values'), 'tags' => 'NAME="badge_reset_values"', 'note' => '<br/><em>' . qa_lang('badges/badge_reset_values_desc') . '</em><br/>'), array('label' => qa_lang('badges/badge_award_button'), 'tags' => 'NAME="badge_award_button"', 'note' => '<br/><em>' . qa_lang('badges/badge_award_button_desc') . '</em><br/><input type="checkbox" name="badge_award_delete"><b>' . qa_lang('badges/badge_award_delete_desc') . '</b><br/>'), array('label' => qa_lang('badges/save_settings'), 'tags' => 'NAME="badge_save_settings"', 'note' => '<br/><em>' . qa_lang('badges/save_settings_desc') . '</em><br/>')));
 }
예제 #3
0
function qa_badge_plugin_user_form($userid)
{
    $handles = qa_userids_to_handles(array($userid));
    $handle = $handles[$userid];
    // displays badge list in user profile
    $result = qa_db_read_all_assoc(qa_db_query_sub('SELECT badge_slug as slug, object_id AS oid FROM ^userbadges WHERE user_id=#', $userid));
    $fields = array();
    if (count($result) > 0) {
        // count badges
        $bin = qa_get_badge_list();
        $badges = array();
        foreach ($result as $info) {
            $slug = $info['slug'];
            $type = $bin[$slug]['type'];
            if (isset($badges[$type][$slug])) {
                $badges[$type][$slug]['count']++;
            } else {
                $badges[$type][$slug]['count'] = 1;
            }
            if ($info['oid']) {
                $badges[$type][$slug]['oid'][] = $info['oid'];
            }
        }
        foreach ($badges as $type => $badge) {
            $typea = qa_get_badge_type($type);
            $types = $typea['slug'];
            $typed = $typea['name'];
            $output = '
							<table>
								<tr>
									<td class="qa-form-wide-label">
										<h3 class="badge-title" title="' . qa_lang('badges/' . $types . '_desc') . '">' . $typed . '</h3>
									</td>
								</tr>';
            foreach ($badge as $slug => $info) {
                $badge_name = qa_lang('badges/' . $slug);
                if (!qa_opt('badge_' . $slug . '_name')) {
                    qa_opt('badge_' . $slug . '_name', $badge_name);
                }
                $name = qa_opt('badge_' . $slug . '_name');
                $count = $info['count'];
                if (qa_opt('badge_show_source_posts')) {
                    $oids = @$info['oid'];
                } else {
                    $oids = null;
                }
                $var = qa_opt('badge_' . $slug . '_var');
                $desc = qa_badge_desc_replace($slug, $var, $name);
                // badge row
                $output .= '
								<tr>
									<td class="badge-container">
										<div class="badge-container-badge">
											<span class="badge-' . $types . '" title="' . $desc . ' (' . $typed . ')">' . qa_html($name) . '</span>&nbsp;<span onclick="jQuery(\'.badge-container-sources-' . $slug . '\').slideToggle()" class="badge-count' . (is_array($oids) ? ' badge-count-link" title="' . qa_lang('badges/badge_count_click') : '') . '">x&nbsp;' . $count . '</span>
										</div>';
                // source row(s) if any
                if (is_array($oids)) {
                    $output .= '
										<div class="badge-container-sources-' . $slug . '" style="display:none">';
                    foreach ($oids as $oid) {
                        $post = qa_db_select_with_pending(qa_db_full_post_selectspec(null, $oid));
                        $title = $post['title'];
                        $anchor = '';
                        if ($post['parentid']) {
                            $anchor = urlencode(qa_anchor($post['type'], $oid));
                            $oid = $post['parentid'];
                            $title = qa_db_read_one_value(qa_db_query_sub('SELECT BINARY title as title FROM ^posts WHERE postid=#', $oid), true);
                        }
                        $length = 30;
                        $text = qa_strlen($title) > $length ? qa_substr($title, 0, $length) . '...' : $title;
                        $output .= '
											<div class="badge-source"><a href="' . qa_path_html(qa_q_request($oid, $title), NULL, qa_opt('site_url')) . ($anchor ? '#' . $anchor : '') . '">' . qa_html($text) . '</a></div>';
                    }
                }
                $output .= '
									</td>
								</tr>';
            }
            $output .= '
							</table>';
            $outa[] = $output;
        }
        $fields[] = array('value' => '<table class="badge-user-tables"><tr><td class="badge-user-table">' . implode('</td><td class="badge-user-table">', $outa) . '</td></tr></table>', 'type' => 'static');
    }
    $ok = null;
    $tags = null;
    $buttons = array();
    if ((bool) qa_opt('badge_email_notify') && qa_get_logged_in_handle() == $handle) {
        // add badge notify checkbox
        if (qa_clicked('badge_email_notify_save')) {
            qa_opt('badge_email_notify_id_' . $userid, (bool) qa_post_text('badge_notify_email_me'));
            $ok = qa_lang('badges/badge_notified_email_me');
        }
        $select = (bool) qa_opt('badge_email_notify_id_' . $userid);
        $tags = 'id="badge-form" action="' . qa_self_html() . '#signature_text" method="POST"';
        $fields[] = array('type' => 'blank');
        $fields[] = array('label' => qa_lang('badges/badge_notify_email_me'), 'type' => 'checkbox', 'tags' => 'NAME="badge_notify_email_me"', 'value' => $select);
        $buttons[] = array('label' => qa_lang_html('main/save_button'), 'tags' => 'NAME="badge_email_notify_save"');
    }
    return array('ok' => $ok && !isset($error) ? $ok : null, 'style' => 'tall', 'tags' => $tags, 'title' => qa_lang('badges/badges'), 'fields' => $fields, 'buttons' => $buttons);
}
 function process_request($request)
 {
     $qa_content = qa_content_prepare();
     $qa_content['title'] = qa_lang('badges/badge_list_title');
     $badges = qa_get_badge_list();
     $totalawarded = 0;
     $qa_content['custom'] = '<em>' . qa_lang('badges/badge_list_pre') . '</em><br />';
     $qa_content['custom2'] = '<table cellspacing="20">';
     $c = 2;
     $result = qa_db_read_all_assoc(qa_db_query_sub('SELECT user_id,badge_slug  FROM ^userbadges'));
     $count = array();
     foreach ($result as $r) {
         if (qa_opt('badge_' . $r['badge_slug'] . '_enabled') == '0') {
             continue;
         }
         if (isset($count[$r['badge_slug']][$r['user_id']])) {
             $count[$r['badge_slug']][$r['user_id']]++;
         } else {
             $count[$r['badge_slug']][$r['user_id']] = 1;
         }
         $totalawarded++;
         if (isset($count[$r['badge_slug']]['count'])) {
             $count[$r['badge_slug']]['count']++;
         } else {
             $count[$r['badge_slug']]['count'] = 1;
         }
     }
     foreach ($badges as $slug => $info) {
         if (qa_opt('badge_' . $slug . '_enabled') == '0') {
             continue;
         }
         $badge_name = qa_badge_name($slug);
         if (!qa_opt('badge_' . $slug . '_name')) {
             qa_opt('badge_' . $slug . '_name', $badge_name);
         }
         $name = qa_opt('badge_' . $slug . '_name');
         $var = qa_opt('badge_' . $slug . '_var');
         $desc = qa_badge_desc_replace($slug, $var, false);
         $type = qa_get_badge_type($info['type']);
         $types = $type['slug'];
         $typen = $type['name'];
         $qa_content['custom' . ++$c] = '<tr><td class="badge-entry"><div class="badge-entry-badge"><span class="badge-' . $types . '" title="' . $typen . '">' . $name . '</span>&nbsp;<span class="badge-entry-desc">' . $desc . '</span>' . (isset($count[$slug]) ? '&nbsp;<span title="' . $count[$slug]['count'] . ' ' . qa_lang('badges/awarded') . '" class="badge-count-link" onclick="jQuery(\'#badge-users-' . $slug . '\').slideToggle()">x' . $count[$slug]['count'] . '</span>' : '') . '</div>';
         // source users
         if (qa_opt('badge_show_source_users') && isset($count[$slug])) {
             $users = array();
             require_once QA_INCLUDE_DIR . 'qa-app-users.php';
             $qa_content['custom' . $c] .= '<div style="display:none" id="badge-users-' . $slug . '" class="badge-users">';
             foreach ($count[$slug] as $uid => $ucount) {
                 if ($uid == 'count') {
                     continue;
                 }
                 if (QA_FINAL_EXTERNAL_USERS) {
                     $handles = qa_get_public_from_userids(array($uid));
                     $handle = @$handles[$uid];
                 } else {
                     $useraccount = qa_db_select_with_pending(qa_db_user_account_selectspec($uid, true));
                     $handle = @$useraccount['handle'];
                 }
                 if (!$handle) {
                     continue;
                 }
                 $users[] = '<a href="' . qa_path_html('user/' . $handle) . '">' . $handle . ($ucount > 1 ? ' x' . $ucount : '') . '</a>';
             }
             $qa_content['custom' . $c] .= implode('<br/>', $users) . '</div>';
         }
         $qa_content['custom' . $c] .= '</td></tr>';
     }
     $qa_content['custom' . ++$c] = '<tr><td class="badge-entry"><span class="total-badges">' . count($badges) . ' ' . qa_lang('badges/badges_total') . '</span>' . ($totalawarded > 0 ? ', <span class="total-badge-count">' . $totalawarded . ' ' . qa_lang('badges/awarded_total') . '</span>' : '') . '</td></tr></table>';
     if (isset($qa_content['navigation']['main']['custom-2'])) {
         $qa_content['navigation']['main']['custom-2']['selected'] = true;
     }
     return $qa_content;
 }
예제 #5
0
function ra_user_badges_list($userid)
{
    if (!qa_opt('badge_active')) {
        return;
    }
    $handles = qa_userids_to_handles(array($userid));
    $handle = $handles[$userid];
    // displays badge list in user profile
    $result = qa_db_read_all_assoc(qa_db_query_sub('SELECT badge_slug as slug, object_id AS oid FROM ^userbadges WHERE user_id=#', $userid));
    if (count($result) > 0) {
        // count badges
        $bin = qa_get_badge_list();
        $badges = array();
        foreach ($result as $info) {
            $slug = $info['slug'];
            $type = $bin[$slug]['type'];
            if (isset($badges[$type][$slug])) {
                $badges[$type][$slug]['count']++;
            } else {
                $badges[$type][$slug]['count'] = 1;
            }
            if ($info['oid']) {
                $badges[$type][$slug]['oid'][] = $info['oid'];
            }
        }
        foreach ($badges as $type => $badge) {
            $typea = qa_get_badge_type($type);
            $types = $typea['slug'];
            $typed = $typea['name'];
            $output = '';
            //$output = '<h3 class="badge-title" title="'.qa_lang('badges/'.$types.'_desc').'">'.$typed.'</h3>';
            foreach ($badge as $slug => $info) {
                $badge_name = qa_badge_name($slug);
                if (!qa_opt('badge_' . $slug . '_name')) {
                    qa_opt('badge_' . $slug . '_name', $badge_name);
                }
                $name = qa_opt('badge_' . $slug . '_name');
                $count = $info['count'];
                if (qa_opt('badge_show_source_posts')) {
                    $oids = @$info['oid'];
                } else {
                    $oids = null;
                }
                $var = qa_opt('badge_' . $slug . '_var');
                $desc = qa_badge_desc_replace($slug, $var, false);
                // badge row
                $output .= '<div class="badge-container-badge">
									<span class="user-badge ' . $types . ' icon-badge" title="' . $desc . ' (' . $typed . ')">' . qa_html($name) . '</span>&nbsp;<span class="badge-count">x&nbsp;' . $count . '</span>' . (is_array($oids) ? '<i class="icon-chevron-down"></i>' : '');
                // source row(s) if any
                if (is_array($oids)) {
                    $output .= '
								<div class="badge-sources ' . $slug . '"><ul>';
                    foreach ($oids as $oid) {
                        $post = qa_db_select_with_pending(qa_db_full_post_selectspec(null, $oid));
                        $title = $post['title'];
                        $anchor = '';
                        if ($post['parentid']) {
                            $anchor = urlencode(qa_anchor($post['type'], $oid));
                            $oid = $post['parentid'];
                            $title = qa_db_read_one_value(qa_db_query_sub('SELECT BINARY title as title FROM ^posts WHERE postid=#', $oid), true);
                        }
                        //$length = 30;
                        $text = $title;
                        $output .= '<li><a href="' . qa_path_html(qa_q_request($oid, $title), NULL, qa_opt('site_url')) . ($anchor ? '#' . $anchor : '') . '">' . qa_html($text) . '</a></li>';
                    }
                    $output .= '</ul></div>';
                }
                $output .= '</div>';
            }
            $outa[] = $output;
        }
        $fields = '<div class="badge-user-block widget"><h3 class="widget-title">' . _ra_lang('Badges') . '</h3><div class="widget-inner">' . implode('', $outa) . '</div></div>';
    }
    return $fields;
}
    function user_activity_form()
    {
        $handle = $this->_user_handle();
        if (!$handle) {
            return;
        }
        $userid = $this->getuserfromhandle($handle);
        if (!$userid) {
            return;
        }
        // update last visit
        if ($userid == qa_get_logged_in_userid() && qa_opt('user_act_list_new')) {
            qa_db_query_sub('CREATE TABLE IF NOT EXISTS ^usermeta (
				meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
				user_id bigint(20) unsigned NOT NULL,
				meta_key varchar(255) DEFAULT NULL,
				meta_value longtext,
				PRIMARY KEY (meta_id),
				UNIQUE (user_id,meta_key)
				) ENGINE=MyISAM  DEFAULT CHARSET=utf8');
            $last_visit = qa_db_read_one_value(qa_db_query_sub('SELECT UNIX_TIMESTAMP(meta_value) FROM ^usermeta WHERE user_id=# AND meta_key=$', qa_get_logged_in_userid(), 'visited_profile'), true);
            qa_db_query_sub('INSERT INTO ^usermeta (user_id,meta_key,meta_value) VALUES(#,$,NOW()) ON DUPLICATE KEY UPDATE meta_value=NOW()', $userid, 'visited_profile');
        } else {
            $last_visit = time();
        }
        $event_query = qa_db_query_sub("SELECT \n\t\t\t\te.event, \n\t\t\t\tBINARY e.params as params, \n\t\t\t\tUNIX_TIMESTAMP(e.datetime) AS datetime\n\t\t\tFROM \n\t\t\t\t^eventlog AS e\n\t\t\tWHERE\n\t\t\t\te.userid=#\n\t\t\t\tAND\n\t\t\t\tDATE_SUB(CURDATE(),INTERVAL # DAY) <= datetime\n\t\t\tORDER BY datetime DESC" . (qa_opt('user_act_list_max') ? " LIMIT " . (int) qa_opt('user_act_list_max') : ""), $userid, qa_opt('user_act_list_age'));
        // no post
        $nopost = array('u_password', 'u_reset', 'u_save', 'u_confirmed', 'u_edit', 'u_level', 'u_block', 'u_unblock', 'u_register', 'in_u_edit', 'in_u_level', 'in_u_block', 'in_u_unblock', 'feedback', 'search');
        // points
        require_once QA_INCLUDE_DIR . 'qa-db-points.php';
        $optionnames = qa_db_points_option_names();
        $options = qa_get_options($optionnames);
        $multi = (int) $options['points_multiple'];
        // compat fudge
        $upvote = '';
        $downvote = '';
        if (@$options['points_per_q_voted_up']) {
            $upvote = '_up';
            $downvote = '_down';
        }
        $option_events['in_q_vote_up'] = (int) $options['points_per_q_voted' . $upvote] * $multi;
        $option_events['in_q_vote_down'] = (int) $options['points_per_q_voted' . $downvote] * $multi * -1;
        $option_events['in_q_unvote_up'] = (int) $options['points_per_q_voted' . $upvote] * $multi * -1;
        $option_events['in_q_unvote_down'] = (int) $options['points_per_q_voted' . $downvote] * $multi;
        $option_events['in_a_vote_up'] = (int) $options['points_per_a_voted' . $upvote] * $multi;
        $option_events['in_a_vote_down'] = (int) $options['points_per_a_voted' . $downvote] * $multi * -1;
        $option_events['in_a_unvote_up'] = (int) $options['points_per_a_voted' . $upvote] * $multi * -1;
        $option_events['in_a_unvote_down'] = (int) $options['points_per_a_voted' . $downvote] * $multi;
        $option_events['in_a_select'] = (int) $options['points_a_selected'] * $multi;
        $option_events['in_a_unselect'] = (int) $options['points_a_selected'] * $multi * -1;
        $option_events['q_post'] = (int) $options['points_post_q'] * $multi;
        $option_events['a_post'] = (int) $options['points_post_a'] * $multi;
        $option_events['a_select'] = (int) $options['points_select_a'] * $multi;
        $option_events['q_vote_up'] = (int) $options['points_vote_up_q'] * $multi;
        $option_events['q_vote_down'] = (int) $options['points_vote_down_q'] * $multi;
        $option_events['a_vote_up'] = (int) $options['points_vote_up_a'] * $multi;
        $option_events['a_vote_down'] = (int) $options['points_vote_down_a'] * $multi;
        $fields = array();
        $events = array();
        $postids = array();
        $count = 0;
        while (($event = qa_db_read_one_assoc($event_query, true)) !== null) {
            if (preg_match('/postid=([0-9]+)/', $event['params'], $m) === 1) {
                $event['postid'] = (int) $m[1];
                $postids[] = (int) $m[1];
                $events[$m[1] . '_' . $count++] = $event;
            } else {
                $events['nopost_' . $count++] = $event;
            }
        }
        // get post info, also makes sure post exists
        $posts = null;
        if (!empty($postids)) {
            $post_query = qa_db_read_all_assoc(qa_db_query_sub('SELECT postid, type, parentid, BINARY title as title FROM ^posts WHERE postid IN (' . implode(',', $postids) . ')'));
            foreach ($post_query as $post) {
                $posts[(string) $post['postid']] = $post;
            }
        }
        foreach ($events as $postid_string => $event) {
            $type = $event['event'];
            $postid = preg_replace('/_.*/', '', $postid_string);
            $post = null;
            $post = @$posts[$postid];
            // these calls allow you to deal with deleted events;
            // uncomment the first one to skip them
            // uncomment the second one to build your own routine based on whether they are deleted.
            if (!in_array($type, $nopost) && $post == null) {
                continue;
            }
            // $deleted = (!in_array($type, $nopost) && $post == null);
            // hide / show exceptions
            if (qa_get_logged_in_level() < QA_USER_LEVEL_ADMIN) {
                if ($userid != qa_get_logged_in_userid()) {
                    // show public
                    $types = explode("\n", qa_opt('user_act_list_show'));
                    if (!in_array($type, $types)) {
                        continue;
                    }
                } else {
                    // hide from owner
                    $types = explode("\n", qa_opt('user_act_list_hide'));
                    if (in_array($type, $types)) {
                        continue;
                    }
                }
            }
            if (!qa_opt('user_act_list_' . $type)) {
                continue;
            }
            $params = array();
            $paramsa = explode("\t", $event['params']);
            foreach ($paramsa as $param) {
                $parama = explode('=', $param);
                if (isset($parama[1])) {
                    $params[$parama[0]] = $parama[1];
                } else {
                    $params[$param] = $param;
                }
            }
            $link = '';
            if (in_array($type, $nopost)) {
                if ($type == 'search') {
                    if ((int) $params['start'] != 0) {
                        continue;
                    }
                    $link = '<a href="' . qa_path_html('search', array('q' => $params['query'])) . '">' . qa_html($params['query']) . '</a>';
                } else {
                    if (in_array($type, array('u_edit', 'u_level', 'u_block', 'u_unblock'))) {
                        $ohandle = $this->getHandleFromID($params['userid']);
                        $link = '<a href="' . qa_path_html('user/' . $ohandle, null, qa_opt('site_url')) . '">' . $ohandle . '</a>';
                    } else {
                        $link = '';
                    }
                }
            } else {
                if ($type == 'badge_awarded') {
                    if (!qa_opt('badge_active') || !function_exists('qa_get_badge_type')) {
                        continue;
                    }
                    if ($post != null) {
                        if (strpos($post['type'], 'Q') !== 0) {
                            $anchor = qa_anchor(strpos($post['type'], 'A') === 0 ? 'A' : 'C', $params['postid']);
                            $parent = qa_db_read_one_assoc(qa_db_query_sub('SELECT parentid,type,BINARY title as title,postid FROM ^posts WHERE postid=#', $post['parentid']), true);
                            if ($parent['type'] == 'A') {
                                $parent = qa_db_read_one_assoc(qa_db_query_sub('SELECT BINARY title as title,postid FROM ^posts WHERE postid=#', $parent['parentid']), true);
                            }
                            $activity_url = qa_path_html(qa_q_request($parent['postid'], $parent['title']), null, qa_opt('site_url'), null, $anchor);
                            $link = '<a href="' . $activity_url . '">' . $parent['title'] . '</a>';
                        } else {
                            $activity_url = qa_path_html(qa_q_request($params['postid'], $post['title']), null, qa_opt('site_url'), null, null);
                            $link = '<a href="' . $activity_url . '">' . $post['title'] . '</a>';
                        }
                    }
                } else {
                    if ($post != null && strpos($event['event'], 'q_') !== 0 && strpos($event['event'], 'in_q_') !== 0) {
                        // comment or answer
                        if (!isset($params['parentid'])) {
                            $params['parentid'] = $post['parentid'];
                        }
                        $parent = qa_db_select_with_pending(qa_db_full_post_selectspec($userid, $params['parentid']));
                        if ($parent['type'] == 'A') {
                            $parent = qa_db_select_with_pending(qa_db_full_post_selectspec($userid, $parent['parentid']));
                        }
                        $anchor = qa_anchor(strpos($event['event'], 'a_') === 0 || strpos($event['event'], 'in_a_') === 0 ? 'A' : 'C', $params['postid']);
                        $activity_url = qa_path_html(qa_q_request($parent['postid'], $parent['title']), null, qa_opt('site_url'), null, $anchor);
                        $link = '<a href="' . $activity_url . '">' . $parent['title'] . '</a>';
                    } else {
                        if ($post != null) {
                            // question
                            if (!isset($params['title'])) {
                                $params['title'] = $posts[$params['postid']]['title'];
                            }
                            if ($params['title'] !== null) {
                                $activity_url = qa_path_html(qa_q_request($params['postid'], $params['title']), null, qa_opt('site_url'));
                                $link = '<a href="' . $activity_url . '">' . $params['title'] . '</a>';
                            }
                        }
                    }
                }
            }
            $time = $event['datetime'];
            if (qa_opt('user_act_list_shading')) {
                $days = (qa_opt('db_time') - $time) / 60 / 60 / 24;
                $col = round($days / qa_opt('user_act_list_age') * 255 / 2);
                $bkg = 255 - round($days / qa_opt('user_act_list_age') * 255 / 8);
                $bkg = dechex($bkg);
                $col = dechex($col);
                if (strlen($col) == 1) {
                    $col = '0' . $col;
                }
                if (strlen($bkg) == 1) {
                    $bkg = '0' . $bkg;
                }
                $col = '#' . $col . $col . $col;
                $bkg = '#' . $bkg . $bkg . $bkg;
            }
            $whenhtml = qa_html(qa_time_to_string(qa_opt('db_time') - $time));
            $when = qa_lang_html_sub('main/x_ago', $whenhtml);
            $when = str_replace(' ', '<br/>', $when);
            $when = preg_replace('/([0-9]+)/', '<span class="qa-history-item-date-no">$1</span>', $when);
            if (strpos($type, '_vote_nil') == 4) {
                if ($params['oldvote'] == '1') {
                    // unvoting an upvote
                    $points = @$option_events[str_replace('_vote_nil', '_unvote_up', $type)];
                } else {
                    // unvoting a downvote
                    $points = @$option_events[str_replace('_vote_nil', '_unvote_down', $type)];
                }
            } else {
                $points = @$option_events[$type];
            }
            $string = qa_opt('user_act_list_' . $type);
            if ($type == 'badge_awarded') {
                $slug = $params['badge_slug'];
                $typea = qa_get_badge_type_by_slug($slug);
                if (!$typea) {
                    continue;
                }
                $types = $typea['slug'];
                $typed = $typea['name'];
                $badge_name = qa_badge_name($slug);
                if (!qa_opt('badge_' . $slug . '_name')) {
                    qa_opt('badge_' . $slug . '_name', $badge_name);
                }
                $var = qa_opt('badge_' . $slug . '_var');
                $name = qa_opt('badge_' . $slug . '_name');
                $desc = qa_badge_desc_replace($slug, $var, false);
                $string = str_replace('^badge', '<span class="badge-' . $types . '" title="' . $desc . ' (' . $typed . ')">' . qa_html($name) . '</span>', $string);
            }
            $fields[] = array('type' => 'static', 'label' => '<div class="qa-history-item-date' . ($time >= $last_visit && strpos($type, 'in_') === 0 ? ' qa-history-item-date-new' : '') . '"' . (qa_opt('user_act_list_shading') ? ' style="color:' . $col . ';background-color:' . $bkg . '"' : '') . '>' . $when . '</div>', 'value' => '<table class="qa-history-item-table"><tr><td class="qa-history-item-type-cell"><div class="qa-history-item-type qa-history-item-' . $type . '">' . $string . '</div></td><td class="qa-history-item-title-cell"><div class="qa-history-item-title">' . $link . '</div></td class="qa-history-item-points-cell"><td align="right">' . ($points ? '<div class="qa-history-item-points qa-history-item-points-' . ($points < 0 ? 'neg">' : 'pos">+') . $points . '</div>' : '&nbsp') . '</td></tr></table>');
        }
        if (empty($fields)) {
            return;
        }
        return array('style' => 'wide', 'title' => qa_opt('user_act_list_title'), 'fields' => $fields);
    }