1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
<?php
# Lifter010: TODO
/*
* Copyright (C) 2004 - Tobias Thelen <tthelen@uos.de>
* Copyright (C) 2004 - Till Glöggler <tgloeggl@uos.de>
* Copyright (C) 2009 - Marcus Lunzenauer <mlunzena@uos.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
/**
* This class awards honours (crowns) to users posting a lot in the bulletin
* boards, writing a lot of wiki pages and so on.
*
* @author mlunzena
*/
class StudipKing {
/**
* How many of each type should be awarded?
*/
const NUM_KINGS = 1;
/**
* key to use for caching
*/
const CACHE_KEY = 'core/kings';
/**
* store kings also in memory
*/
private static $kings;
/**
* Returns the awards of a user as an associative array consisting of
* "award type" => "amount of posts, wiki pages etc." pairs that belong to
* this user. If the 2nd parameter is set to true, the values are
* descriptional strings instead of the raw numbers.
*
* @param string a string containing the MD5ish ID of the user
* @param bool TRUE to return descriptional text, FALSE to return
* raw numbers, which is the default
*
* @return array an associative array mapping the awards to an amount
*/
static function is_king($user_id, $textual = FALSE)
{
$kings = self::get_kings();
$result = isset($kings[$user_id]) ? $kings[$user_id] : [];
if ($textual) {
foreach ($result as $type => $amount) {
$result[$type] = self::textual_representation($type, $amount);
}
}
return $result;
}
private static function get_kings()
{
if (self::$kings === null) {
$cache = \Studip\Cache\Factory::getCache();
# read cache (unserializing a cache miss - FALSE - does not matter)
$kings = unserialize($cache->read(self::CACHE_KEY));
# cache miss, retrieve from database
if ($kings === FALSE) {
$kings = self::get_kings_uncached();
# write to cache with an expiry time of 24 hours
$cache->write(self::CACHE_KEY, serialize($kings), 86400);
}
self::$kings = $kings;
}
return self::$kings;
}
private static function get_kings_uncached()
{
$types = words('files forum news voter votes wiki');
$kings = [];
foreach ($types as $type) {
$method = "{$type}_kings";
foreach (self::$method() as $user_id => $amount) {
if (!isset($kings[$user_id])) {
$kings[$user_id] = [];
}
$kings[$user_id][$type] = $amount;
}
}
return $kings;
}
private static function select_kings($sql)
{
$result = [];
$stmt = DBManager::get()->query($sql . " ORDER BY num DESC LIMIT 0," . self::NUM_KINGS);
foreach ($stmt as $row) {
$result[$row["id"]] = $row["num"];
}
return $result;
}
private static function wiki_kings()
{
return self::select_kings("
SELECT user_id AS id, COUNT(*) AS num
FROM (SELECT user_id FROM wiki_pages UNION SELECT user_id FROM wiki_versions) AS `all_wiki_pages`
GROUP BY user_id");
}
private static function forum_kings()
{
$kings = [];
// sum up postings for all users from all ForumModules available
foreach (PluginEngine::getPlugins(ForumModule::class) as $plugin) {
$table = $plugin->getEntryTableInfo();
$query = "SELECT user_id AS id, COUNT(*) AS num FROM ". $table['table'] ." GROUP BY user_id";
$new_kings = self::select_kings($query);
foreach ($new_kings as $user_id => $num) {
if (!isset($kings[$user_id])) {
$kings[$user_id] = $num;
} else {
$kings[$user_id] += $num;
}
}
}
return $kings;
}
private static function files_kings()
{
return self::select_kings("SELECT user_id AS id, COUNT(*) AS num FROM file_refs GROUP BY user_id");
}
private static function votes_kings()
{
return self::select_kings("SELECT questionnaires.user_id AS id, COUNT(*) AS num
FROM questionnaires
LEFT JOIN questionnaire_questions ON (questionnaires.questionnaire_id = questionnaire_questions.questionnaire_id)
LEFT JOIN questionnaire_answers ON (questionnaire_questions.question_id = questionnaire_answers.question_id)
GROUP BY questionnaires.user_id");
}
private static function voter_kings()
{
return self::select_kings("SELECT user_id AS id, COUNT(*) AS num FROM questionnaire_answers GROUP BY user_id");
}
private static function news_kings()
{
return self::select_kings("SELECT user_id AS id, COUNT(*) AS num FROM news GROUP BY user_id");
}
private static function textual_representation($type, $amount)
{
$alt_text = [
'files' => _('%d hochgeladene Dateien'),
'forum' => _('%d Forums-Beiträge'),
'wiki' => _('%d Wiki-Beiträge'),
'voter' => _('%d abgegebene Stimmen'),
'votes' => _('%d bekommene Stimmen'),
'news' => _('%d eingestellte Ankündigungen')
];
return sprintf($alt_text[$type], $amount);
}
}
|