Passed
Push — develop ( 6bc206...75605a )
by Carsten
10:11
created

PdoPasswordSetter::__invoke()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 15
nc 2
nop 2
dl 0
loc 28
ccs 16
cts 16
cp 1
crap 2
rs 8.8571
c 0
b 0
f 0
1
<?php
2
namespace Germania\UserProfiles;
3
4
use Germania\UserProfiles\Exceptions\SetPasswordException;
5
use Psr\Log\LoggerInterface;
6
use Psr\Log\NullLogger;
7
8
/**
9
 * This Callable updates the password for the given user.
10
 * The password will be hashed by the hash function callable passed
11
 * to the constructor.
12
 *
13
 * Example:
14
 *
15
 *     <?php
16
 *     use Germania\UserProfiles\PdoPasswordSetter;
17
 *
18
 *     $pdo    = new PDO( ... );
19
 *     $hash   = function() { return 'ABCDEF'; };
20
 *     $logger = new Monolog();
21
 *     $table  = 'users';
22
 *
23
 *     $user = 42;
24
 *
25
 *     $setter = new PdoPasswordSetter( $pdo, $hash, $logger, $table);
26
 *     $result = $setter( 42, 'top_secret' );
27
 *     ?>
28
 *
29
 * @author  Carsten Witt <[email protected]>
30
 */
31
class PdoPasswordSetter
32
{
33
34
    /**
35
     * Database table
36
     * @var string
37
     */
38
    public $table = 'users';
39
40
    /**
41
     * @var PDOStatement
0 ignored issues
show
Bug introduced by
The type Germania\UserProfiles\PDOStatement was not found. Did you mean PDOStatement? If so, make sure to prefix the type with \.
Loading history...
42
     */
43
    public $stmt;
44
45
    /**
46
     * @var LoggerInterface
47
     */
48
    public $logger;
49
50
    /**
51
     * @var Callable
52
     */
53
    public $hash_function;
54
55
56
    /**
57
     * @param PDO             $pdo           PDO instance
58
     * @param Callable        $hash_function Hash function callable
59
     * @param LoggerInterface $logger        Optional: PSR-3 Logger
60
     * @param string          $table         Optional: Database table name
61
     */
62 16
    public function __construct( \PDO $pdo, Callable $hash_function, LoggerInterface $logger = null, $table = null)
63
    {
64
        // Setup
65 16
        $this->hash_function = $hash_function;
66 16
        $this->logger        = $logger ?: new NullLogger;
67 16
        $this->table         = $table  ?: $this->table;
68
69
        // Prepare business
70 16
        $sql = "UPDATE {$this->table} SET
71
        password = :password
72
        WHERE id = :user_id
73 4
        LIMIT 1";
74
75
        // Store for later use
76 16
        $this->stmt = $pdo->prepare( $sql );
0 ignored issues
show
Documentation Bug introduced by
It seems like $pdo->prepare($sql) of type PDOStatement is incompatible with the declared type Germania\UserProfiles\PDOStatement of property $stmt.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
77
78 16
    }
79
80
81
82
    /**
83
     * @param  int    $user_id
84
     * @param  string $new_password
85
     *
86
     * @return bool   PDOStatement execution result
87
     *
88
     * @throws SetPasswordException if PDOStatement execution fails
89
     */
90 12
    public function __invoke( $user_id, $new_password )
91
    {
92
93
        // Calc values
94 12
        $hash_function = $this->hash_function;
95 12
        $password_hash = $hash_function( $new_password );
96
97
98
        // Perform
99 12
        $result = $this->stmt->execute([
100 12
            'password' => $password_hash,
101 9
            'user_id'  => $user_id
102 3
        ]);
103
104
        // Evaluate
105
        $loginfo = [
106 12
            'user_id'   => $user_id,
107 12
            'mb_strlen' => mb_strlen($password_hash ),
108 9
            'result'    => $result
109 3
        ];
110
111 12
        if ($result):
112 8
            $this->logger->info("Successfully set password.", $loginfo);
113 8
            return $result;
114
        endif;
115
116 4
        $this->logger->warning("Could not set password?!", $loginfo);
117 4
        throw new SetPasswordException;
118
    }
119
120
121
122
}
123