From e6b7ec1e8fc0e48f16c5a796bcd9d184c266228f Mon Sep 17 00:00:00 2001 From: AdityaPawar6174 Date: Mon, 26 May 2025 18:28:47 +0530 Subject: [PATCH 1/2] Implementation of Task Remainder System with Email Features --- src/cron.php | 5 +- src/functions.php | 331 ++++++++++++++++++++++++---------- src/index.php | 175 ++++++++++++++---- src/pending_subscriptions.txt | 3 +- src/setup_cron.sh | 10 + src/subscribers.txt | 3 + src/tasks.txt | 5 +- src/unsubscribe.php | 67 ++++++- src/verify.php | 70 ++++++- 9 files changed, 529 insertions(+), 140 deletions(-) diff --git a/src/cron.php b/src/cron.php index 0e47a2a..7dd25d7 100644 --- a/src/cron.php +++ b/src/cron.php @@ -1,5 +1,6 @@ \ No newline at end of file diff --git a/src/functions.php b/src/functions.php index f770d6c..d04c2d5 100644 --- a/src/functions.php +++ b/src/functions.php @@ -1,113 +1,260 @@ $id, + 'name' => $name, + 'completed' => $completed + ]; + } + } + + return $tasks; } -/** - * Marks a task as completed or uncompleted - * - * @param string $task_id The ID of the task to mark. - * @param bool $is_completed True to mark as completed, false to mark as uncompleted. - * @return bool True on success, false on failure - */ -function markTaskAsCompleted( string $task_id, bool $is_completed ): bool { - $file = __DIR__ . '/tasks.txt'; - // TODO: Implement this function + +function markTaskAsCompleted($task_id, $is_completed) { + $tasks = getAllTasks(); + $output = ''; + foreach ($tasks as $task) { + $completed = ($task['id'] == $task_id) ? $is_completed : $task['completed']; + $output .= "{$task['id']}|{$task['name']}|$completed\n"; + } + file_put_contents('tasks.txt', $output); } -/** - * Deletes a task from the task list - * - * @param string $task_id The ID of the task to delete. - * @return bool True on success, false on failure. - */ -function deleteTask( string $task_id ): bool { - $file = __DIR__ . '/tasks.txt'; - // TODO: Implement this function +function deleteTask($task_id) { + $tasks = getAllTasks(); + $output = ''; + foreach ($tasks as $task) { + if ($task['id'] !== $task_id) { + $output .= "{$task['id']}|{$task['name']}|{$task['completed']}\n"; + } + } + file_put_contents('tasks.txt', $output); } -/** - * Generates a 6-digit verification code - * - * @return string The generated verification code. - */ -function generateVerificationCode(): string { - // TODO: Implement this function +function generateVerificationCode() { + return str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT); } -/** - * Subscribe an email address to task notifications. - * - * Generates a verification code, stores the pending subscription, - * and sends a verification email to the subscriber. - * - * @param string $email The email address to subscribe. - * @return bool True if verification email sent successfully, false otherwise. - */ -function subscribeEmail( string $email ): bool { - $file = __DIR__ . '/pending_subscriptions.txt'; - // TODO: Implement this function +// function subscribeEmail($email) { +// $email = trim($email); + +// if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { +// return "Invalid email address."; +// } + +// // Checks if already subscribed +// if (file_exists('subscribers.txt')) { +// $subscribers = file('subscribers.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); +// if (in_array($email, $subscribers)) { +// return "Email is already subscribed."; +// } +// } + + +// if (file_exists('pending_subscriptions.txt')) { +// $pending = file('pending_subscriptions.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); +// foreach ($pending as $line) { +// $parts = explode('|', trim($line)); +// if (count($parts) === 2) { +// list($pendingEmail, $code) = $parts; +// if ($pendingEmail === $email) { +// return "Verification already pending for this email."; +// } +// } +// } +// } + + +// $code = generateVerificationCode(); +// file_put_contents('pending_subscriptions.txt', "$email|$code\n", FILE_APPEND); + +// // Sending verification email +// $verification_link = "http://localhost/task-scheduler-AdityaPawar6174/src/verify.php?email=" . urlencode($email) . "&code=$code"; + +// $subject = "Verify subscription to Task Planner"; +// $message = " +//

Click the link below to verify your subscription to Task Planner:

+//

Verify Subscription

+// "; +// $headers = "MIME-Version: 1.0\r\n"; +// $headers .= "Content-type:text/html;charset=UTF-8\r\n"; +// $headers .= "From: no-reply@example.com\r\n"; + +// mail($email, $subject, $message, $headers); + +// return "Verification email sent."; +// } + +function subscribeEmail($email) { + $code = rand(100000, 999999); + + // Prevent duplicate pending subscriptions + if (file_exists('pending_subscriptions.txt')) { + $pending = file('pending_subscriptions.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($pending as $line) { + $parts = explode('|', trim($line)); + if (count($parts) < 2) continue; + list($pendingEmail, $pendingCode) = $parts; + if ($pendingEmail === $email) { + return "Verification already pending for this email."; + } + } + } + + // Save to pending + file_put_contents('pending_subscriptions.txt', "$email|$code\n", FILE_APPEND); + + // Verification link + $encodedEmail = urlencode($email); + $verificationLink = "http://localhost/task-scheduler-AdityaPawar6174/src/verify.php?email=$encodedEmail&code=$code"; + + // HTML message + $subject = "Verify Your Task Scheduler Subscription"; + $message = " + + +

Confirm Your Subscription

+

Thank you for subscribing to Task Scheduler reminders.

+

Please click the link below to verify your email:

+ Verify My Email +

If you didn’t request this, you can ignore this email.

+ + + "; + + // Headers + $headers = "MIME-Version: 1.0\r\n"; + $headers .= "Content-type: text/html; charset=UTF-8\r\n"; + $headers .= "From: Task Scheduler \r\n"; + + mail($email, $subject, $message, $headers); + + return true; } -/** - * Verifies an email subscription - * - * @param string $email The email address to verify. - * @param string $code The verification code. - * @return bool True on success, false on failure. - */ -function verifySubscription( string $email, string $code ): bool { - $pending_file = __DIR__ . '/pending_subscriptions.txt'; - $subscribers_file = __DIR__ . '/subscribers.txt'; - // TODO: Implement this function + + +function verifySubscription($email, $code) { + if (!file_exists('pending_subscriptions.txt')) return false; + + $lines = file('pending_subscriptions.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $new_lines = []; + $is_verified = false; + + foreach ($lines as $line) { + $parts = explode('|', trim($line)); + if (count($parts) === 2) { + list($pendingEmail, $pendingCode) = $parts; + if ($pendingEmail === $email && $pendingCode === $code) { + // Move to verified + file_put_contents('subscribers.txt', "$email\n", FILE_APPEND); + $is_verified = true; + } else { + $new_lines[] = $line; + } + } else { + + } + } + + file_put_contents('pending_subscriptions.txt', implode("\n", $new_lines) . "\n"); + + return $is_verified; } -/** - * Unsubscribes an email from the subscribers list - * - * @param string $email The email address to unsubscribe. - * @return bool True on success, false on failure. - */ -function unsubscribeEmail( string $email ): bool { - $subscribers_file = __DIR__ . '/subscribers.txt'; - // TODO: Implement this function + + +function unsubscribeEmail($email) { + if (!file_exists('subscribers.txt')) return; + + $subscribers = file('subscribers.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $subscribers = array_filter($subscribers, fn($sub) => trim($sub) !== $email); + + file_put_contents('subscribers.txt', implode("\n", $subscribers) . "\n"); } -/** - * Sends task reminders to all subscribers - * Internally calls sendTaskEmail() for each subscriber - */ -function sendTaskReminders(): void { - $subscribers_file = __DIR__ . '/subscribers.txt'; - // TODO: Implement this function + + +function sendTaskReminders() { + $tasks = getAllTasks(); + $pending_tasks = array_filter($tasks, fn($task) => !$task['completed']); + + if (empty($pending_tasks)) return; + + if (!file_exists('subscribers.txt')) return; + + $subscribers = file('subscribers.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($subscribers as $email) { + sendTaskEmail($email, $pending_tasks); + } } -/** - * Sends a task reminder email to a subscriber with pending tasks. - * - * @param string $email The email address of the subscriber. - * @param array $pending_tasks Array of pending tasks to include in the email. - * @return bool True if email was sent successfully, false otherwise. - */ -function sendTaskEmail( string $email, array $pending_tasks ): bool { - $subject = 'Task Planner - Pending Tasks Reminder'; - // TODO: Implement this function + + +function sendTaskEmail($email, $pending_tasks) { + $subject = "Task Planner - Pending Tasks Reminder"; + + // Build HTML task list + $taskListHtml = ""; + + // Unsubscribe link + $encodedEmail = urlencode(base64_encode($email)); + $unsubscribeLink = "http://localhost/task-scheduler-AdityaPawar6174/src/unsubscribe.php?email={$encodedEmail}"; + + // Complete HTML message + $message = " + + + Task Reminder + + +

Pending Tasks Reminder

+

Here are your current pending tasks:

+ $taskListHtml +

+ Unsubscribe from notifications +

+ + + "; + + // Proper HTML headers + $headers = "MIME-Version: 1.0\r\n"; + $headers .= "Content-type: text/html; charset=UTF-8\r\n"; + $headers .= "From: Task Planner \r\n"; + + // Send email + mail($email, $subject, $message, $headers); } + diff --git a/src/index.php b/src/index.php index 7e8c0e6..3b09e4e 100644 --- a/src/index.php +++ b/src/index.php @@ -1,44 +1,157 @@ ` elements or other elements to style the page. Just ensure that the following elements retain their provided IDs. +$tasks = getAllTasks(); ?> - - + + - - + + Task Scheduler + + +

Task Scheduler

- -
- - - -
- - -
    - -
  • - - -
  • -
- - -
- - -
+ +
+ + +
- + +
    + +
  • +
    + + + > +
    + +
    + + +
    +
  • + +
+ +

Subscribe to Email Reminders

+
+ + +
+ + $email_message

"; ?> + diff --git a/src/pending_subscriptions.txt b/src/pending_subscriptions.txt index 7a980d0..7b3a26c 100644 --- a/src/pending_subscriptions.txt +++ b/src/pending_subscriptions.txt @@ -1 +1,2 @@ -// Store the data in JSON format. -- Single entry format : { email: { code: 'xxxxx' } } +Abhinav@gmail.com|873240 +xyz@gmail.com|183143 diff --git a/src/setup_cron.sh b/src/setup_cron.sh index e69de29..671b82a 100644 --- a/src/setup_cron.sh +++ b/src/setup_cron.sh @@ -0,0 +1,10 @@ +PHP_PATH=$(which php) +CRON_PATH=$(realpath cron.php) +CRON_JOB="0 * * * * $PHP_PATH $CRON_PATH" + +crontab -l 2>/dev/null | grep -v "cron.php" > mycron +echo "$CRON_JOB" >> mycron +crontab mycron +rm mycron + +echo "Cron job installed: Runs every hour to send task reminders..." diff --git a/src/subscribers.txt b/src/subscribers.txt index e69de29..44f3408 100644 --- a/src/subscribers.txt +++ b/src/subscribers.txt @@ -0,0 +1,3 @@ +yash@gmail.com +Aditya@gmail.com +vikas@gmail.com \ No newline at end of file diff --git a/src/tasks.txt b/src/tasks.txt index 64c42c7..ff2d46b 100644 --- a/src/tasks.txt +++ b/src/tasks.txt @@ -1 +1,4 @@ -// Store the data in JSON format. +68345dd161dd2|Read Books...|1 +68345df865750|get your groceries|0 +68345e19c5ab2|Go to Saloon|1 +68345e4983efb|Have Capachino at Starbucks...!!!|0 diff --git a/src/unsubscribe.php b/src/unsubscribe.php index 61fe6d4..920f481 100644 --- a/src/unsubscribe.php +++ b/src/unsubscribe.php @@ -1,18 +1,73 @@ - + - + + Unsubscribe + - -

Unsubscribe from Task Updates

- +

Unsubscribed

+

+ Back to Task Scheduler diff --git a/src/verify.php b/src/verify.php index 4209663..cd5eba9 100644 --- a/src/verify.php +++ b/src/verify.php @@ -1,18 +1,74 @@ - + - + + Email Verification + + + - -

Subscription Verification

- +

Email Verification

+

+ Go Back to Task Scheduler - \ No newline at end of file + From e5708f40833c7676113953bf28cbd5949df11d37 Mon Sep 17 00:00:00 2001 From: AdityaPawar6174 Date: Mon, 26 May 2025 18:35:23 +0530 Subject: [PATCH 2/2] minor updates in the functions.php --- src/functions.php | 49 ----------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/src/functions.php b/src/functions.php index d04c2d5..3cdb05b 100644 --- a/src/functions.php +++ b/src/functions.php @@ -62,55 +62,6 @@ function generateVerificationCode() { return str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT); } -// function subscribeEmail($email) { -// $email = trim($email); - -// if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { -// return "Invalid email address."; -// } - -// // Checks if already subscribed -// if (file_exists('subscribers.txt')) { -// $subscribers = file('subscribers.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); -// if (in_array($email, $subscribers)) { -// return "Email is already subscribed."; -// } -// } - - -// if (file_exists('pending_subscriptions.txt')) { -// $pending = file('pending_subscriptions.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); -// foreach ($pending as $line) { -// $parts = explode('|', trim($line)); -// if (count($parts) === 2) { -// list($pendingEmail, $code) = $parts; -// if ($pendingEmail === $email) { -// return "Verification already pending for this email."; -// } -// } -// } -// } - - -// $code = generateVerificationCode(); -// file_put_contents('pending_subscriptions.txt', "$email|$code\n", FILE_APPEND); - -// // Sending verification email -// $verification_link = "http://localhost/task-scheduler-AdityaPawar6174/src/verify.php?email=" . urlencode($email) . "&code=$code"; - -// $subject = "Verify subscription to Task Planner"; -// $message = " -//

Click the link below to verify your subscription to Task Planner:

-//

Verify Subscription

-// "; -// $headers = "MIME-Version: 1.0\r\n"; -// $headers .= "Content-type:text/html;charset=UTF-8\r\n"; -// $headers .= "From: no-reply@example.com\r\n"; - -// mail($email, $subject, $message, $headers); - -// return "Verification email sent."; -// } function subscribeEmail($email) { $code = rand(100000, 999999);