auth_plugin_authpdo   F
last analyzed

Complexity

Total Complexity 133

Size/Duplication

Total Lines 813
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 813
rs 1.787
c 0
b 0
f 0
wmc 133
lcom 1
cbo 2

21 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 128 4
A checkPass() 0 25 5
A getUserData() 0 15 6
B createUser() 0 51 10
F modifyUser() 0 83 23
A deleteUsers() 0 8 3
B retrieveUsers() 0 33 10
B getUserCount() 0 19 7
A addGroup() 0 9 2
A retrieveGroups() 0 11 3
B selectUser() 0 35 10
A deleteUser() 0 25 5
A selectUserGroups() 0 24 5
B selectGroups() 0 27 6
A clearGroupCache() 0 4 1
A joinGroup() 0 8 2
A leaveGroup() 0 8 2
C query() 0 61 13
A debugMsg() 0 17 5
A checkConfig() 0 17 5
A debugSQL() 0 17 6

How to fix   Complexity   

Complex Class

Complex classes like auth_plugin_authpdo often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use auth_plugin_authpdo, and based on these observations, apply Extract Interface, too.

1
<?php
2
use dokuwiki\Utf8\Sort;
3
4
/**
5
 * DokuWiki Plugin authpdo (Auth Component)
6
 *
7
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
8
 * @author  Andreas Gohr <[email protected]>
9
 */
10
11
/**
12
 * Class auth_plugin_authpdo
13
 */
14
class auth_plugin_authpdo extends DokuWiki_Auth_Plugin
15
{
16
17
    /** @var PDO */
18
    protected $pdo;
19
20
    /** @var null|array The list of all groups */
21
    protected $groupcache = null;
22
23
    /**
24
     * Constructor.
25
     */
26
    public function __construct()
27
    {
28
        parent::__construct(); // for compatibility
29
30
        if (!class_exists('PDO')) {
31
            $this->debugMsg('PDO extension for PHP not found.', -1, __LINE__);
32
            $this->success = false;
33
            return;
34
        }
35
36
        if (!$this->getConf('dsn')) {
37
            $this->debugMsg('No DSN specified', -1, __LINE__);
38
            $this->success = false;
39
            return;
40
        }
41
42
        try {
43
            $this->pdo = new PDO(
44
                $this->getConf('dsn'),
45
                $this->getConf('user'),
46
                conf_decodeString($this->getConf('pass')),
47
                array(
48
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // always fetch as array
49
                    PDO::ATTR_EMULATE_PREPARES => true, // emulating prepares allows us to reuse param names
50
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes
51
                )
52
            );
53
        } catch (PDOException $e) {
54
            $this->debugMsg($e);
55
            msg($this->getLang('connectfail'), -1);
56
            $this->success = false;
57
            return;
58
        }
59
60
        // can Users be created?
61
        $this->cando['addUser'] = $this->checkConfig(
62
            array(
63
                'select-user',
64
                'select-user-groups',
65
                'select-groups',
66
                'insert-user',
67
                'insert-group',
68
                'join-group'
69
            )
70
        );
71
72
        // can Users be deleted?
73
        $this->cando['delUser'] = $this->checkConfig(
74
            array(
75
                'select-user',
76
                'select-user-groups',
77
                'select-groups',
78
                'leave-group',
79
                'delete-user'
80
            )
81
        );
82
83
        // can login names be changed?
84
        $this->cando['modLogin'] = $this->checkConfig(
85
            array(
86
                'select-user',
87
                'select-user-groups',
88
                'update-user-login'
89
            )
90
        );
91
92
        // can passwords be changed?
93
        $this->cando['modPass'] = $this->checkConfig(
94
            array(
95
                'select-user',
96
                'select-user-groups',
97
                'update-user-pass'
98
            )
99
        );
100
101
        // can real names be changed?
102
        $this->cando['modName'] = $this->checkConfig(
103
            array(
104
                'select-user',
105
                'select-user-groups',
106
                'update-user-info:name'
107
            )
108
        );
109
110
        // can real email be changed?
111
        $this->cando['modMail'] = $this->checkConfig(
112
            array(
113
                'select-user',
114
                'select-user-groups',
115
                'update-user-info:mail'
116
            )
117
        );
118
119
        // can groups be changed?
120
        $this->cando['modGroups'] = $this->checkConfig(
121
            array(
122
                'select-user',
123
                'select-user-groups',
124
                'select-groups',
125
                'leave-group',
126
                'join-group',
127
                'insert-group'
128
            )
129
        );
130
131
        // can a filtered list of users be retrieved?
132
        $this->cando['getUsers'] = $this->checkConfig(
133
            array(
134
                'list-users'
135
            )
136
        );
137
138
        // can the number of users be retrieved?
139
        $this->cando['getUserCount'] = $this->checkConfig(
140
            array(
141
                'count-users'
142
            )
143
        );
144
145
        // can a list of available groups be retrieved?
146
        $this->cando['getGroups'] = $this->checkConfig(
147
            array(
148
                'select-groups'
149
            )
150
        );
151
152
        $this->success = true;
153
    }
154
155
    /**
156
     * Check user+password
157
     *
158
     * @param string $user the user name
159
     * @param string $pass the clear text password
160
     * @return  bool
161
     */
162
    public function checkPass($user, $pass)
163
    {
164
165
        $userdata = $this->selectUser($user);
166
        if ($userdata == false) return false;
167
168
        // password checking done in SQL?
169
        if ($this->checkConfig(array('check-pass'))) {
170
            $userdata['clear'] = $pass;
171
            $userdata['hash'] = auth_cryptPassword($pass);
172
            $result = $this->query($this->getConf('check-pass'), $userdata);
173
            if ($result === false) return false;
174
            return (count($result) == 1);
175
        }
176
177
        // we do password checking on our own
178
        if (isset($userdata['hash'])) {
179
            // hashed password
180
            $passhash = new \dokuwiki\PassHash();
181
            return $passhash->verify_hash($pass, $userdata['hash']);
182
        } else {
183
            // clear text password in the database O_o
184
            return ($pass === $userdata['clear']);
185
        }
186
    }
187
188
    /**
189
     * Return user info
190
     *
191
     * Returns info about the given user needs to contain
192
     * at least these fields:
193
     *
194
     * name string  full name of the user
195
     * mail string  email addres of the user
196
     * grps array   list of groups the user is in
197
     *
198
     * @param string $user the user name
199
     * @param bool $requireGroups whether or not the returned data must include groups
200
     * @return array|bool containing user data or false
201
     */
202
    public function getUserData($user, $requireGroups = true)
203
    {
204
        $data = $this->selectUser($user);
205
        if ($data == false) return false;
206
207
        if (isset($data['hash'])) unset($data['hash']);
208
        if (isset($data['clean'])) unset($data['clean']);
209
210
        if ($requireGroups) {
211
            $data['grps'] = $this->selectUserGroups($data);
212
            if ($data['grps'] === false) return false;
213
        }
214
215
        return $data;
216
    }
217
218
    /**
219
     * Create a new User [implement only where required/possible]
220
     *
221
     * Returns false if the user already exists, null when an error
222
     * occurred and true if everything went well.
223
     *
224
     * The new user HAS TO be added to the default group by this
225
     * function!
226
     *
227
     * Set addUser capability when implemented
228
     *
229
     * @param string $user
230
     * @param string $clear
231
     * @param string $name
232
     * @param string $mail
233
     * @param null|array $grps
234
     * @return bool|null
235
     */
236
    public function createUser($user, $clear, $name, $mail, $grps = null)
237
    {
238
        global $conf;
239
240
        if (($info = $this->getUserData($user, false)) !== false) {
241
            msg($this->getLang('userexists'), -1);
242
            return false; // user already exists
243
        }
244
245
        // prepare data
246
        if ($grps == null) $grps = array();
247
        array_unshift($grps, $conf['defaultgroup']);
248
        $grps = array_unique($grps);
249
        $hash = auth_cryptPassword($clear);
250
        $userdata = compact('user', 'clear', 'hash', 'name', 'mail');
251
252
        // action protected by transaction
253
        $this->pdo->beginTransaction();
254
        {
255
            // insert the user
256
            $ok = $this->query($this->getConf('insert-user'), $userdata);
257
            if ($ok === false) goto FAIL;
258
            $userdata = $this->getUserData($user, false);
259
            if ($userdata === false) goto FAIL;
260
261
            // create all groups that do not exist, the refetch the groups
262
            $allgroups = $this->selectGroups();
263
            foreach ($grps as $group) {
264
                if (!isset($allgroups[$group])) {
265
                    $ok = $this->addGroup($group);
266
                    if ($ok === false) goto FAIL;
267
                }
268
            }
269
            $allgroups = $this->selectGroups();
270
271
            // add user to the groups
272
            foreach ($grps as $group) {
273
                $ok = $this->joinGroup($userdata, $allgroups[$group]);
274
                if ($ok === false) goto FAIL;
275
            }
276
        }
277
        $this->pdo->commit();
278
        return true;
279
280
        // something went wrong, rollback
281
        FAIL:
282
        $this->pdo->rollBack();
283
        $this->debugMsg('Transaction rolled back', 0, __LINE__);
284
        msg($this->getLang('writefail'), -1);
285
        return null; // return error
286
    }
287
288
    /**
289
     * Modify user data
290
     *
291
     * @param string $user nick of the user to be changed
292
     * @param array $changes array of field/value pairs to be changed (password will be clear text)
293
     * @return  bool
294
     */
295
    public function modifyUser($user, $changes)
296
    {
297
        // secure everything in transaction
298
        $this->pdo->beginTransaction();
299
        {
300
            $olddata = $this->getUserData($user);
301
            $oldgroups = $olddata['grps'];
302
            unset($olddata['grps']);
303
304
            // changing the user name?
305
            if (isset($changes['user'])) {
306
                if ($this->getUserData($changes['user'], false)) goto FAIL;
307
                $params = $olddata;
308
                $params['newlogin'] = $changes['user'];
309
310
                $ok = $this->query($this->getConf('update-user-login'), $params);
311
                if ($ok === false) goto FAIL;
312
            }
313
314
            // changing the password?
315
            if (isset($changes['pass'])) {
316
                $params = $olddata;
317
                $params['clear'] = $changes['pass'];
318
                $params['hash'] = auth_cryptPassword($changes['pass']);
319
320
                $ok = $this->query($this->getConf('update-user-pass'), $params);
321
                if ($ok === false) goto FAIL;
322
            }
323
324
            // changing info?
325
            if (isset($changes['mail']) || isset($changes['name'])) {
326
                $params = $olddata;
327
                if (isset($changes['mail'])) $params['mail'] = $changes['mail'];
328
                if (isset($changes['name'])) $params['name'] = $changes['name'];
329
330
                $ok = $this->query($this->getConf('update-user-info'), $params);
331
                if ($ok === false) goto FAIL;
332
            }
333
334
            // changing groups?
335
            if (isset($changes['grps'])) {
336
                $allgroups = $this->selectGroups();
337
338
                // remove membership for previous groups
339
                foreach ($oldgroups as $group) {
340
                    if (!in_array($group, $changes['grps']) && isset($allgroups[$group])) {
341
                        $ok = $this->leaveGroup($olddata, $allgroups[$group]);
342
                        if ($ok === false) goto FAIL;
343
                    }
344
                }
345
346
                // create all new groups that are missing
347
                $added = 0;
348
                foreach ($changes['grps'] as $group) {
349
                    if (!isset($allgroups[$group])) {
350
                        $ok = $this->addGroup($group);
351
                        if ($ok === false) goto FAIL;
352
                        $added++;
353
                    }
354
                }
355
                // reload group info
356
                if ($added > 0) $allgroups = $this->selectGroups();
357
358
                // add membership for new groups
359
                foreach ($changes['grps'] as $group) {
360
                    if (!in_array($group, $oldgroups)) {
361
                        $ok = $this->joinGroup($olddata, $allgroups[$group]);
362
                        if ($ok === false) goto FAIL;
363
                    }
364
                }
365
            }
366
367
        }
368
        $this->pdo->commit();
369
        return true;
370
371
        // something went wrong, rollback
372
        FAIL:
373
        $this->pdo->rollBack();
374
        $this->debugMsg('Transaction rolled back', 0, __LINE__);
375
        msg($this->getLang('writefail'), -1);
376
        return false; // return error
377
    }
378
379
    /**
380
     * Delete one or more users
381
     *
382
     * Set delUser capability when implemented
383
     *
384
     * @param array $users
385
     * @return  int    number of users deleted
386
     */
387
    public function deleteUsers($users)
388
    {
389
        $count = 0;
390
        foreach ($users as $user) {
391
            if ($this->deleteUser($user)) $count++;
392
        }
393
        return $count;
394
    }
395
396
    /**
397
     * Bulk retrieval of user data [implement only where required/possible]
398
     *
399
     * Set getUsers capability when implemented
400
     *
401
     * @param int $start index of first user to be returned
402
     * @param int $limit max number of users to be returned
403
     * @param array $filter array of field/pattern pairs, null for no filter
404
     * @return  array list of userinfo (refer getUserData for internal userinfo details)
405
     */
406
    public function retrieveUsers($start = 0, $limit = -1, $filter = null)
407
    {
408
        if ($limit < 0) $limit = 10000; // we don't support no limit
409
        if (is_null($filter)) $filter = array();
410
411
        if (isset($filter['grps'])) $filter['group'] = $filter['grps'];
412
        foreach (array('user', 'name', 'mail', 'group') as $key) {
413
            if (!isset($filter[$key])) {
414
                $filter[$key] = '%';
415
            } else {
416
                $filter[$key] = '%' . $filter[$key] . '%';
417
            }
418
        }
419
        $filter['start'] = (int)$start;
420
        $filter['end'] = (int)$start + $limit;
421
        $filter['limit'] = (int)$limit;
422
423
        $result = $this->query($this->getConf('list-users'), $filter);
424
        if (!$result) return array();
425
        $users = array();
426
        if (is_array($result)) {
427
            foreach ($result as $row) {
428
                if (!isset($row['user'])) {
429
                    $this->debugMsg("list-users statement did not return 'user' attribute", -1, __LINE__);
430
                    return array();
431
                }
432
                $users[] = $this->getUserData($row['user']);
433
            }
434
        } else {
435
            $this->debugMsg("list-users statement did not return a list of result", -1, __LINE__);
436
        }
437
        return $users;
438
    }
439
440
    /**
441
     * Return a count of the number of user which meet $filter criteria
442
     *
443
     * @param array $filter array of field/pattern pairs, empty array for no filter
444
     * @return int
445
     */
446
    public function getUserCount($filter = array())
447
    {
448
        if (is_null($filter)) $filter = array();
449
450
        if (isset($filter['grps'])) $filter['group'] = $filter['grps'];
451
        foreach (array('user', 'name', 'mail', 'group') as $key) {
452
            if (!isset($filter[$key])) {
453
                $filter[$key] = '%';
454
            } else {
455
                $filter[$key] = '%' . $filter[$key] . '%';
456
            }
457
        }
458
459
        $result = $this->query($this->getConf('count-users'), $filter);
460
        if (!$result || !isset($result[0]['count'])) {
461
            $this->debugMsg("Statement did not return 'count' attribute", -1, __LINE__);
462
        }
463
        return (int)$result[0]['count'];
464
    }
465
466
    /**
467
     * Create a new group with the given name
468
     *
469
     * @param string $group
470
     * @return bool
471
     */
472
    public function addGroup($group)
473
    {
474
        $sql = $this->getConf('insert-group');
475
476
        $result = $this->query($sql, array(':group' => $group));
477
        $this->clearGroupCache();
478
        if ($result === false) return false;
479
        return true;
480
    }
481
482
    /**
483
     * Retrieve groups
484
     *
485
     * Set getGroups capability when implemented
486
     *
487
     * @param int $start
488
     * @param int $limit
489
     * @return  array
490
     */
491
    public function retrieveGroups($start = 0, $limit = 0)
492
    {
493
        $groups = array_keys($this->selectGroups());
494
        if ($groups === false) return array();
495
496
        if (!$limit) {
497
            return array_splice($groups, $start);
498
        } else {
499
            return array_splice($groups, $start, $limit);
500
        }
501
    }
502
503
    /**
504
     * Select data of a specified user
505
     *
506
     * @param string $user the user name
507
     * @return bool|array user data, false on error
508
     */
509
    protected function selectUser($user)
510
    {
511
        $sql = $this->getConf('select-user');
512
513
        $result = $this->query($sql, array(':user' => $user));
514
        if (!$result) return false;
515
516
        if (count($result) > 1) {
517
            $this->debugMsg('Found more than one matching user', -1, __LINE__);
518
            return false;
519
        }
520
521
        $data = array_shift($result);
522
        $dataok = true;
523
524
        if (!isset($data['user'])) {
525
            $this->debugMsg("Statement did not return 'user' attribute", -1, __LINE__);
526
            $dataok = false;
527
        }
528
        if (!isset($data['hash']) && !isset($data['clear']) && !$this->checkConfig(array('check-pass'))) {
529
            $this->debugMsg("Statement did not return 'clear' or 'hash' attribute", -1, __LINE__);
530
            $dataok = false;
531
        }
532
        if (!isset($data['name'])) {
533
            $this->debugMsg("Statement did not return 'name' attribute", -1, __LINE__);
534
            $dataok = false;
535
        }
536
        if (!isset($data['mail'])) {
537
            $this->debugMsg("Statement did not return 'mail' attribute", -1, __LINE__);
538
            $dataok = false;
539
        }
540
541
        if (!$dataok) return false;
542
        return $data;
543
    }
544
545
    /**
546
     * Delete a user after removing all their group memberships
547
     *
548
     * @param string $user
549
     * @return bool true when the user was deleted
550
     */
551
    protected function deleteUser($user)
552
    {
553
        $this->pdo->beginTransaction();
554
        {
555
            $userdata = $this->getUserData($user);
556
            if ($userdata === false) goto FAIL;
557
            $allgroups = $this->selectGroups();
558
559
            // remove group memberships (ignore errors)
560
            foreach ($userdata['grps'] as $group) {
561
                if (isset($allgroups[$group])) {
562
                    $this->leaveGroup($userdata, $allgroups[$group]);
563
                }
564
            }
565
566
            $ok = $this->query($this->getConf('delete-user'), $userdata);
567
            if ($ok === false) goto FAIL;
568
        }
569
        $this->pdo->commit();
570
        return true;
571
572
        FAIL:
573
        $this->pdo->rollBack();
574
        return false;
575
    }
576
577
    /**
578
     * Select all groups of a user
579
     *
580
     * @param array $userdata The userdata as returned by _selectUser()
581
     * @return array|bool list of group names, false on error
582
     */
583
    protected function selectUserGroups($userdata)
584
    {
585
        global $conf;
586
        $sql = $this->getConf('select-user-groups');
587
        $result = $this->query($sql, $userdata);
588
        if ($result === false) return false;
589
590
        $groups = array($conf['defaultgroup']); // always add default config
591
        if (is_array($result)) {
592
            foreach ($result as $row) {
593
                if (!isset($row['group'])) {
594
                    $this->debugMsg("No 'group' field returned in select-user-groups statement", -1, __LINE__);
595
                    return false;
596
                }
597
                $groups[] = $row['group'];
598
            }
599
        } else {
600
            $this->debugMsg("select-user-groups statement did not return a list of result", -1, __LINE__);
601
        }
602
603
        $groups = array_unique($groups);
604
        Sort::sort($groups);
605
        return $groups;
606
    }
607
608
    /**
609
     * Select all available groups
610
     *
611
     * @return array|bool list of all available groups and their properties
612
     */
613
    protected function selectGroups()
614
    {
615
        if ($this->groupcache) return $this->groupcache;
616
617
        $sql = $this->getConf('select-groups');
618
        $result = $this->query($sql);
619
        if ($result === false) return false;
620
621
        $groups = array();
622
        if (is_array($result)) {
623
            foreach ($result as $row) {
624
                if (!isset($row['group'])) {
625
                    $this->debugMsg("No 'group' field returned from select-groups statement", -1, __LINE__);
626
                    return false;
627
                }
628
629
                // relayout result with group name as key
630
                $group = $row['group'];
631
                $groups[$group] = $row;
632
            }
633
        } else {
634
            $this->debugMsg("select-groups statement did not return a list of result", -1, __LINE__);
635
        }
636
637
        Sort::ksort($groups);
638
        return $groups;
639
    }
640
641
    /**
642
     * Remove all entries from the group cache
643
     */
644
    protected function clearGroupCache()
645
    {
646
        $this->groupcache = null;
647
    }
648
649
    /**
650
     * Adds the user to the group
651
     *
652
     * @param array $userdata all the user data
653
     * @param array $groupdata all the group data
654
     * @return bool
655
     */
656
    protected function joinGroup($userdata, $groupdata)
657
    {
658
        $data = array_merge($userdata, $groupdata);
659
        $sql = $this->getConf('join-group');
660
        $result = $this->query($sql, $data);
661
        if ($result === false) return false;
662
        return true;
663
    }
664
665
    /**
666
     * Removes the user from the group
667
     *
668
     * @param array $userdata all the user data
669
     * @param array $groupdata all the group data
670
     * @return bool
671
     */
672
    protected function leaveGroup($userdata, $groupdata)
673
    {
674
        $data = array_merge($userdata, $groupdata);
675
        $sql = $this->getConf('leave-group');
676
        $result = $this->query($sql, $data);
677
        if ($result === false) return false;
678
        return true;
679
    }
680
681
    /**
682
     * Executes a query
683
     *
684
     * @param string $sql The SQL statement to execute
685
     * @param array $arguments Named parameters to be used in the statement
686
     * @return array|int|bool The result as associative array for SELECTs, affected rows for others, false on error
687
     */
688
    protected function query($sql, $arguments = array())
689
    {
690
        $sql = trim($sql);
691
        if (empty($sql)) {
692
            $this->debugMsg('No SQL query given', -1, __LINE__);
693
            return false;
694
        }
695
696
        // execute
697
        $params = array();
698
        $sth = $this->pdo->prepare($sql);
699
        $result = false;
700
        try {
701
            // prepare parameters - we only use those that exist in the SQL
702
            foreach ($arguments as $key => $value) {
703
                if (is_array($value)) continue;
704
                if (is_object($value)) continue;
705
                if ($key[0] != ':') $key = ":$key"; // prefix with colon if needed
706
                if (strpos($sql, $key) === false) continue; // skip if parameter is missing
707
708
                if (is_int($value)) {
709
                    $sth->bindValue($key, $value, PDO::PARAM_INT);
710
                } else {
711
                    $sth->bindValue($key, $value);
712
                }
713
                $params[$key] = $value; //remember for debugging
714
            }
715
716
            $sth->execute();
717
            // only report last line's result
718
            $hasnextrowset = true;
719
            $currentsql = $sql;
720
            while ($hasnextrowset) {
721
                if (strtolower(substr($currentsql, 0, 6)) == 'select') {
722
                    $result = $sth->fetchAll();
723
                } else {
724
                    $result = $sth->rowCount();
725
                }
726
                $semi_pos = strpos($currentsql, ';');
727
                if ($semi_pos) {
728
                    $currentsql = trim(substr($currentsql, $semi_pos + 1));
729
                }
730
                try {
731
                    $hasnextrowset = $sth->nextRowset(); // run next rowset
732
                } catch (PDOException $rowset_e) {
733
                    $hasnextrowset = false; // driver does not support multi-rowset, should be executed in one time
734
                }
735
            }
736
        } catch (Exception $e) {
737
            // report the caller's line
738
            $trace = debug_backtrace();
739
            $line = $trace[0]['line'];
740
            $dsql = $this->debugSQL($sql, $params, !defined('DOKU_UNITTEST'));
741
            $this->debugMsg($e, -1, $line);
742
            $this->debugMsg("SQL: <pre>$dsql</pre>", -1, $line);
743
        }
744
        $sth->closeCursor();
745
        $sth = null;
0 ignored issues
show
Unused Code introduced by
$sth 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...
746
747
        return $result;
748
    }
749
750
    /**
751
     * Wrapper around msg() but outputs only when debug is enabled
752
     *
753
     * @param string|Exception $message
754
     * @param int $err
755
     * @param int $line
756
     */
757
    protected function debugMsg($message, $err = 0, $line = 0)
758
    {
759
        if (!$this->getConf('debug')) return;
760
        if (is_a($message, 'Exception')) {
761
            $err = -1;
762
            $msg = $message->getMessage();
0 ignored issues
show
Bug introduced by
It seems like $message is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
763
            if (!$line) $line = $message->getLine();
764
        } else {
765
            $msg = $message;
766
        }
767
768
        if (defined('DOKU_UNITTEST')) {
769
            printf("\n%s, %s:%d\n", $msg, __FILE__, $line);
770
        } else {
771
            msg('authpdo: ' . $msg, $err, $line, __FILE__);
772
        }
773
    }
774
775
    /**
776
     * Check if the given config strings are set
777
     *
778
     * @param string[] $keys
779
     * @return  bool
780
     * @author  Matthias Grimm <[email protected]>
781
     *
782
     */
783
    protected function checkConfig($keys)
784
    {
785
        foreach ($keys as $key) {
786
            $params = explode(':', $key);
787
            $key = array_shift($params);
788
            $sql = trim($this->getConf($key));
789
790
            // check if sql is set
791
            if (!$sql) return false;
792
            // check if needed params are there
793
            foreach ($params as $param) {
794
                if (strpos($sql, ":$param") === false) return false;
795
            }
796
        }
797
798
        return true;
799
    }
800
801
    /**
802
     * create an approximation of the SQL string with parameters replaced
803
     *
804
     * @param string $sql
805
     * @param array $params
806
     * @param bool $htmlescape Should the result be escaped for output in HTML?
807
     * @return string
808
     */
809
    protected function debugSQL($sql, $params, $htmlescape = true)
810
    {
811
        foreach ($params as $key => $val) {
812
            if (is_int($val)) {
813
                $val = $this->pdo->quote($val, PDO::PARAM_INT);
814
            } elseif (is_bool($val)) {
815
                $val = $this->pdo->quote($val, PDO::PARAM_BOOL);
816
            } elseif (is_null($val)) {
817
                $val = 'NULL';
818
            } else {
819
                $val = $this->pdo->quote($val);
820
            }
821
            $sql = str_replace($key, $val, $sql);
822
        }
823
        if ($htmlescape) $sql = hsc($sql);
824
        return $sql;
825
    }
826
}
827
828
// vim:ts=4:sw=4:et:
829