summaryrefslogtreecommitdiffstats
path: root/admin/survey/classes/class.SurveyCheck.php
blob: 40dde283c8c2b4daf6a74f8ded29764823cd88db (plain) (blame)
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
<?php

/* 
 * Preverjanje ankete - limiti velikosti, vabil, preverjanmje phishinga...
 * 
 * Zaenkrat samo preverjamo in posljemo mail adminu
 * 
 */

class SurveyCheck {
	

    var $anketa;

    public function __construct($anketa){

        if($anketa == null || $anketa <= 0)
            return 'ID ankete ne obstaja!';

        $this->anketa = $anketa;
    }


    // Preverimo stevilo vprasanj v anketi
    public function checkLimitSpremenljivke(){

        // Ce limit ni nastavljen ignoriramo
        if(!AppSettings::getInstance()->getSetting('app_limits-question_count_limit'))
            return true;

        // Dobimo stevilo vprasanj v anketi
        $stevilo_vprasanj = SurveyInfo::getInstance()->getSurveyQuestionCount();

        // Obvestilo (mail adminu) posljemo pri dosezeni stevilki
        if($stevilo_vprasanj == AppSettings::getInstance()->getSetting('app_limits-question_count_limit')){
            $this->sendAlert($alert_type='limit_spremenljivke', $stevilo_vprasanj);
        }

        // Ce je v anketi ze vec vprasanj kot je limit
        if($stevilo_vprasanj > AppSettings::getInstance()->getSetting('app_limits-question_count_limit')){
            return true;
        }
        else{
            return false;
        }
    }

    // Preverimo stevilo poslanih vabil
    public function checkLimitVabila(){

        // Ce limit ni nastavljen ignoriramo
        if(!AppSettings::getInstance()->getSetting('app_limits-invitation_count_limit'))
            return true;

        // Prestejemo poslana vabila
        $sql = sisplet_query("SELECT count(id) AS stevilo_vabil
                                FROM srv_invitations_recipients
                                WHERE ank_id='".$this->anketa."' AND sent='1' 
                            ");
        $row = mysqli_fetch_array($sql);

        $stevilo_vabil = $row['stevilo_vabil'];

        // Obvestilo (mail adminu) posljemo pri dosezeni stevilki
        if($stevilo_vabil == AppSettings::getInstance()->getSetting('app_limits-invitation_count_limit')){
            $this->sendAlert($alert_type='limit_vabila', $stevilo_vabil);
        }

        // Ce je poslanih ze vec vabil kot je limit
        if($stevilo_vabil > AppSettings::getInstance()->getSetting('app_limits-invitation_count_limit')){
            return true;
        }
        else{
            return false;
        }
    }

    // Preverimo stevilo responsov na anketo
    public function checkLimitResponses(){

        // Ce limit ni nastavljen ignoriramo
        if(!AppSettings::getInstance()->getSetting('app_limits-response_count_limit'))
            return true;

        // Dobimo stevilo odgovorov na anketo
        $stevilo_odgovorov = SurveyInfo::getInstance()->getSurveyAnswersCount();
        $stevilo_odgovorov_limit = AppSettings::getInstance()->getSetting('app_limits-response_count_limit');

        // Obvestilo (mail adminu) posljemo pri dosezeni stevilki
        if($stevilo_odgovorov > 0 && $stevilo_odgovorov % $stevilo_odgovorov_limit === 0){
            $this->sendAlert($alert_type='limit_responses', $stevilo_odgovorov);

            // Deaktiviramo anketo, ce je aktivna ?
        }

        // Ce je na anketo ze vec responsov kot je limit
        if($stevilo_odgovorov > AppSettings::getInstance()->getSetting('app_limits-response_count_limit')){
            return true;
        }
        else{
            return false;
        }
    }

    // Preverimo ce je anketa potencialno phishing
    public function checkPhishing(){
        global $global_user_id;


        // Dobimo stevilo vprasanj v anketi
        $stevilo_vprasanj = SurveyInfo::getInstance()->getSurveyQuestionCount();

        // Ce imamo v anketi 0 ali vec kot 5 vprasanj je vse ok
        if($stevilo_vprasanj >= 5 || $stevilo_vprasanj == 0){
            return false;
        }


        // Dobimo stevilo anket uporabnika
        $sqlA = sisplet_query("SELECT count(id) AS count_surveys FROM srv_anketa WHERE insert_uid='".$global_user_id."'");
        $rowA = mysqli_fetch_array($sqlA);

        // Ce ima uporabnik ze vec anket je vse ok
        if($rowA['count_surveys'] > 1){
            return false;
        }


        // Prestejemo vprasanja po tipu
        $sql = sisplet_query("SELECT count(s.id) AS count_questions
                                FROM srv_spremenljivka s, srv_grupa g
                                WHERE g.ank_id='".$this->anketa."' AND g.id=s.gru_id 
                                    AND (tip='21' OR tip='5') 
                            ");
        $row = mysqli_fetch_array($sql);

        // Ce imamo v anketi manj kot 5 vprasanj in so vsa tipa nagovor ali text je potencialen phishing
        if($row['count_questions'] == $stevilo_vprasanj){
            
            // Posljemo mail adminu
            $this->sendAlert($alert_type='phishing');
            
            return true;
        }
        else{
            return false;
        }
    }

    // Pri izpolnjevanju ankete preverimo stevilo klikov na minuto - ce jih je prevec, respondenta zavrnemo, drugace se lahko sql zafila in streznik ni vec odziven
    public function checkClicksPerMinute(){

        // Ce maximum na minuto ni nastavljen ignoriramo limit
        if(!AppSettings::getInstance()->getSetting('app_limits-clicks_per_minute_limit'))
            return true;

        // Preverimo ce gre za izpolnjevanje ankete
        if($_SERVER["SCRIPT_NAME"] != '/main/survey/index.php')
            return true;

        // Preverimo ce gre za prvi prihod na doloceno stran ankete in ne na prvo stran
        if(isset($_GET['grupa']))
            return true;

        // Preverimo ce je id ankete ustrezno nastavljen
        if(!isset($this->anketa) || $this->anketa <= 0)
            return true;


        $click_time = time();

        $sql = sisplet_query("SELECT click_count, click_time FROM srv_clicks WHERE ank_id='".$this->anketa."'");
        if (mysqli_num_rows($sql) > 0) {

            list($click_count, $first_click_time) = mysqli_fetch_array($sql);

            // Ce nismo znotraj minute vse resetiramo in pustimo naprej
            if($click_time - $first_click_time > 60){
                $sqlI = sisplet_query("UPDATE srv_clicks SET click_count='1', click_time='".$click_time."' WHERE ank_id='".$this->anketa."'");
                return true;
            }

            // Click count je ok - pustimo naprej
            if($click_count <= AppSettings::getInstance()->getSetting('app_limits-clicks_per_minute_limit')){
                $sqlI = sisplet_query("UPDATE srv_clicks SET click_count=click_count+1 WHERE ank_id='".$this->anketa."'");      
                
                // Dosegli smo limit - posljemo mail adminu
                if($click_count == AppSettings::getInstance()->getSetting('app_limits-clicks_per_minute_limit')){

                    // TODO - da se poslje samo 1x, drugace konstantno letijo maili:D
                    // Includamo vse da lahko posljemo mail
                    //include_once('../../vendor/autoload.php');
            
                    // Posljemo mail adminu
                    //$this->sendAlert($alert_type='limit_clicks', $click_count);
                }
                
                return true;
            }
            // Click count je previsok - ZAVRNEMO
            else{
                // Prikazemo error stran ki jo refreshamo na 5 sekund
                $this->displayClicksPerMinuteError();

                return false;
            }
        }
        else{
            $sqlI = sisplet_query("INSERT INTO srv_clicks (ank_id, click_count, click_time) VALUES ('".$this->anketa."', '1', '".$click_time."')");
        }
        
        return true;
    }


    // Posljemo obvestilo adminu o prebitem limitu, phishing anketi...
    private function sendAlert($alert_type, $count=0){
        global $site_url;

        // Alerta ne posljemo na lastnih instalacijah
        if(isLastnaInstalacija())
            return;

        // Dobimo hash ankete
        $anketa_hash = SurveyInfo::getInstance()->getSurveyColumn('hash');

        switch($alert_type){

            case 'limit_spremenljivke':
                $title = 'Opozorilo - dosežena omejitev vprašanj';
                $content = '<a href="'.$site_url.'admin/survey/index.php?anketa='.$this->anketa.'">Anketa '.$this->anketa.'</a> ima doseženo omejitev števila vprašanj ('.$count.')!';

                break;

            case 'limit_responses':
                $title = 'Opozorilo - dosežena omejitev odgovorov';
                $content = '<a href="'.$site_url.'admin/survey/index.php?anketa='.$this->anketa.'">Anketa '.$this->anketa.'</a> ima doseženo omejitev števila odgovorov ('.$count.')!';

                break;

            case 'limit_vabila':
                $title = 'Opozorilo - dosežena omejitev vabil';
                $content = '<a href="'.$site_url.'admin/survey/index.php?anketa='.$this->anketa.'">Anketa '.$this->anketa.'</a> ima doseženo omejitev poslanih vabil ('.$count.')!';

                break;

            case 'phishing':
                $title = 'Opozorilo - potencialna phishing anketa';
                $content = '<a href="'.$site_url.'admin/survey/index.php?anketa='.$this->anketa.'">Anketa '.$this->anketa.'</a> - potencialen phishing!';

                break;

            case 'limit_clicks':
                $title = 'Opozorilo - dosežena omejitev klikov na minuto';
                $content = '<a href="'.$site_url.'admin/survey/index.php?anketa='.$this->anketa.'">Anketa '.$this->anketa.'</a> ima doseženo omejitev klikov na minuto ('.$count.')!';

                break;
        }

        // Dodamo se link do predogleda 
        $content .= '<br><br>Predogled ankete: <a href="'.$site_url.'a/'.$anketa_hash.'&preview=on">'.$site_url.'a/'.$anketa_hash.'&preview=on</a>';

        try{
            $MA = new MailAdapter($anketa=null, $type='admin');
            //$MA->addRecipients('peter.hrvatin@gmail.com');
            $MA->addRecipients('info@1ka.si');
            $resultX = $MA->sendMail($content, $title);
        }
        catch (Exception $e){
        }

        // Zalogiramo opozorilo
        $SL = new SurveyLog();
        $SL->addMessage(SurveyLog::ERROR, $title.' - anketa '.$this->anketa);
        $SL->write();
    }

    // Prikazemo stran z errorjem za presezeno stevilo klikov na minuto
    private function displayClicksPerMinuteError(){
        global $site_url;

        $refresh_every = 5;

        echo '<!DOCTYPE html>';
        echo '<html>';

        echo '<head>';
        echo '    <title>Server Limit Reached</title>';
        echo '    <meta http-equiv="refresh" content="'.$refresh_every.'" />';
        echo '    <meta name="viewport" content="width=device-width, initial-scale=1.0" />';
        
        echo '    <style>
            body{
                display: flex;
                align-content: center;
                height: 90vh;
                
                flex-wrap: wrap;
                align-content: center;
            }
            .main{
                max-width: 1200px;
                margin: 50px auto;
                padding: 0 20px;

                font-family: Montserrat, Arial, Sans-Serif !important;
                color: #505050;
            }
            h1{
                color: #1e88e5;
                text-align: center;
                margin: 30px 0;
            }
            hr{
                margin: 50px 0;

                border: 0;
                border-top: 1px solid #ddeffd;
            }
            .loading{
                margin: 50px 0;
                text-align: center;
            }
            img{
                width: 80px;
                height: 80px;
            }
        </style>';
        echo '</head>';

        echo '<body><div class="main">';
        echo '    <div class="loading"><img src="'.$site_url.'/public/img/icons/spinner.gif" /></div>';
        echo '    <h1>Dosežena omejitev strežnika</h1>';
        echo '    <h3>Prosimo, počakajte nekaj trenutkov. Trenutno je doseženo maksimalno število vnosov ankete na minuto.</h3>';
        echo '    <hr>';
        echo '    <h1>Server Limit Reached</h1>';
        echo '    <h3>Please wait a few moments. Currently, the maximum number of survey entries per minute has been reached.</h3>';
        echo '</div></body>';

        echo '</html>';
        
        die();
    }
}

?>