Issues (21)

src/PdoPasswordSetter.php (2 issues)

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
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 20
    public function __construct( \PDO $pdo, Callable $hash_function, LoggerInterface $logger = null, $table = null)
63
    {
64
        // Setup
65 20
        $this->hash_function = $hash_function;
66 20
        $this->logger        = $logger ?: new NullLogger;
67 20
        $this->table         = $table  ?: $this->table;
68
69
        // Prepare business
70 20
        $sql = "UPDATE {$this->table} SET
71
        password = :password
72
        WHERE id = :user_id
73 4
        LIMIT 1";
74
75
        // Store for later use
76 20
        $this->stmt = $pdo->prepare( $sql );
0 ignored issues
show
Documentation Bug introduced by
It seems like $pdo->prepare($sql) of type PDOStatement or boolean 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 20
    }
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 15
    public function __invoke( $user_id, $new_password )
91
    {
92
93
        // Calc values
94 15
        $hash_function = $this->hash_function;
95 15
        $password_hash = $hash_function( $new_password );
96
97
98
        // Perform
99 15
        $result = $this->stmt->execute([
100 15
            'password' => $password_hash,
101 12
            'user_id'  => $user_id
102 3
        ]);
103
104
        // Evaluate
105
        $loginfo = [
106 15
            'user_id'   => $user_id,
107 15
            'mb_strlen' => mb_strlen($password_hash ),
108 12
            'result'    => $result
109 3
        ];
110
111 15
        if ($result):
112 10
            $this->logger->info("Successfully set password.", $loginfo);
113 10
            return $result;
114
        endif;
115
116 5
        $this->logger->warning("Could not set password?!", $loginfo);
117 5
        throw new SetPasswordException;
118
    }
119
120
121
122
}
123