StandardIdentity::fetchByIdentifier()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 31
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 12
c 2
b 0
f 0
dl 0
loc 31
ccs 12
cts 12
cp 1
rs 9.8666
cc 3
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Palladium\Mapper;
4
5
/**
6
 * SQL logic for authentication attempts using username/password
7
 */
8
9
use Palladium\Component\DataMapper;
10
use Palladium\Entity as Entity;
11
use PDOStatement;
12
use PDO;
13
14
class StandardIdentity extends DataMapper
15
{
16
17
    /**
18
     * @param Entity\StandardIdentity $entity
19
     */
20 4
    public function exists(Entity\StandardIdentity $entity): bool
21
    {
22
        $sql = "SELECT 1
23 4
                  FROM {$this->table}
24
                 WHERE type = :type
25
                   AND fingerprint = :fingerprint
26
                   AND identifier = :identifier
27
                   AND (expires_on IS NULL OR expires_on > :now)";
28
29 4
        $statement = $this->connection->prepare($sql);
30
31 4
        $statement->bindValue(':type', Entity\StandardIdentity::TYPE_STANDARD);
32 4
        $statement->bindValue(':fingerprint', $entity->getFingerprint());
33 4
        $statement->bindValue(':identifier', $entity->getIdentifier());
34 4
        $statement->bindValue(':now', time());
35
36 4
        $statement->execute();
37 4
        $data = $statement->fetch(PDO::FETCH_ASSOC);
38
39 4
        return empty($data) === false;
40
    }
41
42
43
    /**
44
     * @param Entity\StandardIdentity $entity
45
     */
46 16
    public function fetch(Entity\StandardIdentity $entity)
47
    {
48 16
        if ($entity->getId()) {
49 5
            $this->fetchById($entity);
50 5
            return;
51
        }
52
53 12
        $this->fetchByIdentifier($entity);
54 12
    }
55
56
57 12
    private function fetchByIdentifier(Entity\StandardIdentity $entity)
58
    {
59
        $sql = "SELECT identity_id      AS id,
60
                       account_id       AS accountId,
61
                       hash             AS hash,
62
                       status           AS status,
63
                       used_on          AS lastUsed,
64
                       token            AS token,
65
                       token_action     AS tokenAction,
66
                       token_expires_on AS tokenEndOfLife,
67
                       token_payload    AS tokenPayload
68 12
                  FROM {$this->table}
69
                 WHERE type = :type
70
                   AND fingerprint = :fingerprint
71
                   AND identifier = :identifier";
72
73 12
        $statement = $this->connection->prepare($sql);
74
75 12
        $statement->bindValue(':type', $entity->getType());
76 12
        $statement->bindValue(':identifier', $entity->getIdentifier());
77 12
        $statement->bindValue(':fingerprint', $entity->getFingerprint());
78
79 12
        $statement->execute();
80
81 12
        $data = $statement->fetch(PDO::FETCH_ASSOC);
82
83 12
        if ($data) {
84 11
            if ($data['tokenPayload'] !== null) {
85 1
                $data['tokenPayload'] = json_decode($data['tokenPayload'], true);
86
            }
87 11
            $this->applyValues($entity, $data);
88
        }
89 12
    }
90
91
92 5
    private function fetchById(Entity\StandardIdentity $entity)
93
    {
94
        $sql = "SELECT identity_id      AS id,
95
                       identifier       AS identifier,
96
                       account_id       AS accountId,
97
                       hash             AS hash,
98
                       status           AS status,
99
                       used_on          AS lastUsed,
100
                       token            AS token,
101
                       token_action     AS tokenAction,
102
                       token_expires_on AS tokenEndOfLife,
103
                       token_payload    AS tokenPayload
104 5
                  FROM {$this->table}
105
                 WHERE type = :type
106
                   AND identity_id = :id";
107
108 5
        $statement = $this->connection->prepare($sql);
109
110 5
        $statement->bindValue(':type', $entity->getType());
111 5
        $statement->bindValue(':id', $entity->getId());
112
113 5
        $statement->execute();
114
115 5
        $data = $statement->fetch(PDO::FETCH_ASSOC);
116
117 5
        if ($data) {
118 5
            if ($data['tokenPayload'] !== null) {
119 1
                $data['tokenPayload'] = json_decode($data['tokenPayload'], true);
120
            }
121 5
            $this->applyValues($entity, $data);
122
        }
123 5
    }
124
125
126
    /**
127
     * @param Entity\StandardIdentity $entity
128
     */
129 8
    public function store(Entity\StandardIdentity $entity)
130
    {
131 8
        if ($entity->getId() === null) {
132 2
            $this->createIdentity($entity);
133 2
            return;
134
        }
135
136 6
        $this->updateIdentity($entity);
137 6
    }
138
139
140 2
    private function createIdentity(Entity\StandardIdentity $entity)
141
    {
142 2
        $sql = "INSERT INTO {$this->table}
143
                       (type, status, identifier, fingerprint, hash, created_on, token, token_action, token_expires_on, token_payload)
144
                VALUES (:type, :status, :identifier, :fingerprint, :hash, :created, :token, :action, :token_eol, :payload)";
145
146 2
        $statement = $this->connection->prepare($sql);
147
148 2
        $statement->bindValue(':type', Entity\StandardIdentity::TYPE_STANDARD);
149 2
        $statement->bindValue(':status', Entity\StandardIdentity::STATUS_NEW);
150 2
        $statement->bindValue(':identifier', $entity->getIdentifier());
151 2
        $statement->bindValue(':fingerprint', $entity->getFingerprint());
152 2
        $statement->bindValue(':hash', $entity->getHash());
153 2
        $statement->bindValue(':created', time());
154
155 2
        $this->bindToken($statement, $entity);
0 ignored issues
show
Bug introduced by
It seems like $statement can also be of type boolean; however, parameter $statement of Palladium\Mapper\StandardIdentity::bindToken() does only seem to accept PDOStatement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

155
        $this->bindToken(/** @scrutinizer ignore-type */ $statement, $entity);
Loading history...
156
157 2
        $statement->execute();
158
159 2
        $entity->setId($this->connection->lastInsertId());
0 ignored issues
show
Bug introduced by
$this->connection->lastInsertId() of type string is incompatible with the type integer expected by parameter $identityId of Palladium\Entity\Identity::setId(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

159
        $entity->setId(/** @scrutinizer ignore-type */ $this->connection->lastInsertId());
Loading history...
160 2
    }
161
162
163 6
    private function updateIdentity(Entity\StandardIdentity $entity)
164
    {
165 6
        $sql = "UPDATE {$this->table}
166
                   SET hash = :hash,
167
                       identifier = :identifier,
168
                       fingerprint = :fingerprint,
169
                       status = :status,
170
                       used_on = :used,
171
                       expires_on = :expires,
172
                       token = :token,
173
                       token_action = :action,
174
                       token_expires_on = :token_eol,
175
                       token_payload = :payload
176
                 WHERE identity_id = :id";
177
178 6
        $statement = $this->connection->prepare($sql);
179
180 6
        $statement->bindValue(':id', $entity->getId());
181 6
        $statement->bindValue(':hash', $entity->getHash());
182 6
        $statement->bindValue(':identifier', $entity->getIdentifier());
183 6
        $statement->bindValue(':fingerprint', $entity->getFingerprint());
184 6
        $statement->bindValue(':status', $entity->getStatus());
185 6
        $statement->bindValue(':used', $entity->getLastUsed());
186 6
        $statement->bindValue(':expires', $entity->getExpiresOn());
187
188 6
        $this->bindToken($statement, $entity);
0 ignored issues
show
Bug introduced by
It seems like $statement can also be of type boolean; however, parameter $statement of Palladium\Mapper\StandardIdentity::bindToken() does only seem to accept PDOStatement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

188
        $this->bindToken(/** @scrutinizer ignore-type */ $statement, $entity);
Loading history...
189
190 6
        $statement->execute();
191 6
    }
192
193
194 8
    private function bindToken(PDOStatement $statement, Entity\StandardIdentity $entity)
195
    {
196 8
        $statement->bindValue(':token', $entity->getToken());
197 8
        $statement->bindValue(':action', $entity->getTokenAction());
198 8
        $statement->bindValue(':token_eol', $entity->getTokenEndOfLife());
199
200 8
        $payload = $entity->getTokenPayload();
201 8
        if ($payload !== null) {
202 1
            $payload = json_encode($payload);
203
        }
204
205 8
        $statement->bindValue(':payload', $payload);
206 8
    }
207
}
208