Passed
Push — master ( 38c9d5...a24314 )
by Stefan
04:10
created

Sociopath::verdictText()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 1
dl 0
loc 9
rs 9.2
c 0
b 0
f 0
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
namespace core\diag;
13
14
use \Exception;
15
16
require_once(dirname(dirname(__DIR__)) . "/config/_config.php");
17
18
/**
19
 */
20
class Sociopath extends AbstractTest {
21
22
    private $qaArray;
23
    private $previousQuestions;
24
    private $genericVerdictTexts;
25
26
    /**
27
     * 
28
     * @param array $previousGuess list of suspect elements and their current occurence factor (entries of sorts [ INFRA_DEVICE => 0.6, ... ]
29
     * @param array $alreadyAsked questions which were already asked before (index), and the factor modifiers of the response (value)
30
     *
31
     */
32
    public function __construct($previousGuess, $alreadyAsked = []) {
33
        parent::__construct();
34
        $noCanDo = _("There is nothing you can do to solve this problem yourself.");
35
        $noChange = _("Please be patient and try again at a later time. Do NOT change your device configuration.");
36
        $infraInformed = _("The infrastructure operators have automatically been informed and will investigate the issue as soon as possible.");
37
        $this->genericVerdictTexts = [
38
        AbstractTest::INFRA_DEVICE => _("The system has identified possible issues regarding your local device configuration."),
39
        AbstractTest::INFRA_ETLR => _("The system has identified issues with a central infrastructure element. $noCanDo $noChange $infraInformed"),
40
        AbstractTest::INFRA_NRO_IDP => _("The system has identified issues with a central infrastructure element. $noCanDo $noChange  $infraInformed"),
41
        AbstractTest::INFRA_NRO_SP => _("The system has identified issues with a central infrastructure element. $noCanDo $noChange $infraInformed"),
42
        AbstractTest::INFRA_LINK_ETLR_NRO_IDP => _("The system has identified a network connectivity issue within our core infrastructure. $noCanDo $noChange $infraInformed"),
43
        AbstractTest::INFRA_LINK_ETLR_NRO_SP => _("The system has identified a network connectivity issue within our core infrastructure. $noCanDo $noChange $infraInformed"),
44
        AbstractTest::INFRA_IDP_RADIUS => _("The system has identified a problem with the authentication infrastructure at your home organisation. $noCanDo $noChange Your Identity Provider has been informed and is looking into the problem."),
45
        AbstractTest::INFRA_IDP_AUTHBACKEND => _("The system has identified a problem with the authentication infrastructure at your home organisation. $noCanDo $noChange Your Identity Provider has been informed and is looking into the problem."),
46
        AbstractTest::INFRA_NONEXISTENTREALM => _("The system can not find any information at all about the Identity Provider you described. Probably, this is not a participating institution and the account you tried to use does not exist."),
47
        AbstractTest::INFRA_SP_80211 => _("There are likely some issues around the wireless part of the network you are trying to connect to. Wireless networks do not always behave deterministically and consistently. All users at a given location have to share the available bandwidth, and the physical environment (concrete walls, objects in the way, elevation differences) can have a significant impact on your connectivity experience."),
48
        AbstractTest::INFRA_SP_LAN => _("There are likely some issues around the local network infrastructure of the hotspot you are connecting to. $noCanDo $noChange The local hotspot provider has been informed and will look into the issue at their earliest convenience."),
49
        AbstractTest::INFRA_SP_RADIUS => _("There is an issue with the local authentication infrastructure of the hotspot you are connecting to. $noCanDo $noChange The local hotspot provider has been informed and will look into the issue at their earliest convenience."),
50
        ];
51
        // here is an array with yes/no answers per failure category, and the factors by which a Yes modifies the score; No's modify it by 1/factor;
52
        // the order in this array is important: lower numbered questions will be asked first. So make sure you have high-quality questions in the beginning.
53
        // to be clear: "Yes" answers are elsewhere in the class the TRUE case; No's are FALSE, a possible "Don't know or N/A" is NULL
54
        // VERDICTLECTURE is text which is displayed to the end user if his answer led to a HIGHER score in the process. We are storing the answers to determine this.
55
        $this->qaArray = [
56
            0 => ["AREA" => AbstractTest::INFRA_DEVICE,
57
                  "TXT" => _("Have you ever used the network succesfully, e.g. at your home institution without roaming?"),
58
                  "FACTOR" => 0.5,
59
                  "VERDICTLECTURE" => _("If your device has never worked before with this setup, then very likely your device configuation is wrong. You should use appropriate configuration assistants [MGW: see if the realm exists in CAT, then display link to config] or contact your Identity Provider [MGW: show contact info].")],
60
            1 => ["AREA" => AbstractTest::INFRA_DEVICE, 
61
                  "TXT" => _("Did the device previously work when roaming, i.e. at other hotspots away from your home institution?"), 
62
                  "FACTOR" => 0.33,
63
                  "VERDICTLECTURE" => _("If roaming consistently does not work, then very likely your device configuration is wrong. Typical errors causing this symptom include: using a username without the @realm.tld suffix - those potentially work at home, but can not be used when roaming.")],
64
            2 => ["AREA" => AbstractTest::INFRA_DEVICE, 
65
                  "TXT" => _("Did you recently change the configuration on your device?"), 
66
                  "FACTOR" => 3,
67
                  "VERDICTLECTURE" => _("Accounts only need to be configured once, and can then be used anywhere on the planet without any changes. If you recently changed the configuration, that change may very well be at fault. You should never change your network configuration unless explicitly instructed so by your Identity Provider; even in the case of temporary login issues.")],
68
            3 => ["AREA" => AbstractTest::INFRA_DEVICE, 
69
                  "TXT" => _("Do your other devices still work?"),
70
                  "VERDICTLECTURE" => _("If all devices stopped working simultaneously, there may be a problem with your account as such. Maybe your account expired, or you were forced to change the password? These questions are best answered by your Identity Provider [MGW: display contact info]"),
71
                  "FACTOR" => 0.33],
72
            4 => ["AREA" => AbstractTest::INFRA_SP_80211, 
73
                  "TXT" => _("Does the connection get better when you move around?"), 
74
                  "FACTOR" => 3,
75
                  "VERDICTLECTURE" => _("You should move to a different location to achieve better network coverage and service. If you think the exact spot you are at deserves better coverage, you should inform the hotspot provider. [MGW: add contact info]")],
76
            5 => ["AREA" => AbstractTest::INFRA_SP_80211, 
77
                  "TXT" => _("Is the place you are currently at heavily crowded, or is everyone busy with network-intensive tasks?"), 
78
                  "FACTOR" => 3,
79
                  "VERDICTLECTURE" => _("The network is likely overloaded at this location and point in time. You may want to have to wait until later before you get a better connectivity. If you think the network should be reinforced for more capacity at this place, you should inform the hotspot provider. [MGW: add contact info]")],            
80
            6 => ["AREA" => AbstractTest::INFRA_SP_LAN, 
81
                  "TXT" => _("Do you see errors stating something similar to 'Unable to get IP address'?"), 
82
                  "FACTOR" => 3,
83
                  "VERDICTLECTURE" => _("The evidence at hand suggests that there may be an infrastructure problem at this particular hotspot provider. There is nothing you can do to solve this problem locally. Please be patient and try again at a later time.")],
84
        ];
85
        // stow away the current state of guesswork
86
        $this->previousQuestions = $alreadyAsked;
87
        $this->possibleFailureReasons = $previousGuess;
88
        
89
        
90
    }
91
92
    /**
93
     * 
94
     * @param type $questionNumber
95
     * @param bool|NULL $answer TRUE if the answer was "Yes", FALSE if "No", NULL is "Dont know / N/A"
96
     */
97
    public function revaluate($questionNumber, $answer) {
98
        $questionDetails = $this->qaArray[$questionNumber];
99
        if ($answer === TRUE) {
100
            $this->possibleFailureReasons[$questionDetails['AREA']] = $this->possibleFailureReasons[$questionDetails['AREA']] * $questionDetails["FACTOR"];
101
            $this->previousQuestions[$questionNumber] = $questionDetails["FACTOR"];
102
        } elseif ($answer === FALSE) {
103
            $this->possibleFailureReasons[$questionDetails['AREA']] = $this->possibleFailureReasons[$questionDetails['AREA']] / $questionDetails["FACTOR"];
104
            $this->previousQuestions[$questionNumber] = 1/$questionDetails["FACTOR"];
105
        } else {
106
            $this->previousQuestions[$questionNumber] = 1;
107
        }
108
        $this->normaliseResultSet();
109
        
110
        
111
    }
112
    
113
    public function questionOracle() {
114
        reset($this->possibleFailureReasons);
115
        $highestCategory = key($this->possibleFailureReasons);
116
        next($this->possibleFailureReasons);
117
        $nextCategory = key($this->possibleFailureReasons);
118
        if ($this->possibleFailureReasons[$highestCategory] != $this->possibleFailureReasons[$nextCategory]) {
119
            $nextCategory = $highestCategory;
120
        }
121
        // if both are identical, take any of the questions in the pool of both
122
        foreach ($this->qaArray as $questionNumber => $questionDetails) {
123
            // if we find a question we didn't ask before AND it is related to our currently high-scoring problem area, ask it
124
            if (!array_key_exists($questionNumber, $this->previousQuestions) && ( $questionDetails["AREA"] == $highestCategory || $questionDetails["AREA"] == $nextCategory) ) {
125
                return json_encode(["NEXTEXISTS" => TRUE, "NUMBER" => $questionNumber, "TEXT" => $questionDetails["TXT"]]);
126
            }
127
        }
128
        // if we got here, we ran out of questions. Return that fact
129
        return json_encode(["NEXTEXISTS" => FALSE]);
130
    }
131
    
132
    public function getCurrentGuessState() {
133
        return json_encode([ "SUSPECTS" => $this->possibleFailureReasons, "PREVIOUSQUESTIONS" => $this->previousQuestions ]);
134
    }
135
    
136
    public function verdictText($area) {
137
        $text = $this->genericVerdictTexts[$area];
138
        foreach ($this->previousQuestions as $number => $factor) {
139
            if ($this->qaArray[$number]["AREA"] == $area && $factor > 1) {
140
                $text .= "\n\n".$this->qaArray[$number]["VERDICTLECTURE"];
141
            }
142
        }
143
        return $text;
144
    }
145
}
146