Completed
Push — development ( 43bb99...2fa2b9 )
by Thomas
03:02 queued 02:41
created

htdocs/lib2/logic/user.class.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/***************************************************************************
3
 * for license information see LICENSE.md
4
 *
5
 *
6
 *   get/set has to be commited with save
7
 *   add/remove etc. is executed instantly
8
 ***************************************************************************/
9
10
use OcLegacy\Util\PasswordCrypt;
11
12
require_once __DIR__ . '/cracklib.inc.php';
13
require_once __DIR__ . '/../translate.class.php';
14
15
class user
16
{
17
    public $nUserId = 0;
18
19
    public $reUser;
20
    public $reUserStat;
21
22
    /**
23
     * @param string $email
24
     *
25
     * @return null|user
26
     */
27
    public static function fromEMail($email)
28
    {
29
        $userId = (int) sql_value("SELECT `user_id` FROM `user` WHERE `email`='&1'", 0, $email);
30
        if ($userId === 0) {
31
            return null;
32
        }
33
34
        return new user($userId);
35
    }
36
37
    /**
38
     * @param string $username
39
     *
40
     * @return null|user
41
     */
42
    public static function fromUsername($username)
43
    {
44
        $userId = (int) sql_value("SELECT `user_id` FROM `user` WHERE `username`='&1'", 0, $username);
45
        if ($userId === 0) {
46
            return null;
47
        }
48
49
        return new user($userId);
50
    }
51
52
    public function __construct($nNewUserId = ID_NEW)
53
    {
54
        global $opt;
55
56
        $this->reUser = new rowEditor('user');
57
        $this->reUser->addPKInt('user_id', null, false, RE_INSERT_AUTOINCREMENT);
58
        $this->reUser->addString('username', '', false);
59
        $this->reUser->addString('password', null, true);
60
        $this->reUser->addString('email', null, true);
61
        $this->reUser->addString('email_problems', 0, false);
62
        $this->reUser->addDate('last_email_problem', null, true);
63
        $this->reUser->addInt('mailing_problems', 0, false);
64
        $this->reUser->addFloat('latitude', 0, false);
65
        $this->reUser->addFloat('longitude', 0, false);
66
        $this->reUser->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
67
        $this->reUser->addBoolean('is_active_flag', false, false);
68
        $this->reUser->addString('last_name', '', false);
69
        $this->reUser->addString('first_name', '', false);
70
        $this->reUser->addString('country', null, true);
71
        $this->reUser->addBoolean('accept_mailing', 1, false);
72
        $this->reUser->addBoolean('pmr_flag', false, false);
73
        $this->reUser->addString('new_pw_code', null, true);
74
        $this->reUser->addDate('new_pw_date', null, true);
75
        $this->reUser->addDate('date_created', time(), true, RE_INSERT_IGNORE);
76
        $this->reUser->addString('new_email_code', null, true);
77
        $this->reUser->addDate('new_email_date', null, true);
78
        $this->reUser->addString('new_email', null, true);
79
        $this->reUser->addString('uuid', '', false, RE_INSERT_AUTOUUID);
80
        $this->reUser->addBoolean('permanent_login_flag', false, false);
81
        $this->reUser->addInt('watchmail_mode', 1, false);
82
        $this->reUser->addInt('watchmail_hour', 0, false);
83
        $this->reUser->addDate('watchmail_nextmail', time(), false);
84
        $this->reUser->addInt('watchmail_day', 0, false);
85
        $this->reUser->addString('activation_code', '', false);
86
        $this->reUser->addBoolean('no_htmledit_flag', false, false);
87
        $this->reUser->addBoolean('usermail_send_addr', false, false);
88
        $this->reUser->addInt('notify_radius', 0, false);
89
        $this->reUser->addInt('notify_oconly', 1, false);
90
        $this->reUser->addString('language', null, true);
91
        $this->reUser->addInt('admin', 0, false);
92
        $this->reUser->addInt('data_license', $opt['logic']['license']['newusers'], false);
93
        $this->reUser->addInt('node', 0, false);
94
95
        $this->reUserStat = new rowEditor('stat_user');
96
        $this->reUserStat->addPKInt('user_id', null, false, RE_INSERT_AUTOINCREMENT);
97
        $this->reUserStat->addInt('found', 0, false);
98
        $this->reUserStat->addInt('notfound', 0, false);
99
        $this->reUserStat->addInt('note', 0, false);
100
        $this->reUserStat->addInt('hidden', 0, false);
101
102
        $this->nUserId = $nNewUserId + 0;
103
104
        if ($nNewUserId === ID_NEW) {
105
            $this->reUser->addNew(null);
106
        } else {
107
            $this->reUser->load($this->nUserId);
108
            $this->reUserStat->load($this->nUserId);
109
        }
110
    }
111
112
    public function exist()
113
    {
114
        return $this->reUser->exist();
115
    }
116
117
    /**
118
     * @param string $username
119
     *
120
     * @return bool
121
     */
122
    public static function existUsername($username)
123
    {
124
        return sql_value("SELECT COUNT(*) FROM `user` WHERE `username`='&1'", 0, $username) != 0;
125
    }
126
127
    /**
128
     * @param string $email
129
     *
130
     * @return bool
131
     */
132
    public static function existEMail($email)
133
    {
134
        return sql_value("SELECT COUNT(*) FROM `user` WHERE `email`='&1'", 0, $email) != 0;
135
    }
136
137
    public function getUserId()
138
    {
139
        return $this->nUserId;
140
    }
141
142
    public function getUsername()
143
    {
144
        return $this->reUser->getValue('username');
145
    }
146
147
    /**
148
     * @param string $value
149
     * @return bool
150
     */
151 View Code Duplication
    public function setUsername($value)
152
    {
153
        if (!mb_ereg_match(REGEX_USERNAME, $value)) {
154
            return false;
155
        }
156
157
        if (is_valid_email_address($value)) {
158
            return false;
159
        }
160
161
        return $this->reUser->setValue('username', $value);
162
    }
163
164
    public function getUsernameChanged()
165
    {
166
        return $this->reUser->getChanged('username');
167
    }
168
169
    public function getEMail()
170
    {
171
        return $this->reUser->getValue('email');
172
    }
173
174
    public function setEMail($value)
175
    {
176
        if (!is_valid_email_address($value)) {
177
            return false;
178
        }
179
180
        return $this->reUser->setValue('email', $value);
181
    }
182
183
    public function getPassword()
184
    {
185
        return $this->reUser->getValue('password');
186
    }
187
188
    public function setPassword($password)
189
    {
190
        if (!mb_ereg_match(REGEX_PASSWORD, $password)) {
191
            return false;
192
        }
193
194
        if (cracklib_checkpw(
195
            $password,
196
            [
197
                'open',
198
                'caching',
199
                'cache',
200
                $this->getUsername(),
201
                $this->getFirstName(),
202
                $this->getLastName()
203
            ]
204
        ) === false) {
205
            return false;
206
        }
207
208
        $encryptedPassword = PasswordCrypt::encryptPassword($password);
209
210
        return $this->reUser->setValue('password', $encryptedPassword);
211
    }
212
213
    public function getFirstName()
214
    {
215
        return $this->reUser->getValue('first_name');
216
    }
217
218
    /**
219
     * @param string $value
220
     * @return bool
221
     */
222
    public function setFirstName($value)
223
    {
224
        if ($value !== '') {
225
            if (!mb_ereg_match(REGEX_FIRST_NAME, $value)) {
226
                return false;
227
            }
228
        }
229
230
        return $this->reUser->setValue('first_name', $value);
231
    }
232
233
    public function getLastName()
234
    {
235
        return $this->reUser->getValue('last_name');
236
    }
237
238
    /**
239
     * @param string $value
240
     * @return bool
241
     */
242
    public function setLastName($value)
243
    {
244
        if ($value !== '') {
245
            if (!mb_ereg_match(REGEX_LAST_NAME, $value)) {
246
                return false;
247
            }
248
        }
249
250
        return $this->reUser->setValue('last_name', $value);
251
    }
252
253
    public function getCountry()
254
    {
255
        return countriesList::getCountryLocaleName($this->reUser->getValue('country'));
256
    }
257
258
    public function getCountryCode()
259
    {
260
        return $this->reUser->getValue('country');
261
    }
262
263 View Code Duplication
    public function setCountryCode($value)
264
    {
265
        if ($value !== null && (sql_value("SELECT COUNT(*) FROM countries WHERE short='&1'", 0, $value) == 0)) {
266
            return false;
267
        }
268
269
        return $this->reUser->setValue('country', $value);
270
    }
271
272
    public function getLanguageCode()
273
    {
274
        return $this->reUser->getValue('language');
275
    }
276
277 View Code Duplication
    public function setLanguageCode($value)
278
    {
279
        if ($value !== null && (sql_value("SELECT COUNT(*) FROM languages WHERE short='&1'", 0, $value) == 0)) {
280
            return false;
281
        }
282
283
        return $this->reUser->setValue('language', $value);
284
    }
285
286
    public function getLatitude()
287
    {
288
        return $this->reUser->getValue('latitude');
289
    }
290
291
    /**
292
     * @param double $value
293
     * @return bool
294
     */
295 View Code Duplication
    public function setLatitude($value)
296
    {
297
        if (($value + 0) > 90 || ($value + 0) < - 90) {
298
            return false;
299
        }
300
301
        return $this->reUser->setValue('latitude', $value + 0);
302
    }
303
304
    public function getLongitude()
305
    {
306
        return $this->reUser->getValue('longitude');
307
    }
308
309
    /**
310
     * @param double $value
311
     * @return bool
312
     */
313 View Code Duplication
    public function setLongitude($value)
314
    {
315
        if (($value + 0) > 180 || ($value + 0) < -180) {
316
            return false;
317
        }
318
319
        return $this->reUser->setValue('longitude', $value + 0);
320
    }
321
322
    public function getNotifyRadius()
323
    {
324
        return $this->reUser->getValue('notify_radius');
325
    }
326
327
    /**
328
     * @param integer $value
329
     * @return bool
330
     */
331 View Code Duplication
    public function setNotifyRadius($value)
332
    {
333
        if (($value + 0) < 0 || ($value + 0) > 150) {
334
            return false;
335
        }
336
337
        return $this->reUser->setValue('notify_radius', $value + 0);
338
    }
339
340
    public function getNotifyOconly()
341
    {
342
        return $this->reUser->getValue('notify_oconly') != 0;
343
    }
344
345
    /**
346
     * @param boolean $value
347
     * @return bool
348
     */
349
    public function setNotifyOconly($value)
350
    {
351
        return $this->reUser->setValue('notify_oconly', $value ? 1 : 0);
352
    }
353
354
    public function getPermanentLogin()
355
    {
356
        return $this->reUser->getValue('permanent_login_flag');
357
    }
358
359
    public function setPermanentLogin($value)
360
    {
361
        return $this->reUser->setValue('permanent_login_flag', $value);
362
    }
363
364
    public function getAccMailing()
365
    {
366
        return $this->reUser->getValue('accept_mailing');
367
    }
368
369
    public function setAccMailing($value)
370
    {
371
        return $this->reUser->setValue('accept_mailing', $value);
372
    }
373
374
    public function getUsermailSendAddress()
375
    {
376
        return $this->reUser->getValue('usermail_send_addr');
377
    }
378
379
    public function setUsermailSendAddress($value)
380
    {
381
        return $this->reUser->setValue('usermail_send_addr', $value);
382
    }
383
384
    public function getNoHTMLEditor()
385
    {
386
        return $this->reUser->getValue('no_htmledit_flag');
387
    }
388
389
    public function setNoHTMLEditor($value)
390
    {
391
        return $this->reUser->setValue('no_htmledit_flag', $value);
392
    }
393
394
    public function getUsePMR()
395
    {
396
        return $this->reUser->getValue('pmr_flag');
397
    }
398
399
    public function setUsePMR($value)
400
    {
401
        return $this->reUser->setValue('pmr_flag', $value);
402
    }
403
404
    public function getIsActive()
405
    {
406
        return $this->reUser->getValue('is_active_flag');
407
    }
408
409
    public function setIsActive($value)
410
    {
411
        return $this->reUser->setValue('is_active_flag', $value);
412
    }
413
414
    public function getActivationCode()
415
    {
416
        return $this->reUser->getValue('activation_code');
417
    }
418
419
    public function setActivationCode($value)
420
    {
421
        return $this->reUser->setValue('activation_code', $value);
422
    }
423
424
    public function getNewPWCode()
425
    {
426
        return $this->reUser->getValue('new_pw_code');
427
    }
428
429
    /**
430
     * @param string|null $value
431
     * @return bool
432
     */
433
    public function setNewPWCode($value)
434
    {
435
        return $this->reUser->setValue('new_pw_code', $value);
436
    }
437
438
    public function getNewPWDate()
439
    {
440
        return $this->reUser->getValue('new_pw_date');
441
    }
442
443
    /**
444
     * @param integer|null $value
445
     * @return bool
446
     */
447
    public function setNewPWDate($value)
448
    {
449
        return $this->reUser->setValue('new_pw_date', $value);
450
    }
451
452
    public function getNewEMailCode()
453
    {
454
        return $this->reUser->getValue('new_email_code');
455
    }
456
457
    /**
458
     * @param string|null $value
459
     * @return bool
460
     */
461
    public function setNewEMailCode($value)
462
    {
463
        return $this->reUser->setValue('new_email_code', $value);
464
    }
465
466
    public function getNewEMailDate()
467
    {
468
        return $this->reUser->getValue('new_email_date');
469
    }
470
471
    /**
472
     * @param integer|null $value
473
     * @return bool
474
     */
475
    public function setNewEMailDate($value)
476
    {
477
        return $this->reUser->setValue('new_email_date', $value);
478
    }
479
480
    public function getNewEMail()
481
    {
482
        return $this->reUser->getValue('new_email');
483
    }
484
485 View Code Duplication
    public function setNewEMail($value)
486
    {
487
        if ($value !== null) {
488
            if (!is_valid_email_address($value)) {
489
                return false;
490
            }
491
492
            if (user::existEMail($value)) {
493
                return false;
494
            }
495
        }
496
497
        return $this->reUser->setValue('new_email', $value);
498
    }
499
500
    public function getWatchmailMode()
501
    {
502
        return $this->reUser->getValue('watchmail_mode');
503
    }
504
505
    public function setWatchmailMode($value)
506
    {
507
        $this->setWatchmailNext('0000-00-00 00:00:00');
508
509
        return $this->reUser->setValue('watchmail_mode', $value);
510
    }
511
512
    public function getWatchmailHour()
513
    {
514
        return $this->reUser->getValue('watchmail_hour');
515
    }
516
517
    public function setWatchmailHour($value)
518
    {
519
        $this->setWatchmailNext('0000-00-00 00:00:00');
520
521
        return $this->reUser->setValue('watchmail_hour', $value);
522
    }
523
524
    public function getWatchmailDay()
525
    {
526
        return $this->reUser->getValue('watchmail_day');
527
    }
528
529
    public function setWatchmailDay($value)
530
    {
531
        $this->setWatchmailNext('0000-00-00 00:00:00');
532
533
        return $this->reUser->setValue('watchmail_day', $value);
534
    }
535
536
    public function getWatchmailNext()
537
    {
538
        return $this->reUser->getValue('watchmail_nextmail');
539
    }
540
541
    /**
542
     * @param string $value
543
     * @return bool
544
     */
545
    public function setWatchmailNext($value)
546
    {
547
        return $this->reUser->setValue('watchmail_nextmail', $value);
548
    }
549
550
    public function getStatFound()
551
    {
552
        if ($this->reUserStat->exist()) {
553
            return $this->reUserStat->getValue('found');
554
        }
555
556
        return 0;
557
    }
558
559
    public function getStatNotFound()
560
    {
561
        if ($this->reUserStat->exist()) {
562
            return $this->reUserStat->getValue('notfound');
563
        }
564
565
        return 0;
566
    }
567
568
    public function getStatNote()
569
    {
570
        if ($this->reUserStat->exist()) {
571
            return $this->reUserStat->getValue('note');
572
        }
573
574
        return 0;
575
    }
576
577
    public function getStatHidden()
578
    {
579
        if ($this->reUserStat->exist()) {
580
            return $this->reUserStat->getValue('hidden');
581
        }
582
583
        return 0;
584
    }
585
586
    public function getDateRegistered()
587
    {
588
        return $this->reUser->getValue('date_created');
589
    }
590
591
    public function getUUID()
592
    {
593
        return $this->reUser->getValue('uuid');
594
    }
595
596
    public function getLastModified()
597
    {
598
        return $this->reUser->getValue('last_modified');
599
    }
600
601
    public function getDateCreated()
602
    {
603
        return $this->reUser->getValue('date_created');
604
    }
605
606
    public function getAdmin()
607
    {
608
        return $this->reUser->getValue('admin');
609
    }
610
611
    public function getNode()
612
    {
613
        return $this->reUser->getValue('node');
614
    }
615
616
    public function setNode($value)
617
    {
618
        return $this->reUser->setValue('node', $value);
619
    }
620
621
    public function getAnyChanged()
622
    {
623
        return $this->reUser->getAnyChanged();
624
    }
625
626
    // return if successful (with insert)
627
    public function save()
628
    {
629
        sql_slave_exclude();
630
        if ($this->reUser->save()) {
631
            if ($this->getUserId() == ID_NEW) {
632
                $this->nUserId = $this->reUser->getValue('user_id');
633
            }
634
            $this->getStatpic()->invalidate();
635
636
            return true;
637
        }
638
639
        return false;
640
    }
641
642
    public function getStatpic()
643
    {
644
        return new statpic($this->nUserId);
645
    }
646
647
    public static function createCode()
648
    {
649
        return mb_strtoupper(mb_substr(md5(uniqid('', true)), 0, 13));
650
    }
651
652
    public function requestNewPWCode()
653
    {
654
        global $translate;
655
656
        if (!$this->exist()) {
657
            return false;
658
        }
659
660
        $email = $this->getEMail();
661
        if ($email === null || $email === '') {
662
            return false;
663
        }
664
665
        if (!$this->getIsActive()) {
666
            return false;
667
        }
668
669
        $this->setNewPWCode(self::createCode());
670
        if (!$this->reUser->saveField('new_pw_code')) {
671
            return false;
672
        }
673
674
        $this->setNewPWDate(time());
675
        if (!$this->reUser->saveField('new_pw_date')) {
676
            return false;
677
        }
678
679
        // send confirmation
680
        $mail = new mail();
681
        $mail->name = 'newpw';
682
        $mail->to = $email;
683
        $mail->subject = $translate->t('New password code', '', basename(__FILE__), __LINE__);
684
        $mail->assign('code', $this->getNewPWCode());
685
        $mail->send();
686
687
        return true;
688
    }
689
690
    public function clearNewPWCode()
691
    {
692
        $this->setNewPWCode(null);
693
        if (!$this->reUser->saveField('new_pw_code')) {
694
            return false;
695
        }
696
697
        $this->setNewPWDate(null);
698
        if (!$this->reUser->saveField('new_pw_date')) {
699
            return false;
700
        }
701
702
        return true;
703
    }
704
705
    public function requestNewEMail($email)
706
    {
707
        global $translate;
708
709
        if (!$this->exist()) {
710
            return false;
711
        }
712
713
        $storedEMail = $this->getEMail();
714
715
        if (mb_strtolower($storedEMail) == mb_strtolower($email)) {
716
            return false;
717
        }
718
719
        if ($storedEMail === null || $storedEMail == '') {
720
            return false;
721
        }
722
723
        if (!$this->getIsActive()) {
724
            return false;
725
        }
726
727
        $this->setNewEMailCode(self::createCode());
728
        if (!$this->reUser->saveField('new_email_code')) {
729
            return false;
730
        }
731
732
        $this->setNewEMailDate(time());
733
        if (!$this->reUser->saveField('new_email_date')) {
734
            return false;
735
        }
736
737
        $this->setNewEMail($email);
738
        if (!$this->reUser->saveField('new_email')) {
739
            return false;
740
        }
741
742
        // send confirmation
743
        $mail = new mail();
744
        $mail->name = 'newemail';
745
        $mail->to = $email;
746
        $mail->subject = $translate->t('New email code', '', basename(__FILE__), __LINE__);
747
        $mail->assign('code', $this->getNewEMailCode());
748
        $mail->send();
749
750
        return true;
751
    }
752
753
    public function clearNewEMailCode()
754
    {
755
        $this->setNewEMailCode(null);
756
        if (!$this->reUser->saveField('new_email_code')) {
757
            return false;
758
        }
759
760
        $this->setNewEMailDate(null);
761
        if (!$this->reUser->saveField('new_email_date')) {
762
            return false;
763
        }
764
765
        $this->setNewEMail(null);
766
        if (!$this->reUser->saveField('new_email')) {
767
            return false;
768
        }
769
770
        return true;
771
    }
772
773
    public function remindEMail()
774
    {
775
        global $translate;
776
777
        if (!$this->exist()) {
778
            return false;
779
        }
780
781
        $email = $this->getEMail();
782
        if ($email === null || $email === '') {
783
            return false;
784
        }
785
786
        if (!$this->getIsActive()) {
787
            return false;
788
        }
789
790
        // send confirmation
791
        $mail = new mail();
792
        $mail->name = 'remindemail';
793
        $mail->to = $email;
794
        $mail->subject = $translate->t('Reminder to your E-Mail-Address', '', basename(__FILE__), __LINE__);
795
        $mail->assign('username', $this->getUsername());
796
        $mail->assign('email', $email);
797
        $mail->send();
798
799
        return true;
800
    }
801
802
    public function sendRegistrationCode()
803
    {
804
        global $opt, $translate;
805
806
        $countriesList = new countriesList();
807
808
        $mail = new mail();
809
        $mail->name = 'register';
810
        $mail->to = $this->getEMail();
811
        $mail->subject = $translate->t('Registration confirmation', '', basename(__FILE__), __LINE__);
812
        $mail->assign('domain', $opt['page']['domain']);
813
        $mail->assign('activation_page', $opt['page']['absolute_url'] . 'activation.php');
814
        $mail->assign('short_activation_page', $opt['page']['absolute_url'] . 'a.php');
815
        $mail->assign('username', $this->getUsername());
816
        $mail->assign('userid', $this->getUserId());
817
        $mail->assign('last_name', $this->getLastName());
818
        $mail->assign('first_name', $this->getFirstName());
819
        $mail->assign('country', $countriesList::getCountryLocaleName($this->getCountryCode()));
820
        $mail->assign('code', $this->getActivationCode());
821
822
        if ($mail->send()) {
823
            return true;
824
        }
825
826
        return false;
827
    }
828
829
    public function sendEMail($nFromUserId, $sSubject, $sText, $bSendEMailAddress)
830
    {
831
        global $opt, $translate;
832
833
        if ($this->exist() == false) {
834
            return false;
835
        }
836
837
        if ($this->getIsActive() == false) {
838
            return false;
839
        }
840
841
        if ($this->getEMail() === null || $this->getEMail() == '') {
842
            return false;
843
        }
844
845
        if ($sSubject === '') {
846
            return false;
847
        }
848
849
        if ($sText === '') {
850
            return false;
851
        }
852
853
        if (mb_strpos($sSubject, "\n") !== false) {
854
            $sSubject = mb_substr($sSubject, 0, mb_strpos($sSubject, "\n"));
855
        }
856
        $sSubject = mb_trim($sSubject);
857
858
        $fromUser = new user($nFromUserId);
859
        if ($fromUser->exist() == false) {
860
            return false;
861
        }
862
        if ($fromUser->getIsActive() == false) {
863
            return false;
864
        }
865
        if ($fromUser->getEMail() === null || $fromUser->getEMail() === '') {
866
            return false;
867
        }
868
869
        $language = $this->getLanguageCode();
870
        if (!$language) {
871
            $language = $opt['template']['locale'];
872
        }
873
874
        // ok, we can send ...
875
        $mail = new mail();
876
        $mail->name = 'usercontactmail';
877
        $mail->to = $this->getEMail();
878
        $mail->recipient_locale = $this->getLanguageCode();
879
880
        $mail->from = $opt['mail']['usermail'];
881
882
        if ($bSendEMailAddress == true) {
883
            $mail->replyTo = $fromUser->getEMail();
884
            $mail->returnPath = $fromUser->getEMail();
885
        }
886
887
        $mail->subject = $translate->t('E-Mail from', '', basename(__FILE__), __LINE__, '', 1, $language) . ' ' . $fromUser->getUsername() . ': ' . $sSubject;
888
        $mail->assign('usersubject', $sSubject);
889
        $mail->assign('text', $sText);
890
        $mail->assign('username', $this->getUsername());
891
        $mail->assign('sendemailaddress', $bSendEMailAddress);
892
        $mail->assign('fromusername', $fromUser->getUsername());
893
        $mail->assign('fromuserid', $fromUser->getUserId());
894
        $mail->assign('fromuseremail', $fromUser->getEMail());
895
896
        if ($mail->send($opt['page']['default_absolute_url'])) {
897
            // send copy to fromUser
898
            $mail->assign('copy', true);
899
            $mail->to = $fromUser->getEMail();
900
            $mail->send();
901
902
            // log
903
            sql(
904
                "INSERT INTO `email_user` (`ipaddress`, `from_user_id`, `from_email`, `to_user_id`, `to_email`)
905
                 VALUES ('&1', '&2', '&3', '&4', '&5')",
906
                $_SERVER["REMOTE_ADDR"],
907
                $fromUser->getUserId(),
908
                $fromUser->getEMail(),
909
                $this->getUserId(),
910
                $this->getEMail()
911
            );
912
913
            return true;
914
        }
915
916
        return false;
917
    }
918
919 View Code Duplication
    public function canDisable()
920
    {
921
        global $login;
922
        $login->verify();
923
924
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
925
            return false;
926
        }
927
928
        if ($this->getIsActive() != 0) {
929
            return true;
930
        }
931
932
        return false;
933
    }
934
935
    public function disable()
936
    {
937
        global $login, $translate;
938
939
        if ($this->canDisable() == false) {
940
            return false;
941
        }
942
943
        // write old record to log
944
        $backup = array();
945
        $backup['username'] = $this->getUsername();
946
        $backup['email'] = $this->getEMail();
947
        $backup['last_name'] = $this->getLastName();
948
        $backup['first_name'] = $this->getFirstName();
949
        $backup['country'] = $this->getCountryCode();
950
        $backup['latitude'] = $this->getLatitude();
951
        $backup['longitude'] = $this->getLongitude();
952
953
        sql(
954
            "INSERT INTO `logentries` (`module`, `eventid`, `userid`, `objectid1`, `objectid2`, `logtext`, `details`)
955
             VALUES ('user', 6, '&1', '&2', '&3', '&4', '&5')",
956
            $login->userid,
957
            $this->nUserId,
958
            0,
959
            'User ' . sql_escape($this->getUsername()) . ' disabled',
960
            serialize($backup)
961
        );
962
963
        // delete private and system data
964
        sql(
965
            "UPDATE `user` SET `password`=NULL, `email`=NULL, `last_name`='', `first_name`='',
966
                               `country`=NULL, `latitude`=0, `longitude`=0, `is_active_flag`=0, `activation_code`='',
967
                               `new_pw_code`=NULL, `new_pw_date`=NULL, `new_email`=NULL, `new_email_code`=NULL,
968
                               `new_email_date`=NULL, `email_problems`=0, `first_email_problem`=NULL,
969
                               `last_email_problem`=NULL
970
             WHERE `user_id`='&1'",
971
            $this->nUserId
972
        );
973
974
        // non-private data which need not to be deleted:
975
        //
976
        //   - Statpic and profile description texts - published under the data license
977
        //   - profile settings: accept_mailing, pmr_flag, permanent_login_flag, notify_radius,
978
        //                       user_options entries
979
        //   - watch and ignore lists
980
        //   - adoptions: may still be executed if offered to another user
981
982
        // Handling of cache lists is unclear. They may be deleted by the Opencaching team
983
        // if not considered useful.
984
985
        // lock the user's caches
986
        $error = false;
987
        $rs = sql("SELECT `cache_id` FROM `caches` WHERE `user_id`='&1' AND `status` IN (1,2,3)", $this->nUserId);
988
        while (($rCache = sql_fetch_assoc($rs)) && !$error) {
989
            $error = true;
990
            $cache = new cache($rCache['cache_id']);
991
            if ($cache->setStatus(6) && $cache->save()) {
992
                $log = cachelog::createNew($rCache['cache_id'], $login->userid);
993
                if ($log !== false) {
994
                    $log->setType(cachelog::LOGTYPE_LOCKED, true);
995
                    $log->setOcTeamComment(true);
996
                    $log->setDate(date('Y-m-d'));
997
                    $log->setText($translate->t(
998
                        'The user account has been disabled.',
999
                        '',
1000
                        '',
1001
                        0,
1002
                        '',
1003
                        1,
1004
                        $cache->getDefaultDescLanguage()
1005
                    ));
1006
                    $log->setTextHtml(false);
1007
                    if ($log->save()) {
1008
                        $error = false;
1009
                    }
1010
                }
1011
            }
1012
            echo "\n";
1013
        }
1014
        sql_free_result($rs);
1015
1016
        return !$error;
1017
    }
1018
1019
1020 View Code Duplication
    public function canDisableDueLicense()
1021
    {
1022
        global $login;
1023
        $login->verify();
1024
1025
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
1026
            return false;
1027
        }
1028
1029
        return true;
1030
    }
1031
1032
    /**
1033
     * disables user (if not disabled), removes all licensed content from db and
1034
     * replaces every picture with a dummy one
1035
     *
1036
     * @param bool $old_disabled
1037
     * @return string error message, if anything went wrong, true otherwise
1038
     * old_disabled: the user was disabled already before license transition
1039
     * and therefore could not accept/decline the license
1040
     */
1041
    public function disduelicense($old_disabled = false)
1042
    {
1043
1044
        // get translation-object
1045
        global $translate;
1046
1047
        // check if disabled, disable if not
1048
        if (!$this->canDisableDueLicense()) {
1049
            return 'this user must not be disabled';
1050
        }
1051
1052
        if (!$old_disabled) {
1053
            if ($this->canDisable()) {
1054
                if (!$this->disable()) {
1055
                    return 'disable user failed';
1056
                }
1057
            }
1058
        }
1059
1060
        // remember that data license was declined
1061
        sql(
1062
            "UPDATE user SET data_license='&2' WHERE user_id='&1'",
1063
            $this->getUserId(),
1064
            $old_disabled ? NEW_DATA_LICENSE_PASSIVELY_DECLINED : NEW_DATA_LICENSE_ACTIVELY_DECLINED
1065
        );
1066
1067
        /*
1068
         * set all cache_desc and hint to '', save old texts
1069
         */
1070
        // check if there are caches
1071
        $num_caches = sql_value(
1072
            "SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'",
1073
            0,
1074
            $this->getUserId()
1075
        );
1076
        if ($num_caches > 0) {
1077
            $cache_descs = array();
1078
            $rs = sql(
1079
                "SELECT `id`, `language`, `desc`, `hint` " .
1080
                "FROM `cache_desc`,`caches` " .
1081
                "WHERE `caches`.`cache_id`=`cache_desc`.`cache_id` " .
1082
                "AND `caches`.`user_id`='&1'",
1083
                $this->getUserId()
1084
            );
1085
            while ($cache_desc = sql_fetch_array($rs, MYSQL_ASSOC)) {
1086
                $cache_descs[] = $cache_desc;
1087
            }
1088
            sql_free_result($rs);
1089
1090
            // walk through cache_descs and set message for each language
1091
            foreach ($cache_descs as $desc) {
1092
                // save text - added 2013/03/18 to be enable restoring data on reactivation
1093
                // of accounts that were disabled before license transition
1094 View Code Duplication
                if ($desc['desc'] != "") {
1095
                    sql(
1096
                        "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1097
                         VALUES ('&1', '&2', '&3', '&4')",
1098
                        OBJECT_CACHEDESC,
1099
                        $desc['id'],
1100
                        1,
1101
                        $desc['desc']
1102
                    );
1103
                }
1104 View Code Duplication
                if ($desc['hint'] != "") {
1105
                    sql(
1106
                        "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1107
                         VALUES ('&1', '&2', '&3', '&4')",
1108
                        OBJECT_CACHEDESC,
1109
                        $desc['id'],
1110
                        2,
1111
                        $desc['hint']
1112
                    );
1113
                }
1114
1115
                if ($desc['desc'] != "") {
1116
                    if ($old_disabled) {
1117
                        $descmsg = $translate->t("cache description was removed because the owner's account was inactive when the <a href='articles.php?page=impressum#datalicense'>new content license</a> was launched", '', basename(__FILE__), __LINE__, '', 1, $desc['language']);
1118
                    } else {
1119
                        $descmsg = $translate->t('cache description was removed because owner declined content license', '', basename(__FILE__), __LINE__, '', 1, $desc['language']);
1120
                    }
1121
                } else {
1122
                    $descmsg = "";
1123
                }
1124
1125
                sql(
1126
                    "UPDATE `cache_desc` " .
1127
                    "SET `desc`='&1',`hint`='&2' " .
1128
                    "WHERE `id`='&3'",
1129
                    "<em>" . $descmsg . "</em>",
1130
                    '',
1131
                    $desc['id']
1132
                );
1133
            }
1134
1135
            // replace pictures
1136
            $errmesg = $this->replace_pictures(OBJECT_CACHE);
1137
            if ($errmesg !== true) {
1138
                return "removing cache pictures: $errmesg";
1139
            }
1140
        }
1141
1142
        // delete additional waypoint texts
1143
        $rs = sql(
1144
            "SELECT `id`, `description` FROM `coordinates`
1145
             WHERE `type`='&1'
1146
             AND `cache_id` IN (SELECT `cache_id` FROM `caches` WHERE `user_id`='&2')",
1147
            COORDINATE_WAYPOINT,
1148
            $this->getUserId()
1149
        );
1150
        while ($wp = sql_fetch_assoc($rs)) {
1151
            if ($wp['description'] != "") {
1152
                sql(
1153
                    "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1154
                     VALUES ('&1', '&2', '&3', '&4')",
1155
                    OBJECT_WAYPOINT,
1156
                    $wp['id'],
1157
                    0,
1158
                    $wp['description']
1159
                );
1160
            }
1161
1162
            sql("UPDATE `coordinates` SET `description`='' WHERE `id`='&1'", $wp['id']);
1163
        }
1164
        sql_free_result($rs);
1165
1166
        /*
1167
         * set all cache_logs '', save old texts and delete pictures
1168
         */
1169
        $rs = sql("SELECT `id`, `text` FROM `cache_logs` WHERE `user_id`='&1'", $this->getUserId());
1170
        while ($log = sql_fetch_array($rs, MYSQL_ASSOC)) {
1171
            // save text - added 2013/03/18 to be enable restoring data on reactivation
1172
            // of accounts that were disabled before license transition
1173
            sql(
1174
                "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1175
                 VALUES ('&1', '&2', '&3', '&4')",
1176
                OBJECT_CACHELOG,
1177
                $log['id'],
1178
                0,
1179
                $log['text']
1180
            );
1181
1182
            // set text ''
1183
            sql("UPDATE `cache_logs` SET `text`='' WHERE `id`='&1'", $log['id']);
1184
1185
            /*
1186
            // replace pictures
1187
            $errmesg = $this->replace_pictures(OBJECT_CACHELOG);
1188
            if ($errmesg !== true)
1189
                return "removing log pictures: $errmesg";
1190
            */
1191
1192
            // delete log pictures
1193
            $rsp = sql(
1194
                "SELECT `id` FROM `pictures`
1195
                 WHERE `object_type`='&1' AND `object_id`='&2'",
1196
                OBJECT_CACHELOG,
1197
                $log['id']
1198
            );
1199
            while ($pic = sql_fetch_assoc($rsp)) {
1200
                $picture = new picture($pic['id']);
1201
                $picture->delete();
1202
            }
1203
            sql_free_result($rsp);
1204
        }
1205
        sql_free_result($rs);
1206
1207
        // discard achived logs' texts
1208
        sql("UPDATE `cache_logs_archived` SET `text`='' WHERE `user_id`='&1'", $this->getUserId());
1209
1210
        // success
1211
        return true;
1212
    }
1213
1214
    /**
1215
     * replaces all pictures of $this-user with a dummy for the given object-type
1216
     *
1217
     * @param int $object_type object_types-id from table object_types
1218
     *
1219
     * @return bool true, if replacement worked, false otherwise
1220
     */
1221
    public function replace_pictures($object_type)
1222
    {
1223
        // get optionsarray
1224
        global $opt;
1225
1226
        // load bmp-support
1227
        require_once __DIR__ . '/../imagebmp.inc.php';
1228
1229
        // paths cleared by trailing '/'
1230
        if (substr($opt['logic']['pictures']['dir'], - 1) != '/') {
1231
            $picpath = $opt['logic']['pictures']['dir'];
1232
        } else {
1233
            $picpath = substr($opt['logic']['pictures']['dir'], 0, - 1);
1234
        }
1235
1236
        $thumbpath = "$picpath/thumbs";
1237
1238
        $pdummy = isset($opt['logic']['pictures']['dummy']);
1239 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['bgcolor']) && is_array($opt['logic']['pictures']['dummy']['bgcolor'])) {
1240
            $dummybg = $opt['logic']['pictures']['dummy']['bgcolor'];
1241
        } else {
1242
            $dummybg = [
1243
                255,
1244
                255,
1245
                255
1246
            ];
1247
        }
1248
1249 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['text'])) {
1250
            $dummytext = $opt['logic']['pictures']['dummy']['text'];
1251
        } else {
1252
            $dummytext = '';
1253
        }
1254
1255 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['textcolor']) && is_array($opt['logic']['pictures']['dummy']['textcolor'])) {
1256
            $dummytextcolor = $opt['logic']['pictures']['dummy']['textcolor'];
1257
        } else {
1258
            $dummytextcolor = array(
1259
                0,
1260
                0,
1261
                0
1262
            );
1263
        }
1264
1265
        $tmh = 0;
1266
        $tmw = 0;
1267
1268
        /*
1269
         * check log or cache
1270
         */
1271
        if ($object_type == OBJECT_CACHE) {
1272
            // get filenames of the pictures of $this' caches
1273
            $rs = sql(
1274
                "SELECT `pictures`.`url` " .
1275
                "FROM `pictures`,`caches` " .
1276
                "WHERE `caches`.`cache_id`=`pictures`.`object_id`" .
1277
                " AND `pictures`.`object_type`='&1' AND `caches`.`user_id`='&2'",
1278
                OBJECT_CACHE,
1279
                $this->getUserId()
1280
            );
1281
        } elseif ($object_type == OBJECT_CACHELOG) {
1282
            // get filenames of the pictures of $this' logs
1283
            $rs = sql(
1284
                "SELECT `pictures`.`url` " .
1285
                "FROM `pictures`,`cache_logs` " .
1286
                "WHERE `cache_logs`.`id`=`pictures`.`object_id`" .
1287
                " AND `pictures`.`object_type`='&1' AND `cache_logs`.`user_id`='&2'",
1288
                OBJECT_CACHELOG,
1289
                $this->getUserId()
1290
            );
1291
        }
1292
1293
        // set thumb-dimensions
1294
        $tmh = $opt['logic']['pictures']['thumb_max_height'];
1295
        $tmw = $opt['logic']['pictures']['thumb_max_width'];
1296
1297
        $filenames = array();
1298
        while ($url = sql_fetch_array($rs, MYSQL_NUM)) {
1299
            $filenames[] = substr($url['url'], - 40);
1300
        }
1301
1302
        // free result
1303
        sql_free_result($rs);
1304
1305
        /*
1306
         * walk through filenames and replace original
1307
         */
1308
        // check if there is something to replace
1309
        if (count($filenames) > 0) {
1310
            foreach ($filenames as $fn) {
1311
                // get uuid and extension
1312
                $uuid = substr($fn, 0, 36);
1313
                $ext = substr($fn, - 3);
1314
                $thumb_dir1 = substr($uuid, 0, 1);
1315
                $thumb_dir2 = substr($uuid, 1, 1);
1316
1317
                // read original size
1318
                if (file_exists("$picpath/$fn")) {
1319
                    list($w, $h, $t, $attr) = getimagesize("$picpath/$fn");
1320
                } else {
1321
                    $w = 600;
1322
                    $h = 480;
1323
                }
1324
1325
                // create new image
1326
                $im = imagecreatetruecolor($w, $h);
1327
                // allocate colors
1328
                $col_bg = imagecolorallocate($im, $dummybg[0], $dummybg[1], $dummybg[2]);
1329
                $col_text = imagecolorallocate($im, $dummytextcolor[0], $dummytextcolor[1], $dummytextcolor[2]);
1330
1331
                // fill bg
1332
                imagefill($im, 0, 0, $col_bg);
1333
1334
                // check for replacement-image
1335
                if ($pdummy && isset($opt['logic']['pictures']['dummy']['replacepic'])
1336
                    && $opt['logic']['pictures']['dummy']['replacepic'] != $opt['rootpath'] . 'images/'
1337
                    && file_exists($opt['logic']['pictures']['dummy']['replacepic'])
1338
                ) {
1339
                    // get dimensions of the replacement
1340
                    list($rw, $rh, $rt, $rattr) = getimagesize($opt['logic']['pictures']['dummy']['replacepic']);
1341
                    $rwh = 0;
1342
                    if ($rw > $rh) {
1343
                        $rwh = $rh;
1344
                    } else {
1345
                        $rwh = $rw;
1346
                    }
1347
1348
                    // check dimensions of original and set replacement size
1349
                    $rsize = 0;
1350
                    if ($w > $h) {
1351
                        if (($h * 0.85) > $rwh) {
1352
                            $rsize = $rwh;
1353
                        } else {
1354
                            $rsize = $h * 0.9;
1355
                        }
1356
                    } else {
1357
                        if (($w * 0.85) > $rwh) {
1358
                            $rsize = $rwh;
1359
                        } else {
1360
                            $rsize = $w * 0.9;
1361
                        }
1362
                    }
1363
                    $dx = ($w - $rsize) / 2;
1364
                    $dy = ($h - $rsize) / 2;
1365
1366
                    // get replacement image
1367
                    $rext = substr($opt['logic']['pictures']['dummy']['replacepic'], - 3);
1368
                    $rim = null;
1369
                    if ($rext == 'jpg') {
1370
                        $rim = imagecreatefromjpeg($opt['logic']['pictures']['dummy']['replacepic']);
1371 View Code Duplication
                    } elseif ($rext == 'png') {
1372
                        $rim = imagecreatefrompng($opt['logic']['pictures']['dummy']['replacepic']);
1373
                    } elseif ($rext == 'gif') {
1374
                        $rim = imagecreatefromgif($opt['logic']['pictures']['dummy']['replacepic']);
1375 View Code Duplication
                    } elseif ($rext == 'bmp') {
1376
                        $rim = imagecreatefrombmp($opt['logic']['pictures']['dummy']['replacepic']);
1377
                    }
1378
1379
                    // copy image
1380
                    if (!is_null($rim)) {
1381
                        imagecopyresampled($im, $rim, $dx, $dy, 0, 0, $rsize, $rsize, $rw, $rh);
1382
                    }
1383
                } else {
1384
                    // set text
1385
                    if ($dummytext != '') {
1386
                        imagestring($im, 1, 10, $h / 2, $dummytext, $col_text);
1387
                    } else {
1388
                        imageline($im, 0, 0, $w, $h, 0xff0000);
1389
                        imageline($im, 0, $h, $w, 0, 0xff0000);
1390
                    }
1391
                }
1392
1393
                // save dummy
1394
                if ($ext == 'jpg') {
1395
                    if (!imagejpeg($im, "$picpath/$fn", 75)) {
1396
                        return "save dummy failed [$ext]";
1397
                    }
1398
                } elseif ($ext == 'png') {
1399
                    if (!imagepng($im, "$picpath/$fn", 4)) {
1400
                        return "save dummy failed [$ext]";
1401
                    }
1402
                } elseif ($ext == 'gif') {
1403
                    if (!imagegif($im, "$picpath/$fn")) {
1404
                        return "save dummy failed [$ext]";
1405
                    }
1406
                } elseif ($ext == 'bmp') {
1407
                    if (!imagebmp($im, "$picpath/$fn")) {
1408
                        return "save dummy failed [$ext]";
1409
                    }
1410
                } else {
1411
                    return "save dummy failed [$ext], unknown extension";
1412
                }
1413
1414
                // set thumb-dimensions
1415
                if (($h > $tmh) || ($w > $tmw)) {
1416
                    if ($h > $w) {
1417
                        $th = $tmh;
1418
                        $tw = $w * ($th / $h);
1419
                    } else {
1420
                        $tw = $tmw;
1421
                        $th = $h * ($tw / $w);
1422
                    }
1423
                } else {
1424
                    $tw = $w;
1425
                    $th = $h;
1426
                }
1427
1428
                // copy dummy
1429
                $tim = imagecreatetruecolor($tw, $th);
1430
                imagecopyresampled($tim, $im, 0, 0, 0, 0, $tw, $th, $w, $h);
1431
1432
                // check directories or create them
1433 View Code Duplication
                if (!file_exists("$thumbpath/$thumb_dir1")) {
1434
                    if (!mkdir("$thumbpath/$thumb_dir1")) {
1435
                        return 'mkdir in thumbpath failed';
1436
                    }
1437
                }
1438 View Code Duplication
                if (!file_exists("$thumbpath/$thumb_dir1/$thumb_dir2")) {
1439
                    if (!mkdir("$thumbpath/$thumb_dir1/$thumb_dir2")) {
1440
                        return 'mkdir in thumbpath failed';
1441
                    }
1442
                }
1443
1444
                // save thumb
1445
                if ($ext == 'jpg') {
1446
                    if (!imagejpeg($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn", 75)) {
1447
                        return "save thumb failed [$ext]";
1448
                    }
1449 View Code Duplication
                } elseif ($ext == 'png') {
1450
                    if (!imagepng($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn", 4)) {
1451
                        return "save thumb failed [$ext]";
1452
                    }
1453
                } elseif ($ext == 'gif') {
1454
                    if (!imagegif($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn")) {
1455
                        return "save thumb failed [$ext]";
1456
                    }
1457 View Code Duplication
                } elseif ($ext == 'bmp') {
1458
                    if (!imagebmp($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn")) {
1459
                        return "save thumb failed [$ext]";
1460
                    }
1461
                } else {
1462
                    return "save thumb failed [$ext], unknown extension";
1463
                }
1464
            }
1465
        }
1466
1467
        // success
1468
        return true;
1469
    }
1470
1471
    public function canDelete()
1472
    {
1473
        global $login;
1474
        $login->verify();
1475
1476
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
1477
            return false;
1478
        }
1479
1480
        return
1481
            sql_value("SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'", 0, $this->nUserId)
1482
            + sql_value("SELECT COUNT(*) FROM `cache_logs` WHERE `user_id`='&1'", 0, $this->nUserId)
1483
            + sql_value("SELECT COUNT(*) FROM `cache_logs_archived` WHERE `user_id`='&1'", 0, $this->nUserId)
0 ignored issues
show
Deprecated Code introduced by
The function sql_value() has been deprecated with message: use DBAL Conenction instead. See adminreports.php for an example implementation

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
1484
            + sql_value("SELECT COUNT(*) FROM `cache_reports` WHERE `userid`='&1'", 0, $this->nUserId)
1485
            == 0;
1486
    }
1487
1488
    public function delete()
1489
    {
1490
        global $login;
1491
1492
        if ($this->canDelete() == false) {
1493
            return false;
1494
        }
1495
1496
        // write old record to log
1497
        $backup = array();
1498
        $backup['username'] = $this->getUsername();
1499
        $backup['email'] = $this->getEMail();
1500
        $backup['last_name'] = $this->getLastName();
1501
        $backup['first_name'] = $this->getFirstName();
1502
1503
        sql(
1504
            "INSERT INTO `logentries` (`module`, `eventid`, `userid`, `objectid1`, `objectid2`, `logtext`, `details`)
1505
             VALUES ('user', 7, '&1', '&2', '&3', '&4', '&5')",
1506
            $login->userid,
1507
            $this->nUserId,
1508
            0,
1509
            'User ' . sql_escape($this->getUsername()) . ' deleted',
1510
            serialize($backup)
1511
        );
1512
1513
        sql('SET @allowdelete=1');
1514
        sql("DELETE FROM `user` WHERE `user_id`='&1'", $this->nUserId);
1515
        // all data in depending tables is cleared via trigger
1516
1517
        $this->reload();
1518
1519
        return true;
1520
    }
1521
1522
    // email bounce processing
1523
    public function addEmailProblem($licenseEmail = false)
1524
    {
1525
        // mailing_problems is a bit-flag field to remember nonDelivered, important mailings
1526
        if ($licenseEmail) {
1527
            if (!$this->reUser->setValue('mailing_problems', $this->reUser->getValue('mailing_problems') | 1)) {
1528
                return false;
1529
            }
1530
        }
1531
1532
        return $this->reUser->setValue('email_problems', $this->getEmailProblems() + 1) &&
1533
        $this->reUser->setValue('last_email_problem', date('Y-m-d H:i:s')) &&
1534
        $this->save();
1535
    }
1536
1537
    public function getEmailProblems()
1538
    {
1539
        // see also common.inc.php "SELECT `email_problems`"
1540
        return $this->reUser->getValue('email_problems');
1541
    }
1542
1543
    public function getDataLicense()
1544
    {
1545
        return $this->reUser->getValue('data_license');
1546
    }
1547
1548
    public function getLicenseDeclined()
1549
    {
1550
        return $this->getDataLicense() == NEW_DATA_LICENSE_ACTIVELY_DECLINED ||
1551
        $this->getDataLicense() == NEW_DATA_LICENSE_PASSIVELY_DECLINED;
1552
    }
1553
1554
    public function missedDataLicenseMail()
1555
    {
1556
        return $this->reUser->getValue('mailing_problems') & 1;
1557
    }
1558
1559
    public function shownDataLicenseMail()
1560
    {
1561
        return
1562
            $this->reUser->setValue('mailing_problems', $this->reUser->getValue('mailing_problems') & ~1)
1563
            && $this->save();
1564
    }
1565
1566
    public function confirmEmailAddress()
1567
    {
1568
        return $this->reUser->setValue('email_problems', 0) && $this->save();
1569
    }
1570
1571
    public function reload()
1572
    {
1573
        $this->reUser->reload();
1574
        $this->reUserStat->reload();
1575
    }
1576
1577
    public function getGivenRatings()
1578
    {
1579
        // get number of cache ratings for this user
1580
        return sql_value(
1581
            "SELECT COUNT(`user_id`)
1582
             FROM `cache_rating`
1583
             WHERE `user_id`='&1'",
1584
            0,
1585
            $this->getUserId()
1586
        );
1587
    }
1588
1589
    public function getRatingParameters()
1590
    {
1591
        global $opt;
1592
1593
        $findsPerRating = $opt['logic']['rating']['findsPerRating'];
1594
        $finds = $this->getStatFound();
1595
        $ratings = $this->getGivenRatings();
1596
1597
        return [
1598
            'maxRatings' => floor($finds / $findsPerRating),
1599
            'givenRatings' => $ratings,
1600
            'findsUntilNextRating' => ($ratings + 1) * $findsPerRating - $finds,
1601
        ];
1602
    }
1603
1604
    public function allowRatings()
1605
    {
1606
        $ratingParams = $this->getRatingParameters();
1607
        return $ratingParams['givenRatings'] < $ratingParams['maxRatings'];
1608
    }
1609
1610
    public function showStatFounds()
1611
    {
1612
        // whether to show the number of founds on log page
1613
        // TODO: make customisable in user profile, see #241
1614
        return false;
1615
    }
1616
1617
    public function guessLanguage()
1618
    {
1619
        global $opt;
1620
1621
        $language = false;
1622
1623
        // If the user has selected a country and a translation is available for
1624
        // that country's primary language, use this language.
1625
1626
        $country = $this->getCountryCode();
1627
        if ($country) {
1628
            foreach ($opt['locale'] as $code => $props) {
1629
                if ($props['mostly_translated'] && in_array($country, $props['primary_lang_of'])) {
1630
                    $language = $code;
1631
                }
1632
            }
1633
        }
1634
1635
        if (!$language) {
1636
            // If the user has logged caches with at least three descriptions,
1637
            // at least 65% of those descriptions have the same language,
1638
            // and a translation is available for that language, use it.
1639
1640
            $rs = sql(
1641
                "
1642
                SELECT COUNT(*) AS `count`, `cache_desc`.`language`
1643
                FROM `cache_logs`
1644
                JOIN `cache_desc` ON `cache_desc`.`cache_id`=`cache_logs`.`cache_id`
1645
                WHERE `cache_logs`.`user_id`='&1'
1646
                GROUP BY `cache_desc`.`language`
1647
                ORDER BY `count` DESC",
1648
                $this->nUserId
1649
            );
1650
            $total = 0;
1651
            while ($r = sql_fetch_assoc($rs)) {
1652
                if ($total == 0) {
1653
                    $first = $r;
1654
                }
1655
                $total += $r['count'];
1656
            }
1657
            sql_free_result($rs);
1658
            $locale = $opt['locale'];
1659
            if ($total >= 3 && $first['count'] / $total >= 0.65) {
1660
                if (isset($locale[$first['language']]) && $locale[$first['language']]['mostly_translated']) {
1661
                    $language = $first['language'];
1662
                }
1663
            }
1664
        }
1665
1666
        return $language;
1667
    }
1668
}
1669