Completed
Push — development ( 1b87d2...43bb99 )
by Thomas
06:02
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 self($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 self($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 float $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 float $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 int $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 bool $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 int|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 int|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 (self::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 self($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 View Code Duplication
    public function canDisableDueLicense()
1020
    {
1021
        global $login;
1022
        $login->verify();
1023
1024
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
1025
            return false;
1026
        }
1027
1028
        return true;
1029
    }
1030
1031
    /**
1032
     * disables user (if not disabled), removes all licensed content from db and
1033
     * replaces every picture with a dummy one
1034
     *
1035
     * @param bool $old_disabled
1036
     * @return string error message, if anything went wrong, true otherwise
1037
     * old_disabled: the user was disabled already before license transition
1038
     * and therefore could not accept/decline the license
1039
     */
1040
    public function disduelicense($old_disabled = false)
1041
    {
1042
1043
        // get translation-object
1044
        global $translate;
1045
1046
        // check if disabled, disable if not
1047
        if (!$this->canDisableDueLicense()) {
1048
            return 'this user must not be disabled';
1049
        }
1050
1051
        if (!$old_disabled) {
1052
            if ($this->canDisable()) {
1053
                if (!$this->disable()) {
1054
                    return 'disable user failed';
1055
                }
1056
            }
1057
        }
1058
1059
        // remember that data license was declined
1060
        sql(
1061
            "UPDATE user SET data_license='&2' WHERE user_id='&1'",
1062
            $this->getUserId(),
1063
            $old_disabled ? NEW_DATA_LICENSE_PASSIVELY_DECLINED : NEW_DATA_LICENSE_ACTIVELY_DECLINED
1064
        );
1065
1066
        /*
1067
         * set all cache_desc and hint to '', save old texts
1068
         */
1069
        // check if there are caches
1070
        $num_caches = sql_value(
1071
            "SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'",
1072
            0,
1073
            $this->getUserId()
1074
        );
1075
        if ($num_caches > 0) {
1076
            $cache_descs = array();
1077
            $rs = sql(
1078
                'SELECT `id`, `language`, `desc`, `hint` ' .
1079
                'FROM `cache_desc`,`caches` ' .
1080
                'WHERE `caches`.`cache_id`=`cache_desc`.`cache_id` ' .
1081
                "AND `caches`.`user_id`='&1'",
1082
                $this->getUserId()
1083
            );
1084
            while ($cache_desc = sql_fetch_array($rs, MYSQL_ASSOC)) {
1085
                $cache_descs[] = $cache_desc;
1086
            }
1087
            sql_free_result($rs);
1088
1089
            // walk through cache_descs and set message for each language
1090
            foreach ($cache_descs as $desc) {
1091
                // save text - added 2013/03/18 to be enable restoring data on reactivation
1092
                // of accounts that were disabled before license transition
1093 View Code Duplication
                if ($desc['desc'] != '') {
1094
                    sql(
1095
                        "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1096
                         VALUES ('&1', '&2', '&3', '&4')",
1097
                        OBJECT_CACHEDESC,
1098
                        $desc['id'],
1099
                        1,
1100
                        $desc['desc']
1101
                    );
1102
                }
1103 View Code Duplication
                if ($desc['hint'] != '') {
1104
                    sql(
1105
                        "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1106
                         VALUES ('&1', '&2', '&3', '&4')",
1107
                        OBJECT_CACHEDESC,
1108
                        $desc['id'],
1109
                        2,
1110
                        $desc['hint']
1111
                    );
1112
                }
1113
1114
                if ($desc['desc'] != '') {
1115
                    if ($old_disabled) {
1116
                        $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']);
1117
                    } else {
1118
                        $descmsg = $translate->t('cache description was removed because owner declined content license', '', basename(__FILE__), __LINE__, '', 1, $desc['language']);
1119
                    }
1120
                } else {
1121
                    $descmsg = '';
1122
                }
1123
1124
                sql(
1125
                    'UPDATE `cache_desc` ' .
1126
                    "SET `desc`='&1',`hint`='&2' " .
1127
                    "WHERE `id`='&3'",
1128
                    '<em>' . $descmsg . '</em>',
1129
                    '',
1130
                    $desc['id']
1131
                );
1132
            }
1133
1134
            // replace pictures
1135
            $errmesg = $this->replace_pictures(OBJECT_CACHE);
1136
            if ($errmesg !== true) {
1137
                return "removing cache pictures: $errmesg";
1138
            }
1139
        }
1140
1141
        // delete additional waypoint texts
1142
        $rs = sql(
1143
            "SELECT `id`, `description` FROM `coordinates`
1144
             WHERE `type`='&1'
1145
             AND `cache_id` IN (SELECT `cache_id` FROM `caches` WHERE `user_id`='&2')",
1146
            COORDINATE_WAYPOINT,
1147
            $this->getUserId()
1148
        );
1149
        while ($wp = sql_fetch_assoc($rs)) {
1150
            if ($wp['description'] != '') {
1151
                sql(
1152
                    "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1153
                     VALUES ('&1', '&2', '&3', '&4')",
1154
                    OBJECT_WAYPOINT,
1155
                    $wp['id'],
1156
                    0,
1157
                    $wp['description']
1158
                );
1159
            }
1160
1161
            sql("UPDATE `coordinates` SET `description`='' WHERE `id`='&1'", $wp['id']);
1162
        }
1163
        sql_free_result($rs);
1164
1165
        /*
1166
         * set all cache_logs '', save old texts and delete pictures
1167
         */
1168
        $rs = sql("SELECT `id`, `text` FROM `cache_logs` WHERE `user_id`='&1'", $this->getUserId());
1169
        while ($log = sql_fetch_array($rs, MYSQL_ASSOC)) {
1170
            // save text - added 2013/03/18 to be enable restoring data on reactivation
1171
            // of accounts that were disabled before license transition
1172
            sql(
1173
                "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1174
                 VALUES ('&1', '&2', '&3', '&4')",
1175
                OBJECT_CACHELOG,
1176
                $log['id'],
1177
                0,
1178
                $log['text']
1179
            );
1180
1181
            // set text ''
1182
            sql("UPDATE `cache_logs` SET `text`='' WHERE `id`='&1'", $log['id']);
1183
1184
            /*
1185
            // replace pictures
1186
            $errmesg = $this->replace_pictures(OBJECT_CACHELOG);
1187
            if ($errmesg !== true)
1188
                return "removing log pictures: $errmesg";
1189
            */
1190
1191
            // delete log pictures
1192
            $rsp = sql(
1193
                "SELECT `id` FROM `pictures`
1194
                 WHERE `object_type`='&1' AND `object_id`='&2'",
1195
                OBJECT_CACHELOG,
1196
                $log['id']
1197
            );
1198
            while ($pic = sql_fetch_assoc($rsp)) {
1199
                $picture = new picture($pic['id']);
1200
                $picture->delete();
1201
            }
1202
            sql_free_result($rsp);
1203
        }
1204
        sql_free_result($rs);
1205
1206
        // discard achived logs' texts
1207
        sql("UPDATE `cache_logs_archived` SET `text`='' WHERE `user_id`='&1'", $this->getUserId());
1208
1209
        // success
1210
        return true;
1211
    }
1212
1213
    /**
1214
     * replaces all pictures of $this-user with a dummy for the given object-type
1215
     *
1216
     * @param int $object_type object_types-id from table object_types
1217
     *
1218
     * @return bool true, if replacement worked, false otherwise
1219
     */
1220
    public function replace_pictures($object_type)
1221
    {
1222
        // get optionsarray
1223
        global $opt;
1224
1225
        // load bmp-support
1226
        require_once __DIR__ . '/../imagebmp.inc.php';
1227
1228
        // paths cleared by trailing '/'
1229
        if (substr($opt['logic']['pictures']['dir'], - 1) != '/') {
1230
            $picpath = $opt['logic']['pictures']['dir'];
1231
        } else {
1232
            $picpath = substr($opt['logic']['pictures']['dir'], 0, - 1);
1233
        }
1234
1235
        $thumbpath = "$picpath/thumbs";
1236
1237
        $pdummy = isset($opt['logic']['pictures']['dummy']);
1238 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['bgcolor']) && is_array($opt['logic']['pictures']['dummy']['bgcolor'])) {
1239
            $dummybg = $opt['logic']['pictures']['dummy']['bgcolor'];
1240
        } else {
1241
            $dummybg = [
1242
                255,
1243
                255,
1244
                255,
1245
            ];
1246
        }
1247
1248 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['text'])) {
1249
            $dummytext = $opt['logic']['pictures']['dummy']['text'];
1250
        } else {
1251
            $dummytext = '';
1252
        }
1253
1254 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['textcolor']) && is_array($opt['logic']['pictures']['dummy']['textcolor'])) {
1255
            $dummytextcolor = $opt['logic']['pictures']['dummy']['textcolor'];
1256
        } else {
1257
            $dummytextcolor = array(
1258
                0,
1259
                0,
1260
                0,
1261
            );
1262
        }
1263
1264
        $tmh = 0;
1265
        $tmw = 0;
1266
1267
        /*
1268
         * check log or cache
1269
         */
1270
        if ($object_type == OBJECT_CACHE) {
1271
            // get filenames of the pictures of $this' caches
1272
            $rs = sql(
1273
                'SELECT `pictures`.`url` ' .
1274
                'FROM `pictures`,`caches` ' .
1275
                'WHERE `caches`.`cache_id`=`pictures`.`object_id`' .
1276
                " AND `pictures`.`object_type`='&1' AND `caches`.`user_id`='&2'",
1277
                OBJECT_CACHE,
1278
                $this->getUserId()
1279
            );
1280
        } elseif ($object_type == OBJECT_CACHELOG) {
1281
            // get filenames of the pictures of $this' logs
1282
            $rs = sql(
1283
                'SELECT `pictures`.`url` ' .
1284
                'FROM `pictures`,`cache_logs` ' .
1285
                'WHERE `cache_logs`.`id`=`pictures`.`object_id`' .
1286
                " AND `pictures`.`object_type`='&1' AND `cache_logs`.`user_id`='&2'",
1287
                OBJECT_CACHELOG,
1288
                $this->getUserId()
1289
            );
1290
        }
1291
1292
        // set thumb-dimensions
1293
        $tmh = $opt['logic']['pictures']['thumb_max_height'];
1294
        $tmw = $opt['logic']['pictures']['thumb_max_width'];
1295
1296
        $filenames = array();
1297
        while ($url = sql_fetch_array($rs, MYSQL_NUM)) {
1298
            $filenames[] = substr($url['url'], - 40);
1299
        }
1300
1301
        // free result
1302
        sql_free_result($rs);
1303
1304
        /*
1305
         * walk through filenames and replace original
1306
         */
1307
        // check if there is something to replace
1308
        if (count($filenames) > 0) {
1309
            foreach ($filenames as $fn) {
1310
                // get uuid and extension
1311
                $uuid = substr($fn, 0, 36);
1312
                $ext = substr($fn, - 3);
1313
                $thumb_dir1 = substr($uuid, 0, 1);
1314
                $thumb_dir2 = substr($uuid, 1, 1);
1315
1316
                // read original size
1317
                if (file_exists("$picpath/$fn")) {
1318
                    list($w, $h, $t, $attr) = getimagesize("$picpath/$fn");
1319
                } else {
1320
                    $w = 600;
1321
                    $h = 480;
1322
                }
1323
1324
                // create new image
1325
                $im = imagecreatetruecolor($w, $h);
1326
                // allocate colors
1327
                $col_bg = imagecolorallocate($im, $dummybg[0], $dummybg[1], $dummybg[2]);
1328
                $col_text = imagecolorallocate($im, $dummytextcolor[0], $dummytextcolor[1], $dummytextcolor[2]);
1329
1330
                // fill bg
1331
                imagefill($im, 0, 0, $col_bg);
1332
1333
                // check for replacement-image
1334
                if ($pdummy && isset($opt['logic']['pictures']['dummy']['replacepic'])
1335
                    && $opt['logic']['pictures']['dummy']['replacepic'] != $opt['rootpath'] . 'images/'
1336
                    && file_exists($opt['logic']['pictures']['dummy']['replacepic'])
1337
                ) {
1338
                    // get dimensions of the replacement
1339
                    list($rw, $rh, $rt, $rattr) = getimagesize($opt['logic']['pictures']['dummy']['replacepic']);
1340
                    $rwh = 0;
1341
                    if ($rw > $rh) {
1342
                        $rwh = $rh;
1343
                    } else {
1344
                        $rwh = $rw;
1345
                    }
1346
1347
                    // check dimensions of original and set replacement size
1348
                    $rsize = 0;
1349
                    if ($w > $h) {
1350
                        if (($h * 0.85) > $rwh) {
1351
                            $rsize = $rwh;
1352
                        } else {
1353
                            $rsize = $h * 0.9;
1354
                        }
1355
                    } else {
1356
                        if (($w * 0.85) > $rwh) {
1357
                            $rsize = $rwh;
1358
                        } else {
1359
                            $rsize = $w * 0.9;
1360
                        }
1361
                    }
1362
                    $dx = ($w - $rsize) / 2;
1363
                    $dy = ($h - $rsize) / 2;
1364
1365
                    // get replacement image
1366
                    $rext = substr($opt['logic']['pictures']['dummy']['replacepic'], - 3);
1367
                    $rim = null;
1368
                    if ($rext == 'jpg') {
1369
                        $rim = imagecreatefromjpeg($opt['logic']['pictures']['dummy']['replacepic']);
1370 View Code Duplication
                    } elseif ($rext == 'png') {
1371
                        $rim = imagecreatefrompng($opt['logic']['pictures']['dummy']['replacepic']);
1372
                    } elseif ($rext == 'gif') {
1373
                        $rim = imagecreatefromgif($opt['logic']['pictures']['dummy']['replacepic']);
1374 View Code Duplication
                    } elseif ($rext == 'bmp') {
1375
                        $rim = imagecreatefrombmp($opt['logic']['pictures']['dummy']['replacepic']);
1376
                    }
1377
1378
                    // copy image
1379
                    if (null !== $rim) {
1380
                        imagecopyresampled($im, $rim, $dx, $dy, 0, 0, $rsize, $rsize, $rw, $rh);
1381
                    }
1382
                } else {
1383
                    // set text
1384
                    if ($dummytext != '') {
1385
                        imagestring($im, 1, 10, $h / 2, $dummytext, $col_text);
1386
                    } else {
1387
                        imageline($im, 0, 0, $w, $h, 0xff0000);
1388
                        imageline($im, 0, $h, $w, 0, 0xff0000);
1389
                    }
1390
                }
1391
1392
                // save dummy
1393
                if ($ext == 'jpg') {
1394
                    if (!imagejpeg($im, "$picpath/$fn", 75)) {
1395
                        return "save dummy failed [$ext]";
1396
                    }
1397
                } elseif ($ext == 'png') {
1398
                    if (!imagepng($im, "$picpath/$fn", 4)) {
1399
                        return "save dummy failed [$ext]";
1400
                    }
1401
                } elseif ($ext == 'gif') {
1402
                    if (!imagegif($im, "$picpath/$fn")) {
1403
                        return "save dummy failed [$ext]";
1404
                    }
1405
                } elseif ($ext == 'bmp') {
1406
                    if (!imagebmp($im, "$picpath/$fn")) {
1407
                        return "save dummy failed [$ext]";
1408
                    }
1409
                } else {
1410
                    return "save dummy failed [$ext], unknown extension";
1411
                }
1412
1413
                // set thumb-dimensions
1414
                if (($h > $tmh) || ($w > $tmw)) {
1415
                    if ($h > $w) {
1416
                        $th = $tmh;
1417
                        $tw = $w * ($th / $h);
1418
                    } else {
1419
                        $tw = $tmw;
1420
                        $th = $h * ($tw / $w);
1421
                    }
1422
                } else {
1423
                    $tw = $w;
1424
                    $th = $h;
1425
                }
1426
1427
                // copy dummy
1428
                $tim = imagecreatetruecolor($tw, $th);
1429
                imagecopyresampled($tim, $im, 0, 0, 0, 0, $tw, $th, $w, $h);
1430
1431
                // check directories or create them
1432 View Code Duplication
                if (!file_exists("$thumbpath/$thumb_dir1")) {
1433
                    if (!mkdir("$thumbpath/$thumb_dir1")) {
1434
                        return 'mkdir in thumbpath failed';
1435
                    }
1436
                }
1437 View Code Duplication
                if (!file_exists("$thumbpath/$thumb_dir1/$thumb_dir2")) {
1438
                    if (!mkdir("$thumbpath/$thumb_dir1/$thumb_dir2")) {
1439
                        return 'mkdir in thumbpath failed';
1440
                    }
1441
                }
1442
1443
                // save thumb
1444
                if ($ext == 'jpg') {
1445
                    if (!imagejpeg($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn", 75)) {
1446
                        return "save thumb failed [$ext]";
1447
                    }
1448 View Code Duplication
                } elseif ($ext == 'png') {
1449
                    if (!imagepng($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn", 4)) {
1450
                        return "save thumb failed [$ext]";
1451
                    }
1452
                } elseif ($ext == 'gif') {
1453
                    if (!imagegif($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn")) {
1454
                        return "save thumb failed [$ext]";
1455
                    }
1456 View Code Duplication
                } elseif ($ext == 'bmp') {
1457
                    if (!imagebmp($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn")) {
1458
                        return "save thumb failed [$ext]";
1459
                    }
1460
                } else {
1461
                    return "save thumb failed [$ext], unknown extension";
1462
                }
1463
            }
1464
        }
1465
1466
        // success
1467
        return true;
1468
    }
1469
1470
    public function canDelete()
1471
    {
1472
        global $login;
1473
        $login->verify();
1474
1475
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
1476
            return false;
1477
        }
1478
1479
        return
1480
            sql_value("SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'", 0, $this->nUserId)
1481
            + sql_value("SELECT COUNT(*) FROM `cache_logs` WHERE `user_id`='&1'", 0, $this->nUserId)
1482
            + sql_value("SELECT COUNT(*) FROM `cache_logs_archived` WHERE `user_id`='&1'", 0, $this->nUserId)
1483
            + sql_value("SELECT COUNT(*) FROM `cache_reports` WHERE `userid`='&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
            == 0;
1485
    }
1486
1487
    public function delete()
1488
    {
1489
        global $login;
1490
1491
        if ($this->canDelete() == false) {
1492
            return false;
1493
        }
1494
1495
        // write old record to log
1496
        $backup = array();
1497
        $backup['username'] = $this->getUsername();
1498
        $backup['email'] = $this->getEMail();
1499
        $backup['last_name'] = $this->getLastName();
1500
        $backup['first_name'] = $this->getFirstName();
1501
1502
        sql(
1503
            "INSERT INTO `logentries` (`module`, `eventid`, `userid`, `objectid1`, `objectid2`, `logtext`, `details`)
1504
             VALUES ('user', 7, '&1', '&2', '&3', '&4', '&5')",
1505
            $login->userid,
1506
            $this->nUserId,
1507
            0,
1508
            'User ' . sql_escape($this->getUsername()) . ' deleted',
1509
            serialize($backup)
1510
        );
1511
1512
        sql('SET @allowdelete=1');
1513
        sql("DELETE FROM `user` WHERE `user_id`='&1'", $this->nUserId);
1514
        // all data in depending tables is cleared via trigger
1515
1516
        $this->reload();
1517
1518
        return true;
1519
    }
1520
1521
    // email bounce processing
1522
    public function addEmailProblem($licenseEmail = false)
1523
    {
1524
        // mailing_problems is a bit-flag field to remember nonDelivered, important mailings
1525
        if ($licenseEmail) {
1526
            if (!$this->reUser->setValue('mailing_problems', $this->reUser->getValue('mailing_problems') | 1)) {
1527
                return false;
1528
            }
1529
        }
1530
1531
        return $this->reUser->setValue('email_problems', $this->getEmailProblems() + 1) &&
1532
        $this->reUser->setValue('last_email_problem', date('Y-m-d H:i:s')) &&
1533
        $this->save();
1534
    }
1535
1536
    public function getEmailProblems()
1537
    {
1538
        // see also common.inc.php "SELECT `email_problems`"
1539
        return $this->reUser->getValue('email_problems');
1540
    }
1541
1542
    public function getDataLicense()
1543
    {
1544
        return $this->reUser->getValue('data_license');
1545
    }
1546
1547
    public function getLicenseDeclined()
1548
    {
1549
        return $this->getDataLicense() == NEW_DATA_LICENSE_ACTIVELY_DECLINED ||
1550
        $this->getDataLicense() == NEW_DATA_LICENSE_PASSIVELY_DECLINED;
1551
    }
1552
1553
    public function missedDataLicenseMail()
1554
    {
1555
        return $this->reUser->getValue('mailing_problems') & 1;
1556
    }
1557
1558
    public function shownDataLicenseMail()
1559
    {
1560
        return
1561
            $this->reUser->setValue('mailing_problems', $this->reUser->getValue('mailing_problems') & ~1)
1562
            && $this->save();
1563
    }
1564
1565
    public function confirmEmailAddress()
1566
    {
1567
        return $this->reUser->setValue('email_problems', 0) && $this->save();
1568
    }
1569
1570
    public function reload()
1571
    {
1572
        $this->reUser->reload();
1573
        $this->reUserStat->reload();
1574
    }
1575
1576
    public function getGivenRatings()
1577
    {
1578
        // get number of cache ratings for this user
1579
        return sql_value(
1580
            "SELECT COUNT(`user_id`)
1581
             FROM `cache_rating`
1582
             WHERE `user_id`='&1'",
1583
            0,
1584
            $this->getUserId()
1585
        );
1586
    }
1587
1588
    public function getRatingParameters()
1589
    {
1590
        global $opt;
1591
1592
        $findsPerRating = $opt['logic']['rating']['findsPerRating'];
1593
        $finds = $this->getStatFound();
1594
        $ratings = $this->getGivenRatings();
1595
1596
        return [
1597
            'maxRatings' => floor($finds / $findsPerRating),
1598
            'givenRatings' => $ratings,
1599
            'findsUntilNextRating' => ($ratings + 1) * $findsPerRating - $finds,
1600
        ];
1601
    }
1602
1603
    public function allowRatings()
1604
    {
1605
        $ratingParams = $this->getRatingParameters();
1606
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