Passed
Push — master ( b95824...35ec11 )
by Tomasz
03:55
created

IdPlist   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 151
Duplicated Lines 41.72 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 63
loc 151
rs 10
c 0
b 0
f 0
wmc 25
lcom 1
cbo 3

5 Methods

Rating   Name   Duplication   Size   Complexity  
A orderIdentityProviders() 0 17 3
C listAllIdentityProviders() 63 63 11
A setCurrentLocation() 0 11 3
C getIdpDistance() 0 23 7
A geoDistance() 0 7 1

How to fix   Duplicated Code   

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:

1
<?php
2
3
/* 
4
 * ******************************************************************************
5
 * Copyright 2011-2017 DANTE Ltd. and GÉANT on behalf of the GN3, GN3+, GN4-1 
6
 * and GN4-2 consortia
7
 * 
8
 *  License: see the web/copyright.php file in the file structure
9
 * ******************************************************************************
10
 */
11
12
13
namespace core;
14
15
use \Exception;
16
17
class IdPlist {
18
    /**
19
     * Order active identity providers according to their distance and name
20
     * @param array $currentLocation - current location
21
     * @return array $IdPs -  list of arrays ('id', 'name');
22
     */
23
    public static function orderIdentityProviders($country, $currentLocation = NULL) {
24
        $idps = $this->listAllIdentityProviders(1, $country);
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...
25
        $here = $this->setCurrentLocation($currentLocation);
26
        $idpTitle = [];
27
        $resultSet = [];
28
        foreach ($idps as $idp) {
29
            $idpTitle[$idp['entityID']] = $idp['title'];
30
            $d = $this->getIdpDistance($idp, $here);
31
            $resultSet[$idp['entityID']] = $d . " " . $idp['title'];
32
        }
33
        asort($resultSet);
34
        $outarray = [];
35
        foreach (array_keys($resultSet) as $r) {
36
            $outarray[] = ['idp' => $r, 'title' => $idpTitle[$r]];
37
        }
38
        return($outarray);
39
    }
40
    
41
    
42
    /**
43
     * Lists all identity providers in the database
44
     * adding information required by DiscoJuice.
45
     * 
46
     * @param int $activeOnly if set to non-zero will cause listing of only those institutions which have some valid profiles defined.
47
     * @param string $country if set, only list IdPs in a specific country
48
     * @return array the list of identity providers
49
     *
50
     */
51 View Code Duplication
    public static function listAllIdentityProviders($activeOnly = 0, $country = "") {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
52
        $handle = DBConnection::handle("INST");
53
        $handle->exec("SET SESSION group_concat_max_len=10000");
54
        $query = "SELECT distinct institution.inst_id AS inst_id, institution.country AS country,
55
                     group_concat(concat_ws('===',institution_option.option_name,LEFT(institution_option.option_value,200), institution_option.option_lang) separator '---') AS options
56
                     FROM institution ";
57
        if ($activeOnly == 1) {
58
            $query .= "JOIN v_active_inst ON institution.inst_id = v_active_inst.inst_id ";
59
        }
60
        $query .= "JOIN institution_option ON institution.inst_id = institution_option.institution_id ";
61
        $query .= "WHERE (institution_option.option_name = 'general:instname' 
62
                          OR institution_option.option_name = 'general:geo_coordinates'
63
                          OR institution_option.option_name = 'general:logo_file') ";
64
65
        $query .= ($country != "" ? "AND institution.country = ? " : "");
66
67
        $query .= "GROUP BY institution.inst_id ORDER BY inst_id";
68
69
        $allIDPs = ($country != "" ? $handle->exec($query, "s", $country) : $handle->exec($query));
70
        $returnarray = [];
71
        // SELECTs never return a booleans, always an object
72
        while ($queryResult = mysqli_fetch_object(/** @scrutinizer ignore-type */ $allIDPs)) {
73
            $institutionOptions = explode('---', $queryResult->options);
74
            $oneInstitutionResult = [];
75
            $geo = [];
76
            $names = [];
77
78
            $oneInstitutionResult['entityID'] = $queryResult->inst_id;
79
            $oneInstitutionResult['country'] = strtoupper($queryResult->country);
80
            foreach ($institutionOptions as $institutionOption) {
81
                $opt = explode('===', $institutionOption);
82
                switch ($opt[0]) {
83
                    case 'general:logo_file':
84
                        $oneInstitutionResult['icon'] = $queryResult->inst_id;
85
                        break;
86
                    case 'general:geo_coordinates':
87
                        $at1 = json_decode($opt[1], true);
88
                        $geo[] = $at1;
89
                        break;
90
                    case 'general:instname':
91
                        $names[] = [
92
                            'lang' => $opt[2],
93
                            'value' => $opt[1]
94
                        ];
95
                        break;
96
                    default:
97
                        break;
98
                }
99
            }
100
101
            $name = _("Unnamed Entity");
102
            if (count($names) != 0) {
103
                $langObject = new \core\common\Language();
104
                $name = $langObject->getLocalisedValue($names);
105
            }
106
            $oneInstitutionResult['title'] = $name;
107
            if (count($geo) > 0) {
108
                $oneInstitutionResult['geo'] = $geo;
109
            }
110
            $returnarray[] = $oneInstitutionResult;
111
        }
112
        return $returnarray;
113
    }
114
115
116
    private function setCurrentLocation($currentLocation) {
117
        if (is_null($currentLocation)) {
118
            $currentLocation = ['lat' => "90", 'lon' => "0"];
119
            $loc = new \core\DeviceLocation();
120
            $userLocation = $loc->locateDevice;
0 ignored issues
show
Bug introduced by
The property locateDevice does not seem to exist in core\DeviceLocation.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
121
            if ($userLocation['status'] == 'ok') {
122
                $currentLocation = $userLocation['geo'];
123
            }
124
        }
125
        return($currentLocation);
126
    }
127
    
128
    private function getIdpDistance($idp, $location) {
129
        $dist = 10000;
130
        if (isset($idp['geo'])) {
131
            $G = $idp['geo'];
132
            if (isset($G['lon'])) {
133
                $d1 = $this->geoDistance($location, $G);
134
                if ($d1 < $dist) {
135
                    $dist = $d1;
136
                }
137
            } else {
138
                foreach ($G as $g) {
139
                    $d1 = $this->geoDistance($location, $g);
140
                    if ($d1 < $dist) {
141
                        $dist = $d1;
142
                    }
143
                }
144
            }
145
        }
146
        if ($dist > 100) {
147
            $dist = 10000;
148
        }
149
        return(sprintf("%06d", $dist));
150
    }
151
    
152
    /**
153
     * Calculate the distance in km between two points given their
154
     * geo coordinates.
155
     * @param array $point1 - first point as an 'lat', 'lon' array 
156
     * @param array $profile1 - second point as an 'lat', 'lon' array 
157
     * @return float distance in km
158
     */
159
    private function geoDistance($point1, $profile1) {
160
161
        $distIntermediate = sin(deg2rad($point1['lat'])) * sin(deg2rad($profile1['lat'])) +
162
                cos(deg2rad($point1['lat'])) * cos(deg2rad($profile1['lat'])) * cos(deg2rad($point1['lon'] - $profile1['lon']));
163
        $dist = rad2deg(acos($distIntermediate)) * 60 * 1.1852;
164
        return(round($dist));
165
    }
166
    
167
}