Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Storage 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 Storage, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 25 | class Storage |
||
| 26 | { |
||
| 27 | /** @var \PDO */ |
||
| 28 | private $db; |
||
| 29 | |||
| 30 | /** @var \DateTime */ |
||
| 31 | private $dateTime; |
||
| 32 | |||
| 33 | public function __construct(PDO $db, DateTime $dateTime) |
||
| 34 | { |
||
| 35 | $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
||
| 36 | if ('sqlite' === $db->getAttribute(PDO::ATTR_DRIVER_NAME)) { |
||
| 37 | $db->query('PRAGMA foreign_keys = ON'); |
||
| 38 | } |
||
| 39 | |||
| 40 | $this->db = $db; |
||
| 41 | $this->dateTime = $dateTime; |
||
| 42 | } |
||
| 43 | |||
| 44 | /** |
||
| 45 | * @return array |
||
| 46 | */ |
||
| 47 | public function getUsers() |
||
| 48 | { |
||
| 49 | $stmt = $this->db->prepare( |
||
| 50 | <<< 'SQL' |
||
| 51 | SELECT |
||
| 52 | user_id, |
||
| 53 | date_time, |
||
| 54 | totp_secret, |
||
| 55 | yubi_key, |
||
| 56 | is_disabled |
||
| 57 | FROM |
||
| 58 | users |
||
| 59 | SQL |
||
| 60 | ); |
||
| 61 | $stmt->execute(); |
||
| 62 | |||
| 63 | $userList = []; |
||
| 64 | foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { |
||
| 65 | $userList[] = [ |
||
| 66 | 'user_id' => $row['user_id'], |
||
| 67 | 'is_disabled' => (bool) $row['is_disabled'], |
||
| 68 | 'two_factor' => !is_null($row['totp_secret']) || !is_null($row['yubi_key']), |
||
| 69 | ]; |
||
| 70 | } |
||
| 71 | |||
| 72 | return $userList; |
||
| 73 | } |
||
| 74 | |||
| 75 | /** |
||
| 76 | * @return array|false |
||
| 77 | */ |
||
| 78 | View Code Duplication | public function getUserCertificateInfo($commonName) |
|
|
|
|||
| 79 | { |
||
| 80 | $stmt = $this->db->prepare( |
||
| 81 | <<< 'SQL' |
||
| 82 | SELECT |
||
| 83 | u.user_id AS user_id, |
||
| 84 | u.is_disabled AS user_is_disabled, |
||
| 85 | c.display_name AS display_name, |
||
| 86 | c.is_disabled AS certificate_is_disabled |
||
| 87 | FROM |
||
| 88 | users u, certificates c |
||
| 89 | WHERE |
||
| 90 | u.user_id = c.user_id AND |
||
| 91 | c.common_name = :common_name |
||
| 92 | SQL |
||
| 93 | ); |
||
| 94 | |||
| 95 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 96 | $stmt->execute(); |
||
| 97 | |||
| 98 | return $stmt->fetch(PDO::FETCH_ASSOC); |
||
| 99 | } |
||
| 100 | |||
| 101 | /** |
||
| 102 | * @return string|null |
||
| 103 | */ |
||
| 104 | View Code Duplication | public function getVootToken($userId) |
|
| 105 | { |
||
| 106 | $this->addUser($userId); |
||
| 107 | $stmt = $this->db->prepare( |
||
| 108 | <<< 'SQL' |
||
| 109 | SELECT |
||
| 110 | voot_token |
||
| 111 | FROM |
||
| 112 | users |
||
| 113 | WHERE |
||
| 114 | user_id = :user_id |
||
| 115 | SQL |
||
| 116 | ); |
||
| 117 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 118 | $stmt->execute(); |
||
| 119 | |||
| 120 | return $stmt->fetchColumn(); |
||
| 121 | } |
||
| 122 | |||
| 123 | View Code Duplication | public function setVootToken($userId, $vootToken) |
|
| 124 | { |
||
| 125 | $this->addUser($userId); |
||
| 126 | $stmt = $this->db->prepare( |
||
| 127 | <<< 'SQL' |
||
| 128 | UPDATE |
||
| 129 | users |
||
| 130 | SET |
||
| 131 | voot_token = :voot_token |
||
| 132 | WHERE |
||
| 133 | user_id = :user_id |
||
| 134 | SQL |
||
| 135 | ); |
||
| 136 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 137 | $stmt->bindValue(':voot_token', $vootToken, PDO::PARAM_STR); |
||
| 138 | |||
| 139 | $stmt->execute(); |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * @return bool |
||
| 144 | */ |
||
| 145 | View Code Duplication | public function hasVootToken($userId) |
|
| 146 | { |
||
| 147 | $this->addUser($userId); |
||
| 148 | $stmt = $this->db->prepare( |
||
| 149 | <<< 'SQL' |
||
| 150 | SELECT |
||
| 151 | voot_token |
||
| 152 | FROM |
||
| 153 | users |
||
| 154 | WHERE |
||
| 155 | user_id = :user_id |
||
| 156 | SQL |
||
| 157 | ); |
||
| 158 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 159 | $stmt->execute(); |
||
| 160 | |||
| 161 | return !is_null($stmt->fetchColumn()); |
||
| 162 | } |
||
| 163 | |||
| 164 | public function deleteVootToken($userId) |
||
| 165 | { |
||
| 166 | $this->addUser($userId); |
||
| 167 | $stmt = $this->db->prepare( |
||
| 168 | <<< 'SQL' |
||
| 169 | UPDATE |
||
| 170 | users |
||
| 171 | SET |
||
| 172 | voot_token = NULL |
||
| 173 | WHERE |
||
| 174 | user_id = :user_id |
||
| 175 | SQL |
||
| 176 | ); |
||
| 177 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 178 | |||
| 179 | $stmt->execute(); |
||
| 180 | } |
||
| 181 | |||
| 182 | /** |
||
| 183 | * @return bool |
||
| 184 | */ |
||
| 185 | public function hasTotpSecret($userId) |
||
| 186 | { |
||
| 187 | $this->addUser($userId); |
||
| 188 | $stmt = $this->db->prepare( |
||
| 189 | <<< 'SQL' |
||
| 190 | SELECT |
||
| 191 | totp_secret |
||
| 192 | FROM |
||
| 193 | users |
||
| 194 | WHERE |
||
| 195 | user_id = :user_id |
||
| 196 | SQL |
||
| 197 | ); |
||
| 198 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 199 | $stmt->execute(); |
||
| 200 | |||
| 201 | return !is_null($stmt->fetchColumn()); |
||
| 202 | } |
||
| 203 | |||
| 204 | /** |
||
| 205 | * @return string|null |
||
| 206 | */ |
||
| 207 | View Code Duplication | public function getTotpSecret($userId) |
|
| 208 | { |
||
| 209 | $this->addUser($userId); |
||
| 210 | $stmt = $this->db->prepare( |
||
| 211 | <<< 'SQL' |
||
| 212 | SELECT |
||
| 213 | totp_secret |
||
| 214 | FROM |
||
| 215 | users |
||
| 216 | WHERE |
||
| 217 | user_id = :user_id |
||
| 218 | SQL |
||
| 219 | ); |
||
| 220 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 221 | $stmt->execute(); |
||
| 222 | |||
| 223 | return $stmt->fetchColumn(); |
||
| 224 | } |
||
| 225 | |||
| 226 | public function setTotpSecret($userId, $totpSecret) |
||
| 227 | { |
||
| 228 | $this->addUser($userId); |
||
| 229 | $stmt = $this->db->prepare( |
||
| 230 | <<< 'SQL' |
||
| 231 | UPDATE |
||
| 232 | users |
||
| 233 | SET |
||
| 234 | totp_secret = :totp_secret |
||
| 235 | WHERE |
||
| 236 | user_id = :user_id |
||
| 237 | SQL |
||
| 238 | ); |
||
| 239 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 240 | $stmt->bindValue(':totp_secret', $totpSecret, PDO::PARAM_STR); |
||
| 241 | |||
| 242 | $stmt->execute(); |
||
| 243 | } |
||
| 244 | |||
| 245 | View Code Duplication | public function deleteTotpSecret($userId) |
|
| 246 | { |
||
| 247 | $this->addUser($userId); |
||
| 248 | $stmt = $this->db->prepare( |
||
| 249 | <<< 'SQL' |
||
| 250 | UPDATE |
||
| 251 | users |
||
| 252 | SET |
||
| 253 | totp_secret = NULL |
||
| 254 | WHERE |
||
| 255 | user_id = :user_id |
||
| 256 | SQL |
||
| 257 | ); |
||
| 258 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 259 | $stmt->execute(); |
||
| 260 | } |
||
| 261 | |||
| 262 | View Code Duplication | public function deleteUser($userId) |
|
| 263 | { |
||
| 264 | $this->addUser($userId); |
||
| 265 | $stmt = $this->db->prepare( |
||
| 266 | <<< 'SQL' |
||
| 267 | DELETE FROM |
||
| 268 | users |
||
| 269 | WHERE |
||
| 270 | user_id = :user_id |
||
| 271 | SQL |
||
| 272 | ); |
||
| 273 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 274 | $stmt->execute(); |
||
| 275 | } |
||
| 276 | |||
| 277 | View Code Duplication | public function addCertificate($userId, $commonName, $displayName, DateTime $validFrom, DateTime $validTo) |
|
| 278 | { |
||
| 279 | $this->addUser($userId); |
||
| 280 | $stmt = $this->db->prepare( |
||
| 281 | <<< 'SQL' |
||
| 282 | INSERT INTO certificates |
||
| 283 | (common_name, user_id, display_name, valid_from, valid_to) |
||
| 284 | VALUES |
||
| 285 | (:common_name, :user_id, :display_name, :valid_from, :valid_to) |
||
| 286 | SQL |
||
| 287 | ); |
||
| 288 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 289 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 290 | $stmt->bindValue(':display_name', $displayName, PDO::PARAM_STR); |
||
| 291 | $stmt->bindValue(':valid_from', $validFrom->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 292 | $stmt->bindValue(':valid_to', $validTo->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 293 | $stmt->execute(); |
||
| 294 | } |
||
| 295 | |||
| 296 | /** |
||
| 297 | * @return array |
||
| 298 | */ |
||
| 299 | public function getCertificates($userId) |
||
| 300 | { |
||
| 301 | $this->addUser($userId); |
||
| 302 | $stmt = $this->db->prepare( |
||
| 303 | <<< 'SQL' |
||
| 304 | SELECT |
||
| 305 | common_name, |
||
| 306 | display_name, |
||
| 307 | valid_from, |
||
| 308 | valid_to, |
||
| 309 | is_disabled |
||
| 310 | FROM |
||
| 311 | certificates |
||
| 312 | WHERE |
||
| 313 | user_id = :user_id |
||
| 314 | SQL |
||
| 315 | ); |
||
| 316 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 317 | $stmt->execute(); |
||
| 318 | |||
| 319 | $certificateList = []; |
||
| 320 | foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { |
||
| 321 | $row['is_disabled'] = (bool) $row['is_disabled']; |
||
| 322 | $certificateList[] = $row; |
||
| 323 | } |
||
| 324 | |||
| 325 | return $certificateList; |
||
| 326 | } |
||
| 327 | |||
| 328 | public function disableCertificate($commonName) |
||
| 329 | { |
||
| 330 | $stmt = $this->db->prepare( |
||
| 331 | <<< 'SQL' |
||
| 332 | UPDATE |
||
| 333 | certificates |
||
| 334 | SET |
||
| 335 | is_disabled = 1 |
||
| 336 | WHERE |
||
| 337 | common_name = :common_name |
||
| 338 | SQL |
||
| 339 | ); |
||
| 340 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 341 | $stmt->execute(); |
||
| 342 | } |
||
| 343 | |||
| 344 | public function deleteCertificate($commonName) |
||
| 345 | { |
||
| 346 | $stmt = $this->db->prepare( |
||
| 347 | <<< 'SQL' |
||
| 348 | DELETE FROM |
||
| 349 | certificates |
||
| 350 | WHERE |
||
| 351 | common_name = :common_name |
||
| 352 | SQL |
||
| 353 | ); |
||
| 354 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 355 | $stmt->execute(); |
||
| 356 | } |
||
| 357 | |||
| 358 | public function enableCertificate($commonName) |
||
| 359 | { |
||
| 360 | $stmt = $this->db->prepare( |
||
| 361 | <<< 'SQL' |
||
| 362 | UPDATE |
||
| 363 | certificates |
||
| 364 | SET |
||
| 365 | is_disabled = 0 |
||
| 366 | WHERE |
||
| 367 | common_name = :common_name |
||
| 368 | SQL |
||
| 369 | ); |
||
| 370 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 371 | $stmt->execute(); |
||
| 372 | } |
||
| 373 | |||
| 374 | View Code Duplication | public function disableUser($userId) |
|
| 375 | { |
||
| 376 | $this->addUser($userId); |
||
| 377 | $stmt = $this->db->prepare( |
||
| 378 | <<< 'SQL' |
||
| 379 | UPDATE |
||
| 380 | users |
||
| 381 | SET |
||
| 382 | is_disabled = 1 |
||
| 383 | WHERE |
||
| 384 | user_id = :user_id |
||
| 385 | SQL |
||
| 386 | ); |
||
| 387 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 388 | $stmt->execute(); |
||
| 389 | } |
||
| 390 | |||
| 391 | View Code Duplication | public function enableUser($userId) |
|
| 392 | { |
||
| 393 | $this->addUser($userId); |
||
| 394 | $stmt = $this->db->prepare( |
||
| 395 | <<< 'SQL' |
||
| 396 | UPDATE |
||
| 397 | users |
||
| 398 | SET |
||
| 399 | is_disabled = 0 |
||
| 400 | WHERE |
||
| 401 | user_id = :user_id |
||
| 402 | SQL |
||
| 403 | ); |
||
| 404 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 405 | $stmt->execute(); |
||
| 406 | } |
||
| 407 | |||
| 408 | /** |
||
| 409 | * @return bool |
||
| 410 | */ |
||
| 411 | View Code Duplication | public function isDisabledUser($userId) |
|
| 412 | { |
||
| 413 | $this->addUser($userId); |
||
| 414 | $stmt = $this->db->prepare( |
||
| 415 | <<< 'SQL' |
||
| 416 | SELECT |
||
| 417 | is_disabled |
||
| 418 | FROM |
||
| 419 | users |
||
| 420 | WHERE |
||
| 421 | user_id = :user_id |
||
| 422 | SQL |
||
| 423 | ); |
||
| 424 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 425 | $stmt->execute(); |
||
| 426 | |||
| 427 | return (bool) $stmt->fetchColumn(); |
||
| 428 | } |
||
| 429 | |||
| 430 | /** |
||
| 431 | * @return array |
||
| 432 | */ |
||
| 433 | public function getAllLogEntries() |
||
| 434 | { |
||
| 435 | $stmt = $this->db->prepare( |
||
| 436 | <<< 'SQL' |
||
| 437 | SELECT |
||
| 438 | user_id, |
||
| 439 | common_name, |
||
| 440 | connected_at, |
||
| 441 | disconnected_at, |
||
| 442 | bytes_transferred |
||
| 443 | FROM |
||
| 444 | connection_log |
||
| 445 | WHERE |
||
| 446 | disconnected_at IS NOT NULL |
||
| 447 | ORDER BY |
||
| 448 | connected_at |
||
| 449 | SQL |
||
| 450 | ); |
||
| 451 | |||
| 452 | $stmt->execute(); |
||
| 453 | |||
| 454 | return $stmt->fetchAll(PDO::FETCH_ASSOC); |
||
| 455 | } |
||
| 456 | |||
| 457 | View Code Duplication | public function clientConnect($profileId, $commonName, $ip4, $ip6, DateTime $connectedAt) |
|
| 458 | { |
||
| 459 | // this query is so complex, because we want to store the user_id in the |
||
| 460 | // log as well, not just the common_name... the user may delete the |
||
| 461 | // certificate, or the user account may be deleted... |
||
| 462 | $stmt = $this->db->prepare( |
||
| 463 | <<< 'SQL' |
||
| 464 | INSERT INTO connection_log |
||
| 465 | ( |
||
| 466 | user_id, |
||
| 467 | profile_id, |
||
| 468 | common_name, |
||
| 469 | ip4, |
||
| 470 | ip6, |
||
| 471 | connected_at |
||
| 472 | ) |
||
| 473 | VALUES |
||
| 474 | ( |
||
| 475 | ( |
||
| 476 | SELECT |
||
| 477 | u.user_id |
||
| 478 | FROM |
||
| 479 | users u, certificates c |
||
| 480 | WHERE |
||
| 481 | u.user_id = c.user_id |
||
| 482 | AND |
||
| 483 | c.common_name = :common_name |
||
| 484 | ), |
||
| 485 | :profile_id, |
||
| 486 | :common_name, |
||
| 487 | :ip4, |
||
| 488 | :ip6, |
||
| 489 | :connected_at |
||
| 490 | ) |
||
| 491 | SQL |
||
| 492 | ); |
||
| 493 | |||
| 494 | $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR); |
||
| 495 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 496 | $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR); |
||
| 497 | $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR); |
||
| 498 | $stmt->bindValue(':connected_at', $connectedAt->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 499 | $stmt->execute(); |
||
| 500 | } |
||
| 501 | |||
| 502 | public function clientDisconnect($profileId, $commonName, $ip4, $ip6, DateTime $connectedAt, DateTime $disconnectedAt, $bytesTransferred) |
||
| 503 | { |
||
| 504 | $stmt = $this->db->prepare( |
||
| 505 | <<< 'SQL' |
||
| 506 | UPDATE |
||
| 507 | connection_log |
||
| 508 | SET |
||
| 509 | disconnected_at = :disconnected_at, |
||
| 510 | bytes_transferred = :bytes_transferred |
||
| 511 | WHERE |
||
| 512 | profile_id = :profile_id |
||
| 513 | AND |
||
| 514 | common_name = :common_name |
||
| 515 | AND |
||
| 516 | ip4 = :ip4 |
||
| 517 | AND |
||
| 518 | ip6 = :ip6 |
||
| 519 | AND |
||
| 520 | connected_at = :connected_at |
||
| 521 | SQL |
||
| 522 | ); |
||
| 523 | |||
| 524 | $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR); |
||
| 525 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 526 | $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR); |
||
| 527 | $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR); |
||
| 528 | $stmt->bindValue(':connected_at', $connectedAt->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 529 | $stmt->bindValue(':disconnected_at', $disconnectedAt->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 530 | $stmt->bindValue(':bytes_transferred', $bytesTransferred, PDO::PARAM_INT); |
||
| 531 | $stmt->execute(); |
||
| 532 | } |
||
| 533 | |||
| 534 | /** |
||
| 535 | * @return array|false |
||
| 536 | */ |
||
| 537 | View Code Duplication | public function getLogEntry($dateTimeUnix, $ipAddress) |
|
| 538 | { |
||
| 539 | $stmt = $this->db->prepare( |
||
| 540 | <<< 'SQL' |
||
| 541 | SELECT |
||
| 542 | user_id, |
||
| 543 | profile_id, |
||
| 544 | common_name, |
||
| 545 | ip4, |
||
| 546 | ip6, |
||
| 547 | connected_at, |
||
| 548 | disconnected_at |
||
| 549 | FROM |
||
| 550 | connection_log |
||
| 551 | WHERE |
||
| 552 | (ip4 = :ip_address OR ip6 = :ip_address) |
||
| 553 | AND |
||
| 554 | connected_at < :date_time_unix |
||
| 555 | AND |
||
| 556 | (disconnected_at > :date_time_unix OR disconnected_at IS NULL) |
||
| 557 | SQL |
||
| 558 | ); |
||
| 559 | $stmt->bindValue(':ip_address', $ipAddress, PDO::PARAM_STR); |
||
| 560 | $stmt->bindValue(':date_time_unix', $dateTimeUnix, PDO::PARAM_STR); |
||
| 561 | $stmt->execute(); |
||
| 562 | |||
| 563 | // XXX can this also contain multiple results? I don't think so, but |
||
| 564 | // make sure! |
||
| 565 | return $stmt->fetch(PDO::FETCH_ASSOC); |
||
| 566 | } |
||
| 567 | |||
| 568 | /** |
||
| 569 | * @return int |
||
| 570 | */ |
||
| 571 | View Code Duplication | public function getTotpAttemptCount($userId) |
|
| 572 | { |
||
| 573 | $this->addUser($userId); |
||
| 574 | $stmt = $this->db->prepare( |
||
| 575 | <<< 'SQL' |
||
| 576 | SELECT |
||
| 577 | COUNT(*) |
||
| 578 | FROM |
||
| 579 | totp_log |
||
| 580 | WHERE user_id = :user_id |
||
| 581 | SQL |
||
| 582 | ); |
||
| 583 | |||
| 584 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 585 | $stmt->execute(); |
||
| 586 | |||
| 587 | return (int) $stmt->fetchColumn(); |
||
| 588 | } |
||
| 589 | |||
| 590 | /** |
||
| 591 | * @return bool true if recording succeeds, false if it cannot due to replay |
||
| 592 | */ |
||
| 593 | public function recordTotpKey($userId, $totpKey) |
||
| 594 | { |
||
| 595 | $this->addUser($userId); |
||
| 596 | $stmt = $this->db->prepare( |
||
| 597 | <<< 'SQL' |
||
| 598 | INSERT INTO totp_log |
||
| 599 | (user_id, totp_key, date_time) |
||
| 600 | VALUES |
||
| 601 | (:user_id, :totp_key, :date_time) |
||
| 602 | SQL |
||
| 603 | ); |
||
| 604 | |||
| 605 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 606 | $stmt->bindValue(':totp_key', $totpKey, PDO::PARAM_STR); |
||
| 607 | $stmt->bindValue(':date_time', $this->dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 608 | |||
| 609 | try { |
||
| 610 | $stmt->execute(); |
||
| 611 | } catch (PDOException $e) { |
||
| 612 | // unable to record the TOTP, most likely replay |
||
| 613 | return false; |
||
| 614 | } |
||
| 615 | |||
| 616 | return true; |
||
| 617 | } |
||
| 618 | |||
| 619 | View Code Duplication | public function cleanConnectionLog(DateTime $dateTime) |
|
| 620 | { |
||
| 621 | $stmt = $this->db->prepare( |
||
| 622 | <<< 'SQL' |
||
| 623 | DELETE FROM |
||
| 624 | connection_log |
||
| 625 | WHERE |
||
| 626 | connected_at < :date_time |
||
| 627 | AND |
||
| 628 | disconnected_at IS NOT NULL |
||
| 629 | SQL |
||
| 630 | ); |
||
| 631 | |||
| 632 | $stmt->bindValue(':date_time', $dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 633 | |||
| 634 | return $stmt->execute(); |
||
| 635 | } |
||
| 636 | |||
| 637 | View Code Duplication | public function cleanUserMessages(DateTime $dateTime) |
|
| 638 | { |
||
| 639 | $stmt = $this->db->prepare( |
||
| 640 | <<< 'SQL' |
||
| 641 | DELETE FROM |
||
| 642 | user_messages |
||
| 643 | WHERE |
||
| 644 | date_time < :date_time |
||
| 645 | SQL |
||
| 646 | ); |
||
| 647 | |||
| 648 | $stmt->bindValue(':date_time', $dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 649 | |||
| 650 | return $stmt->execute(); |
||
| 651 | } |
||
| 652 | |||
| 653 | View Code Duplication | public function cleanTotpLog(DateTime $dateTime) |
|
| 668 | |||
| 669 | /** |
||
| 670 | * @return array |
||
| 671 | */ |
||
| 672 | View Code Duplication | public function systemMessages($type) |
|
| 673 | { |
||
| 674 | $stmt = $this->db->prepare( |
||
| 675 | <<< 'SQL' |
||
| 676 | SELECT |
||
| 677 | id, message, date_time |
||
| 678 | FROM |
||
| 679 | system_messages |
||
| 680 | WHERE |
||
| 681 | type = :type |
||
| 682 | SQL |
||
| 683 | ); |
||
| 684 | |||
| 685 | $stmt->bindValue(':type', $type, PDO::PARAM_STR); |
||
| 686 | $stmt->execute(); |
||
| 687 | |||
| 688 | return $stmt->fetchAll(PDO::FETCH_ASSOC); |
||
| 689 | } |
||
| 690 | |||
| 691 | public function addSystemMessage($type, $message) |
||
| 692 | { |
||
| 693 | $stmt = $this->db->prepare( |
||
| 694 | <<< 'SQL' |
||
| 695 | INSERT INTO system_messages |
||
| 696 | (type, message, date_time) |
||
| 697 | VALUES |
||
| 707 | |||
| 708 | public function deleteSystemMessage($messageId) |
||
| 721 | |||
| 722 | /** |
||
| 723 | * @return array |
||
| 724 | */ |
||
| 725 | View Code Duplication | public function userMessages($userId) |
|
| 746 | |||
| 747 | View Code Duplication | public function addUserMessage($userId, $type, $message) |
|
| 765 | |||
| 766 | public function init() |
||
| 845 | |||
| 846 | View Code Duplication | private function addUser($userId) |
|
| 881 | } |
||
| 882 |
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.