|
1
|
|
|
<?php |
|
2
|
|
|
/* ********************************************************************************* |
|
3
|
|
|
* (c) 2011-15 GÉANT on behalf of the GN3, GN3plus and GN4 consortia |
|
4
|
|
|
* License: see the LICENSE file in the root directory |
|
5
|
|
|
***********************************************************************************/ |
|
6
|
|
|
?> |
|
7
|
|
|
<?php |
|
8
|
|
|
/** |
|
9
|
|
|
* |
|
10
|
|
|
* |
|
11
|
|
|
* This is the definition of the CAT class |
|
12
|
|
|
* @author Stefan Winter <[email protected]> |
|
13
|
|
|
* @author Tomasz Wolniewicz <[email protected]> |
|
14
|
|
|
* |
|
15
|
|
|
* @package Developer |
|
16
|
|
|
*/ |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* necessary includes |
|
20
|
|
|
*/ |
|
21
|
|
|
session_start(); |
|
22
|
|
|
require_once("Helper.php"); |
|
23
|
|
|
require_once("Federation.php"); |
|
24
|
|
|
|
|
25
|
|
|
/** |
|
26
|
|
|
* Define some variables which need to be globally accessible |
|
27
|
|
|
* and some general purpose methods |
|
28
|
|
|
* |
|
29
|
|
|
* @author Stefan Winter <[email protected]> |
|
30
|
|
|
* @author Tomasz Wolniewicz <[email protected]> |
|
31
|
|
|
* |
|
32
|
|
|
* @package Developer |
|
33
|
|
|
*/ |
|
34
|
|
|
class CAT { |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* which version is this? |
|
38
|
|
|
* even if we are unreleased, keep track of internal version-to-be |
|
39
|
|
|
* developers need to set this in code. The user-displayed string |
|
40
|
|
|
* is generated into $VERSION below |
|
41
|
|
|
*/ |
|
42
|
|
|
public static $VERSION_MAJOR = 1; |
|
43
|
|
|
public static $VERSION_MINOR = 2; |
|
44
|
|
|
public static $VERSION_PATCH = 0; |
|
45
|
|
|
public static $VERSION_EXTRA = ""; |
|
46
|
|
|
public static $RELEASE_VERSION = FALSE; |
|
47
|
|
|
public static $USER_API_VERSION = 2; |
|
48
|
|
|
|
|
49
|
|
|
/* |
|
50
|
|
|
* This is the user-displayed string; controlled by the four options above |
|
51
|
|
|
* It is generated in the constructor. |
|
52
|
|
|
*/ |
|
53
|
|
|
|
|
54
|
|
|
public static $VERSION; |
|
55
|
|
|
/** |
|
56
|
|
|
/** |
|
57
|
|
|
* database which this class queries by default |
|
58
|
|
|
* |
|
59
|
|
|
* @var string |
|
60
|
|
|
*/ |
|
61
|
|
|
private static $LANG = ''; |
|
62
|
|
|
private static $DB_TYPE = "INST"; |
|
63
|
|
|
/** |
|
64
|
|
|
* Constructor sets the language by calling set_lang |
|
65
|
|
|
* and stores language settings in object properties |
|
66
|
|
|
* additionally it also sets static variables $laing_index and $root |
|
67
|
|
|
*/ |
|
68
|
|
|
public function __construct() { |
|
69
|
|
|
$A = $this->set_lang(); |
|
70
|
|
|
self::$locale = $A[1]; |
|
71
|
|
|
$a = __DIR__; |
|
72
|
|
|
self::$root = dirname($a); |
|
73
|
|
|
|
|
74
|
|
|
|
|
75
|
|
|
if (CAT::$RELEASE_VERSION) { |
|
76
|
|
|
$temp_version = "CAT-".CAT::$VERSION_MAJOR.".".CAT::$VERSION_MINOR; |
|
77
|
|
|
if (CAT::$VERSION_PATCH != 0) |
|
78
|
|
|
$temp_version .= ".".CAT::$VERSION_PATCH; |
|
79
|
|
|
if (CAT::$VERSION_EXTRA != "") |
|
80
|
|
|
$temp_version .= "-".CAT::$VERSION_EXTRA; |
|
81
|
|
|
CAT::$VERSION = sprintf(_("Release %s"), $temp_version ); |
|
82
|
|
|
} |
|
83
|
|
|
else |
|
84
|
|
|
CAT::$VERSION = _("Unreleased SVN Revision"); |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* |
|
89
|
|
|
*/ |
|
90
|
|
|
public function totalIdPs($level) { |
|
91
|
|
|
switch ($level) { |
|
92
|
|
|
case "ALL": |
|
93
|
|
|
$idpcount = DBConnection::exec(CAT::$DB_TYPE, "SELECT COUNT(inst_id) AS instcount FROM institution"); |
|
94
|
|
|
break; |
|
95
|
|
|
case "VALIDPROFILE": |
|
96
|
|
|
$idpcount = DBConnection::exec(CAT::$DB_TYPE, "SELECT COUNT(DISTINCT institution.inst_id) AS instcount FROM institution,profile WHERE institution.inst_id = profile.inst_id AND profile.sufficient_config = 1"); |
|
97
|
|
|
break; |
|
98
|
|
|
case "PUBLICPROFILE": |
|
99
|
|
|
$idpcount = DBConnection::exec(CAT::$DB_TYPE, "SELECT COUNT(DISTINCT institution.inst_id) AS instcount FROM institution,profile WHERE institution.inst_id = profile.inst_id AND profile.showtime = 1"); |
|
100
|
|
|
break; |
|
101
|
|
|
default: |
|
102
|
|
|
return -1; |
|
103
|
|
|
} |
|
104
|
|
|
$dbresult = mysqli_fetch_object($idpcount); |
|
105
|
|
|
return $dbresult->instcount; |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* Sets the gettext domain |
|
110
|
|
|
* |
|
111
|
|
|
* @param string $domain |
|
112
|
|
|
* @return string previous seting so that you can restore it later |
|
113
|
|
|
*/ |
|
114
|
|
|
public static function set_locale($domain) { |
|
115
|
|
|
$olddomain = textdomain(NULL); |
|
116
|
|
|
debug(4, "set_locale($domain)\n"); |
|
117
|
|
|
debug(4, CAT::$root . "\n"); |
|
118
|
|
|
textdomain($domain); |
|
119
|
|
|
bindtextdomain($domain, CAT::$root . "/translation/"); |
|
120
|
|
|
return $olddomain; |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
/** |
|
124
|
|
|
* set_lang does all language setting magic |
|
125
|
|
|
* checks if lang has been declared in the http call |
|
126
|
|
|
* if not, checks for saved lang in the SESSION |
|
127
|
|
|
* or finally checks browser properties. |
|
128
|
|
|
* Only one of the supported langiages can be set |
|
129
|
|
|
* if a match is not found, the default langiage is used |
|
130
|
|
|
* @param $hardsetlang - this is currently not used but |
|
131
|
|
|
* will allow to forst lang setting if this was ever required |
|
132
|
|
|
*/ |
|
133
|
|
|
private static function set_lang($hardsetlang = 0) { |
|
134
|
|
|
$lang_converted = []; |
|
135
|
|
|
if ($hardsetlang !== 0) { |
|
136
|
|
|
$hardsetlocale = $hardsetlang; |
|
137
|
|
|
$lang_converted[] = $hardsetlocale; |
|
138
|
|
|
$_SESSION['language'] = $hardsetlocale; |
|
139
|
|
|
} elseif (isset($_REQUEST['lang'])) { |
|
140
|
|
|
$hardsetlocale = $_REQUEST['lang']; |
|
141
|
|
|
$lang_converted[] = $hardsetlocale; |
|
142
|
|
|
$_SESSION['language'] = $hardsetlocale; |
|
143
|
|
|
} elseif (isset($_SESSION['language'])) { |
|
144
|
|
|
$hardsetlocale = $_SESSION['language']; |
|
145
|
|
|
$lang_converted[] = $hardsetlocale; |
|
146
|
|
|
} elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { |
|
147
|
|
|
$langs = explode(",", $_SERVER["HTTP_ACCEPT_LANGUAGE"]); |
|
148
|
|
|
foreach ($langs as $lang) { |
|
149
|
|
|
preg_match("/(.*);+.*/", $lang, $result); |
|
150
|
|
|
$lang_converted[] = (isset($result[1]) && $result[1] ? $result[1] : $lang); |
|
151
|
|
|
} |
|
152
|
|
|
}; |
|
153
|
|
|
// always add configured locale as last resort |
|
154
|
|
|
$defaultlocale = Config::$APPEARANCE['defaultlocale']; |
|
155
|
|
|
$lang_converted[] = Config::$LANGUAGES[$defaultlocale]['locale']; |
|
156
|
|
|
$lang_index = $defaultlocale; |
|
157
|
|
|
|
|
158
|
|
|
setlocale(LC_ALL, 0); |
|
159
|
|
|
|
|
160
|
|
|
foreach ($lang_converted as $try_lang) { |
|
161
|
|
|
// madness! setlocale is completely unflexible. If $try_lang is "en" |
|
162
|
|
|
// it will fail, because it only knows en_US, en_GB a.s.o. |
|
163
|
|
|
// we need to map stuff manually |
|
164
|
|
|
$thelang = $try_lang; |
|
165
|
|
|
|
|
166
|
|
|
foreach (Config::$LANGUAGES as $language => $value) |
|
167
|
|
|
if (preg_match("/^" . $language . ".*/", $try_lang)) { |
|
168
|
|
|
$thelang = $value['locale']; |
|
169
|
|
|
$lang_index = $language; |
|
170
|
|
|
} |
|
171
|
|
|
|
|
172
|
|
|
// echo "Trying to set language to $thelang..."; |
|
|
|
|
|
|
173
|
|
|
// putenv("LC_ALL=$thelang"); |
|
174
|
|
|
if (setlocale(LC_ALL, $thelang)) |
|
175
|
|
|
break; |
|
176
|
|
|
} |
|
177
|
|
|
putenv("LC_ALL=" . $thelang); |
|
|
|
|
|
|
178
|
|
|
debug(4, "selected lang:$lang_index:$thelang\n"); |
|
179
|
|
|
debug(4, $lang_converted); |
|
180
|
|
|
return([$lang_index, $thelang]); |
|
181
|
|
|
} |
|
182
|
|
|
|
|
183
|
|
|
/** |
|
184
|
|
|
* gets the language setting in CAT |
|
185
|
|
|
*/ |
|
186
|
|
|
static public function get_lang() { |
|
187
|
|
|
if(self::$LANG === '') |
|
188
|
|
|
list(self::$LANG, $xx) = self::set_lang(); |
|
|
|
|
|
|
189
|
|
|
return self::$LANG; |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
/** |
|
193
|
|
|
* Prepares a list of countries known to the CAT. |
|
194
|
|
|
* |
|
195
|
|
|
* @param int $active_only is set and nonzero will cause that only countries with some institutions underneath will be listed |
|
196
|
|
|
* @return array Array indexed by (uppercase) lang codes and sorted according to the current locale |
|
197
|
|
|
*/ |
|
198
|
|
|
public function printCountryList($active_only = 0) { |
|
199
|
|
|
$olddomain = $this->set_locale("core"); |
|
200
|
|
|
if ($active_only) { |
|
201
|
|
|
$federations = DBConnection::exec(CAT::$DB_TYPE, "SELECT DISTINCT LOWER(institution.country) AS country FROM institution JOIN profile |
|
202
|
|
|
ON institution.inst_id = profile.inst_id WHERE profile.showtime = 1 ORDER BY country"); |
|
203
|
|
|
while ($a = mysqli_fetch_object($federations)) { |
|
204
|
|
|
$b = $a->country; |
|
205
|
|
|
$F = new Federation($b); |
|
206
|
|
|
$c = strtoupper($F->name); |
|
207
|
|
|
$C[$c] = isset(Federation::$FederationList[$c]) ? Federation::$FederationList[$c] : $c; |
|
|
|
|
|
|
208
|
|
|
} |
|
209
|
|
|
} else { |
|
210
|
|
|
new Federation; |
|
211
|
|
|
$C = Federation::$FederationList; |
|
212
|
|
|
} |
|
213
|
|
|
asort($C, SORT_LOCALE_STRING); |
|
214
|
|
|
$this->set_locale($olddomain); |
|
215
|
|
|
return($C); |
|
216
|
|
|
} |
|
217
|
|
|
|
|
218
|
|
|
/** |
|
219
|
|
|
* Writes an audit log entry to the audit log file. These audits are semantic logs; they don't record every single modification |
|
220
|
|
|
* in the database, but provide a logical "who did what" overview. The exact modification SQL statements are logged |
|
221
|
|
|
* automatically with writeSQLAudit() instead. The log file path is configurable in _config.php. |
|
222
|
|
|
* |
|
223
|
|
|
* @param string $user persistent identifier of the user who triggered the action |
|
224
|
|
|
* @param string $category type of modification, from the fixed vocabulary: "NEW", "OWN", "MOD", "DEL" |
|
225
|
|
|
* @param string $message message to log into the audit log |
|
226
|
|
|
* @return boolean TRUE if successful. Will terminate script execution on failure. |
|
227
|
|
|
*/ |
|
228
|
|
|
public static function writeAudit($user, $category, $message) { |
|
229
|
|
|
switch ($category) { |
|
230
|
|
|
case "NEW": // created a new object |
|
231
|
|
|
case "OWN": // ownership changes |
|
232
|
|
|
case "MOD": // modified existing object |
|
233
|
|
|
case "DEL": // deleted an object |
|
234
|
|
|
ob_start(); |
|
235
|
|
|
printf("%-015s",microtime(TRUE)); |
|
236
|
|
|
print " ($category) "; |
|
237
|
|
|
print_r(" ".$user.": ".$message."\n"); |
|
|
|
|
|
|
238
|
|
|
$output = ob_get_clean(); |
|
239
|
|
View Code Duplication |
if (Config::$PATHS['logdir']) { |
|
|
|
|
|
|
240
|
|
|
$f = fopen(Config::$PATHS['logdir'] . "/audit-activity.log", "a"); |
|
241
|
|
|
fwrite($f, $output); |
|
242
|
|
|
fclose($f); |
|
243
|
|
|
} else { |
|
244
|
|
|
print $output; |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
return TRUE; |
|
248
|
|
|
default: |
|
249
|
|
|
exit(1); |
|
250
|
|
|
} |
|
251
|
|
|
} |
|
252
|
|
|
|
|
253
|
|
|
/** |
|
254
|
|
|
* Write an audit log entry to the SQL log file. Every SQL statement which is not a simple SELECT one will be written |
|
255
|
|
|
* to the log file. The log file path is configurable in _config.php. |
|
256
|
|
|
* |
|
257
|
|
|
* @param string $query the SQL query to be logged |
|
258
|
|
|
*/ |
|
259
|
|
|
public static function writeSQLAudit($query) { |
|
260
|
|
|
// clean up text to be in one line, with no extra spaces |
|
261
|
|
|
$logtext1 = preg_replace("/[\n\r]/", "", $query); |
|
262
|
|
|
$logtext = preg_replace("/ +/", " ", $logtext1); |
|
263
|
|
|
ob_start(); |
|
264
|
|
|
printf("%-015s",microtime(TRUE)); |
|
265
|
|
|
print(" ".$logtext."\n"); |
|
|
|
|
|
|
266
|
|
|
$output = ob_get_clean(); |
|
267
|
|
View Code Duplication |
if (Config::$PATHS['logdir']) { |
|
|
|
|
|
|
268
|
|
|
$f = fopen(Config::$PATHS['logdir'] . "/audit-SQL.log", "a"); |
|
269
|
|
|
fwrite($f, $output); |
|
270
|
|
|
fclose($f); |
|
271
|
|
|
} else { |
|
272
|
|
|
print $output; |
|
273
|
|
|
} |
|
274
|
|
|
} |
|
275
|
|
|
|
|
276
|
|
|
/** |
|
277
|
|
|
* stores the location of the root directory |
|
278
|
|
|
* @static string $root |
|
279
|
|
|
*/ |
|
280
|
|
|
public static $root; |
|
281
|
|
|
|
|
282
|
|
|
/** |
|
283
|
|
|
* language display name for the language set by the constructor |
|
284
|
|
|
*/ |
|
285
|
|
|
public static $locale; |
|
286
|
|
|
|
|
287
|
|
|
} |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.