29f3eda13eb111b2b049797019b804cef678771d
[gamestick-pjgsapi.git] / src / ProfileDb.php
1 <?php
2 require_once 'Profile.php';
3
4 /**
5  * Functions to work with player profiles
6  */
7 class ProfileDb
8 {
9     protected PDO $db;
10
11     public function __construct()
12     {
13         $dbFile = static::getDbFilePath();
14         $this->db = new PDO(
15             'sqlite:' . $dbFile,
16             '', '',
17             [
18                 PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
19                 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
20             ]
21         );
22         $this->createTablesIfNeeded();
23     }
24
25     public static function getDbFilePath()
26     {
27         return dirname(__FILE__, 2) . '/data/profiles.sqlite3';
28     }
29
30     public function getProfileByHardwareId(string $hwId): ?Profile
31     {
32         $stmt = $this->db->prepare('SELECT * FROM gamesticks WHERE hwId = :id');
33         $stmt->setFetchMode(PDO::FETCH_CLASS, 'Profile');
34         $stmt->execute([':id' => $hwId]);
35         $row = $stmt->fetch();
36         return $row === false ? null : $row;
37     }
38
39     public function getProfileBySessionId(string $sessionId): ?Profile
40     {
41         $stmt = $this->db->prepare('SELECT * FROM gamesticks WHERE sessionId = :id');
42         $stmt->setFetchMode(PDO::FETCH_CLASS, 'Profile');
43         $stmt->execute([':id' => $sessionId]);
44         $row = $stmt->fetch();
45         return $row === false ? null : $row;
46     }
47
48     public function getProfileByVerificationCode(string $code): ?Profile
49     {
50         $stmt = $this->db->prepare('SELECT * FROM gamesticks WHERE verificationCode = :code');
51         $stmt->setFetchMode(PDO::FETCH_CLASS, 'Profile');
52         $stmt->execute([':code' => $code]);
53         $row = $stmt->fetch();
54         return $row === false ? null : $row;
55     }
56
57     public function createProfile(string $hwId): Profile
58     {
59         $stmt = $this->db->prepare(
60             <<<SQL
61             INSERT INTO gamesticks
62             (hwId, sessionId, verificationCode)
63             VALUES (:hwId, :sessionId, :verificationCode)
64 SQL
65         );
66         $stmt->execute(
67             [
68                 ':hwId'             => $hwId,
69                 ':sessionId'        => 's' . str_replace(':', '', $hwId),
70                 ':verificationCode' => date('His'),
71             ]
72         );
73         return $this->getProfileByHardwareId($hwId);
74     }
75
76     public function updateProfile(string $hwId, array $values): ?Profile
77     {
78         $params = [
79             'hwId' => $hwId,
80         ];
81
82         $sql = 'UPDATE gamesticks SET';
83         $sqlParts = [];
84         foreach ($values as $column => $value) {
85             $sqlParts[] = ' ' . $column . '= :' . $column;
86             $params[':' . $column] = $value;
87         }
88         $sql .= implode(', ', $sqlParts) . ' WHERE hwId = :hwId';
89
90         $stmt = $this->db->prepare($sql);
91         $stmt->execute($params);
92
93         return $this->getProfileByHardwareId($hwId);
94     }
95
96     protected function createTablesIfNeeded()
97     {
98         $res = $this->db->query(
99             'SELECT name FROM sqlite_master WHERE type = "table" AND name = "gamesticks"'
100         )->fetch();
101         if ($res !== false) {
102             return;
103         }
104
105         $this->db->exec(
106             <<<SQL
107         CREATE TABLE gamesticks (
108             id INTEGER PRIMARY KEY AUTOINCREMENT,
109             hwId TEXT NOT NULL,
110             sessionId TEXT,
111             verificationCode TEXT DEFAULT NULL,
112             gamerTag TEXT DEFAULT NULL,
113             founderFlag INTEGER DEFAULT 0 NOT NULL,
114             founderName TEXT DEFAULT NULL,
115             minAge INTEGER DEFAULT 3 NOT NULL,
116             avatar TEXT DEFAULT NULL,
117
118             created_at TEXT DEFAULT CURRENT_TIMESTAMP
119         )
120 SQL
121         );
122     }
123 }
124 ?>