Completed
Push — next ( 5f2bc0...cef70f )
by Thomas
25s queued 12s
created

user::replace_pictures()   F

Complexity

Conditions 53
Paths > 20000

Size

Total Lines 249

Duplication

Lines 49
Ratio 19.68 %

Importance

Changes 0
Metric Value
cc 53
nc 4424256
nop 1
dl 49
loc 249
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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);
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...
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);
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...
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;
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...
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;
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...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
264
    {
265
        if ($value !== null && (sql_value("SELECT COUNT(*) FROM countries WHERE short='&1'", 0, $value) == 0)) {
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...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
278
    {
279
        if ($value !== null && (sql_value("SELECT COUNT(*) FROM languages WHERE short='&1'", 0, $value) == 0)) {
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...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 sql_value(
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...
554
                'SELECT COUNT(*)
555
                 FROM (SELECT cache_id
556
                       FROM cache_logs
557
                       WHERE user_id = "&1"
558
                       AND type = 1
559
                       GROUP BY cache_id
560
                ) as tmp
561
                ',
562
                0,
563
                $this->getUserId()
564
            );
565
        }
566
567
        return 0;
568
    }
569
570
    public function getStatNotFound()
571
    {
572
        if ($this->reUserStat->exist()) {
573
            return $this->reUserStat->getValue('notfound');
574
        }
575
576
        return 0;
577
    }
578
579
    public function getStatNote()
580
    {
581
        if ($this->reUserStat->exist()) {
582
            return $this->reUserStat->getValue('note');
583
        }
584
585
        return 0;
586
    }
587
588
    public function getStatHidden()
589
    {
590
        if ($this->reUserStat->exist()) {
591
            return $this->reUserStat->getValue('hidden');
592
        }
593
594
        return 0;
595
    }
596
597
    public function getDateRegistered()
598
    {
599
        return $this->reUser->getValue('date_created');
600
    }
601
602
    public function getUUID()
603
    {
604
        return $this->reUser->getValue('uuid');
605
    }
606
607
    public function getLastModified()
608
    {
609
        return $this->reUser->getValue('last_modified');
610
    }
611
612
    public function getDateCreated()
613
    {
614
        return $this->reUser->getValue('date_created');
615
    }
616
617
    public function getAdmin()
618
    {
619
        return $this->reUser->getValue('admin');
620
    }
621
622
    public function getNode()
623
    {
624
        return $this->reUser->getValue('node');
625
    }
626
627
    public function setNode($value)
628
    {
629
        return $this->reUser->setValue('node', $value);
630
    }
631
632
    public function getAnyChanged()
633
    {
634
        return $this->reUser->getAnyChanged();
635
    }
636
637
    // return if successful (with insert)
638
    public function save()
639
    {
640
        sql_slave_exclude();
0 ignored issues
show
Deprecated Code introduced by
The function sql_slave_exclude() 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...
641
        if ($this->reUser->save()) {
642
            if ($this->getUserId() == ID_NEW) {
643
                $this->nUserId = $this->reUser->getValue('user_id');
644
            }
645
            $this->getStatpic()->invalidate();
646
647
            return true;
648
        }
649
650
        return false;
651
    }
652
653
    public function getStatpic()
654
    {
655
        return new statpic($this->nUserId);
656
    }
657
658
    public static function createCode()
659
    {
660
        return mb_strtoupper(mb_substr(md5(uniqid('', true)), 0, 13));
661
    }
662
663
    public function requestNewPWCode()
664
    {
665
        global $translate;
666
667
        if (!$this->exist()) {
668
            return false;
669
        }
670
671
        $email = $this->getEMail();
672
        if ($email === null || $email === '') {
673
            return false;
674
        }
675
676
        if (!$this->getIsActive()) {
677
            return false;
678
        }
679
680
        $this->setNewPWCode(self::createCode());
681
        if (!$this->reUser->saveField('new_pw_code')) {
682
            return false;
683
        }
684
685
        $this->setNewPWDate(time());
686
        if (!$this->reUser->saveField('new_pw_date')) {
687
            return false;
688
        }
689
690
        // send confirmation
691
        $mail = new mail();
692
        $mail->name = 'newpw';
693
        $mail->to = $email;
694
        $mail->subject = $translate->t('New password code', '', basename(__FILE__), __LINE__);
695
        $mail->assign('code', $this->getNewPWCode());
696
        $mail->send();
697
698
        return true;
699
    }
700
701
    public function clearNewPWCode()
702
    {
703
        $this->setNewPWCode(null);
704
        if (!$this->reUser->saveField('new_pw_code')) {
705
            return false;
706
        }
707
708
        $this->setNewPWDate(null);
709
        if (!$this->reUser->saveField('new_pw_date')) {
710
            return false;
711
        }
712
713
        return true;
714
    }
715
716
    public function requestNewEMail($email)
717
    {
718
        global $translate;
719
720
        if (!$this->exist()) {
721
            return false;
722
        }
723
724
        $storedEMail = $this->getEMail();
725
726
        if (mb_strtolower($storedEMail) == mb_strtolower($email)) {
727
            return false;
728
        }
729
730
        if ($storedEMail === null || $storedEMail == '') {
731
            return false;
732
        }
733
734
        if (!$this->getIsActive()) {
735
            return false;
736
        }
737
738
        $this->setNewEMailCode(self::createCode());
739
        if (!$this->reUser->saveField('new_email_code')) {
740
            return false;
741
        }
742
743
        $this->setNewEMailDate(time());
744
        if (!$this->reUser->saveField('new_email_date')) {
745
            return false;
746
        }
747
748
        $this->setNewEMail($email);
749
        if (!$this->reUser->saveField('new_email')) {
750
            return false;
751
        }
752
753
        // send confirmation
754
        $mail = new mail();
755
        $mail->name = 'newemail';
756
        $mail->to = $email;
757
        $mail->subject = $translate->t('New email code', '', basename(__FILE__), __LINE__);
758
        $mail->assign('code', $this->getNewEMailCode());
759
        $mail->send();
760
761
        return true;
762
    }
763
764
    public function clearNewEMailCode()
765
    {
766
        $this->setNewEMailCode(null);
767
        if (!$this->reUser->saveField('new_email_code')) {
768
            return false;
769
        }
770
771
        $this->setNewEMailDate(null);
772
        if (!$this->reUser->saveField('new_email_date')) {
773
            return false;
774
        }
775
776
        $this->setNewEMail(null);
777
        if (!$this->reUser->saveField('new_email')) {
778
            return false;
779
        }
780
781
        return true;
782
    }
783
784
    public function remindEMail()
785
    {
786
        global $translate;
787
788
        if (!$this->exist()) {
789
            return false;
790
        }
791
792
        $email = $this->getEMail();
793
        if ($email === null || $email === '') {
794
            return false;
795
        }
796
797
        if (!$this->getIsActive()) {
798
            return false;
799
        }
800
801
        // send confirmation
802
        $mail = new mail();
803
        $mail->name = 'remindemail';
804
        $mail->to = $email;
805
        $mail->subject = $translate->t('Reminder to your E-Mail-Address', '', basename(__FILE__), __LINE__);
806
        $mail->assign('username', $this->getUsername());
807
        $mail->assign('email', $email);
808
        $mail->send();
809
810
        return true;
811
    }
812
813
    public function sendRegistrationCode()
814
    {
815
        global $opt, $translate;
816
817
        $countriesList = new countriesList();
818
819
        $mail = new mail();
820
        $mail->name = 'register';
821
        $mail->to = $this->getEMail();
822
        $mail->subject = $translate->t('Registration confirmation', '', basename(__FILE__), __LINE__);
823
        $mail->assign('domain', $opt['page']['domain']);
824
        $mail->assign('activation_page', $opt['page']['absolute_url'] . 'activation.php');
825
        $mail->assign('short_activation_page', $opt['page']['absolute_url'] . 'a.php');
826
        $mail->assign('username', $this->getUsername());
827
        $mail->assign('userid', $this->getUserId());
828
        $mail->assign('last_name', $this->getLastName());
829
        $mail->assign('first_name', $this->getFirstName());
830
        $mail->assign('country', $countriesList::getCountryLocaleName($this->getCountryCode()));
831
        $mail->assign('code', $this->getActivationCode());
832
833
        if ($mail->send()) {
834
            return true;
835
        }
836
837
        return false;
838
    }
839
840
    public function sendEMail($nFromUserId, $sSubject, $sText, $bSendEMailAddress)
841
    {
842
        global $opt, $translate;
843
844
        if ($this->exist() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
845
            return false;
846
        }
847
848
        if ($this->getIsActive() == false) {
849
            return false;
850
        }
851
852
        if ($this->getEMail() === null || $this->getEMail() == '') {
853
            return false;
854
        }
855
856
        if ($sSubject === '') {
857
            return false;
858
        }
859
860
        if ($sText === '') {
861
            return false;
862
        }
863
864
        if (mb_strpos($sSubject, "\n") !== false) {
865
            $sSubject = mb_substr($sSubject, 0, mb_strpos($sSubject, "\n"));
866
        }
867
        $sSubject = mb_trim($sSubject);
868
869
        $fromUser = new self($nFromUserId);
870
        if ($fromUser->exist() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
871
            return false;
872
        }
873
        if ($fromUser->getIsActive() == false) {
874
            return false;
875
        }
876
        if ($fromUser->getEMail() === null || $fromUser->getEMail() === '') {
877
            return false;
878
        }
879
880
        $language = $this->getLanguageCode();
881
        if (!$language) {
882
            $language = $opt['template']['locale'];
883
        }
884
885
        // ok, we can send ...
886
        $mail = new mail();
887
        $mail->name = 'usercontactmail';
888
        $mail->to = $this->getEMail();
889
        $mail->recipient_locale = $this->getLanguageCode();
890
891
        $mail->from = $opt['mail']['usermail'];
892
893
        if ($bSendEMailAddress == true) {
894
            $mail->replyTo = $fromUser->getEMail();
895
            $mail->returnPath = $fromUser->getEMail();
896
        }
897
898
        $mail->subject = $translate->t('E-Mail from', '', basename(__FILE__), __LINE__, '', 1, $language) . ' ' . $fromUser->getUsername() . ': ' . $sSubject;
899
        $mail->assign('usersubject', $sSubject);
900
        $mail->assign('text', $sText);
901
        $mail->assign('username', $this->getUsername());
902
        $mail->assign('sendemailaddress', $bSendEMailAddress);
903
        $mail->assign('fromusername', $fromUser->getUsername());
904
        $mail->assign('fromuserid', $fromUser->getUserId());
905
        $mail->assign('fromuseremail', $fromUser->getEMail());
906
907
        if ($mail->send($opt['page']['default_absolute_url'])) {
908
            // send copy to fromUser
909
            $mail->assign('copy', true);
910
            $mail->to = $fromUser->getEMail();
911
            $mail->send();
912
913
            // log
914
            sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
915
                "INSERT INTO `email_user` (`ipaddress`, `from_user_id`, `from_email`, `to_user_id`, `to_email`)
916
                 VALUES ('&1', '&2', '&3', '&4', '&5')",
917
                $_SERVER['REMOTE_ADDR'],
918
                $fromUser->getUserId(),
919
                $fromUser->getEMail(),
920
                $this->getUserId(),
921
                $this->getEMail()
922
            );
923
924
            return true;
925
        }
926
927
        return false;
928
    }
929
930 View Code Duplication
    public function canDisable()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
931
    {
932
        global $login;
933
        $login->verify();
934
935
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
936
            return false;
937
        }
938
939
        if ($this->getIsActive() != 0) {
940
            return true;
941
        }
942
943
        return false;
944
    }
945
946
    public function disable()
947
    {
948
        global $login, $translate;
949
950
        if ($this->canDisable() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
951
            return false;
952
        }
953
954
        // write old record to log
955
        $backup = array();
956
        $backup['username'] = $this->getUsername();
957
        $backup['email'] = $this->getEMail();
958
        $backup['last_name'] = $this->getLastName();
959
        $backup['first_name'] = $this->getFirstName();
960
        $backup['country'] = $this->getCountryCode();
961
        $backup['latitude'] = $this->getLatitude();
962
        $backup['longitude'] = $this->getLongitude();
963
964
        sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
965
            "INSERT INTO `logentries` (`module`, `eventid`, `userid`, `objectid1`, `objectid2`, `logtext`, `details`)
966
             VALUES ('user', 6, '&1', '&2', '&3', '&4', '&5')",
967
            $login->userid,
968
            $this->nUserId,
969
            0,
970
            'User ' . sql_escape($this->getUsername()) . ' disabled',
0 ignored issues
show
Deprecated Code introduced by
The function sql_escape() 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...
971
            serialize($backup)
972
        );
973
974
        // delete private and system data
975
        sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
976
            "UPDATE `user` SET `password`=NULL, `email`=NULL, `last_name`='', `first_name`='',
977
                               `country`=NULL, `latitude`=0, `longitude`=0, `is_active_flag`=0, `activation_code`='',
978
                               `new_pw_code`=NULL, `new_pw_date`=NULL, `new_email`=NULL, `new_email_code`=NULL,
979
                               `new_email_date`=NULL, `email_problems`=0, `first_email_problem`=NULL,
980
                               `last_email_problem`=NULL
981
             WHERE `user_id`='&1'",
982
            $this->nUserId
983
        );
984
985
        // non-private data which need not to be deleted:
986
        //
987
        //   - Statpic and profile description texts - published under the data license
988
        //   - profile settings: accept_mailing, pmr_flag, permanent_login_flag, notify_radius,
989
        //                       user_options entries
990
        //   - watch and ignore lists
991
        //   - adoptions: may still be executed if offered to another user
992
993
        // Handling of cache lists is unclear. They may be deleted by the Opencaching team
994
        // if not considered useful.
995
996
        // lock the user's caches
997
        $error = false;
998
        $rs = sql("SELECT `cache_id` FROM `caches` WHERE `user_id`='&1' AND `status` IN (1,2,3)", $this->nUserId);
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
999
        while (($rCache = sql_fetch_assoc($rs)) && !$error) {
0 ignored issues
show
Deprecated Code introduced by
The function sql_fetch_assoc() 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...
1000
            $error = true;
1001
            $cache = new cache($rCache['cache_id']);
1002
            if ($cache->setStatus(6) && $cache->save()) {
1003
                $log = cachelog::createNew($rCache['cache_id'], $login->userid);
1004
                if ($log !== false) {
1005
                    $log->setType(cachelog::LOGTYPE_LOCKED, true);
1006
                    $log->setOcTeamComment(true);
1007
                    $log->setDate(date('Y-m-d'));
1008
                    $log->setText($translate->t(
1009
                        'The user account has been disabled.',
1010
                        '',
1011
                        '',
1012
                        0,
1013
                        '',
1014
                        1,
1015
                        $cache->getDefaultDescLanguage()
1016
                    ));
1017
                    $log->setTextHtml(false);
1018
                    if ($log->save()) {
1019
                        $error = false;
1020
                    }
1021
                }
1022
            }
1023
            echo "\n";
1024
        }
1025
        sql_free_result($rs);
0 ignored issues
show
Deprecated Code introduced by
The function sql_free_result() 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...
1026
1027
        return !$error;
1028
    }
1029
1030 View Code Duplication
    public function canDisableDueLicense()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1031
    {
1032
        global $login;
1033
        $login->verify();
1034
1035
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
1036
            return false;
1037
        }
1038
1039
        return true;
1040
    }
1041
1042
    /**
1043
     * disables user (if not disabled), removes all licensed content from db and
1044
     * replaces every picture with a dummy one
1045
     *
1046
     * @param bool $old_disabled
1047
     * @return string error message, if anything went wrong, true otherwise
1048
     * old_disabled: the user was disabled already before license transition
1049
     * and therefore could not accept/decline the license
1050
     */
1051
    public function disduelicense($old_disabled = false)
1052
    {
1053
1054
        // get translation-object
1055
        global $translate;
1056
1057
        // check if disabled, disable if not
1058
        if (!$this->canDisableDueLicense()) {
1059
            return 'this user must not be disabled';
1060
        }
1061
1062
        if (!$old_disabled) {
1063
            if ($this->canDisable()) {
1064
                if (!$this->disable()) {
1065
                    return 'disable user failed';
1066
                }
1067
            }
1068
        }
1069
1070
        // remember that data license was declined
1071
        sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1072
            "UPDATE user SET data_license='&2' WHERE user_id='&1'",
1073
            $this->getUserId(),
1074
            $old_disabled ? NEW_DATA_LICENSE_PASSIVELY_DECLINED : NEW_DATA_LICENSE_ACTIVELY_DECLINED
1075
        );
1076
1077
        /*
1078
         * set all cache_desc and hint to '', save old texts
1079
         */
1080
        // check if there are caches
1081
        $num_caches = sql_value(
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...
1082
            "SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'",
1083
            0,
1084
            $this->getUserId()
1085
        );
1086
        if ($num_caches > 0) {
1087
            $cache_descs = array();
1088
            $rs = sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1089
                'SELECT `id`, `language`, `desc`, `hint` ' .
1090
                'FROM `cache_desc`,`caches` ' .
1091
                'WHERE `caches`.`cache_id`=`cache_desc`.`cache_id` ' .
1092
                "AND `caches`.`user_id`='&1'",
1093
                $this->getUserId()
1094
            );
1095
            while ($cache_desc = sql_fetch_array($rs, MYSQLI_ASSOC)) {
0 ignored issues
show
Documentation introduced by
$rs is of type object<mysqli_result>, but the function expects a resource.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to sql_fetch_array() has too many arguments starting with MYSQLI_ASSOC.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Deprecated Code introduced by
The function sql_fetch_array() 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...
1096
                $cache_descs[] = $cache_desc;
1097
            }
1098
            sql_free_result($rs);
0 ignored issues
show
Deprecated Code introduced by
The function sql_free_result() 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...
1099
1100
            // walk through cache_descs and set message for each language
1101
            foreach ($cache_descs as $desc) {
1102
                // save text - added 2013/03/18 to be enable restoring data on reactivation
1103
                // of accounts that were disabled before license transition
1104 View Code Duplication
                if ($desc['desc'] != '') {
1105
                    sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
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
                        1,
1111
                        $desc['desc']
1112
                    );
1113
                }
1114 View Code Duplication
                if ($desc['hint'] != '') {
1115
                    sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1116
                        "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1117
                         VALUES ('&1', '&2', '&3', '&4')",
1118
                        OBJECT_CACHEDESC,
1119
                        $desc['id'],
1120
                        2,
1121
                        $desc['hint']
1122
                    );
1123
                }
1124
1125
                if ($desc['desc'] != '') {
1126
                    if ($old_disabled) {
1127
                        $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']);
1128
                    } else {
1129
                        $descmsg = $translate->t('cache description was removed because owner declined content license', '', basename(__FILE__), __LINE__, '', 1, $desc['language']);
1130
                    }
1131
                } else {
1132
                    $descmsg = '';
1133
                }
1134
1135
                sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1136
                    'UPDATE `cache_desc` ' .
1137
                    "SET `desc`='&1',`hint`='&2' " .
1138
                    "WHERE `id`='&3'",
1139
                    '<em>' . $descmsg . '</em>',
1140
                    '',
1141
                    $desc['id']
1142
                );
1143
            }
1144
1145
            // replace pictures
1146
            $errmesg = $this->replace_pictures(OBJECT_CACHE);
1147
            if ($errmesg !== true) {
1148
                return "removing cache pictures: $errmesg";
1149
            }
1150
        }
1151
1152
        // delete additional waypoint texts
1153
        $rs = sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1154
            "SELECT `id`, `description` FROM `coordinates`
1155
             WHERE `type`='&1'
1156
             AND `cache_id` IN (SELECT `cache_id` FROM `caches` WHERE `user_id`='&2')",
1157
            COORDINATE_WAYPOINT,
1158
            $this->getUserId()
1159
        );
1160
        while ($wp = sql_fetch_assoc($rs)) {
0 ignored issues
show
Deprecated Code introduced by
The function sql_fetch_assoc() 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...
1161
            if ($wp['description'] != '') {
1162
                sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1163
                    "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1164
                     VALUES ('&1', '&2', '&3', '&4')",
1165
                    OBJECT_WAYPOINT,
1166
                    $wp['id'],
1167
                    0,
1168
                    $wp['description']
1169
                );
1170
            }
1171
1172
            sql("UPDATE `coordinates` SET `description`='' WHERE `id`='&1'", $wp['id']);
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1173
        }
1174
        sql_free_result($rs);
0 ignored issues
show
Deprecated Code introduced by
The function sql_free_result() 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...
1175
1176
        /*
1177
         * set all cache_logs '', save old texts and delete pictures
1178
         */
1179
        $rs = sql("SELECT `id`, `text` FROM `cache_logs` WHERE `user_id`='&1'", $this->getUserId());
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1180
        while ($log = sql_fetch_array($rs, MYSQLI_ASSOC)) {
0 ignored issues
show
Documentation introduced by
$rs is of type object<mysqli_result>, but the function expects a resource.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to sql_fetch_array() has too many arguments starting with MYSQLI_ASSOC.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Deprecated Code introduced by
The function sql_fetch_array() 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...
1181
            // save text - added 2013/03/18 to be enable restoring data on reactivation
1182
            // of accounts that were disabled before license transition
1183
            sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1184
                "INSERT IGNORE INTO `saved_texts` (`object_type`, `object_id`, `subtype`, `text`)
1185
                 VALUES ('&1', '&2', '&3', '&4')",
1186
                OBJECT_CACHELOG,
1187
                $log['id'],
1188
                0,
1189
                $log['text']
1190
            );
1191
1192
            // set text ''
1193
            sql("UPDATE `cache_logs` SET `text`='' WHERE `id`='&1'", $log['id']);
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1194
1195
            /*
1196
            // replace pictures
1197
            $errmesg = $this->replace_pictures(OBJECT_CACHELOG);
1198
            if ($errmesg !== true)
1199
                return "removing log pictures: $errmesg";
1200
            */
1201
1202
            // delete log pictures
1203
            $rsp = sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1204
                "SELECT `id` FROM `pictures`
1205
                 WHERE `object_type`='&1' AND `object_id`='&2'",
1206
                OBJECT_CACHELOG,
1207
                $log['id']
1208
            );
1209
            while ($pic = sql_fetch_assoc($rsp)) {
0 ignored issues
show
Deprecated Code introduced by
The function sql_fetch_assoc() 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...
1210
                $picture = new picture($pic['id']);
1211
                $picture->delete();
1212
            }
1213
            sql_free_result($rsp);
0 ignored issues
show
Deprecated Code introduced by
The function sql_free_result() 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...
1214
        }
1215
        sql_free_result($rs);
0 ignored issues
show
Deprecated Code introduced by
The function sql_free_result() 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...
1216
1217
        // discard achived logs' texts
1218
        sql("UPDATE `cache_logs_archived` SET `text`='' WHERE `user_id`='&1'", $this->getUserId());
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1219
1220
        // success
1221
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return true; (boolean) is incompatible with the return type documented by user::disduelicense of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1222
    }
1223
1224
    /**
1225
     * replaces all pictures of $this-user with a dummy for the given object-type
1226
     *
1227
     * @param int $object_type object_types-id from table object_types
1228
     *
1229
     * @return bool true, if replacement worked, false otherwise
1230
     */
1231
    public function replace_pictures($object_type)
1232
    {
1233
        // get optionsarray
1234
        global $opt;
1235
1236
        // load bmp-support
1237
        require_once __DIR__ . '/../imagebmp.inc.php';
1238
1239
        // paths cleared by trailing '/'
1240
        if (substr($opt['logic']['pictures']['dir'], - 1) != '/') {
1241
            $picpath = $opt['logic']['pictures']['dir'];
1242
        } else {
1243
            $picpath = substr($opt['logic']['pictures']['dir'], 0, - 1);
1244
        }
1245
1246
        $thumbpath = "$picpath/thumbs";
1247
1248
        $pdummy = isset($opt['logic']['pictures']['dummy']);
1249 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['bgcolor']) && is_array($opt['logic']['pictures']['dummy']['bgcolor'])) {
1250
            $dummybg = $opt['logic']['pictures']['dummy']['bgcolor'];
1251
        } else {
1252
            $dummybg = [
1253
                255,
1254
                255,
1255
                255,
1256
            ];
1257
        }
1258
1259 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['text'])) {
1260
            $dummytext = $opt['logic']['pictures']['dummy']['text'];
1261
        } else {
1262
            $dummytext = '';
1263
        }
1264
1265 View Code Duplication
        if ($pdummy && isset($opt['logic']['pictures']['dummy']['textcolor']) && is_array($opt['logic']['pictures']['dummy']['textcolor'])) {
1266
            $dummytextcolor = $opt['logic']['pictures']['dummy']['textcolor'];
1267
        } else {
1268
            $dummytextcolor = array(
1269
                0,
1270
                0,
1271
                0,
1272
            );
1273
        }
1274
1275
        $tmh = 0;
0 ignored issues
show
Unused Code introduced by
$tmh is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1276
        $tmw = 0;
0 ignored issues
show
Unused Code introduced by
$tmw is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1277
1278
        /*
1279
         * check log or cache
1280
         */
1281
        if ($object_type == OBJECT_CACHE) {
1282
            // get filenames of the pictures of $this' caches
1283
            $rs = sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1284
                'SELECT `pictures`.`url` ' .
1285
                'FROM `pictures`,`caches` ' .
1286
                'WHERE `caches`.`cache_id`=`pictures`.`object_id`' .
1287
                " AND `pictures`.`object_type`='&1' AND `caches`.`user_id`='&2'",
1288
                OBJECT_CACHE,
1289
                $this->getUserId()
1290
            );
1291
        } elseif ($object_type == OBJECT_CACHELOG) {
1292
            // get filenames of the pictures of $this' logs
1293
            $rs = sql(
0 ignored issues
show
Deprecated Code introduced by
The function sql() 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...
1294
                'SELECT `pictures`.`url` ' .
1295
                'FROM `pictures`,`cache_logs` ' .
1296
                'WHERE `cache_logs`.`id`=`pictures`.`object_id`' .
1297
                " AND `pictures`.`object_type`='&1' AND `cache_logs`.`user_id`='&2'",
1298
                OBJECT_CACHELOG,
1299
                $this->getUserId()
1300
            );
1301
        }
1302
1303
        // set thumb-dimensions
1304
        $tmh = $opt['logic']['pictures']['thumb_max_height'];
1305
        $tmw = $opt['logic']['pictures']['thumb_max_width'];
1306
1307
        $filenames = array();
1308
        while ($url = sql_fetch_array($rs, MYSQLI_NUM)) {
0 ignored issues
show
Bug introduced by
The variable $rs does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Documentation introduced by
$rs is of type object<mysqli_result>, but the function expects a resource.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to sql_fetch_array() has too many arguments starting with MYSQLI_NUM.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Deprecated Code introduced by
The function sql_fetch_array() 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...
1309
            $filenames[] = substr($url['url'], - 40);
1310
        }
1311
1312
        // free result
1313
        sql_free_result($rs);
0 ignored issues
show
Deprecated Code introduced by
The function sql_free_result() 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...
1314
1315
        /*
1316
         * walk through filenames and replace original
1317
         */
1318
        // check if there is something to replace
1319
        if (count($filenames) > 0) {
1320
            foreach ($filenames as $fn) {
1321
                // get uuid and extension
1322
                $uuid = substr($fn, 0, 36);
1323
                $ext = substr($fn, - 3);
1324
                $thumb_dir1 = substr($uuid, 0, 1);
1325
                $thumb_dir2 = substr($uuid, 1, 1);
1326
1327
                // read original size
1328
                if (file_exists("$picpath/$fn")) {
1329
                    list($w, $h, $t, $attr) = getimagesize("$picpath/$fn");
0 ignored issues
show
Unused Code introduced by
The assignment to $t is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $attr is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
1330
                } else {
1331
                    $w = 600;
1332
                    $h = 480;
1333
                }
1334
1335
                // create new image
1336
                $im = imagecreatetruecolor($w, $h);
1337
                // allocate colors
1338
                $col_bg = imagecolorallocate($im, $dummybg[0], $dummybg[1], $dummybg[2]);
1339
                $col_text = imagecolorallocate($im, $dummytextcolor[0], $dummytextcolor[1], $dummytextcolor[2]);
1340
1341
                // fill bg
1342
                imagefill($im, 0, 0, $col_bg);
1343
1344
                // check for replacement-image
1345
                if ($pdummy && isset($opt['logic']['pictures']['dummy']['replacepic'])
1346
                    && $opt['logic']['pictures']['dummy']['replacepic'] != $opt['rootpath'] . 'images/'
1347
                    && file_exists($opt['logic']['pictures']['dummy']['replacepic'])
1348
                ) {
1349
                    // get dimensions of the replacement
1350
                    list($rw, $rh, $rt, $rattr) = getimagesize($opt['logic']['pictures']['dummy']['replacepic']);
0 ignored issues
show
Unused Code introduced by
The assignment to $rt is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $rattr is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
1351
                    $rwh = 0;
0 ignored issues
show
Unused Code introduced by
$rwh is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1352
                    if ($rw > $rh) {
1353
                        $rwh = $rh;
1354
                    } else {
1355
                        $rwh = $rw;
1356
                    }
1357
1358
                    // check dimensions of original and set replacement size
1359
                    $rsize = 0;
0 ignored issues
show
Unused Code introduced by
$rsize is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1360
                    if ($w > $h) {
1361
                        if (($h * 0.85) > $rwh) {
1362
                            $rsize = $rwh;
1363
                        } else {
1364
                            $rsize = $h * 0.9;
1365
                        }
1366
                    } else {
1367
                        if (($w * 0.85) > $rwh) {
1368
                            $rsize = $rwh;
1369
                        } else {
1370
                            $rsize = $w * 0.9;
1371
                        }
1372
                    }
1373
                    $dx = ($w - $rsize) / 2;
1374
                    $dy = ($h - $rsize) / 2;
1375
1376
                    // get replacement image
1377
                    $rext = substr($opt['logic']['pictures']['dummy']['replacepic'], - 3);
1378
                    $rim = null;
1379
                    if ($rext == 'jpg') {
1380
                        $rim = imagecreatefromjpeg($opt['logic']['pictures']['dummy']['replacepic']);
1381 View Code Duplication
                    } elseif ($rext == 'png') {
1382
                        $rim = imagecreatefrompng($opt['logic']['pictures']['dummy']['replacepic']);
1383
                    } elseif ($rext == 'gif') {
1384
                        $rim = imagecreatefromgif($opt['logic']['pictures']['dummy']['replacepic']);
1385 View Code Duplication
                    } elseif ($rext == 'bmp') {
1386
                        $rim = imagecreatefrombmp($opt['logic']['pictures']['dummy']['replacepic']);
1387
                    }
1388
1389
                    // copy image
1390
                    if (null !== $rim) {
1391
                        imagecopyresampled($im, $rim, $dx, $dy, 0, 0, $rsize, $rsize, $rw, $rh);
1392
                    }
1393
                } else {
1394
                    // set text
1395
                    if ($dummytext != '') {
1396
                        imagestring($im, 1, 10, $h / 2, $dummytext, $col_text);
1397
                    } else {
1398
                        imageline($im, 0, 0, $w, $h, 0xff0000);
1399
                        imageline($im, 0, $h, $w, 0, 0xff0000);
1400
                    }
1401
                }
1402
1403
                // save dummy
1404
                if ($ext == 'jpg') {
1405
                    if (!imagejpeg($im, "$picpath/$fn", 75)) {
1406
                        return "save dummy failed [$ext]";
1407
                    }
1408
                } elseif ($ext == 'png') {
1409
                    if (!imagepng($im, "$picpath/$fn", 4)) {
1410
                        return "save dummy failed [$ext]";
1411
                    }
1412
                } elseif ($ext == 'gif') {
1413
                    if (!imagegif($im, "$picpath/$fn")) {
1414
                        return "save dummy failed [$ext]";
1415
                    }
1416
                } elseif ($ext == 'bmp') {
1417
                    if (!imagebmp($im, "$picpath/$fn")) {
1418
                        return "save dummy failed [$ext]";
1419
                    }
1420
                } else {
1421
                    return "save dummy failed [$ext], unknown extension";
1422
                }
1423
1424
                // set thumb-dimensions
1425
                if (($h > $tmh) || ($w > $tmw)) {
1426
                    if ($h > $w) {
1427
                        $th = $tmh;
1428
                        $tw = $w * ($th / $h);
1429
                    } else {
1430
                        $tw = $tmw;
1431
                        $th = $h * ($tw / $w);
1432
                    }
1433
                } else {
1434
                    $tw = $w;
1435
                    $th = $h;
1436
                }
1437
1438
                // copy dummy
1439
                $tim = imagecreatetruecolor($tw, $th);
1440
                imagecopyresampled($tim, $im, 0, 0, 0, 0, $tw, $th, $w, $h);
1441
1442
                // check directories or create them
1443 View Code Duplication
                if (!file_exists("$thumbpath/$thumb_dir1")) {
1444
                    if (!mkdir("$thumbpath/$thumb_dir1")) {
1445
                        return 'mkdir in thumbpath failed';
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'mkdir in thumbpath failed'; (string) is incompatible with the return type documented by user::replace_pictures of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1446
                    }
1447
                }
1448 View Code Duplication
                if (!file_exists("$thumbpath/$thumb_dir1/$thumb_dir2")) {
1449
                    if (!mkdir("$thumbpath/$thumb_dir1/$thumb_dir2")) {
1450
                        return 'mkdir in thumbpath failed';
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'mkdir in thumbpath failed'; (string) is incompatible with the return type documented by user::replace_pictures of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1451
                    }
1452
                }
1453
1454
                // save thumb
1455
                if ($ext == 'jpg') {
1456
                    if (!imagejpeg($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn", 75)) {
1457
                        return "save thumb failed [$ext]";
1458
                    }
1459 View Code Duplication
                } elseif ($ext == 'png') {
1460
                    if (!imagepng($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn", 4)) {
1461
                        return "save thumb failed [$ext]";
1462
                    }
1463
                } elseif ($ext == 'gif') {
1464
                    if (!imagegif($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn")) {
1465
                        return "save thumb failed [$ext]";
1466
                    }
1467 View Code Duplication
                } elseif ($ext == 'bmp') {
1468
                    if (!imagebmp($tim, "$thumbpath/$thumb_dir1/$thumb_dir2/$fn")) {
1469
                        return "save thumb failed [$ext]";
1470
                    }
1471
                } else {
1472
                    return "save thumb failed [$ext], unknown extension";
1473
                }
1474
            }
1475
        }
1476
1477
        // success
1478
        return true;
1479
    }
1480
1481
    public function canGdprDelete(): bool
1482
    {
1483
        global $login;
1484
        $login->verify();
1485
1486
        return !($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER);
1487
    }
1488
1489
    public function canDelete()
1490
    {
1491
        global $login;
1492
        $login->verify();
1493
1494
        if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER) {
1495
            return false;
1496
        }
1497
1498
        return
1499
            sql_value("SELECT COUNT(*) FROM `caches` 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...
1500
            + sql_value("SELECT COUNT(*) FROM `cache_logs` 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...
1501
            + 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...
1502
            + 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...
1503
            == 0;
1504
    }
1505
1506
    public function delete()
1507
    {
1508
        global $login;
1509
1510
        if ($this->canDelete() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

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

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1681
                }
1682
            }
1683
        }
1684
1685
        return $language;
1686
    }
1687
}
1688