-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.php
More file actions
279 lines (247 loc) · 10.1 KB
/
Copy pathconfig.php
File metadata and controls
279 lines (247 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
<?php
session_start();
// Set correct timezone for Bangladesh
date_default_timezone_set('Asia/Dhaka');
// Database configuration
define('DB_HOST', 'localhost');
define('DB_NAME', 'habit_tracker');
define('DB_USER', 'root');
define('DB_PASS', '');
// Create database connection
try {
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4", DB_USER, DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log("Database connection error: " . $e->getMessage());
die("ERROR: Could not connect to database. Please try again later.");
}
// Check if user is logged in
function is_logged_in()
{
return isset($_SESSION['user_id']) && isset($_SESSION['username']) && isset($_SESSION['email']);
}
// Redirect if not logged in
function require_login()
{
if (!is_logged_in()) {
header('Location: index.php');
exit;
}
}
// CSRF protection functions
function generate_csrf_token()
{
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
function validate_csrf_token($token)
{
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}
// Input sanitization
function sanitize_input($data)
{
if (is_array($data)) {
return array_map('sanitize_input', $data);
}
return htmlspecialchars(trim($data), ENT_QUOTES, 'UTF-8');
}
// Validate date format
function validate_date($date, $format = 'Y-m-d')
{
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) === $date;
}
// Function to handle daily login rewards and streaks
function handle_daily_login($pdo, $user_id)
{
$today = date('Y-m-d');
// Check if user already logged in today
$stmt = $pdo->prepare("SELECT last_login_date, login_streak FROM user_settings WHERE user_id = ?");
$stmt->execute([$user_id]);
$settings = $stmt->fetch();
$last_login = $settings['last_login_date'] ?? null;
$current_streak = $settings['login_streak'] ?? 0;
if (!$last_login || $last_login != $today) {
$yesterday = date('Y-m-d', strtotime('-1 day'));
// Check if consecutive login
if ($last_login == $yesterday) {
$new_streak = $current_streak + 1;
} else {
$new_streak = 1; // Reset streak
}
// Award login point
$stmt = $pdo->prepare("UPDATE user_points SET points = points + 1 WHERE user_id = ?");
$stmt->execute([$user_id]);
// Update login streak and date
if ($settings) {
$stmt = $pdo->prepare("UPDATE user_settings SET last_login_date = ?, login_streak = ? WHERE user_id = ?");
$stmt->execute([$today, $new_streak, $user_id]);
} else {
$stmt = $pdo->prepare("INSERT INTO user_settings (user_id, last_login_date, login_streak) VALUES (?, ?, ?)");
$stmt->execute([$user_id, $today, $new_streak]);
}
// Award bonus for streak milestones
if ($new_streak % 7 == 0) {
$bonus_points = floor($new_streak / 7) * 5;
$stmt = $pdo->prepare("UPDATE user_points SET points = points + ? WHERE user_id = ?");
$stmt->execute([$bonus_points, $user_id]);
}
return ['points' => 1, 'streak' => $new_streak];
}
return false;
}
// Function to check and award achievements
function check_achievements($pdo, $user_id, $action, $context = [])
{
$achievements = [
'first-habit' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT COUNT(*) FROM habits WHERE user_id = ?");
$stmt->execute([$user_id]);
return $stmt->fetchColumn() == 1;
},
'three-habits' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT COUNT(*) FROM habits WHERE user_id = ?");
$stmt->execute([$user_id]);
return $stmt->fetchColumn() >= 3;
},
'ten-points' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT points FROM user_points WHERE user_id = ?");
$stmt->execute([$user_id]);
return $stmt->fetchColumn() >= 10;
},
'group-explorer' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT COUNT(*) FROM group_members WHERE user_id = ?");
$stmt->execute([$user_id]);
return $stmt->fetchColumn() >= 1;
},
'social-butterfly' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT COUNT(DISTINCT group_id) FROM group_members WHERE user_id = ?");
$stmt->execute([$user_id]);
return $stmt->fetchColumn() >= 3;
},
'habit-mentor' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT COUNT(*) FROM habits WHERE user_id = ? AND is_visible_to_group = 1");
$stmt->execute([$user_id]);
return $stmt->fetchColumn() >= 5;
},
'three-day-streak' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT current_streak FROM user_streaks WHERE user_id = ?");
$stmt->execute([$user_id]);
$streaks = $stmt->fetchAll();
foreach ($streaks as $streak) {
if ($streak['current_streak'] >= 3) {
return true;
}
}
return false;
},
'seven-day-streak' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT current_streak FROM user_streaks WHERE user_id = ?");
$stmt->execute([$user_id]);
$streaks = $stmt->fetchAll();
foreach ($streaks as $streak) {
if ($streak['current_streak'] >= 7) {
return true;
}
}
return false;
},
'fourteen-day-streak' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT current_streak FROM user_streaks WHERE user_id = ?");
$stmt->execute([$user_id]);
$streaks = $stmt->fetchAll();
foreach ($streaks as $streak) {
if ($streak['current_streak'] >= 14) {
return true;
}
}
return false;
},
'thirty-day-streak' => function ($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT current_streak FROM user_streaks WHERE user_id = ?");
$stmt->execute([$user_id]);
$streaks = $stmt->fetchAll();
foreach ($streaks as $streak) {
if ($streak['current_streak'] >= 30) {
return true;
}
}
return false;
}
];
foreach ($achievements as $achievement_name => $check_function) {
// Check if user already has this achievement
$stmt = $pdo->prepare("SELECT id FROM user_achievements WHERE user_id = ? AND achievement_name = ?");
$stmt->execute([$user_id, $achievement_name]);
if (!$stmt->fetch() && $check_function($pdo, $user_id)) {
// Award achievement
$stmt = $pdo->prepare("INSERT INTO user_achievements (user_id, achievement_name) VALUES (?, ?)");
$stmt->execute([$user_id, $achievement_name]);
// Add points for achievement
$stmt = $pdo->prepare("UPDATE user_points SET points = points + 5 WHERE user_id = ?");
$stmt->execute([$user_id]);
}
}
}
// Function to check and mark missed habits (runs once per day per user)
function check_missed_habits($pdo, $user_id)
{
$today = date('Y-m-d');
// Check if we've already run today
$stmt = $pdo->prepare("SELECT last_missed_check FROM user_settings WHERE user_id = ?");
$stmt->execute([$user_id]);
$settings = $stmt->fetch();
if ($settings && $settings['last_missed_check'] == $today) {
return; // Already checked today
}
$yesterday = date('Y-m-d', strtotime('-1 day'));
// Get all active habits
$stmt = $pdo->prepare("
SELECT id, frequency, custom_days, start_date, end_date
FROM habits
WHERE user_id = ? AND (end_date IS NULL OR end_date >= ?) AND start_date <= ?
");
$stmt->execute([$user_id, $yesterday, $yesterday]);
$habits = $stmt->fetchAll();
foreach ($habits as $habit) {
// Check if habit should have been done yesterday
$should_have_done = false;
$day_of_week = date('N', strtotime($yesterday)); // 1=Monday, 7=Sunday
if ($habit['frequency'] === 'daily') {
$should_have_done = true;
} elseif ($habit['frequency'] === 'weekly') {
// Weekly habits are done on specific days
if (!empty($habit['custom_days'])) {
$custom_days = explode(',', $habit['custom_days']);
$should_have_done = in_array($day_of_week, $custom_days);
}
} elseif ($habit['frequency'] === 'custom' && !empty($habit['custom_days'])) {
$custom_days = explode(',', $habit['custom_days']);
$should_have_done = in_array($day_of_week, $custom_days);
}
// If habit should have been done yesterday but wasn't, mark as missed
if ($should_have_done) {
// Check if already has an entry for yesterday
$stmt = $pdo->prepare("SELECT id FROM habit_progress WHERE habit_id = ? AND progress_date = ?");
$stmt->execute([$habit['id'], $yesterday]);
if (!$stmt->fetch()) {
// No entry for yesterday, mark as missed
$stmt = $pdo->prepare("INSERT INTO habit_progress (habit_id, progress_date, completed) VALUES (?, ?, 0)");
$stmt->execute([$habit['id'], $yesterday]);
}
}
}
// Update last check date
if ($settings) {
$stmt = $pdo->prepare("UPDATE user_settings SET last_missed_check = ? WHERE user_id = ?");
$stmt->execute([$today, $user_id]);
} else {
$stmt = $pdo->prepare("INSERT INTO user_settings (user_id, last_missed_check) VALUES (?, ?)");
$stmt->execute([$user_id, $today]);
}
}