/home/u764571690/domains/savitrfoundation.com/public_html/scholar/pages
Edit: /home/u764571690/domains/savitrfoundation.com/public_html/scholar/pages/tasks.php (71075B)
'/',
'domain' => '',
'secure' => false,
'httponly' => true,
'samesite' => 'Lax',
'lifetime' => 2592000
]);
session_start();
}
require_once __DIR__ . '/../db.php';
// ✅ PERFORMANCE: Local cache class for pages/cache directory
class LocalSimpleCache extends SimpleCache {
private static $cacheDir = __DIR__ . '/cache';
private static $defaultTTL = 300;
public static function init() {
if (!file_exists(self::$cacheDir)) {
@mkdir(self::$cacheDir, 0755, true);
}
}
public static function get($key) {
self::init();
$file = self::$cacheDir . '/' . md5($key) . '.cache';
if (!file_exists($file)) return false;
$data = @unserialize(file_get_contents($file));
if ($data === false) return false;
if (time() > $data['expires']) {
@unlink($file);
return false;
}
return $data['value'];
}
public static function set($key, $value, $ttl = null) {
self::init();
$ttl = $ttl ?? self::$defaultTTL;
$file = self::$cacheDir . '/' . md5($key) . '.cache';
$data = ['value' => $value, 'expires' => time() + $ttl, 'created' => time()];
$fp = @fopen($file, 'c+');
if ($fp === false) return @file_put_contents($file, serialize($data)) !== false;
$lockAcquired = false;
for ($i = 0; $i < 10; $i++) {
if (flock($fp, LOCK_EX | LOCK_NB)) {
$lockAcquired = true;
break;
}
usleep(500000);
}
if ($lockAcquired) {
ftruncate($fp, 0);
fwrite($fp, serialize($data));
flock($fp, LOCK_UN);
fclose($fp);
return true;
} else {
fclose($fp);
return @file_put_contents($file, serialize($data)) !== false;
}
}
public static function delete($key) {
self::init();
$file = self::$cacheDir . '/' . md5($key) . '.cache';
return @unlink($file);
}
}
if (!isset($_SESSION['user_logged_in']) || $_SESSION['user_logged_in'] !== true) {
header('Location: ../student');
exit();
}
$applicantId = (int)($_SESSION['applicant_id'] ?? 0);
$userId = $_SESSION['user_id'] ?? '';
$userName = $_SESSION['user_name'] ?? 'Student';
try {
$stmt = $pdo->prepare("
UPDATE user_task_completion utc
JOIN important_tasks t ON utc.task_id = t.id
SET utc.is_completed = 1,
utc.subscribed = 1,
utc.completed_at = NOW()
WHERE utc.user_id = ?
AND utc.is_completed = 0
AND utc.visit_count >= 5
AND utc.verification_scheduled_at IS NOT NULL
AND utc.verification_scheduled_at <= NOW()
AND (t.task_type = 'youtube_channel' OR t.task_type = 'instagram_page' OR t.task_type = 'google_review')
");
$stmt->execute([$userId]);
} catch (Exception $e) {
error_log("Auto-completion error: " . $e->getMessage());
}
// ✅ PERFORMANCE: Cache tasks list for 2 minutes (reduced for real-time updates)
$tasksCacheKey = 'tasks_active_' . $userId;
$tasks = LocalSimpleCache::get($tasksCacheKey);
if ($tasks === false) {
try {
$stmt = $pdo->prepare("
SELECT t.*,
COALESCE(utc.is_completed, 0) as is_completed,
COALESCE(utc.video_watched, 0) as video_watched,
COALESCE(utc.video_liked, 0) as video_liked,
COALESCE(utc.comment_posted, 0) as comment_posted,
COALESCE(utc.subscribed, 0) as subscribed,
COALESCE(utc.visit_count, 0) as visit_count,
utc.last_visit_at,
utc.verification_scheduled_at,
utc.completed_at
FROM important_tasks t
LEFT JOIN user_task_completion utc ON t.id = utc.task_id AND utc.user_id = ?
WHERE t.is_active = 1
ORDER BY t.id DESC
");
$stmt->execute([$userId]);
$tasks = $stmt->fetchAll(PDO::FETCH_ASSOC);
LocalSimpleCache::set($tasksCacheKey, $tasks, 120); // Cache for 2 minutes (reduced for real-time updates)
} catch (Exception $e) {
$error_message = "Error loading tasks: " . $e->getMessage();
error_log($error_message);
$tasks = [];
}
}
// Handle task visit tracking
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'track_visit') {
// Clear any output before JSON
if (ob_get_level()) {
ob_clean();
}
header('Content-Type: application/json; charset=UTF-8');
$taskId = (int)($_POST['task_id'] ?? 0);
if ($taskId > 0) {
try {
// ✅ OPTIMIZED: Single query to get task type and update visit count
$stmt = $pdo->prepare("
SELECT task_type FROM important_tasks WHERE id = ?
");
$stmt->execute([$taskId]);
$taskType = $stmt->fetchColumn();
// Insert or update visit count
$stmt = $pdo->prepare("
INSERT INTO user_task_completion (user_id, task_id, visit_count, last_visit_at)
VALUES (?, ?, 1, NOW())
ON DUPLICATE KEY UPDATE
visit_count = visit_count + 1,
last_visit_at = NOW()
");
$stmt->execute([$userId, $taskId]);
// Get updated visit count in same query
$stmt = $pdo->prepare("
SELECT visit_count FROM user_task_completion WHERE user_id = ? AND task_id = ?
");
$stmt->execute([$userId, $taskId]);
$visitCount = $stmt->fetchColumn() ?: 0;
// If visit count >= 5 and task is subscribe/follow/review type, schedule verification
if ($visitCount >= 5 && ($taskType === 'youtube_channel' || $taskType === 'instagram_page' || $taskType === 'google_review')) {
$stmt = $pdo->prepare("
UPDATE user_task_completion
SET verification_scheduled_at = DATE_ADD(NOW(), INTERVAL 30 MINUTE)
WHERE user_id = ? AND task_id = ?
");
$stmt->execute([$userId, $taskId]);
}
// ✅ Clear cache when task is updated
LocalSimpleCache::delete('tasks_active_' . $userId);
echo json_encode(['success' => true, 'visit_count' => $visitCount]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid task ID']);
}
exit();
}
// Handle task completion update via AJAX
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
// Clear any output before JSON
if (ob_get_level()) {
ob_clean();
}
header('Content-Type: application/json; charset=UTF-8');
if ($_POST['action'] === 'get_visit_count') {
$taskId = (int)($_POST['task_id'] ?? 0);
if ($taskId > 0) {
try {
$stmt = $pdo->prepare("SELECT visit_count FROM user_task_completion WHERE user_id = ? AND task_id = ?");
$stmt->execute([$userId, $taskId]);
$visitCount = $stmt->fetchColumn() ?: 0;
echo json_encode(['success' => true, 'visit_count' => $visitCount]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid task ID']);
}
exit();
}
if ($_POST['action'] === 'check_completion') {
$taskId = (int)($_POST['task_id'] ?? 0);
if ($taskId > 0) {
try {
$stmt = $pdo->prepare("
SELECT visit_count, verification_scheduled_at, is_completed, task_type
FROM user_task_completion utc
JOIN important_tasks t ON utc.task_id = t.id
WHERE utc.user_id = ? AND utc.task_id = ?
");
$stmt->execute([$userId, $taskId]);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
if ($data && $data['visit_count'] >= 5 &&
($data['task_type'] === 'youtube_channel' || $data['task_type'] === 'instagram_page' || $data['task_type'] === 'google_review')) {
// Check if 30 minutes have passed since verification was scheduled
if ($data['verification_scheduled_at']) {
$scheduledTime = strtotime($data['verification_scheduled_at']);
$currentTime = time();
$minutesPassed = ($currentTime - $scheduledTime) / 60;
if ($minutesPassed >= 30 && !$data['is_completed']) {
// Mark as completed
$updateStmt = $pdo->prepare("
UPDATE user_task_completion
SET is_completed = 1, subscribed = 1, completed_at = NOW()
WHERE user_id = ? AND task_id = ?
");
$updateStmt->execute([$userId, $taskId]);
echo json_encode(['success' => true, 'is_completed' => true]);
} else {
echo json_encode(['success' => true, 'is_completed' => (bool)$data['is_completed']]);
}
} else {
echo json_encode(['success' => true, 'is_completed' => (bool)$data['is_completed']]);
}
} else {
echo json_encode(['success' => true, 'is_completed' => false]);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid task ID']);
}
exit();
}
if ($_POST['action'] === 'mark_complete') {
$taskId = (int)($_POST['task_id'] ?? 0);
if ($taskId > 0) {
try {
// Check if user has visited the task at least once
$stmt = $pdo->prepare("
SELECT visit_count FROM user_task_completion
WHERE user_id = ? AND task_id = ?
");
$stmt->execute([$userId, $taskId]);
$visitData = $stmt->fetch(PDO::FETCH_ASSOC);
$visitCount = $visitData ? (int)$visitData['visit_count'] : 0;
// If user hasn't visited the task, show warning
if ($visitCount === 0) {
echo json_encode([
'success' => false,
'error' => 'You have not completed this task. Please visit the task link first before marking it as complete.',
'visit_required' => true
]);
exit();
}
// Mark task as completed
$stmt = $pdo->prepare("
INSERT INTO user_task_completion (user_id, task_id, is_completed, completed_at, video_watched, video_liked, comment_posted, subscribed)
VALUES (?, ?, 1, NOW(), 1, 1, 1, 1)
ON DUPLICATE KEY UPDATE
is_completed = 1,
completed_at = NOW(),
video_watched = 1,
video_liked = 1,
comment_posted = 1,
subscribed = 1,
updated_at = CURRENT_TIMESTAMP
");
$stmt->execute([$userId, $taskId]);
// Clear cache
LocalSimpleCache::delete('tasks_active_' . $userId);
echo json_encode(['success' => true, 'message' => 'Task marked as completed']);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid task ID']);
}
exit();
}
if ($_POST['action'] === 'update_task_status') {
$taskId = (int)($_POST['task_id'] ?? 0);
$field = $_POST['field'] ?? '';
$value = (int)($_POST['value'] ?? 0);
if ($taskId > 0 && in_array($field, ['video_watched', 'video_liked', 'comment_posted', 'subscribed'])) {
try {
// Insert or update task completion
$stmt = $pdo->prepare("
INSERT INTO user_task_completion (user_id, task_id, $field)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE
$field = ?,
updated_at = CURRENT_TIMESTAMP
");
$stmt->execute([$userId, $taskId, $value, $value]);
// Check if all required actions are completed
$checkStmt = $pdo->prepare("
SELECT video_watched, video_liked, comment_posted, subscribed, task_type
FROM user_task_completion utc
JOIN important_tasks t ON utc.task_id = t.id
WHERE utc.user_id = ? AND utc.task_id = ?
");
$checkStmt->execute([$userId, $taskId]);
$taskData = $checkStmt->fetch(PDO::FETCH_ASSOC);
$isCompleted = false;
if ($taskData) {
if ($taskData['task_type'] === 'youtube_video') {
$isCompleted = $taskData['video_watched'] == 1 &&
$taskData['video_liked'] == 1 &&
$taskData['comment_posted'] == 1;
} elseif ($taskData['task_type'] === 'youtube_channel') {
$isCompleted = $taskData['subscribed'] == 1;
} elseif ($taskData['task_type'] === 'instagram_post') {
$isCompleted = $taskData['video_watched'] == 1 &&
$taskData['video_liked'] == 1 &&
$taskData['comment_posted'] == 1;
} elseif ($taskData['task_type'] === 'instagram_page') {
$isCompleted = $taskData['subscribed'] == 1;
} elseif ($taskData['task_type'] === 'google_review') {
$isCompleted = $taskData['subscribed'] == 1; // Using subscribed field for review completion
}
}
// Update completion status
if ($isCompleted) {
$updateStmt = $pdo->prepare("
UPDATE user_task_completion
SET is_completed = 1, completed_at = CURRENT_TIMESTAMP
WHERE user_id = ? AND task_id = ?
");
$updateStmt->execute([$userId, $taskId]);
// ✅ Clear cache when task is completed
LocalSimpleCache::delete('tasks_active_' . $userId);
}
echo json_encode(['success' => true, 'is_completed' => $isCompleted]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid parameters']);
}
exit();
}
if ($_POST['action'] === 'refresh_task_status') {
$taskId = (int)($_POST['task_id'] ?? 0);
if ($taskId > 0) {
try {
// Get current task status from database
$stmt = $pdo->prepare("
SELECT
COALESCE(utc.is_completed, 0) as is_completed,
COALESCE(utc.visit_count, 0) as visit_count
FROM important_tasks t
LEFT JOIN user_task_completion utc ON t.id = utc.task_id AND utc.user_id = ?
WHERE t.id = ?
");
$stmt->execute([$userId, $taskId]);
$taskStatus = $stmt->fetch(PDO::FETCH_ASSOC);
if ($taskStatus) {
// Clear cache to force refresh
LocalSimpleCache::delete('tasks_active_' . $userId);
echo json_encode([
'success' => true,
'is_completed' => (bool)$taskStatus['is_completed'],
'visit_count' => (int)$taskStatus['visit_count']
]);
} else {
echo json_encode(['success' => false, 'error' => 'Task not found']);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
} else {
// Refresh all tasks status
try {
// Clear cache
LocalSimpleCache::delete('tasks_active_' . $userId);
// Get all tasks with current status
$stmt = $pdo->prepare("
SELECT
t.id,
COALESCE(utc.is_completed, 0) as is_completed,
COALESCE(utc.visit_count, 0) as visit_count
FROM important_tasks t
LEFT JOIN user_task_completion utc ON t.id = utc.task_id AND utc.user_id = ?
WHERE t.is_active = 1
");
$stmt->execute([$userId]);
$allTasksStatus = $stmt->fetchAll(PDO::FETCH_ASSOC);
$statusMap = [];
foreach ($allTasksStatus as $task) {
$statusMap[$task['id']] = [
'is_completed' => (bool)$task['is_completed'],
'visit_count' => (int)$task['visit_count']
];
}
echo json_encode(['success' => true, 'tasks' => $statusMap]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
}
exit();
}
}
?>
Important Tasks - Student Dashboard - Savitr Foundation Scholarship
Welcome,
Scholar ID:
Important Tasks
How to Complete Tasks:
YouTube Videos: Click "Watch Video & Comment Your ID" to watch the full video and comment with your Scholar ID ().
Instagram Videos: Click "Watch Video & Comment Your ID" to watch the full video and comment with your Scholar ID ().
YouTube/Instagram Channels/Pages: Click "Open Task" and subscribe/follow. हम 30 मिनट में verify करेंगे और task automatically complete हो जाएगा।
Google Reviews: Click "Leave Google Review" to open Google Maps/Google Business page. Leave a review with your Scholar ID (). हम 30 मिनट में verify करेंगे और task automatically complete हो जाएगा।
No tasks available at the moment.
Check back later for new tasks!
Task Type
Task Detail
Task Link
Status
'YouTube Video',
'youtube_channel' => 'YouTube Channel',
'instagram_post' => 'Instagram Post',
'instagram_page' => 'Instagram Page',
'google_review' => 'Google Review'
];
echo $typeNames[$task['task_type']] ?? $task['task_type'];
?>
Watch the full video and comment your Scholar ID ()
Watch the full video and comment your Scholar ID ()
Subscribe/Follow the channel/page
Leave a Google Review with your Scholar ID ()
Watch Video & Comment Your ID
Watch Video & Comment Your ID
Leave Google Review
Open Task
Mark as Complete