Skip to content

Commit

Permalink
[ENH] add functionality to send later scheduled sending
Browse files Browse the repository at this point in the history
  • Loading branch information
amaninyumu1 committed Jun 15, 2024
1 parent d7df56d commit 7aaffb2
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 9 deletions.
65 changes: 65 additions & 0 deletions modules/smtp/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,71 @@ function connect_to_smtp_server($address, $name, $port, $user, $pass, $tls, $ser
}
}

if (!hm_exists('get_schedule_date')) {
function get_schedule_date($format, $only_label = false) {
if ($format == 'later_in_day') {
$date_string = 'today 18:00';
$label = 'Later in the day';
} elseif ($format == 'tomorrow') {
$date_string = '+1 day 08:00';
$label = 'Tomorrow';
} elseif ($format == 'next_weekend') {
$date_string = 'next Saturday 08:00';
$label = 'Next weekend';
} elseif ($format == 'next_week') {
$date_string = 'next week 08:00';
$label = 'Next week';
} elseif ($format == 'next_month') {
$date_string = 'next month 08:00';
$label = 'Next month';
} else {
$date_string = $format;
$label = 'Certain date';
}
$time = strtotime($date_string);
if ($only_label) {
return [$label, date('D, H:i', $time)];
}
return date('D, d M Y H:i', $time);
}}

/**
* @subpackage imap/functions
*/
if (!hm_exists('schedule_formats')) {
function schedule_formats() {
$values = array(
'tomorrow',
'next_weekend',
'next_week',
'next_month'
);
if (date('H') <= 16) {
array_push($values, 'later_in_day');
}
return $values;
}}

if (!hm_exists('schedule_dropdown')) {
function schedule_dropdown($output, $schedule = false) {
$values = schedule_formats();

$txt = '<div class="dropdown d-inline-block">
<ul class="dropdown-menu" aria-labelledby="dropdownMenuSnooze">';
foreach ($values as $format) {
$labels = get_schedule_date($format, true);
$txt .= '<li><a href="#" class="snooze_helper dropdown-item d-flex justify-content-between gap-5" data-value="'.$format.'"><span>'.$output->trans($labels[0]).'</span> <span class="text-end">'.$labels[1].'</span></a></li>';
}
$txt .= '<li><hr class="dropdown-divider"></li>';
$txt .= '<li><label for="schedule_input_date" class="snooze_date_picker dropdown-item cursor-pointer">'.$output->trans('Pick a date').'</label>';
$txt .= '<input id="schedule_input_date" type="datetime-local" min="'.date('Y-m-d\Th:m').'" class="snooze_input_date" style="visibility: hidden; position: absolute; height: 0;">';
$txt .= '<input class="snooze_input" style="display:none;"></li>';
$txt .= '</ul></div>';

return $txt;
}}


if (!hm_exists('delete_smtp_server')) {
function delete_smtp_server($smtp_server_id) {
Hm_SMTP_List::del($smtp_server_id);
Expand Down
6 changes: 5 additions & 1 deletion modules/smtp/hm-mime-message.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ class Hm_MIME_Msg {
private $final_msg = '';

/* build mime message data */
function __construct($to, $subject, $body, $from, $html=false, $cc='', $bcc='', $in_reply_to_id='', $from_name='', $reply_to='') {
function __construct($to, $subject, $body, $from, $html=false, $cc='', $bcc='', $in_reply_to_id='', $from_name='', $reply_to='', $schedule='') {
if ($cc) {
$this->headers['Cc'] = $cc;
}
if ($schedule) {
$this->headers['X-Schedule'] = $schedule;
}

if ($in_reply_to_id) {
$this->headers['In-Reply-To'] = $in_reply_to_id;
}
Expand Down
96 changes: 90 additions & 6 deletions modules/smtp/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ public function process() {
}
}



/**
* @subpackage smtp/handler
*/
Expand Down Expand Up @@ -164,6 +166,7 @@ public function process() {
}
}


/**
* @subpackage smtp/handler
*/
Expand Down Expand Up @@ -273,6 +276,7 @@ public function process() {
$draft_id = array_key_exists('draft_id', $this->request->post) ? $this->request->post['draft_id'] : false;
$draft_notice = array_key_exists('draft_notice', $this->request->post) ? $this->request->post['draft_notice'] : false;
$uploaded_files = array_key_exists('uploaded_files', $this->request->post) ? $this->request->post['uploaded_files'] : false;
$schedule=array_key_exists('schedule', $this->request->post) ? $this->request->post['schedule'] : '';

if (array_key_exists('delete_uploaded_files', $this->request->post) && $this->request->post['delete_uploaded_files']) {
delete_uploaded_files($this->session, $draft_id);
Expand All @@ -287,7 +291,7 @@ public function process() {
}
$new_draft_id = save_imap_draft(array('draft_smtp' => $smtp, 'draft_to' => $to, 'draft_body' => $body,
'draft_subject' => $subject, 'draft_cc' => $cc, 'draft_bcc' => $bcc,
'draft_in_reply_to' => $inreplyto), $draft_id, $this->session,
'draft_in_reply_to' => $inreplyto, 'schedule'=>$schedule), $draft_id, $this->session,
$this, $this->cache, $uploaded_files);
if ($new_draft_id >= 0) {
if ($draft_notice) {
Expand Down Expand Up @@ -629,6 +633,30 @@ function get_mime_type($filename)
}
}

class Hm_Handler_process_schedule_sending extends Hm_Handler_Module
{
public function process()
{
// Check if the user has selected to send the email tomorrow morning at 08:00 AM
if(array_key_exists('send_tomorrow_morning', $this->request->post)) {
die("send_tomorrow_morning");
}
// Check if the user has selected to send the email send_today_afternoon at 1:00 PM
if(array_key_exists('send_today_afternoon', $this->request->post)) {
die("send_today_afternoon");
}
// Check if the user has selected to send the email schedule_sending
if(array_key_exists('schedule_sending', $this->request->post)) {
list($success, $form) = $this->process_form(array('send_date', 'send_time'));
if($success){
var_dump($this->request->post['send_date'] , $this->request->post['send_time']);
die();
}
}
}

}

/**
* @subpackage smtp/handler
*/
Expand Down Expand Up @@ -1186,11 +1214,57 @@ protected function output() {
}
}
}

$date = new DateTimeImmutable();
$Tomorrow_morning = "Send Tomorrow Morning {$date->modify('+1 day')->format('d F')} at 08:00 AM";
$afternoon=$date->setTime(13,00)->format('H:i:s');
if($date->format('H:i:s')>$afternoon){
$Send_afternoon="Send Tomorrow Afternoon {$date->modify('+1 day')->format('d F')} at 1:00 PM";
}else{
$Send_afternoon="Send Today Afternoon {$date->format('d F')} at 1:00 PM";
}

$res .= '</table>'.
smtp_server_dropdown($this->module_output(), $this, $recip, $selected_id).
'<button class="smtp_send_placeholder btn btn-primary mt-3" type="button" '.$send_disabled.'>'.$this->trans('Send').'</button><input class="smtp_send d-none" type="submit" value="'.$this->trans('Send').'" name="smtp_send"/>';
'<div class="btn-group">
<button class="smtp_send_placeholder btn btn-primary mt-3" type="button" '.$send_disabled.'>'.$this->trans('Send').'</button><input class="smtp_send d-none" type="submit" value="'.$this->trans('Send').'" name="smtp_send"/>
<button type="button" class="btn btn-primary mt-3 dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false" '.$send_disabled.'>
<span class="visually-hidden">Toggle Dropdown</span>
</button>
'.schedule_dropdown($this).'
</div>'.
'<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Choose a date and time</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="post" action="?page=compose">
<div class="form-floating mb-3">
<input type="date" class="form-control" id="send_date" name="send_date" placeholder="Date" required>
<label for="send_date">Date</label>
</div>
<div class="form-floating mb-3">
<input type="time" class="form-control" id="send_time" name="send_time" placeholder="Time" required>
<label for="send_time">Time</label>
</div>
<button type="submit" name="schedule_sending" class="btn btn-primary">'.$this->trans('Schedule sending').'</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
';
if ($this->get('list_path') && ($reply_type == 'reply' || $reply_type == 'reply_all')) {
$res .= '<input class="smtp_send_archive btn btn-primary mt-3" type="button" value="'.$this->trans('Send & Archive').'" name="smtp_send" '.$send_disabled.'/>';
}
Expand Down Expand Up @@ -1847,7 +1921,7 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache, $uploaded_files

$specials = get_special_folders($mod, $imap_profile['id']);

if (!array_key_exists('draft', $specials) || !$specials['draft']) {
if ((!array_key_exists('draft', $specials) || !$specials['draft']) && !array_key_exists('schedule', $atts)) {
Hm_Msgs::add('ERRThere is no draft directory configured for this account.');
return -1;
}
Expand All @@ -1865,7 +1939,8 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache, $uploaded_files
$atts['draft_bcc'],
'',
$name,
$atts['draft_in_reply_to']
$atts['draft_in_reply_to'],
$atts['schedule']
);

$mime->add_attachments($uploaded_files);
Expand All @@ -1874,8 +1949,17 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache, $uploaded_files
$msg = str_replace("\r\n", "\n", $mime->get_mime_msg());
$msg = str_replace("\n", "\r\n", $msg);
$msg = rtrim($msg)."\r\n";
$folder=!empty($atts['schedule']) ? 'Scheduled' : $specials['draft'];
if (!empty($atts['schedule'])) {
$folder ='Scheduled';
if (!count($imap->get_mailbox_status($folder))) {
$imap->create_mailbox($folder);
}
}else{
$folder = $specials['draft'];
}

if ($imap->append_start($specials['draft'], strlen($msg), false, true)) {
if ($imap->append_start($folder, strlen($msg), false, true)) {
$imap->append_feed($msg."\r\n");
if (!$imap->append_end()) {
Hm_Msgs::add('ERRAn error occurred saving the draft message');
Expand Down
7 changes: 7 additions & 0 deletions modules/smtp/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
add_handler('compose', 'load_smtp_servers_from_config', true, 'smtp', 'load_smtp_reply_to_details', 'after');
add_handler('compose', 'add_smtp_servers_to_page_data', true, 'smtp', 'load_smtp_servers_from_config', 'after');
add_handler('compose', 'process_compose_form_submit', true, 'smtp', 'load_smtp_servers_from_config', 'after');
add_handler('compose', 'process_schedule_sending', true, 'smtp', 'load_smtp_servers_from_config', 'after');
add_output('compose', 'compose_form_start', true, 'smtp', 'content_section_start', 'after');
add_output('compose', 'compose_form_draft_list', true, 'smtp', 'compose_form_start', 'before');
add_output('compose', 'compose_form_content', true, 'smtp', 'compose_form_start', 'after');
add_output('compose', 'compose_form_end', true, 'smtp', 'compose_form_content', 'after');
add_output('compose', 'compose_form_attach', true, 'smtp', 'compose_form_end', 'after');
add_handler('compose', 'load_smtp_is_imap_forward', true, 'smtp', 'load_user_data', 'after');


add_handler('functional_api', 'default_smtp_server', true, 'smtp');

add_handler('profiles', 'load_smtp_servers_from_config', true, 'smtp', 'load_user_data', 'after');
Expand Down Expand Up @@ -142,6 +144,11 @@
),
'allowed_post' => array(
'post_archive' => FILTER_VALIDATE_INT,
'send_tomorrow_morning' => FILTER_DEFAULT,
'send_today_afternoon' => FILTER_DEFAULT,
'schedule_sending' => FILTER_DEFAULT,
'send_date' => FILTER_DEFAULT,
'send_time' => FILTER_DEFAULT,
'attachment_id' => FILTER_DEFAULT,
'smtp_compose_type' => FILTER_VALIDATE_INT,
'new_smtp_name' => FILTER_DEFAULT,
Expand Down
5 changes: 3 additions & 2 deletions modules/smtp/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ var send_archive = function() {
document.getElementsByClassName("smtp_send_placeholder")[0].click();
}

var save_compose_state = function(no_files, notice) {
var save_compose_state = function(no_files, notice, schedule) {
var no_icon = true;
if (notice) {
no_icon = false;
Expand Down Expand Up @@ -151,6 +151,7 @@ var save_compose_state = function(no_files, notice) {
{'name': 'draft_in_reply_to', 'value': inreplyto},
{'name': 'delete_uploaded_files', 'value': no_files},
{'name': 'draft_to', 'value': to},
{'name': 'schedule', 'value': schedule},
{'name': 'uploaded_files', 'value': uploaded_files}],
function(res) {
$('.smtp_send_placeholder').prop('disabled', false);
Expand Down Expand Up @@ -437,7 +438,7 @@ $(function () {
}
if (hm_page_name() === 'compose') {
init_resumable_upload()

imap_setup_snooze()
var interval = Hm_Utils.get_from_global('compose_save_interval', 30);
Hm_Timer.add_job(function() { save_compose_state(); }, interval, true);
$('.draft_title').on("click", function() { $('.draft_list').toggle(); });
Expand Down

0 comments on commit 7aaffb2

Please sign in to comment.