Completed
Push — master ( ee79b5...34b090 )
by Stefan
04:54
created

Federation   C

Complexity

Total Complexity 66

Size/Duplication

Total Lines 605
Duplicated Lines 4.46 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 27
loc 605
rs 5.7154
wmc 66
lcom 1
cbo 7

9 Methods

Rating   Name   Duplication   Size   Complexity  
B downloadStatsCore() 0 21 6
C downloadStats() 12 31 8
B __construct() 15 293 4
A newIdP() 0 17 4
B listIdentityProviders() 0 25 3
B listFederationAdmins() 0 14 5
C listExternalEntities() 0 70 17
C getExternalDBEntityDetails() 0 27 8
D listAllIdentityProviders() 0 57 11

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Federation often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Federation, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* * *********************************************************************************
4
 * (c) 2011-15 GÉANT on behalf of the GN3, GN3plus and GN4 consortia
5
 * License: see the LICENSE file in the root directory
6
 * ********************************************************************************* */
7
?>
8
<?php
9
10
/**
11
 * This file contains the Federation class.
12
 * 
13
 * @author Stefan Winter <[email protected]>
14
 * @author Tomasz Wolniewicz <[email protected]>
15
 * 
16
 * @package Developer
17
 * 
18
 */
19
/**
20
 * necessary includes
21
 */
22
require_once("CAT.php");
23
require_once('IdP.php');
24
require_once('EntityWithDBProperties.php');
25
26
/**
27
 * This class represents an consortium federation.
28
 * It is semantically a country(!). Do not confuse this with a TLD; a federation
29
 * may span more than one TLD, and a TLD may be distributed across multiple federations.
30
 *
31
 * Example: a federation "fr" => "France" may also contain other TLDs which
32
 *              belong to France in spite of their different TLD
33
 * Example 2: Domains ending in .edu are present in multiple different
34
 *              federations
35
 *
36
 * @author Stefan Winter <[email protected]>
37
 * @author Tomasz Wolniewicz <[email protected]>
38
 *
39
 * @license see LICENSE file in root directory
40
 *
41
 * @package Developer
42
 */
43
class Federation extends EntityWithDBProperties {
44
45
    /**
46
     * all known federation, in an array with ISO short name as an index, and localised version of the pretty-print name as value.
47
     * The static value is only filled with meaningful content after the first object has been instantiated. That is because it is not
48
     * possible to define static properties with function calls like _().
49
     * 
50
     * @var array of all known federations
51
     */
52
    public static $FederationList = [];
53
54
    private static function downloadStatsCore($federationid = NULL) {
55
        $grossAdmin = 0;
56
        $grossUser = 0;
57
58
        $dataArray = [];
59
60
        foreach (Devices::listDevices() as $index => $device_array) {
61
            $query = "SELECT SUM(downloads_admin) AS admin, SUM(downloads_user) AS user FROM downloads, profile, institution WHERE device_id = '$index' AND downloads.profile_id = profile.profile_id AND profile.inst_id = institution.inst_id ";
62
            if ($federationid != NULL) {
63
                $query .= "AND institution.country = '" . $federationid . "'";
64
            }
65
            $number_query = DBConnection::exec("INST", $query);
66
            while ($queryResult = mysqli_fetch_object($number_query)) {
67
                $dataArray[$device_array['display']] = ["ADMIN" => ( $queryResult->admin === NULL ? "0" : $queryResult->admin), "USER" => ($queryResult->user === NULL ? "0" : $queryResult->user)];
68
                $grossAdmin = $grossAdmin + $queryResult->admin;
69
                $grossUser = $grossUser + $queryResult->user;
70
            }
71
        }
72
        $dataArray["TOTAL"] = ["ADMIN" => $grossAdmin, "USER" => $grossUser];
73
        return $dataArray;
74
    }
75
76
    public static function downloadStats($format, $federationid = NULL) {
77
        $data = Federation::downloadStatsCore($federationid);
78
        $retstring = "";
79
        
80
        switch ($format) {
81
            case "table":
82 View Code Duplication
                foreach ($data as $device => $numbers) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
                    if ($device == "TOTAL") {
84
                        continue;
85
                    }
86
                    $retstring .= "<tr><td>$device</td><td>".$numbers['ADMIN']."</td><td>".$numbers['USER']."</td></tr>";
87
                }
88
                $retstring .= "<tr><td><strong>TOTAL</strong></td><td><strong>".$data['TOTAL']['ADMIN']."</strong></td><td><strong>".$data['TOTAL']['USER']."</strong></td></tr>";
89
                break;
90
            case "XML":
91
                $retstring .= "<federation id='" . ( $federationid == NULL ? "ALL" : $federationid ) . "' ts='".date("Y-m-d") . "T" . date("H:i:s")."'>\n";
92 View Code Duplication
                foreach ($data as $device => $numbers) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
                    if ($device == "TOTAL") {
94
                        continue;
95
                    }
96
                    $retstring .= "  <device name='" . $device . "'>\n    <downloads group='admin'>".$numbers['ADMIN']."</downloads>\n    <downloads group='user'>".$numbers['USER']."</downloads>\n  </device>";
97
                }
98
                $retstring .= "<total>\n  <downloads group='admin'>".$data['TOTAL']['ADMIN']."</downloads>\n  <downloads group='user'>".$data['TOTAL']['USER']."</downloads>\n</total>\n";
99
                $retstring .= "</federation>";
100
                break;
101
            default:
102
               return false;
103
        }
104
105
        return $retstring;
106
    }
107
108
    /**
109
     *
110
     * Constructs a Federation object.
111
     *
112
     * @param string $fedname - textual representation of the Federation object
113
     *        Example: "lu" (for Luxembourg)
114
     */
115
    public function __construct($fedname = "") {
116
117
        // initialise the superclass variables
118
119
        $this->databaseType = "INST";
120
        $this->entityOptionTable = "federation_option";
121
        $this->entityIdColumn = "federation_id";
122
        $this->identifier = $fedname;
123
        $this->name = $fedname;
124
        $this->attributes = [];
125
126
        /* Federations are created in DB with bootstrapFederation, and listed via listFederations
127
         */
128
        $oldlocale = CAT::set_locale('core');
129
130
        Federation::$FederationList = [
131
            'AD' => _("Andorra"),
132
            'AT' => _("Austria"),
133
            'BE' => _("Belgium"),
134
            'BG' => _("Bulgaria"),
135
            'CY' => _("Cyprus"),
136
            'CZ' => _("Czech Republic"),
137
            'DK' => _("Denmark"),
138
            'EE' => _("Estonia"),
139
            'FI' => _("Finland"),
140
            'FR' => _("France"),
141
            'DE' => _("Germany"),
142
            'GR' => _("Greece"),
143
            'HR' => _("Croatia"),
144
            'IE' => _("Ireland"),
145
            'IS' => _("Iceland"),
146
            'IT' => _("Italy"),
147
            'HU' => _("Hungary"),
148
            'LU' => _("Luxembourg"),
149
            'LV' => _("Latvia"),
150
            'LT' => _("Lithuania"),
151
            'MK' => _("Macedonia"),
152
            'RS' => _("Serbia"),
153
            'NL' => _("Netherlands"),
154
            'NO' => _("Norway"),
155
            'PL' => _("Poland"),
156
            'PT' => _("Portugal"),
157
            'RO' => _("Romania"),
158
            'SI' => _("Slovenia"),
159
            'ES' => _("Spain"),
160
            'SE' => _("Sweden"),
161
            'SK' => _("Slovakia"),
162
            'CH' => _("Switzerland"),
163
            'TR' => _("Turkey"),
164
            'UK' => _("United Kingdom"),
165
            'TEST' => 'TEST Country',
166
            'AU' => _("Australia"),
167
            'CA' => _("Canada"),
168
            'IL' => _("Israel"),
169
            'JP' => _("Japan"),
170
            'NZ' => _("New Zealand"),
171
            'US' => _("U.S.A."),
172
            'BR' => _("Brazil"),
173
            'CL' => _("Chile"),
174
            'PE' => _("Peru"),
175
            'VE' => _("Venezuela"),
176
            'DEFAULT' => _("Default"),
177
            'AM' => _("Armenia"),
178
            'AZ' => _("Azerbaijan"),
179
            'BY' => _("Belarus"),
180
            'EC' => _("Ecuador"),
181
            'HK' => _("Hong Kong"),
182
            'KE' => _("Kenya"),
183
            'KG' => _("Kyrgyzstan"),
184
            'KR' => _("Korea"),
185
            'KZ' => _("Kazakhstan"),
186
            'MA' => _("Morocco"),
187
            'MD' => _("Moldova"),
188
            'ME' => _("Montenegro"),
189
            'MO' => _("Macau"),
190
            'MT' => _("Malta"),
191
            'RU' => _("Russia"),
192
            'SG' => _("Singapore"),
193
            'TH' => _("Thailand"),
194
            'TW' => _("Taiwan"),
195
            'ZA' => _("South Africa"),
196
            'AF' => 'Afghanistan',
197
            'AL' => 'Albania',
198
            'DZ' => 'Algeria',
199
            'AS' => 'American Samoa',
200
            'AO' => 'Angola',
201
            'AI' => 'Anguilla',
202
            'AQ' => 'Antarctica',
203
            'AG' => 'Antigua And Barbuda',
204
            'AR' => 'Argentina',
205
            'AW' => 'Aruba',
206
            'BS' => 'Bahamas, The',
207
            'BH' => 'Bahrain',
208
            'BD' => 'Bangladesh',
209
            'BB' => 'Barbados',
210
            'BZ' => 'Belize',
211
            'BJ' => 'Benin',
212
            'BM' => 'Bermuda',
213
            'BT' => 'Bhutan',
214
            'BO' => 'Bolivia',
215
            'BA' => 'Bosnia And Herzegovina',
216
            'BW' => 'Botswana',
217
            'BV' => 'Bouvet Island',
218
            'IO' => 'British Indian Ocean Territory',
219
            'BN' => 'Brunei',
220
            'BF' => 'Burkina Faso',
221
            'MM' => 'Burma',
222
            'BI' => 'Burundi',
223
            'KH' => 'Cambodia',
224
            'CM' => 'Cameroon',
225
            'CV' => 'Cape Verde',
226
            'KY' => 'Cayman Islands',
227
            'CF' => 'Central African Republic',
228
            'TD' => 'Chad',
229
            'CN' => 'China',
230
            'CX' => 'Christmas Island',
231
            'CC' => 'Cocos (keeling) Islands',
232
            'CO' => 'Colombia',
233
            'KM' => 'Comoros',
234
            'CG' => 'Congo (brazzaville) ',
235
            'CD' => 'Congo (kinshasa)',
236
            'CK' => 'Cook Islands',
237
            'CR' => 'Costa Rica',
238
            'CI' => 'CÔte D’ivoire',
239
            'CU' => 'Cuba',
240
            'CW' => 'CuraÇao',
241
            'DJ' => 'Djibouti',
242
            'DM' => 'Dominica',
243
            'DO' => 'Dominican Republic',
244
            'EG' => 'Egypt',
245
            'SV' => 'El Salvador',
246
            'GQ' => 'Equatorial Guinea',
247
            'ER' => 'Eritrea',
248
            'ET' => 'Ethiopia',
249
            'FK' => 'Falkland Islands (islas Malvinas)',
250
            'FO' => 'Faroe Islands',
251
            'FJ' => 'Fiji',
252
            'GF' => 'French Guiana',
253
            'PF' => 'French Polynesia',
254
            'TF' => 'French Southern And Antarctic Lands',
255
            'GA' => 'Gabon',
256
            'GM' => 'Gambia, The',
257
            'GE' => 'Georgia',
258
            'GH' => 'Ghana',
259
            'GI' => 'Gibraltar',
260
            'GL' => 'Greenland',
261
            'GD' => 'Grenada',
262
            'GP' => 'Guadeloupe',
263
            'GU' => 'Guam',
264
            'GT' => 'Guatemala',
265
            'GG' => 'Guernsey',
266
            'GN' => 'Guinea',
267
            'GW' => 'Guinea-bissau',
268
            'GY' => 'Guyana',
269
            'HT' => 'Haiti',
270
            'HM' => 'Heard Island And Mcdonald Islands',
271
            'HN' => 'Honduras',
272
            'IN' => 'India',
273
            'ID' => 'Indonesia',
274
            'IR' => 'Iran',
275
            'IQ' => 'Iraq',
276
            'IM' => 'Isle Of Man',
277
            'JM' => 'Jamaica',
278
            'JE' => 'Jersey',
279
            'JO' => 'Jordan',
280
            'KI' => 'Kiribati',
281
            'KP' => 'Korea, North',
282
            'KW' => 'Kuwait',
283
            'LA' => 'Laos',
284
            'LB' => 'Lebanon',
285
            'LS' => 'Lesotho',
286
            'LR' => 'Liberia',
287
            'LY' => 'Libya',
288
            'LI' => 'Liechtenstein',
289
            'MG' => 'Madagascar',
290
            'MW' => 'Malawi',
291
            'MY' => 'Malaysia',
292
            'MV' => 'Maldives',
293
            'ML' => 'Mali',
294
            'MH' => 'Marshall Islands',
295
            'MQ' => 'Martinique',
296
            'MR' => 'Mauritania',
297
            'MU' => 'Mauritius',
298
            'YT' => 'Mayotte',
299
            'MX' => 'Mexico',
300
            'FM' => 'Micronesia, Federated States Of',
301
            'MC' => 'Monaco',
302
            'MN' => 'Mongolia',
303
            'MS' => 'Montserrat',
304
            'MZ' => 'Mozambique',
305
            'NA' => 'Namibia',
306
            'NR' => 'Nauru',
307
            'NP' => 'Nepal',
308
            'NC' => 'New Caledonia',
309
            'NI' => 'Nicaragua',
310
            'NE' => 'Niger',
311
            'NG' => 'Nigeria',
312
            'NU' => 'Niue',
313
            'NF' => 'Norfolk Island',
314
            'MP' => 'Northern Mariana Islands',
315
            'OM' => 'Oman',
316
            'PK' => 'Pakistan',
317
            'PW' => 'Palau',
318
            'PA' => 'Panama',
319
            'PG' => 'Papua New Guinea',
320
            'PY' => 'Paraguay',
321
            'PH' => 'Philippines',
322
            'PN' => 'Pitcairn Islands',
323
            'PR' => 'Puerto Rico',
324
            'QA' => 'Qatar',
325
            'RE' => 'Reunion',
326
            'RW' => 'Rwanda',
327
            'BL' => 'Saint Barthelemy',
328
            'SH' => 'Saint Helena, Ascension, And Tristan Da Cunha',
329
            'KN' => 'Saint Kitts And Nevis',
330
            'LC' => 'Saint Lucia',
331
            'MF' => 'Saint Martin',
332
            'PM' => 'Saint Pierre And Miquelon',
333
            'VC' => 'Saint Vincent And The Grenadines',
334
            'WS' => 'Samoa',
335
            'SM' => 'San Marino',
336
            'ST' => 'Sao Tome And Principe',
337
            'SA' => 'Saudi Arabia',
338
            'SN' => 'Senegal',
339
            'SC' => 'Seychelles',
340
            'SL' => 'Sierra Leone',
341
            'SX' => 'Sint Maarten',
342
            'SB' => 'Solomon Islands',
343
            'SO' => 'Somalia',
344
            'GS' => 'South Georgia And South Sandwich Islands',
345
            'SS' => 'South Sudan',
346
            'LK' => 'Sri Lanka',
347
            'SD' => 'Sudan',
348
            'SR' => 'Suriname',
349
            'SZ' => 'Swaziland',
350
            'SY' => 'Syria',
351
            'TJ' => 'Tajikistan',
352
            'TZ' => 'Tanzania',
353
            'TL' => 'Timor-leste',
354
            'TG' => 'Togo',
355
            'TK' => 'Tokelau',
356
            'TO' => 'Tonga',
357
            'TT' => 'Trinidad And Tobago',
358
            'TN' => 'Tunisia',
359
            'TM' => 'Turkmenistan',
360
            'TC' => 'Turks And Caicos Islands',
361
            'TV' => 'Tuvalu',
362
            'UG' => 'Uganda',
363
            'UA' => 'Ukraine',
364
            'AE' => 'United Arab Emirates',
365
            'GB' => 'United Kingdom',
366
            'UY' => 'Uruguay',
367
            'UZ' => 'Uzbekistan',
368
            'VU' => 'Vanuatu',
369
            'VA' => 'Vatican City',
370
            'VN' => 'Vietnam',
371
            'VG' => 'Virgin Islands, British',
372
            'VI' => 'Virgin Islands, United States ',
373
            'WF' => 'Wallis And Futuna',
374
            'EH' => 'Western Sahara',
375
            'YE' => 'Yemen',
376
            'ZM' => 'Zambia',
377
            'ZW' => 'Zimbabwe',
378
        ];
379
380
        CAT::set_locale($oldlocale);
381
382
        $fedAttributes = DBConnection::exec($this->databaseType, "SELECT DISTINCT option_name,option_value, row FROM federation_option
383
              WHERE federation_id = '$this->name'  ORDER BY option_name");
384
385
        $optioninstance = Options::instance();
386
387 View Code Duplication
        while ($queryResult = mysqli_fetch_object($fedAttributes)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
388
            $lang = "";
0 ignored issues
show
Unused Code introduced by
$lang is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
389
            // decode base64 for files (respecting multi-lang)
390
            $optinfo = $optioninstance->optionType($queryResult->option_name);
391
            $flag = $optinfo['flag'];
392
393
            if ($optinfo['type'] != "file") {
394
                $this->attributes[] = array("name" => $queryResult->option_name, "value" => $queryResult->option_value, "level" => "FED", "row" => $queryResult->row, "flag" => $flag);
395
            } else {
396
                
397
                $decodedAttribute = $this->decodeFileAttribute($queryResult->option_value);
398
399
                $this->attributes[] = array("name" => $queryResult->option_name, "value" => ($decodedAttribute['lang'] == "" ? $decodedAttribute['content'] : serialize($decodedAttribute)), "level" => "FED", "row" => $queryResult->row, "flag" => $flag);
400
            }
401
        }
402
        $this->attributes[] = array("name" => "internal:country",
403
            "value" => $this->name,
404
            "level" => "FED",
405
            "row" => 0,
406
            "flag" => NULL);
407
    }
408
409
    /**
410
     * Creates a new IdP inside the federation.
411
     * 
412
     * @param string $owner_id Persistent identifier of the user for whom this IdP is created (first administrator)
413
     * @param string $level Privilege level of the first administrator (was he blessed by a federation admin or a peer?)
414
     * @param string $mail e-mail address with which the user was invited to administer (useful for later user identification if the user chooses a "funny" real name)
415
     * @return int identifier of the new IdP
416
     */
417
    public function newIdP($owner_id, $level, $mail) {
418
        DBConnection::exec($this->databaseType, "INSERT INTO institution (country) VALUES('$this->name')");
419
        $identifier = DBConnection::lastID($this->databaseType);
420
        if ($identifier == 0 || !CAT::writeAudit($owner_id, "NEW", "IdP $identifier")) {
0 ignored issues
show
Bug Best Practice introduced by
The expression \CAT::writeAudit($owner_...', "IdP {$identifier}") of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
421
            echo "<p>" . _("Could not create a new Institution!") . "</p>";
422
            exit(1);
423
        }
424
        // escape all strings
425
        $escapedOwnerId = DBConnection::escape_value($this->databaseType, $owner_id);
426
        $escapedLevel = DBConnection::escape_value($this->databaseType, $level);
427
        $escapedMail = DBConnection::escape_value($this->databaseType, $mail);
428
429
        if ($escapedOwnerId != "PENDING") {
430
            DBConnection::exec($this->databaseType, "INSERT INTO ownership (user_id,institution_id, blesslevel, orig_mail) VALUES('$escapedOwnerId', $identifier, '$escapedLevel', '$escapedMail')");
431
        }
432
        return $identifier;
433
    }
434
435
    /**
436
     * Lists all Identity Providers in this federation
437
     *
438
     * @param int $active_only if set to non-zero will list only those institutions which have some valid profiles defined.
439
     * @return array (Array of IdP instances)
440
     *
441
     */
442
    public function listIdentityProviders($active_only = 0) {
443
        if ($active_only) {
444
            $allIDPs = DBConnection::exec($this->databaseType, "SELECT distinct institution.inst_id AS inst_id
445
               FROM institution
446
               JOIN profile ON institution.inst_id = profile.inst_id
447
               WHERE institution.country = '$this->name' 
448
               AND profile.showtime = 1
449
               ORDER BY inst_id");
450
        } else {
451
            $allIDPs = DBConnection::exec($this->databaseType, "SELECT inst_id FROM institution
452
               WHERE country = '$this->name' ORDER BY inst_id");
453
        }
454
455
        $returnarray = [];
456
        while ($a = mysqli_fetch_object($allIDPs)) {
457
            $idp = new IdP($a->inst_id);
458
            $name = $idp->name;
459
            $A = ['entityID' => $idp->identifier,
460
                'title' => $name,
461
                'country' => strtoupper($idp->federation),
462
                'instance' => $idp];
463
            $returnarray[$idp->identifier] = $A;
464
        }
465
        return $returnarray;
466
    }
467
468
    public function listFederationAdmins() {
469
        $returnarray = [];
470
        $query = "SELECT user_id FROM user_options WHERE option_name = 'user:fedadmin' AND option_value = '" . strtoupper($this->name) . "'";
471
        if (Config::$CONSORTIUM['name'] == "eduroam" && isset(Config::$CONSORTIUM['deployment-voodoo']) && Config::$CONSORTIUM['deployment-voodoo'] == "Operations Team") { // SW: APPROVED
472
            $query = "SELECT eptid as user_id FROM view_admin WHERE role = 'fedadmin' AND realm = '" . strtolower($this->name) . "'";
473
        }
474
        
475
        $admins = DBConnection::exec("USER", $query);
476
        
477
        while ($a = mysqli_fetch_object($admins)) {
478
            $returnarray[] = $a->user_id;
479
        }
480
        return $returnarray;
481
    }
482
483
    public function listExternalEntities($unmapped_only) {
484
        $returnarray = [];
485
        $countrysuffix = "";
486
487
        if ($this->name != "") {
488
            $countrysuffix = " WHERE country = '" . strtolower($this->name) . "'";
489
        }
490
        
491
        if (Config::$CONSORTIUM['name'] == "eduroam" && isset(Config::$CONSORTIUM['deployment-voodoo']) && Config::$CONSORTIUM['deployment-voodoo'] == "Operations Team") { // SW: APPROVED
492
            $usedarray = [];
493
            $externals = DBConnection::exec("EXTERNAL", "SELECT id_institution AS id, country, inst_realm as realmlist, name AS collapsed_name, contact AS collapsed_contact 
494
                                                                                FROM view_active_idp_institution $countrysuffix");
495
            $already_used = DBConnection::exec($this->databaseType, "SELECT DISTINCT external_db_id FROM institution 
496
                                                                                                     WHERE external_db_id IS NOT NULL 
497
                                                                                                     AND external_db_syncstate = " . EXTERNAL_DB_SYNCSTATE_SYNCED);
498
            $pending_invite = DBConnection::exec($this->databaseType, "SELECT DISTINCT external_db_uniquehandle FROM invitations 
499
                                                                                                      WHERE external_db_uniquehandle IS NOT NULL 
500
                                                                                                      AND invite_created >= TIMESTAMPADD(DAY, -1, NOW()) 
501
                                                                                                      AND used = 0");
502
            while ($a = mysqli_fetch_object($already_used)) {
503
                $usedarray[] = $a->external_db_id;
504
            }
505
            while ($a = mysqli_fetch_object($pending_invite)) {
506
                if (!in_array($a->external_db_uniquehandle, $usedarray)) {
507
                    $usedarray[] = $a->external_db_uniquehandle;
508
                }
509
            }
510
            while ($a = mysqli_fetch_object($externals)) {
511
                if (($unmapped_only === TRUE) && (in_array($a->id, $usedarray))) {
512
                        continue;
513
                }
514
                $names = explode('#', $a->collapsed_name);
515
                // trim name list to current best language match
516
                $available_languages = [];
517
                foreach ($names as $name) {
518
                    $thislang = explode(': ', $name, 2);
519
                    $available_languages[$thislang[0]] = $thislang[1];
520
                }
521
                if (array_key_exists(CAT::get_lang(), $available_languages)) {
522
                    $thelangauge = $available_languages[CAT::get_lang()];
523
                } else if (array_key_exists("en", $available_languages)) {
524
                    $thelangauge = $available_languages["en"];
525
                } else { // whatever. Pick one out of the list
526
                    $thelangauge = array_pop($available_languages);
527
                }
528
                $contacts = explode('#', $a->collapsed_contact);
529
530
531
                $mailnames = "";
532
                foreach ($contacts as $contact) {
533
                    $matches = [];
534
                    preg_match("/^n: (.*), e: (.*), p: .*$/", $contact, $matches);
535
                    if ($matches[2] != "") {
536
                        if ($mailnames != "") {
537
                            $mailnames .= ", ";
538
                        }
539
                        // extracting real names is nice, but the <> notation
540
                        // really gets screwed up on POSTs and HTML safety
541
                        // so better not do this; use only mail addresses
542
                        // keeping the old codeline in case we revive this
543
                        // $mailnames .= '"'.$matches[1].'" <'.$matches[2].'>';
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

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.

Loading history...
544
                        $mailnames .= $matches[2];
545
                    }
546
                }
547
                $returnarray[] = ["ID" => $a->id, "name" => $thelangauge, "contactlist" => $mailnames, "country" => $a->country, "realmlist" => $a->realmlist];
548
            }
549
        }
550
551
        return $returnarray;
552
    }
553
554
    public static function getExternalDBEntityDetails($external_id, $realm = NULL) {
555
        $list = [];
556
        if (Config::$CONSORTIUM['name'] == "eduroam" && isset(Config::$CONSORTIUM['deployment-voodoo']) && Config::$CONSORTIUM['deployment-voodoo'] == "Operations Team") { // SW: APPROVED
557
            $scanforrealm = "";
558
            if ($realm !== NULL) {
559
                $scanforrealm = "OR inst_realm LIKE '%$realm%'";
560
            }
561
            $info_list = DBConnection::exec("EXTERNAL", "SELECT name AS collapsed_name, inst_realm as realmlist, contact AS collapsed_contact, country FROM view_active_idp_institution WHERE id_institution = $external_id $scanforrealm");
562
            // split names and contacts into proper pairs
563
            while ($a = mysqli_fetch_object($info_list)) {
564
                $names = explode('#', $a->collapsed_name);
565
                foreach ($names as $name) {
566
                    $perlang = explode(': ', $name, 2);
567
                    $list['names'][$perlang[0]] = $perlang[1];
568
                }
569
                $contacts = explode('#', $a->collapsed_contact);
570
                foreach ($contacts as $contact) {
571
                    $email_1 = explode('e: ', $contact);
572
                    $email_2 = explode(',', $email_1[1]);
573
                    $list['admins'][] = ["email" => $email_2[0]];
574
                }
575
                $list['country'] = $a->country;
576
                $list['realmlist'] = $a->realmlist;
577
            }
578
        }
579
        return $list;
580
    }
581
582
    /**
583
     * Lists all identity providers in the database
584
     * adding information required by DiscoJuice.
585
     * @param int $active_only if and set to non-zero will
586
     * cause listing of only those institutions which have some valid profiles defined.
587
     *
588
     */
589
    public static function listAllIdentityProviders($active_only = 0, $country = 0) {
590
        DBConnection::exec($this->databaseType, "SET SESSION group_concat_max_len=10000");
0 ignored issues
show
Bug introduced by
The variable $this does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
591
        $query = "SELECT distinct institution.inst_id AS inst_id, institution.country AS country,
592
                     group_concat(concat_ws('===',institution_option.option_name,LEFT(institution_option.option_value,200)) separator '---') AS options
593
                     FROM institution ";
594
        if ($active_only == 1) {
595
            $query .= "JOIN profile ON institution.inst_id = profile.inst_id ";
596
        }
597
        $query .= "JOIN institution_option ON institution.inst_id = institution_option.institution_id ";
598
        $query .= "WHERE (institution_option.option_name = 'general:instname' 
599
                          OR institution_option.option_name = 'general:geo_coordinates'
600
                          OR institution_option.option_name = 'general:logo_file') ";
601
        if ($active_only == 1) {
602
            $query .= "AND profile.showtime = 1 ";
603
        }
604
        if ($country) {
605
            // escape the parameter
606
            $country = DBConnection::escape_value($this->databaseType, $country);
607
            $query .= "AND institution.country = '$country' ";
608
        }
609
        $query .= "GROUP BY institution.inst_id ORDER BY inst_id";
610
        $allIDPs = DBConnection::exec($this->databaseType, $query);
611
        $returnarray = [];
612
        while ($queryResult = mysqli_fetch_object($allIDPs)) {
613
            $institutionOptions = explode('---', $queryResult->options);
614
            $oneInstitutionResult = [];
615
            $geo = [];
616
            $names = [];
617
            
618
            $oneInstitutionResult['entityID'] = $queryResult->inst_id;
619
            $oneInstitutionResult['country'] = strtoupper($queryResult->country);
620
            foreach ($institutionOptions as $institutionOption) {
621
                $opt = explode('===', $institutionOption);
622
                if ($opt[0] == 'general:logo_file') {
623
                    $oneInstitutionResult['icon'] = $queryResult->inst_id;
624
                }
625
                if ($opt[0] == 'general:geo_coordinates') {
626
                    $at1 = unserialize($opt[1]);
627
                    $geo[] = $at1;
628
                }
629
                if ($opt[0] == 'general:instname') {
630
                    $names[] = ['value' => $opt[1]];
631
                }
632
            }
633
634
            $name = _("Unnamed Entity");
635
            if (count($names) != 0) {
636
                $name = getLocalisedValue($names, CAT::get_lang());
637
            }
638
            $oneInstitutionResult['title'] = $name;
639
            if (count($geo) > 0) {
640
                $oneInstitutionResult['geo'] = $geo;
641
            }
642
            $returnarray[] = $oneInstitutionResult;
643
        }
644
        return $returnarray;
645
    }
646
647
}
648